From 3aa3212fea10e3a1a2dcfd80368e6eb5a7031f66 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 31 Oct 2023 14:58:15 -0400 Subject: [PATCH 001/167] Documenting GC optimization (#672) --- .../main/java/org/roaringbitmap/FastAggregation.java | 9 +++++++++ .../roaringbitmap/buffer/BufferFastAggregation.java | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java b/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java index f1806d4e0..ef8695add 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java @@ -397,6 +397,9 @@ public static RoaringBitmap workShyAnd(long[] buffer, RoaringBitmap... bitmaps) Arrays.fill(words, -1L); Container tmp = new BitmapContainer(words, -1); for (Container container : slice) { + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) Container and = tmp.iand(container); if (and != tmp) { tmp = and; @@ -445,6 +448,9 @@ private static int workShyAndCardinality(RoaringBitmap... bitmaps) { continue; } Container container = bitmap.highLowContainer.getContainerAtIndex(index); + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) Container and = tmp.iand(container); if (and != tmp) { tmp = and; @@ -553,6 +559,9 @@ public static RoaringBitmap workAndMemoryShyAnd(long[] buffer, RoaringBitmap... continue; } Container container = bitmap.highLowContainer.getContainerAtIndex(idx); + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) Container and = tmp.iand(container); if (and != tmp) { tmp = and; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java index 7d3ef7c4b..fb8154fe5 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java @@ -478,6 +478,9 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, Arrays.fill(words, -1L); MappeableContainer tmp = new MappeableBitmapContainer(LongBuffer.wrap(words), -1); for (MappeableContainer container : slice) { + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) MappeableContainer and = tmp.iand(container); if (and != tmp) { tmp = and; @@ -560,6 +563,9 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, Arrays.fill(words, -1L); MappeableContainer tmp = new MappeableBitmapContainer(LongBuffer.wrap(words), -1); for (MappeableContainer container : slice) { + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) MappeableContainer and = tmp.iand(container); if (and != tmp) { tmp = and; @@ -620,6 +626,9 @@ private static int workShyAndCardinality(ImmutableRoaringBitmap... bitmaps) { continue; } MappeableContainer container = bitmap.highLowContainer.getContainerAtIndex(index); + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) MappeableContainer and = tmp.iand(container); if (and != tmp) { tmp = and; @@ -738,6 +747,9 @@ public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer, continue; } MappeableContainer container = bitmap.highLowContainer.getContainerAtIndex(idx); + // We only assign to 'tmp' when 'tmp != tmp.iand(container)' + // as a garbage-collection optimization: we want to avoid + // the write barrier. (Richard Startin) MappeableContainer and = tmp.iand(container); if (and != tmp) { tmp = and; From e1253a4f70d0d3b3b01e0c424f5397d263a9397e Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 14:57:56 +0100 Subject: [PATCH 002/167] Counting new capacity of RunContainer unified (#674) * common routine for counting new capacity in RunContainer * common routine for counting new capacity in MappeableArrayContainer * common routine for counting new capacity in MappeableRunContainer * common routine for counting new capacity in ArrayContainer * checkstyle --- .../org/roaringbitmap/ArrayContainer.java | 18 +++--- .../java/org/roaringbitmap/RunContainer.java | 47 ++++++---------- .../buffer/MappeableArrayContainer.java | 13 +++-- .../buffer/MappeableRunContainer.java | 55 ++++++++++--------- .../org/roaringbitmap/TestRunContainer.java | 2 +- 5 files changed, 62 insertions(+), 73 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index c7ffaff12..f52952ee1 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -595,10 +595,7 @@ private void increaseCapacity() { // temporarily allow an illegally large size, as long as the operation creating // the illegal container does not return it. private void increaseCapacity(boolean allowIllegalSize) { - int newCapacity = (this.content.length == 0) ? DEFAULT_INIT_SIZE - : this.content.length < 64 ? this.content.length * 2 - : this.content.length < 1067 ? this.content.length * 3 / 2 - : this.content.length * 5 / 4; + int newCapacity = computeCapacity(this.content.length); // never allocate more than we will ever need if (newCapacity > ArrayContainer.DEFAULT_MAX_SIZE && !allowIllegalSize) { newCapacity = ArrayContainer.DEFAULT_MAX_SIZE; @@ -610,13 +607,14 @@ private void increaseCapacity(boolean allowIllegalSize) { } this.content = Arrays.copyOf(this.content, newCapacity); } - + private int computeCapacity(int oldCapacity) { + return oldCapacity == 0 ? DEFAULT_INIT_SIZE + : oldCapacity < 64 ? oldCapacity * 2 + : oldCapacity < 1024 ? oldCapacity * 3 / 2 + : oldCapacity * 5 / 4; + } private int calculateCapacity(int min) { - int newCapacity = - (this.content.length == 0) ? DEFAULT_INIT_SIZE - : this.content.length < 64 ? this.content.length * 2 - : this.content.length < 1024 ? this.content.length * 3 / 2 - : this.content.length * 5 / 4; + int newCapacity = computeCapacity(this.content.length); if (newCapacity < min) { newCapacity = min; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index 5542ecfbb..c63b46919 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -871,19 +871,7 @@ private Container convertToLazyBitmapIfNeeded() { // Push all values length to the end of the array (resize array if needed) private void copyToOffset(int offset) { - final int minCapacity = 2 * (offset + nbrruns); - if (valueslength.length < minCapacity) { - // expensive case where we need to reallocate - int newCapacity = valueslength.length; - while (newCapacity < minCapacity) { - newCapacity = (newCapacity == 0) ? DEFAULT_INIT_SIZE - : newCapacity < 64 ? newCapacity * 2 - : newCapacity < 1024 ? newCapacity * 3 / 2 : newCapacity * 5 / 4; - } - char[] newvalueslength = new char[newCapacity]; - copyValuesLength(this.valueslength, 0, newvalueslength, offset, nbrruns); - this.valueslength = newvalueslength; - } else { + if (!ensureCapacity(offset, 2 * (offset + nbrruns))) { // efficient case where we just copy copyValuesLength(this.valueslength, 0, this.valueslength, offset, nbrruns); } @@ -915,19 +903,19 @@ public void deserialize(DataInput in) throws IOException { } // not actually used anywhere, but potentially useful - void ensureCapacity(int minNbRuns) { + boolean ensureCapacity(int offset, int minNbRuns) { final int minCapacity = 2 * minNbRuns; if (valueslength.length < minCapacity) { int newCapacity = valueslength.length; - while (newCapacity < minCapacity) { - newCapacity = (newCapacity == 0) ? DEFAULT_INIT_SIZE - : newCapacity < 64 ? newCapacity * 2 - : newCapacity < 1024 ? newCapacity * 3 / 2 : newCapacity * 5 / 4; + while(newCapacity < minCapacity) { + newCapacity = computeCapacity(newCapacity); } char[] nv = new char[newCapacity]; - copyValuesLength(valueslength, 0, nv, 0, nbrruns); + copyValuesLength(valueslength, 0, nv, offset, nbrruns); valueslength = nv; + return true; } + return false; } @Override @@ -1244,17 +1232,13 @@ private Container ilazyorToRun(ArrayContainer x) { return convertToLazyBitmapIfNeeded(); } - private void increaseCapacity() { - int newCapacity = (valueslength.length == 0) ? DEFAULT_INIT_SIZE - : valueslength.length < 64 ? valueslength.length * 2 - : valueslength.length < 1024 ? valueslength.length * 3 / 2 - : valueslength.length * 5 / 4; - char[] nv = new char[newCapacity]; - System.arraycopy(valueslength, 0, nv, 0, 2 * nbrruns); - valueslength = nv; + private int computeCapacity(int oldCapacity) { + return oldCapacity == 0 ? DEFAULT_INIT_SIZE + : oldCapacity < 64 ? oldCapacity * 2 + : oldCapacity < 1024 ? oldCapacity * 3 / 2 + : oldCapacity * 5 / 4; } - private void incrementLength(int index) { valueslength[2 * index + 1]++; } @@ -1884,7 +1868,10 @@ public Container limit(int maxcardinality) { private void makeRoomAtIndex(int index) { if (2 * (nbrruns + 1) > valueslength.length) { - increaseCapacity(); + int newCapacity = computeCapacity(valueslength.length); + char[] newValuesLength = new char[newCapacity]; + copyValuesLength(valueslength, 0, newValuesLength, 0, nbrruns); + valueslength = newValuesLength; } copyValuesLength(valueslength, index, valueslength, index + 1, nbrruns - index); nbrruns++; @@ -2198,7 +2185,7 @@ void smartAppend(char start, char length) { if ((nbrruns == 0) || ((start) > (oldend = (getValue(nbrruns - 1)) + (getLength(nbrruns - 1))) + 1)) { // we add a new one - ensureCapacity(nbrruns + 1); + ensureCapacity(0, nbrruns + 1); valueslength[2 * nbrruns] = start; valueslength[2 * nbrruns + 1] = length; nbrruns++; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index f86dc6bb0..436d0b2b0 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -733,9 +733,7 @@ private void increaseCapacity() { // the illegal container does not return it. // not thread safe! private void increaseCapacity(boolean allowIllegalSize) { - int len = this.content.limit(); - int newCapacity = (len == 0) ? DEFAULT_INIT_SIZE - : len < 64 ? len * 2 : this.content.limit() < 1067 ? len * 3 / 2 : len * 5 / 4; + int newCapacity = calculateCapacity(); // do not allocate more than we will ever need if (newCapacity > MappeableArrayContainer.DEFAULT_MAX_SIZE && !allowIllegalSize) { newCapacity = MappeableArrayContainer.DEFAULT_MAX_SIZE; @@ -751,10 +749,15 @@ private void increaseCapacity(boolean allowIllegalSize) { this.content = newContent; } - private int calculateCapacity(int min){ + private int calculateCapacity() { int len = this.content.limit(); int newCapacity = (len == 0) ? DEFAULT_INIT_SIZE - : len < 64 ? len * 2 : len < 1024 ? len * 3 / 2 : len * 5 / 4; + : len < 64 ? len * 2 : len < 1067 ? len * 3 / 2 : len * 5 / 4; + return newCapacity; + } + + private int calculateCapacity(int min){ + int newCapacity = calculateCapacity(); if (newCapacity < min) { newCapacity = min; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index 3c29a2689..d9d9ae21d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -14,6 +14,7 @@ import java.nio.CharBuffer; import java.util.Arrays; import java.util.Iterator; +import java.util.Optional; import static java.nio.ByteOrder.LITTLE_ENDIAN; import static org.roaringbitmap.Util.*; @@ -762,24 +763,35 @@ private MappeableContainer convertToLazyBitmapIfNeeded() { // Push all values length to the end of the array (resize array if needed) private void copyToOffset(int offset) { - final int minCapacity = 2 * (offset + nbrruns); - if (valueslength.capacity() < minCapacity) { + int minCapacity = 2 * (offset + nbrruns); + Optional newvalueslength = computeNewCapacity(valueslength.capacity(), minCapacity); + if (newvalueslength.isPresent()) { // expensive case where we need to reallocate - int newCapacity = valueslength.capacity(); - while (newCapacity < minCapacity) { - newCapacity = (newCapacity == 0) ? DEFAULT_INIT_SIZE - : newCapacity < 64 ? newCapacity * 2 - : newCapacity < 1024 ? newCapacity * 3 / 2 : newCapacity * 5 / 4; - } - CharBuffer newvalueslength = CharBuffer.allocate(newCapacity); - copyValuesLength(this.valueslength, 0, newvalueslength, offset, nbrruns); - this.valueslength = newvalueslength; + copyValuesLength(this.valueslength, 0, newvalueslength.get(), offset, nbrruns); + this.valueslength = newvalueslength.get(); } else { // efficient case where we just copy copyValuesLength(this.valueslength, 0, this.valueslength, offset, nbrruns); } } + private static Optional computeNewCapacity(int oldCapacity, int minCapacity) { + if (oldCapacity < minCapacity) { + int newCapacity = oldCapacity; + while ((newCapacity = computeNewCapacity(newCapacity)) < minCapacity) { + } + return Optional.of(CharBuffer.allocate(newCapacity)); + } + return Optional.empty(); + } + + private static int computeNewCapacity(int oldCapacity) { + return oldCapacity == 0 ? DEFAULT_INIT_SIZE + : oldCapacity < 64 ? oldCapacity * 2 + : oldCapacity < 1024 ? oldCapacity * 3 / 2 + : oldCapacity * 5 / 4; + } + private void copyValuesLength(CharBuffer src, int srcIndex, CharBuffer dst, int dstIndex, int length) { if (BufferUtil.isBackedBySimpleArray(src) && BufferUtil.isBackedBySimpleArray(dst)) { @@ -812,18 +824,11 @@ private void decrementValue() { // not thread safe! // not actually used anywhere, but potentially useful private void ensureCapacity(int minNbRuns) { - final int minCapacity = 2 * minNbRuns; - if (valueslength.capacity() < minCapacity) { - int newCapacity = valueslength.capacity(); - while (newCapacity < minCapacity) { - newCapacity = (newCapacity == 0) ? DEFAULT_INIT_SIZE - : newCapacity < 64 ? newCapacity * 2 - : newCapacity < 1024 ? newCapacity * 3 / 2 : newCapacity * 5 / 4; - } - final CharBuffer nv = CharBuffer.allocate(newCapacity); + Optional nv = computeNewCapacity(valueslength.capacity(), 2 * minNbRuns); + if (nv.isPresent()) { valueslength.rewind(); - nv.put(valueslength); - valueslength = nv; + nv.get().put(valueslength); + valueslength = nv.get(); } } @@ -1165,11 +1170,7 @@ private MappeableContainer ilazyorToRun(MappeableArrayContainer x) { // not thread safe! private void increaseCapacity() { - int newCapacity = (valueslength.capacity() == 0) ? DEFAULT_INIT_SIZE - : valueslength.capacity() < 64 ? valueslength.capacity() * 2 - : valueslength.capacity() < 1024 ? valueslength.capacity() * 3 / 2 - : valueslength.capacity() * 5 / 4; - + int newCapacity = computeNewCapacity(valueslength.capacity()); final CharBuffer nv = CharBuffer.allocate(newCapacity); valueslength.rewind(); nv.put(valueslength); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java index 3b376f5d3..8c354f075 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java @@ -3165,7 +3165,7 @@ public void ensureCapacity() { rc.add((char) 13); assertTrue(rc.contains((char) 13)); - rc.ensureCapacity(10); + rc.ensureCapacity(0, 10); assertTrue(rc.contains((char) 13)); } From 16f60700cb907c9d21598a1f1e40254bed2bc986 Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 17:16:59 +0100 Subject: [PATCH 003/167] factory method for array container deduplication (#667) --- .../java/org/roaringbitmap/BitSetUtil.java | 28 +++++++++++++++---- .../buffer/BufferBitSetUtil.java | 14 +--------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java index 211e8f78b..4d59b2bb4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java @@ -5,6 +5,8 @@ import java.nio.ByteOrder; import java.util.BitSet; +import static java.lang.Long.numberOfTrailingZeros; + /*** * @@ -20,8 +22,18 @@ public class BitSetUtil { // 64-bit // word - private static ArrayContainer arrayContainerOf(final int from, final int to, - final int cardinality, final long[] words) { + /** + * Creates array container's content char buffer. + * + * @param from first value of the range + * @param to last value of the range + * @param cardinality new buffer cardinality, expected to be less than 4096 and more than present + * values in given bitmap + * @param words bitmap + * @return array container's content char buffer + */ + public static char[] arrayContainerBufferOf(final int from, final int to, final int cardinality, + final long[] words) { // precondition: cardinality is max 4096 final char[] content = new char[cardinality]; int index = 0; @@ -29,12 +41,16 @@ private static ArrayContainer arrayContainerOf(final int from, final int to, for (int i = from, socket = 0; i < to; ++i, socket += Long.SIZE) { long word = words[i]; while (word != 0) { - long t = word & -word; - content[index++] = (char) (socket + Long.bitCount(t - 1)); - word ^= t; + content[index++] = (char) (socket + numberOfTrailingZeros(word)); + word &= (word - 1); } } - return new ArrayContainer(content); + return content; + } + + private static ArrayContainer arrayContainerOf(final int from, final int to, + final int cardinality, final long[] words) { + return new ArrayContainer(arrayContainerBufferOf(from, to, cardinality, words)); } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java index 78192dcc6..88917b901 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java @@ -10,8 +10,6 @@ import java.nio.LongBuffer; import java.util.BitSet; -import static java.lang.Long.numberOfTrailingZeros; - /*** * @@ -29,17 +27,7 @@ public class BufferBitSetUtil { private static MappeableArrayContainer arrayContainerOf(final int from, final int to, final int cardinality, final long[] words) { - // precondition: cardinality is max 4096 - final char[] content = new char[cardinality]; - int index = 0; - - for (int i = from, socket = 0; i < to; ++i, socket += Long.SIZE) { - long word = words[i]; - while (word != 0) { - content[index++] = (char) (socket + numberOfTrailingZeros(word)); - word &= (word - 1); - } - } + char[] content = BitSetUtil.arrayContainerBufferOf(from, to, cardinality, words); return new MappeableArrayContainer(CharBuffer.wrap(content), cardinality); } From 5883b227ba555f7310093574e06adf7ae49647b9 Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 18:37:12 +0100 Subject: [PATCH 004/167] Already invalid comments (#676) * already optimal mappable array constructors * container materialising already done --- RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java | 1 - 1 file changed, 1 deletion(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 18a3462f0..622811e12 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -389,7 +389,6 @@ public static int andCardinality(final RoaringBitmap x1, final RoaringBitmap x2) if (s1 == s2) { final Container c1 = x1.highLowContainer.getContainerAtIndex(pos1); final Container c2 = x2.highLowContainer.getContainerAtIndex(pos2); - // TODO: could be made faster if we did not have to materialize container answer += c1.andCardinality(c2); ++pos1; ++pos2; From ae1ff83c94c77449b20c7b67b165d1107390fa93 Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 18:41:15 +0100 Subject: [PATCH 005/167] Binary search on part of array only (#670) * binary search from start index * incorrect start index * binary search from start index also in MappeableRunContainer --- .../java/org/roaringbitmap/ArrayContainer.java | 14 ++++++++------ .../java/org/roaringbitmap/RunContainer.java | 8 ++++---- .../buffer/MappeableArrayContainer.java | 16 ++++++++++------ .../buffer/MappeableRunContainer.java | 8 ++++---- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index f52952ee1..eeec2021b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -112,7 +112,7 @@ public Container add(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = Util.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = Util.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -473,7 +473,7 @@ public Container iadd(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = Util.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = Util.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -637,7 +637,8 @@ public Container inot(final int firstOfRange, final int lastOfRange) { if (startIndex < 0) { startIndex = -startIndex - 1; } - int lastIndex = Util.unsignedBinarySearch(content, 0, cardinality, (char) (lastOfRange - 1)); + int lastIndex = Util.unsignedBinarySearch(content, startIndex, cardinality, + (char) (lastOfRange - 1)); if (lastIndex < 0) { lastIndex = -lastIndex - 1 - 1; } @@ -767,7 +768,7 @@ public Container iremove(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = Util.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = Util.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -884,7 +885,8 @@ public Container not(final int firstOfRange, final int lastOfRange) { if (startIndex < 0) { startIndex = -startIndex - 1; } - int lastIndex = Util.unsignedBinarySearch(content, 0, cardinality, (char) (lastOfRange - 1)); + int lastIndex = Util.unsignedBinarySearch(content, startIndex, cardinality, + (char) (lastOfRange - 1)); if (lastIndex < 0) { lastIndex = -lastIndex - 2; } @@ -1066,7 +1068,7 @@ public Container remove(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = Util.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = Util.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index c63b46919..0c16aa5f7 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -1074,8 +1074,8 @@ public Container iadd(int begin, int end) { } int bIndex = unsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = - unsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) (end - 1)); + int eIndex = unsignedInterleavedBinarySearch(this.valueslength, + bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); if (bIndex >= 0 && eIndex >= 0) { mergeValuesLength(bIndex, eIndex); @@ -1558,8 +1558,8 @@ public Container iremove(int begin, int end) { } int bIndex = unsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = - unsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) (end - 1)); + int eIndex = unsignedInterleavedBinarySearch(this.valueslength, + bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); // note, eIndex is looking for (end-1) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index 436d0b2b0..e7889cb08 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -130,7 +130,8 @@ public MappeableContainer add(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, + (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -588,7 +589,8 @@ public MappeableContainer iadd(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, + (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -782,7 +784,7 @@ public MappeableContainer inot(final int firstOfRange, final int lastOfRange) { startIndex = -startIndex - 1; } int lastIndex = - BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) (lastOfRange - 1)); + BufferUtil.unsignedBinarySearch(content, startIndex, cardinality, (char) (lastOfRange - 1)); if (lastIndex < 0) { lastIndex = -lastIndex - 1 - 1; } @@ -943,7 +945,8 @@ public MappeableContainer iremove(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, + (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -1073,7 +1076,7 @@ public MappeableContainer not(final int firstOfRange, final int lastOfRange) { startIndex = -startIndex - 1; } int lastIndex = - BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) (lastOfRange - 1)); + BufferUtil.unsignedBinarySearch(content, startIndex, cardinality, (char) (lastOfRange - 1)); if (lastIndex < 0) { lastIndex = -lastIndex - 2; } @@ -1379,7 +1382,8 @@ public MappeableContainer remove(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) (end - 1)); + int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, + (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index d9d9ae21d..632d6f53e 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -1008,8 +1008,8 @@ public MappeableContainer iadd(int begin, int end) { int bIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, - (char) (end - 1)); + int eIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, + bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); if (bIndex >= 0 && eIndex >= 0) { mergeValuesLength(bIndex, eIndex); @@ -1477,8 +1477,8 @@ public MappeableContainer iremove(int begin, int end) { int bIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, - (char) (end - 1)); + int eIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, + bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); if (bIndex >= 0) { if (eIndex < 0) { From 0be3468ed826e1c163e4280ba63e1f71f7519be6 Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 18:42:45 +0100 Subject: [PATCH 006/167] more effective buffer copying when limiting mappable container (#664) --- .../buffer/MappeableRunContainer.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index 632d6f53e..630231f01 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -1803,15 +1803,18 @@ public MappeableContainer limit(int maxcardinality) { break; } } - - CharBuffer newBuf = CharBuffer.allocate(2 * (r + 1)); - for (int i = 0; i < 2 * (r + 1); ++i) { - newBuf.put(valueslength.get(i)); // could be optimized + CharBuffer newBuf; + if (BufferUtil.isBackedBySimpleArray(valueslength)) { + char[] newArray = Arrays.copyOf(valueslength.array(), 2 * (r + 1)); + newBuf = CharBuffer.wrap(newArray); + } else { + newBuf = CharBuffer.allocate(2 * (r + 1)); + for (int i = 0; i < 2 * (r + 1); i++) { + newBuf.put(valueslength.get(i)); + } } MappeableRunContainer rc = new MappeableRunContainer(newBuf, r + 1); - - rc.setLength(r, - (char) ((rc.getLength(r)) - cardinality + maxcardinality)); + rc.setLength(r, (char) (rc.getLength(r) - cardinality + maxcardinality)); return rc; } From 23a855bf2c1d31d6e29143c699a8219a17ca0d75 Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 21:25:28 +0100 Subject: [PATCH 007/167] More performant LongUtils.compareHigh() (#639) * convert byte to int in a loop once only * simplified comparison of byte arrays * enrolled version should be the fastest * some compareTo methods can be replaced by more simple and performant appropriate equals() method * avoid duplicate method call * closely related unnecessary local variable * checkstyle * comparison of reference is unnecessary * unnecessary local variable * condition covered by subsequent conditions * mismatch simplification * use long instead of byte[6] * avoid backward value conversion, when original is available * mismatch() has to return length of shorter array, when all elements are equal * bugfix: bytes are reordered * bugfix: low 6 bytes, not high ones * bugfix: two different conditions cannot be merged into one --- .../java/org/roaringbitmap/ArraysShim.java | 13 ++-- .../roaringbitmap/art/AbstractShuttle.java | 5 +- .../roaringbitmap/art/BackwardShuttle.java | 6 +- .../org/roaringbitmap/art/ForwardShuttle.java | 6 +- .../org/roaringbitmap/art/KeyIterator.java | 4 + .../java/org/roaringbitmap/art/LeafNode.java | 4 + .../org/roaringbitmap/longlong/LongUtils.java | 74 ++++++------------- .../longlong/Roaring64Bitmap.java | 70 ++++++++---------- .../roaringbitmap/longlong/TestLongUtils.java | 15 ---- 9 files changed, 75 insertions(+), 122 deletions(-) delete mode 100644 RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestLongUtils.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArraysShim.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArraysShim.java index ba8272f08..e4cdd7c03 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArraysShim.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArraysShim.java @@ -48,17 +48,14 @@ public static int mismatch(byte[] a, int aFromIndex, int aToIndex, int aLength = aToIndex - aFromIndex; int bLength = bToIndex - bFromIndex; int length = Math.min(aLength, bLength); - int i = 0; - boolean foundMismatch = false; - for (; i < length; i++) { + for (int i = 0; i < length; i++) { if (a[aFromIndex + i] != b[bFromIndex + i]) { - foundMismatch = true; - break; + return i; } } - if (!foundMismatch && aLength == bLength) { - return -1; + if (aLength != bLength) { + return length; } - return (!foundMismatch && aLength != bLength) ? length : i; + return -1; } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java index d15efc5c6..7dd79b12e 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java @@ -30,9 +30,10 @@ public void initShuttle() { public void initShuttleFrom(long key) { depth = -1; // reset byte[] high = LongUtils.highPart(key); + long highAsLong = LongUtils.rightShiftHighPart(key); visitToLeafFrom(high, 0, art.getRoot()); // If the target container doesn't exist, we may end up in the previous existing leaf here - if (currentBeforeHigh(getCurrentLeafNode().getKeyBytes(), high)) { + if (currentBeforeHigh(getCurrentLeafNode().getKey(), highAsLong)) { // Move the following leaf instead hasRun = true; // make it actually move moveToNextLeaf(); @@ -40,7 +41,7 @@ public void initShuttleFrom(long key) { hasRun = false; // reset } - protected abstract boolean currentBeforeHigh(byte[] current, byte[] high); + protected abstract boolean currentBeforeHigh(long current, long high); @Override public boolean moveToNextLeaf() { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java index 21287bf68..c9d7fab2d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java @@ -1,7 +1,5 @@ package org.roaringbitmap.art; -import org.roaringbitmap.longlong.LongUtils; - /** * visit the leaf node space in descending order */ @@ -12,8 +10,8 @@ public class BackwardShuttle extends AbstractShuttle { } @Override - protected boolean currentBeforeHigh(byte[] current, byte[] high) { - return LongUtils.compareHigh(current, high) > 0; + protected boolean currentBeforeHigh(long current, long high) { + return current > high; } @Override diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java index 081165418..0f708d320 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java @@ -1,7 +1,5 @@ package org.roaringbitmap.art; -import org.roaringbitmap.longlong.LongUtils; - /** * visit the leaf node space in ascending order. */ @@ -12,8 +10,8 @@ public class ForwardShuttle extends AbstractShuttle { } @Override - protected boolean currentBeforeHigh(byte[] current, byte[] high) { - return LongUtils.compareHigh(current, high) < 0; + protected boolean currentBeforeHigh(long current, long high) { + return current < high; } @Override diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java index 1c5829445..4c7c20eb4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java @@ -26,6 +26,10 @@ public byte[] next() { return current.getKeyBytes(); } + public long nextKey() { + return current.getKey(); + } + public long currentContainerIdx() { return current.getContainerIdx(); } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNode.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNode.java index 7ba4d9a37..ce344215d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNode.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNode.java @@ -136,4 +136,8 @@ public long getContainerIdx() { public byte[] getKeyBytes() { return LongUtils.highPart(key); } + + public long getKey() { + return key >>> 16; + } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java index 7de7234af..c1df22d2b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java @@ -11,7 +11,7 @@ public class LongUtils { * @return the high 48 bit */ public static byte[] highPart(long num) { - byte[] high48 = new byte[]{ + return new byte[]{ (byte) ((num >>> 56) & 0xff), (byte) ((num >>> 48) & 0xff), (byte) ((num >>> 40) & 0xff), @@ -19,7 +19,6 @@ public static byte[] highPart(long num) { (byte) ((num >>> 24) & 0xff), (byte) ((num >>> 16) & 0xff) }; - return high48; } /** @@ -40,16 +39,26 @@ public static char lowPart(long num) { * @return the long data */ public static long toLong(byte[] high, char low) { - byte byte6 = (byte) (low >>> 8 & 0xFFL); - byte byte7 = (byte) low; - return (high[0] & 0xFFL) << 56 - | (high[1] & 0xFFL) << 48 - | (high[2] & 0xFFL) << 40 - | (high[3] & 0xFFL) << 32 - | (high[4] & 0xFFL) << 24 - | (high[5] & 0xFFL) << 16 - | (byte6 & 0xFFL) << 8 - | (byte7 & 0xFFL); + return toLong(high) << 16 | low; + } + + /** + * Reconstruct the long data. + * + * @param high the high 48 bit + * @return the long data + */ + public static long toLong(byte[] high) { + return (high[0] & 0xFFL) << 40 + | (high[1] & 0xFFL) << 32 + | (high[2] & 0xFFL) << 24 + | (high[3] & 0xFFL) << 16 + | (high[4] & 0xFFL) << 8 + | (high[5] & 0xFFL); + } + + public static long toLong(long high, char low) { + return high << 16 | low; } /** @@ -88,36 +97,6 @@ public static long fromBDBytes(byte[] work) { | (long) (work[7] & 0xff); } - /** - * compare according to the dictionary order - * - * @param a a byte array - * @param b another byte array - * @return 1 indicates a greater than b,0 indicates equal,-1 indicates a smaller than b - */ - public static int compareHigh(byte[] a, byte[] b) { - return compareTo(a, 0, a.length, b, 0, b.length); - } - - private static int compareTo(byte[] buffer1, int offset1, int length1, - byte[] buffer2, int offset2, int length2) { - if (buffer1 == buffer2 - && offset1 == offset2 - && length1 == length2) { - return 0; - } - int end1 = offset1 + length1; - int end2 = offset2 + length2; - for (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) { - int a = (buffer1[i] & 0xff); - int b = (buffer2[j] & 0xff); - if (a != b) { - return a - b; - } - } - return length1 - length2; - } - /** * initialize a long value with the given fist 32 bit * @@ -171,15 +150,10 @@ public static byte[] highPartInPlace(long num, byte[] high48) { * checks if given high48 is the maximum possible one * (e.g. it is the case for -1L, which is the maximum unsigned long) * - * @param high48 the byte array + * @param key long * @return true if this the maximum high part */ - public static boolean isMaxHigh(byte[] high48) { - return high48[0] == -1 - && high48[1] == -1 - && high48[2] == -1 - && high48[3] == -1 - && high48[4] == -1 - && high48[5] == -1; + public static boolean isMaxHigh(long key) { + return (key & 0xFF_FF_FF_FF_FF_FFL) == 0xFF_FF_FF_FF_FF_FFL; } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java index c9d1c612d..34129d44f 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java @@ -208,12 +208,12 @@ public void forAllInRange(long start, int length, final RelativeRangeConsumer rr return; // nothing else to do } final long end = start + length; - final byte[] endHigh = LongUtils.highPart(end); + final long endHigh = LongUtils.rightShiftHighPart(end); long filledUntil = start; LeafNode node = leafIterator.next(); - byte[] high = node.getKeyBytes(); - while (LongUtils.compareHigh(high, endHigh) <= 0) { + long high = node.getKey(); + while (high <= endHigh) { // fill missing values until start of container long containerStart = LongUtils.toLong(high, (char) 0); if (filledUntil < containerStart) { @@ -254,7 +254,7 @@ public void forAllInRange(long start, int length, final RelativeRangeConsumer rr } if (leafIterator.hasNext()) { node = leafIterator.next(); - high = node.getKeyBytes(); + high = node.getKey(); } else { break; } @@ -279,15 +279,15 @@ public void forEachInRange(long start, int length, final LongConsumer lc) { @Override public long rankLong(long id) { long result = 0; - byte[] high = LongUtils.highPart(id); + long high = LongUtils.rightShiftHighPart(id); + byte[] highBytes = LongUtils.highPart(id); char low = LongUtils.lowPart(id); - ContainerWithIndex containerWithIndex = highLowContainer.searchContainer(high); + ContainerWithIndex containerWithIndex = highLowContainer.searchContainer(highBytes); KeyIterator keyIterator = highLowContainer.highKeyIterator(); if (containerWithIndex == null) { while (keyIterator.hasNext()) { - byte[] highKey = keyIterator.next(); - int res = LongUtils.compareHigh(highKey, high); - if (res > 0) { + long highKey = keyIterator.nextKey(); + if (highKey > high) { break; } else { long containerIdx = keyIterator.currentContainerIdx(); @@ -297,10 +297,10 @@ public long rankLong(long id) { } } else { while (keyIterator.hasNext()) { - byte[] key = keyIterator.next(); + long key = keyIterator.nextKey(); long containerIdx = keyIterator.currentContainerIdx(); Container container = highLowContainer.getContainer(containerIdx); - if (LongUtils.compareHigh(key, high) == 0) { + if (key == high) { result += container.rank(low); break; } else { @@ -424,10 +424,10 @@ public void andNot(final Roaring64Bitmap x2) { */ public void flip(final long rangeStart, final long rangeEnd) { - if(rangeStart >= 0 && rangeEnd >= 0 && rangeStart >= rangeEnd){ + if(rangeEnd >= 0 && rangeStart >= rangeEnd){ // both numbers in positive range, and start is beyond end, nothing to do. return; - } else if(rangeStart < 0 && rangeEnd < 0 && rangeStart >= rangeEnd){ + } else if(rangeStart < 0 && rangeStart >= rangeEnd){ // both numbers in negative range, and start is beyond end, nothing to do. return; } else if(rangeStart < 0 && rangeEnd > 0) { @@ -776,19 +776,19 @@ public void addRange(final long rangeStart, final long rangeEnd) { throw new IllegalArgumentException("Invalid range [" + rangeStart + "," + rangeEnd + ")"); } - byte[] startHigh = LongUtils.highPart(rangeStart); + long startHigh = LongUtils.rightShiftHighPart(rangeStart); int startLow = LongUtils.lowPart(rangeStart); - byte[] endHigh = LongUtils.highPart(rangeEnd - 1); + long endHigh = LongUtils.rightShiftHighPart(rangeEnd - 1); int endLow = LongUtils.lowPart(rangeEnd - 1); + long rangeStartVal = rangeStart; - byte[] startHighKey = startHigh; - for (; LongUtils.compareHigh(startHighKey, endHigh) <= 0; ) { - final int containerStart = - (LongUtils.compareHigh(startHighKey, startHigh) == 0) ? startLow : 0; + long startHighKey = LongUtils.rightShiftHighPart(rangeStart); + byte[] startHighKeyBytes = LongUtils.highPart(rangeStart); + while (startHighKey <= endHigh) { + final int containerStart = startHighKey == startHigh ? startLow : 0; // last container may contain partial range - final int containerLast = (LongUtils.compareHigh(startHighKey, endHigh) == 0) ? endLow - : Util.maxLowBitAsInteger(); - ContainerWithIndex containerWithIndex = highLowContainer.searchContainer(startHighKey); + final int containerLast = startHighKey == endHigh ? endLow : Util.maxLowBitAsInteger(); + ContainerWithIndex containerWithIndex = highLowContainer.searchContainer(startHighKeyBytes); if (containerWithIndex != null) { long containerIdx = containerWithIndex.getContainerIdx(); Container freshContainer = highLowContainer.getContainer(containerIdx) @@ -796,7 +796,7 @@ public void addRange(final long rangeStart, final long rangeEnd) { highLowContainer.replaceContainer(containerIdx, freshContainer); } else { Container freshContainer = Container.rangeOfOnes(containerStart, containerLast + 1); - highLowContainer.put(startHighKey, freshContainer); + highLowContainer.put(startHighKeyBytes, freshContainer); } if (LongUtils.isMaxHigh(startHighKey)) { @@ -804,7 +804,8 @@ public void addRange(final long rangeStart, final long rangeEnd) { } //increase the high rangeStartVal = rangeStartVal + (containerLast - containerStart) + 1; - startHighKey = LongUtils.highPart(rangeStartVal); + startHighKey = LongUtils.rightShiftHighPart(rangeStartVal); + startHighKeyBytes = LongUtils.highPart(rangeStartVal); } } @@ -935,7 +936,6 @@ private abstract class PeekableIterator implements PeekableLongIterator { abstract PeekableCharIterator getIterator(Container container); abstract boolean compare(long next, long val); - abstract boolean compareHigh(byte[] next, byte[] val); @Override public boolean hasNext() { @@ -978,13 +978,14 @@ public void advanceIfNeeded(long minval) { return; } - byte[] minHigh = LongUtils.highPart(minval); - if (!Arrays.equals(this.high, minHigh)) { + long minHigh = LongUtils.rightShiftHighPart(minval); + long high = LongUtils.toLong(this.high); + if (minHigh != high) { // advance outer if (keyIte.hasNext()) { LeafNode leafNode = keyIte.next(); this.high = leafNode.getKeyBytes(); - if (compareHigh(this.high, minHigh)) { + if (compare(leafNode.getKey(), minHigh)) { long containerIdx = leafNode.getContainerIdx(); Container container = highLowContainer.getContainer(containerIdx); charIterator = getIterator(container); @@ -1012,7 +1013,8 @@ public void advanceIfNeeded(long minval) { } } - if (Arrays.equals(this.high, minHigh)) { + byte[] minHighBytes = LongUtils.highPart(minval); + if (Arrays.equals(this.high, minHighBytes)) { // advance inner char low = LongUtils.lowPart(minval); charIterator.advanceIfNeeded(low); @@ -1051,11 +1053,6 @@ PeekableCharIterator getIterator(Container container) { boolean compare(long next, long val) { return Long.compareUnsigned(next, val) >= 0; } - - @Override - boolean compareHigh(byte[] next, byte[] val) { - return LongUtils.compareHigh(next, val) >= 0; - } } private class ReversePeekableIterator extends PeekableIterator { @@ -1072,10 +1069,5 @@ PeekableCharIterator getIterator(Container container) { boolean compare(long next, long val) { return Long.compareUnsigned(next, val) <= 0; } - - @Override - boolean compareHigh(byte[] next, byte[] val) { - return LongUtils.compareHigh(next, val) <= 0; - } } } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestLongUtils.java b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestLongUtils.java deleted file mode 100644 index 5bff24bd4..000000000 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestLongUtils.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.roaringbitmap.longlong; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class TestLongUtils { - @Test - public void testHighPart() { - Assertions.assertFalse(LongUtils.isMaxHigh(LongUtils.highPart(0))); - Assertions.assertFalse(LongUtils.isMaxHigh(LongUtils.highPart(Long.MAX_VALUE))); - Assertions.assertFalse(LongUtils.isMaxHigh(LongUtils.highPart(Long.MIN_VALUE))); - - Assertions.assertTrue(LongUtils.isMaxHigh(LongUtils.highPart(-1L))); - } -} From 5a4d2e6c46f06de2afd963160b0826a8e330a8e4 Mon Sep 17 00:00:00 2001 From: xtonik Date: Thu, 2 Nov 2023 21:41:11 +0100 Subject: [PATCH 008/167] AddOffset optimization (#669) * Skip unnecessary offset computations * Skip unnecessary offset computations for mappable bitmap --- .../src/main/java/org/roaringbitmap/RoaringBitmap.java | 7 +++++-- .../org/roaringbitmap/buffer/MutableRoaringBitmap.java | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 622811e12..9ae064da1 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -224,11 +224,14 @@ public static RoaringBitmap addOffset(final RoaringBitmap x, long offset) { for(int pos = 0; pos < x.highLowContainer.size(); pos++) { int key = (x.highLowContainer.getKeyAtIndex(pos)); key += container_offset; + if (key + 1 < 0 || key > 0xFFFF) { + continue; + } Container c = x.highLowContainer.getContainerAtIndex(pos); Container[] offsetted = Util.addOffset(c, (char)in_container_offset); - boolean keyok = (key >= 0) && (key <= 0xFFFF); - boolean keypok = (key + 1 >= 0) && (key + 1 <= 0xFFFF); + boolean keyok = key >= 0; + boolean keypok = key + 1 <= 0xFFFF; if( !offsetted[0].isEmpty() && keyok) { int current_size = answer.highLowContainer.size(); int lastkey = 0; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java index 180f31945..fb9e35b48 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java @@ -107,11 +107,14 @@ public static MutableRoaringBitmap addOffset(final ImmutableRoaringBitmap x, lon for(int pos = 0; pos < x.highLowContainer.size(); pos++) { int key = (x.highLowContainer.getKeyAtIndex(pos)); key += container_offset; + if (key + 1 < 0 || key > 0xFFFF) { + continue; + } MappeableContainer c = x.highLowContainer.getContainerAtIndex(pos); MappeableContainer[] offsetted = BufferUtil.addOffset(c, (char)in_container_offset); - boolean keyok = (key >= 0) && (key <= 0xFFFF); - boolean keypok = (key + 1 >= 0) && (key + 1 <= 0xFFFF); + boolean keyok = key >= 0; + boolean keypok = key + 1 <= 0xFFFF; if( !offsetted[0].isEmpty() && keyok) { int current_size = answer.highLowContainer.size(); int lastkey = 0; From 9397d3a543acb1f3f86d5a5bdb496880cc6d3a69 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 2 Nov 2023 21:32:43 -0400 Subject: [PATCH 009/167] Trying to verify issue with flips. (#677) --- .../org/roaringbitmap/TestRoaringBitmap.java | 16 ++++++++++++++++ .../roaringbitmap/buffer/TestRoaringBitmap.java | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java index 47c52db0f..c983489d0 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java @@ -5460,6 +5460,7 @@ public void testIssue566() { System.out.println("[issue566] RoaringBitmap bits per entry: " + roaringbits * 1.0 / roaringBitMap.getCardinality()); assertTrue(roaringbits < bitsetbits); } + @Test public void issue623() { RoaringBitmap r = new RoaringBitmap(); @@ -5475,4 +5476,19 @@ public void issue623() { assertTrue(r.contains(i, i + 1)); } } + + @Test + public void test1235() { + RoaringBitmap r = RoaringBitmap.bitmapOf(1, 2, 3, 5); + r.flip(4); + assertEquals(r, RoaringBitmap.bitmapOf(1, 2, 3, 4, 5)); + } + + @Test + public void test2345() { + RoaringBitmap r = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5); + r.flip(1); + assertEquals(r, RoaringBitmap.bitmapOf(2, 3, 4, 5)); + } + } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java index 687236f2c..d68faa6ab 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java @@ -3965,4 +3965,19 @@ public void issue623() { } } + + + @Test + public void test1235() { + MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(1, 2, 3, 5); + r.flip(4); + assertEquals(r, MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5)); + } + + @Test + public void test2345() { + MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5); + r.flip(1); + assertEquals(r, MutableRoaringBitmap.bitmapOf(2, 3, 4, 5)); + } } From 443fd309998cdddf18a95677ef0fe477001349bc Mon Sep 17 00:00:00 2001 From: xtonik Date: Fri, 3 Nov 2023 02:33:37 +0100 Subject: [PATCH 010/167] AdvanceIfNeeded on bitmap container optimized (#665) * advanceIfNeeded optimization * expected and actual value swap * cleanup mesh & warnings * temporary performance comparison removed * Update jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java Co-authored-by: Daniel Lemire --------- Co-authored-by: Daniel Lemire --- .../org/roaringbitmap/BitmapContainer.java | 73 ++++++++++--------- .../buffer/MappeableBitmapContainer.java | 18 +++-- .../TestReverseIteratorsOfContainers.java | 4 +- .../buffer/TestIntIteratorFlyweight.java | 19 +++-- .../AdvanceIfNeededBenchmark.java | 54 ++++++++++++++ 5 files changed, 115 insertions(+), 53 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index 884d383b9..02a2feeaf 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -1764,20 +1764,23 @@ public void wrap(long[] b) { @Override public void advanceIfNeeded(char minval) { - if ((minval) >= (x + 1) * 64) { - x = (minval) / 64; - w = bitmap[x]; + if (!hasNext()) { + return; + } + if (minval >= x * 64) { + if (minval >= (x + 1) * 64) { + x = minval / 64; + w = bitmap[x]; + } + w &= ~0L << (minval & 63); while (w == 0) { - ++x; - if (x == bitmap.length) { + x++; + if (!hasNext()) { return; } w = bitmap[x]; } } - while (hasNext() && ((peekNext()) < (minval))) { - next(); // could be optimized - } } @Override @@ -1807,29 +1810,30 @@ public char next() { @Override public void advanceIfNeeded(char minval) { - if ((minval) >= (x + 1) * 64) { - - int nextX = (minval) / 64; - nextRank += bitCount(w); - for(x = x + 1; x < nextX; ++x) { - w = bitmap[x]; + if (!hasNext()) { + return; + } + if (minval >= x * 64) { + if (minval >= (x + 1) * 64) { + int nextX = minval / 64; nextRank += bitCount(w); + for(x = x + 1; x < nextX; x++) { + w = bitmap[x]; + nextRank += bitCount(w); + } + w = bitmap[nextX]; } - - x = nextX; - w = bitmap[x]; - + nextRank += bitCount(w); + w &= ~0L << (minval & 63); + nextRank -= bitCount(w); while (w == 0) { ++x; - if (x == bitmap.length) { + if (!hasNext()) { return; } w = bitmap[x]; } } - while (hasNext() && ((peekNext()) < (minval))) { - next(); // could be optimized - } } @Override @@ -1889,19 +1893,22 @@ public int nextAsInt() { @Override public void advanceIfNeeded(char maxval) { - if ((maxval) <= (position - 1) * 64) { - position = (maxval) / 64; - word = bitmap[position]; - while (word == 0) { - --position; - if (position == 0) { - break; + if (maxval < (position + 1) * 64) { + if (maxval < position * 64) { + position = maxval / 64; + } + long currentWord = bitmap[position]; + currentWord &= ~0L >>> (63 - (maxval & 63)); + if (position > 0) { + while (currentWord == 0) { + position--; + if (position == 0) { + break; + } + currentWord = bitmap[position]; } - word = bitmap[position]; } - } - while (hasNext() && ((peekNext()) > (maxval))) { - next(); // could be optimized + word = currentWord; } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index a09c32852..b54f99a20 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -2190,21 +2190,23 @@ void wrap(MappeableBitmapContainer p) { @Override public void advanceIfNeeded(char minval) { - if (minval >= (x + 1) * 64) { - x = minval >>> 6; - w = parent.bitmap.get(x); + if (!hasNext()) { + return; + } + if (minval >= x * 64) { + if (minval >= (x + 1) * 64) { + x = minval / 64; + w = parent.bitmap.get(x); + } + w &= ~0L << (minval & 63); while (w == 0) { - ++x; + x++; if (x == len) { return; } w = parent.bitmap.get(x); } } - while (hasNext() && (peekNext() < minval)) { - next(); // could be optimized - } - } @Override diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java index fc1c97c54..40b347b13 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java @@ -134,8 +134,8 @@ public void testSkipsDenseReverse(Converter converter) { PeekableCharIterator pii = container.getReverseCharIterator(); char c = (char) (2 * i); pii.advanceIfNeeded(c); - assertEquals(pii.peekNext(), 2 * i); - assertEquals(pii.next(), 2 * i); + assertEquals(2 * i, pii.peekNext()); + assertEquals(2 * i, pii.next()); } } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java index f5e74d184..24199e7cf 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java @@ -34,7 +34,7 @@ private static List asList(IntIterator ints) { } private static int[] takeSortedAndDistinct(Random source, int count) { - LinkedHashSet ints = new LinkedHashSet(count); + LinkedHashSet ints = new LinkedHashSet<>(count); for (int size = 0; size < count; size++) { int next; do { @@ -43,8 +43,7 @@ private static int[] takeSortedAndDistinct(Random source, int count) { } // we add a range of continuous values for(int k = 1000; k < 10000; ++k) { - if(!ints.contains(k)) - ints.add(k); + ints.add(k); } int[] unboxed = Ints.toArray(ints); Arrays.sort(unboxed); @@ -69,7 +68,7 @@ public void testEmptyIteration() { @Test public void testIteration() { - final Random source = new Random(0xcb000a2b9b5bdfb6l); + final Random source = new Random(0xcb000a2b9b5bdfb6L); final int[] data = takeSortedAndDistinct(source, 450000); MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data); @@ -106,7 +105,7 @@ public void testIteration() { @Test public void testIterationFromBitmap() { - final Random source = new Random(0xcb000a2b9b5bdfb6l); + final Random source = new Random(0xcb000a2b9b5bdfb6L); final int[] data = takeSortedAndDistinct(source, 450000); MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data); @@ -121,8 +120,8 @@ public void testIterationFromBitmap() { iter2.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); - assertEquals(j.peekNext(),data[k]); - assertEquals(iter2.peekNext(),data[k]); + assertEquals(data[k], j.peekNext()); + assertEquals(data[k], iter2.peekNext()); } @@ -142,7 +141,7 @@ public void testIterationFromBitmap() { @Test public void testIterationFromBitmapClone() { - final Random source = new Random(0xcb000a2b9b5bdfb6l); + final Random source = new Random(0xcb000a2b9b5bdfb6L); final int[] data = takeSortedAndDistinct(source, 450000); MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data); @@ -162,11 +161,11 @@ public void testIterationFromBitmapClone() { @Test public void testIteration1() { - final Random source = new Random(0xcb000a2b9b5bdfb6l); + final Random source = new Random(0xcb000a2b9b5bdfb6L); final int[] data1 = takeSortedAndDistinct(source, 450000); final int[] data = Arrays.copyOf(data1, data1.length + 50000); - LinkedHashSet data1Members = new LinkedHashSet(); + LinkedHashSet data1Members = new LinkedHashSet<>(); for (int i : data1) { data1Members.add(i); } diff --git a/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java new file mode 100644 index 000000000..48f5f7500 --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java @@ -0,0 +1,54 @@ +package org.roaringbitmap; + +import com.google.common.primitives.Ints; +import org.openjdk.jmh.annotations.*; +import org.roaringbitmap.buffer.MutableRoaringBitmap; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 2000) +@Measurement(iterations = 10, timeUnit = TimeUnit.MILLISECONDS, time = 2000) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Benchmark) +public class AdvanceIfNeededBenchmark { + public static MutableRoaringBitmap c2; + public static PeekableIntIterator it; + + private static int[] takeSortedAndDistinct(Random source, int count) { + LinkedHashSet ints = new LinkedHashSet<>(count); + for (int size = 0; size < count; size++) { + int next; + do { + next = source.nextInt(1000000); + } while (!ints.add(next)); + } + // we add a range of continuous values + for(int k = 1000; k < 10000; ++k) { + ints.add(k); + } + int[] unboxed = Ints.toArray(ints); + Arrays.sort(unboxed); + return unboxed; + } + static { + final Random source = new Random(0xcb000a2b9b5bdfb6L); + final int[] data = takeSortedAndDistinct(source, 450000); + c2 = MutableRoaringBitmap.bitmapOf(data); + + } + @Setup(Level.Iteration) + public void setup() { + it = c2.getIntIterator(); + c2.first(); + } + + @Benchmark + public MutableRoaringBitmap advanceIfNeeded() { + it.advanceIfNeeded((char) (59 + 15 * 64)); + return c2; + } +} From 28482341ca11a62b24bd8b30a8889aa87f266289 Mon Sep 17 00:00:00 2001 From: xtonik Date: Fri, 3 Nov 2023 02:34:04 +0100 Subject: [PATCH 011/167] real iand between run and array container (#668) * real iand between run and array container * faster run container iteration * real iandnot between array and run container * real iandnot between array and run mappable container --- .../org/roaringbitmap/ArrayContainer.java | 29 +++++++++++++++---- .../buffer/MappeableArrayContainer.java | 29 ++++++++++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index eeec2021b..c3cea2c26 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -556,8 +556,18 @@ public Container iand(BitmapContainer value2) { @Override public Container iand(RunContainer x) { - // possible performance issue, not taking advantage of possible inplace - return x.and(this); + PeekableCharIterator it = x.getCharIterator(); + int removed = 0; + for (int i = 0; i < cardinality; i++) { + it.advanceIfNeeded(content[i]); + if (it.peekNext() == content[i]) { + content[i - removed] = content[i]; + } else { + removed++; + } + } + cardinality -= removed; + return this; } @@ -582,9 +592,18 @@ public ArrayContainer iandNot(BitmapContainer value2) { @Override public Container iandNot(RunContainer x) { - // possible performance issue, not taking advantage of possible inplace - // could adapt algo above - return andNot(x); + PeekableCharIterator it = x.getCharIterator(); + int removed = 0; + for (int i = 0; i < cardinality; i++) { + it.advanceIfNeeded(content[i]); + if (it.peekNext() != content[i]) { + content[i - removed] = content[i]; + } else { + removed++; + } + } + cardinality -= removed; + return this; } private void increaseCapacity() { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index e7889cb08..c3a9a6858 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -683,10 +683,20 @@ public MappeableContainer iand(MappeableBitmapContainer value2) { } - // Note it is never inplace, may wish to fix @Override public MappeableContainer iand(final MappeableRunContainer value2) { - return value2.and(this); + PeekableCharIterator it = value2.getCharIterator(); + int removed = 0; + for (int i = 0; i < cardinality; i++) { + it.advanceIfNeeded(content.get(i)); + if (it.peekNext() == content.get(i)) { + content.put(i - removed, content.get(i)); + } else { + removed++; + } + } + cardinality -= removed; + return this; } @Override @@ -723,8 +733,19 @@ public MappeableArrayContainer iandNot(MappeableBitmapContainer value2) { } @Override - public MappeableContainer iandNot(final MappeableRunContainer value2) { // not inplace, revisit? - return andNot(value2); + public MappeableContainer iandNot(final MappeableRunContainer value2) { + PeekableCharIterator it = value2.getCharIterator(); + int removed = 0; + for (int i = 0; i < cardinality; i++) { + it.advanceIfNeeded(content.get(i)); + if (it.peekNext() != content.get(i)) { + content.put(i - removed, content.get(i)); + } else { + removed++; + } + } + cardinality -= removed; + return this; } private void increaseCapacity() { From 53ba593e8a1fb288a705837dc3bad057f2a50bc0 Mon Sep 17 00:00:00 2001 From: xtonik Date: Fri, 17 Nov 2023 23:45:31 +0100 Subject: [PATCH 012/167] Avoid computing cardinality for run container (#685) * avoid compute cardinality for run container using contains() instead * benchmark for optimized checkedAdd() * benchmark uses enums for testing scenarios --- .../java/org/roaringbitmap/RoaringBitmap.java | 19 ++- .../buffer/MutableRoaringBitmap.java | 19 ++- .../roaringbitmap/CheckedAddBenchmark.java | 130 ++++++++++++++++++ 3 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 9ae064da1..2c3d57f8c 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -1560,13 +1560,22 @@ public boolean checkedAdd(final int x) { final int i = highLowContainer.getIndex(hb); if (i >= 0) { Container c = highLowContainer.getContainerAtIndex(i); - int oldCard = c.getCardinality(); // we need to keep the newContainer if a switch between containers type // occur, in order to get the new cardinality - Container newCont = c.add(Util.lowbits(x)); - highLowContainer.setContainerAtIndex(i, newCont); - if (newCont.getCardinality() > oldCard) { - return true; + Container newCont; + if (c instanceof RunContainer) { // do not compute cardinality + if (!c.contains(Util.lowbits(x))) { + newCont = c.add(Util.lowbits(x)); + highLowContainer.setContainerAtIndex(i, newCont); + return true; + } + } else { // it is faster to use getCardinality() than contains() for other container types + int oldCard = c.getCardinality(); + newCont = c.add(Util.lowbits(x)); + highLowContainer.setContainerAtIndex(i, newCont); + if (newCont.getCardinality() > oldCard) { + return true; + } } } else { final ArrayContainer newac = new ArrayContainer(); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java index fb9e35b48..e35f5f50b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java @@ -1022,15 +1022,26 @@ public boolean checkedAdd(final int x) { final int i = highLowContainer.getIndex(hb); if (i >= 0) { MappeableContainer C = highLowContainer.getContainerAtIndex(i); - int oldcard = C.getCardinality(); - C = C.add(BufferUtil.lowbits(x)); - getMappeableRoaringArray().setContainerAtIndex(i, C); - return C.getCardinality() > oldcard; + char lowX = BufferUtil.lowbits(x); + MappeableContainer newCont; + if (C instanceof MappeableRunContainer) { // do not compute cardinality + if (!C.contains(lowX)) { + newCont = C.add(lowX); + getMappeableRoaringArray().setContainerAtIndex(i, newCont); + return true; + } + } else { // it is faster to use getCardinality() than contains() for other container types + int oldCard = C.getCardinality(); + newCont = C.add(lowX); + getMappeableRoaringArray().setContainerAtIndex(i, newCont); + return newCont.getCardinality() > oldCard; + } } else { final MappeableArrayContainer newac = new MappeableArrayContainer(); getMappeableRoaringArray().insertNewKeyValueAt(-i - 1, hb, newac.add(BufferUtil.lowbits(x))); return true; } + return false; } /** diff --git a/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java new file mode 100644 index 000000000..3a9d59e5c --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java @@ -0,0 +1,130 @@ +package org.roaringbitmap; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 3, timeUnit = TimeUnit.MILLISECONDS, time = 2000) +@Measurement(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 2000) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class CheckedAddBenchmark { + + private static final int valuesCount = 10_000_000; + + @Param({"HALF_DUPLICATED", "UNIQUE"}) + public InputDataType inputData; + + @Param({"RUN", "BITMAP"}) + public ContainerType containerType; + + public RoaringBitmap bitmap; + + public int[] a; + + public enum InputDataType { + @SuppressWarnings("unused") + HALF_DUPLICATED { + @Override + public int getValue(int i) { + // leads to pairs of same value, resulting bitmap has half size, it does not affect + // benchmark results + return i >> 2; + } + }, + @SuppressWarnings("unused") + UNIQUE { + @Override + public int getValue(int i) { + return i; + } + }; + + protected abstract int getValue(int i); + + public int[] getValues() { + int[] a = new int[valuesCount]; + for (int i = 0; i < valuesCount; i++) { + a[i] = getValue(i); + } + return a; + } + } + + public enum ContainerType { + @SuppressWarnings("unused") + RUN { + @Override + public RoaringBitmap createBitmap(int[] values) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(values); + bitmap.runOptimize(); + if (!(bitmap.getContainerPointer().getContainer() instanceof RunContainer)) { + throw new IllegalStateException("Container is not run!!!"); + } + return bitmap; + } + }, + @SuppressWarnings("unused") + BITMAP { + @Override + public RoaringBitmap createBitmap(int[] values) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(values); + if (!(bitmap.getContainerPointer().getContainer() instanceof BitmapContainer)) { + throw new IllegalStateException("Container is not bitmap!!!"); + } + return bitmap; + } + }; + + public abstract RoaringBitmap createBitmap(int[] values); + } + + @Setup(Level.Invocation) + public void setUp() { + a = inputData.getValues(); + bitmap = containerType.createBitmap(a); + } + + @Benchmark + public boolean optimized() { + boolean contains = false; + for (int i = 0; i < valuesCount; i++) { + contains ^= bitmap.checkedAdd(a[i]); + } + return contains; + } + + @Benchmark + public boolean original() { + boolean contains = false; + for (int i = 0; i < valuesCount; i++) { + contains ^= checkedAddOriginal(a[i]); + } + return contains; + } + + public boolean checkedAddOriginal(final int x) { + final char hb = Util.highbits(x); + final int i = bitmap.highLowContainer.getIndex(hb); + if (i >= 0) { + Container c = bitmap.highLowContainer.getContainerAtIndex(i); + int oldCard = c.getCardinality(); + // we need to keep the newContainer if a switch between containers type + // occur, in order to get the new cardinality + Container newCont = c.add(Util.lowbits(x)); + bitmap.highLowContainer.setContainerAtIndex(i, newCont); + + //noinspection RedundantIfStatement + if (newCont.getCardinality() > oldCard) { + return true; + } + } else { + @SuppressWarnings("SpellCheckingInspection") final ArrayContainer newac = + new ArrayContainer(); + bitmap.highLowContainer.insertNewKeyValueAt(-i - 1, hb, newac.add(Util.lowbits(x))); + return true; + } + return false; + } +} \ No newline at end of file From 9fde8c5a4747cefd3bf5b297475a0211f7c08b58 Mon Sep 17 00:00:00 2001 From: xtonik Date: Fri, 17 Nov 2023 23:46:12 +0100 Subject: [PATCH 013/167] Use isEmpty() on bitmap instead of getCardinality() > 0 (#684) * use isEmpty() on bitmap instead of getCardinality() * not empty is correct --- .../java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java | 2 +- .../java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java index 35ddd417a..29ce0ce64 100644 --- a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java +++ b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java @@ -85,7 +85,7 @@ public void add(RoaringBitmapSliceIndex otherBsi) { private void addDigit(RoaringBitmap foundSet, int i) { RoaringBitmap carry = RoaringBitmap.and(this.bA[i], foundSet); this.bA[i].xor(foundSet); - if (carry.getCardinality() > 0) { + if (!carry.isEmpty()) { if (i + 1 >= this.bitCount()) { grow(this.bitCount() + 1); } diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java index 3abdb0ed3..7ac2bfd92 100644 --- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java +++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java @@ -121,7 +121,7 @@ public boolean hasRunCompression() { public void addDigit(MutableRoaringBitmap foundSet, int i) { MutableRoaringBitmap carry = MutableRoaringBitmap.and(this.bA[i], foundSet); this.getMutableSlice(i).xor(foundSet); - if (carry.getCardinality() > 0) { + if (!carry.isEmpty()) { if (i + 1 >= this.bitCount()) { grow(this.bitCount() + 1); } From c79d0d66c2f93c56af3cf6a28c5b328f02824a8a Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 18 Nov 2023 00:19:33 +0100 Subject: [PATCH 014/167] Methods for replacing children for Node various type optimized (#675) * skip use numberOfTrailingZeros() if value is equal to zero * replaceChildren() optimization for Node256 * use of toUnsignedInt() when values are not empty * replaceChildren() simplification for Node4 and Node16 * replaceChildren() optimization for Node48 * unintended import change * temporary benchmark removed --- .../java/org/roaringbitmap/art/Node16.java | 8 +------ .../java/org/roaringbitmap/art/Node256.java | 23 ++++++++----------- .../java/org/roaringbitmap/art/Node4.java | 8 +------ .../java/org/roaringbitmap/art/Node48.java | 18 ++++++++------- 4 files changed, 22 insertions(+), 35 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node16.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node16.java index c12689679..46d40913b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node16.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node16.java @@ -243,12 +243,6 @@ public int serializeNodeBodySizeInBytes() { @Override public void replaceChildren(Node[] children) { - int pos = this.getNextLargerPos(ILLEGAL_IDX); - int offset = 0; - while (pos != ILLEGAL_IDX) { - this.children[pos] = children[offset]; - pos = this.getNextLargerPos(pos); - offset++; - } + System.arraycopy(children, 0, this.children, 0, count); } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node256.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node256.java index de4cf1cf6..0f41c4cb4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node256.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node256.java @@ -57,13 +57,11 @@ public void replaceNode(int pos, Node freshOne) { public int getMinPos() { for (int i = 0; i < 4; i++) { long longVal = bitmapMask[i]; - int v = Long.numberOfTrailingZeros(longVal); - if (v == 64) { + if (longVal == 0) { continue; - } else { - int res = i * 64 + v; - return res; } + int v = Long.numberOfTrailingZeros(longVal); + return i * 64 + v; } return ILLEGAL_IDX; } @@ -95,13 +93,11 @@ public int getNextLargerPos(int pos) { public int getMaxPos() { for (int i = 3; i >= 0; i--) { long longVal = bitmapMask[i]; - int v = Long.numberOfLeadingZeros(longVal); - if (v == 64) { + if (longVal == 0) { continue; - } else { - int res = i * 64 + (63 - v); - return res; } + int v = Long.numberOfLeadingZeros(longVal); + return i * 64 + (63 - v); } return ILLEGAL_IDX; } @@ -186,11 +182,12 @@ public void replaceChildren(Node[] children) { int offset = 0; int x = 0; for (long longv : bitmapMask) { - int w = Long.bitCount(longv); - for (int i = 0; i < w; i++) { + int w = 0; + while (longv != 0) { int pos = x * 64 + numberOfTrailingZeros(longv); - this.children[pos] = children[offset + i]; + this.children[pos] = children[offset + w]; longv &= (longv - 1); + w++; } offset += w; x++; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node4.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node4.java index 434453611..205c238db 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node4.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node4.java @@ -167,13 +167,7 @@ public int serializeNodeBodySizeInBytes() { @Override public void replaceChildren(Node[] children) { - int pos = getNextLargerPos(ILLEGAL_IDX); - int offset = 0; - while (pos != ILLEGAL_IDX) { - this.children[pos] = children[offset]; - pos = getNextLargerPos(pos); - offset++; - } + System.arraycopy(children, 0, this.children, 0, count); } /** diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node48.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node48.java index 87d25e1fb..e255fbbe3 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node48.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node48.java @@ -268,16 +268,18 @@ public int serializeNodeBodySizeInBytes() { } @Override - public void replaceChildren(Node[] children) { + void replaceChildren(Node[] children) { int step = 0; for (int i = 0; i < LONGS_USED; i++) { - long longv = childIndex[i]; - for (int j = BYTES_PER_LONG - 1; j >= 0; j--) { - byte bytePos = (byte) (longv >>> (j << INDEX_SHIFT)); - int unsignedPos = Byte.toUnsignedInt(bytePos); - if (bytePos != EMPTY_VALUE) { - this.children[unsignedPos] = children[step]; - step++; + long longv = Long.reverseBytes(childIndex[i]); + if (longv != INIT_LONG_VALUE) { + for (int j = 0; j < BYTES_PER_LONG; j++) { + long currentByte = longv & 0xFF; + if (currentByte != 0xFF) { + this.children[(int) currentByte] = children[step]; + step++; + } + longv >>>= 8; } } } From 9af100da66e83b2de12c2f938b106e70086aa4b0 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 18 Nov 2023 00:20:39 +0100 Subject: [PATCH 015/167] retired getContainer() removed (#678) --- .../src/main/java/org/roaringbitmap/RoaringArray.java | 9 --------- .../main/java/org/roaringbitmap/RoaringBitmap.java | 8 ++++++-- .../org/roaringbitmap/buffer/MutableRoaringArray.java | 11 ----------- 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java index b90c01c64..3a5d53e4a 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java @@ -663,15 +663,6 @@ void extendArray(int k) { } } - // involves a binary search - protected Container getContainer(char x) { - int i = getContainerIndex(x); - if (i < 0) { - return null; - } - return this.values[i]; - } - protected int getContainerIndex(char x) { int i = this.binarySearch(0, size, x); return i; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 2c3d57f8c..ff1151b18 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -1640,8 +1640,12 @@ public RoaringBitmap clone() { @Override public boolean contains(final int x) { final char hb = Util.highbits(x); - final Container c = highLowContainer.getContainer(hb); - return c != null && c.contains(Util.lowbits(x)); + int index = highLowContainer.getContainerIndex(hb); + if (index < 0) { + return false; + } + final Container c = highLowContainer.getContainerAtIndex(index); + return c.contains(Util.lowbits(x)); } /** diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java index e451d1fb6..85fdffc9f 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java @@ -437,17 +437,6 @@ public int getCardinality(int i) { return getContainerAtIndex(i).getCardinality(); } - // retired method (inefficient) - // involves a binary search - /*@Override - public MappeableContainer getContainer(char x) { - final int i = this.binarySearch(0, size, x); - if (i < 0) { - return null; - } - return this.values[i]; - }*/ - @Override public int getContainerIndex(char x) { return this.binarySearch(0, size, x); From 16fee438875c2821dcaa23c0b6f8e5c5f9e13a2f Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 18 Nov 2023 00:21:25 +0100 Subject: [PATCH 016/167] variable is set to the same value as it has (#679) --- .../src/main/java/org/roaringbitmap/art/ContainerIterator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java index f2e476257..d12edee8e 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java @@ -64,7 +64,6 @@ public boolean hasNext() { if (container != null) { currentContainer = container; consumedCurrent = false; - this.currentSecondLevelArrIteOver = false; currentSecondLevelArrIdx++; foundOneContainer = true; break; From abdd6ffb4fa3991263b8017e60cc0ff9ac2096c9 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 18 Nov 2023 00:23:25 +0100 Subject: [PATCH 017/167] Make faster removal of top values (#680) * benchmark for removal top values from bitmap * remove current value when iterating on bitmap works properly * use remove() to delete first K values --- .../bsi/buffer/BitSliceIndexBase.java | 5 +- .../org/roaringbitmap/bsi/BufferBSITest.java | 18 +++ .../SelectTopValuesBenchmark.java | 125 ++++++++++++++++++ 3 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java index c40c836b0..f867941da 100644 --- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java +++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java @@ -318,14 +318,11 @@ public MutableRoaringBitmap topK(ImmutableRoaringBitmap foundSet, int k) { MutableRoaringBitmap F = ImmutableRoaringBitmap.or(G, E); long n = F.getLongCardinality() - k; if (n > 0) { - // TODO: make faster IntIterator i = F.getIntIterator(); - MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); while (i.hasNext() && n > 0) { - turnoff.add(i.next()); + F.remove(i.next()); --n; } - F.andNot(turnoff); } if (F.getCardinality() != k) diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java index 9f5a68a5e..0a0aead81 100644 --- a/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java +++ b/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java @@ -5,6 +5,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.RoaringBitmap; import org.roaringbitmap.bsi.buffer.ImmutableBitSliceIndex; import org.roaringbitmap.bsi.buffer.MutableBitSliceIndex; import org.roaringbitmap.buffer.ImmutableRoaringBitmap; @@ -404,6 +406,22 @@ public void testTransposeWithCount() throws ExecutionException, InterruptedExcep } + @Test + public void removeTopValuesWhenIterating() { + RoaringBitmap expected = new RoaringBitmap(); + expected.add(210, 1000); + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(10, 1000); + + IntIterator it = bitmap.getIntIterator(); + int n = 200; + while (it.hasNext() && n > 0) { + bitmap.remove(it.next()); + --n; + } + + Assertions.assertEquals(expected, bitmap); + } @Test public void testTopK() { diff --git a/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java new file mode 100644 index 000000000..a43e05ec8 --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java @@ -0,0 +1,125 @@ +package org.roaringbitmap; + +import org.openjdk.jmh.annotations.*; +import org.roaringbitmap.buffer.MutableRoaringBitmap; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 3, timeUnit = TimeUnit.MILLISECONDS, time = 1000) +@Measurement(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 1000) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Benchmark) +public class SelectTopValuesBenchmark { + + @Param({"200"}) + int n; + + @Param({"10000"}) + public int count; + + public MutableRoaringBitmap bitmap; + + @Setup(Level.Iteration) + public void setup() { + bitmap = new MutableRoaringBitmap(); + for (int i = 0; i < count; i++) { + bitmap.add(i * 100); + } + } + + @Benchmark + public MutableRoaringBitmap limitIncludingAndNot() { + MutableRoaringBitmap turnoff = bitmap.limit(n); + bitmap.andNot(turnoff); + return bitmap; + } + + @Benchmark + public MutableRoaringBitmap limit() { + return bitmap.limit(n); + } + + + @Benchmark + public MutableRoaringBitmap add() { + IntIterator it = bitmap.getIntIterator(); + MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); + int i = n; + while (it.hasNext() && i > 0) { + turnoff.add(it.next()); + i--; + } + return bitmap; + } + + @Benchmark + public MutableRoaringBitmap addIncludingAndNot() { + IntIterator it = bitmap.getIntIterator(); + MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); + int i = n; + while (it.hasNext() && i > 0) { + turnoff.add(it.next()); + i--; + } + bitmap.andNot(turnoff); + return bitmap; + } + + @Benchmark + public MutableRoaringBitmap remove() { + IntIterator it = bitmap.getIntIterator(); + int i = n; + while (it.hasNext() && i > 0) { + bitmap.remove(it.next()); + i--; + } + return bitmap; + } + + @Benchmark + public MutableRoaringBitmap batchIterator() { + BatchIterator it = bitmap.getBatchIterator(); + int[] buffer = new int[n]; + MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); + it.nextBatch(buffer); + for (int i = 0; i < n; i++) { + turnoff.add(buffer[i]); + } + return turnoff; + } + + @Benchmark + public MutableRoaringBitmap batchIteratorIncludingAndNot() { + BatchIterator it = bitmap.getBatchIterator(); + int[] buffer = new int[n]; + MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); + it.nextBatch(buffer); + for (int i = 0; i < n; i++) { + turnoff.add(buffer[i]); + } + bitmap.andNot(turnoff); + return bitmap; + } + + @Benchmark + public MutableRoaringBitmap batchIteratorAddAtOnce() { + BatchIterator it = bitmap.getBatchIterator(); + int[] buffer = new int[n]; + MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); + it.nextBatch(buffer); + turnoff.add(buffer); + return turnoff; + } + + @Benchmark + public MutableRoaringBitmap batchIteratorAddAtOnceIncludingAndNot() { + BatchIterator it = bitmap.getBatchIterator(); + int[] buffer = new int[n]; + MutableRoaringBitmap turnoff = new MutableRoaringBitmap(); + it.nextBatch(buffer); + turnoff.add(buffer); + bitmap.andNot(turnoff); + return bitmap; + } +} \ No newline at end of file From 8dd4a5ec22531704ab834db66af89804c17fe37e Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 18 Nov 2023 00:25:06 +0100 Subject: [PATCH 018/167] avoid ior() with full container (#681) --- .../java/org/roaringbitmap/RoaringBitmap.java | 16 ++++++++-------- .../buffer/ImmutableRoaringBitmap.java | 8 ++++---- .../buffer/MutableRoaringBitmap.java | 8 ++++---- .../java/org/roaringbitmap/TestRunContainer.java | 7 +++++++ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index ff1151b18..4f3fa11c6 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -1419,10 +1419,10 @@ public void orNot(final RoaringBitmap other, long rangeEnd) { s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = highLowContainer.getContainerAtIndex(pos1) - .ior(key == maxKey - ? RunContainer.rangeOfOnes(0, lastRun) - : RunContainer.full()); + newValues[size] = key == maxKey + ? highLowContainer.getContainerAtIndex(pos1).ior( + RunContainer.rangeOfOnes(0, lastRun)) + : RunContainer.full(); ++pos1; s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement @@ -1507,10 +1507,10 @@ public static RoaringBitmap orNot( s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = x1.highLowContainer.getContainerAtIndex(pos1) - .ior(key == maxKey - ? RunContainer.rangeOfOnes(0, lastRun) - : RunContainer.full()); + newValues[size] = key == maxKey + ? x1.highLowContainer.getContainerAtIndex(pos1).ior( + RunContainer.rangeOfOnes(0, lastRun)) + : RunContainer.full(); ++pos1; s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java index e4443e369..146e92b9e 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java @@ -482,10 +482,10 @@ public static MutableRoaringBitmap orNot( s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = x1.highLowContainer.getContainerAtIndex(pos1) - .ior(key == maxKey - ? MappeableRunContainer.rangeOfOnes(0, lastRun) - : MappeableRunContainer.full()); + newValues[size] = key == maxKey + ? x1.highLowContainer.getContainerAtIndex(pos1).ior( + MappeableRunContainer.rangeOfOnes(0, lastRun)) + : MappeableRunContainer.full(); ++pos1; s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java index e35f5f50b..0d14472ab 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java @@ -972,10 +972,10 @@ public void orNot(ImmutableRoaringBitmap other, long rangeEnd) { s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = highLowContainer.getContainerAtIndex(pos1) - .ior(key == maxKey - ? MappeableRunContainer.rangeOfOnes(0, lastRun) - : MappeableRunContainer.full()); + newValues[size] = key == maxKey + ? highLowContainer.getContainerAtIndex(pos1).ior( + MappeableRunContainer.rangeOfOnes(0, lastRun)) + : MappeableRunContainer.full(); ++pos1; s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java index 8c354f075..b31b14c08 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java @@ -3948,6 +3948,13 @@ public void testRangeConsumer() { consumer10.assertAllPresent(); } + @Test + public void iorWithFullContainer() { + Container container = new ArrayContainer(new char[] {1, 3, 4, (char)-1}); + container = container.ior(RunContainer.full()); + assertEquals(RunContainer.full(), container); + } + private static int lower16Bits(int x) { return ((char)x) & 0xFFFF; } From ed2c88f313aaf449c67940682d6683b89b9c9bf6 Mon Sep 17 00:00:00 2001 From: ashishkf <74931069+ashishkf@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:42:45 -0800 Subject: [PATCH 019/167] unit test to expose batchiterator.advanceIfNeeded bug and fix (#689) * Added unit test for expose batchiterator.advanceIfNext bug * Fix batchiterator's advanceIfNeeded to logic to handle run lengths of zero * Addressed comments --- .../roaringbitmap/buffer/RunBatchIterator.java | 9 +++++---- .../RoaringBitmapBatchIteratorTest.java | 1 + ...ImmutableRoaringBitmapBatchIteratorTest.java | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java index 1ba04f7ea..4b4c2fea3 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java @@ -62,14 +62,15 @@ public void advanceIfNeeded(char target) { do { int runStart = runs.getValue(run); int runLength = runs.getLength(run); - if (runStart <= target && runStart + runLength > target) { - cursor = target - runStart; - break; - } if (runStart > target) { cursor = 0; break; } + int offset = target - runStart; + if (offset <= runLength) { + cursor = offset; + break; + } ++run; cursor = 0; } while (run != runs.numberOfRuns()); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java index 3ad09607f..98be641cb 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java @@ -208,4 +208,5 @@ public void testBatchIteratorWithAdvanceIfNeeded() { assertEquals(batch[1], (3 << 16) + 5); assertEquals(batch[2], (3 << 16) + 10); } + } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java index 4adeb5654..9f874d89e 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java @@ -8,10 +8,12 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import org.roaringbitmap.BatchIterator; import org.roaringbitmap.IntIterator; import org.roaringbitmap.RoaringBitmapWriter; +import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -192,4 +194,19 @@ public void testBatchIteratorWithAdvanceIfNeeded() { assertEquals(batch[1], (3 << 16) + 5); assertEquals(batch[2], (3 << 16) + 10); } + + @ParameterizedTest + @ValueSource(ints = {10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 24}) + public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { + MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24); + bitmap.runOptimize(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(number); + assertTrue(it.hasNext()); + int[] batch = new int[10]; + int n = it.nextBatch(batch); + int i = Arrays.binarySearch(batch, 0, n, number); + assertTrue(i >= 0, "key " + number + " not found"); + assertEquals(batch[i], number); + } } From 975ee28c29d2d0cc2bebb884ebcba0ac9eb57a2c Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 13 Dec 2023 20:56:10 -0500 Subject: [PATCH 020/167] [Gradle Release Plugin] - pre tag commit: '1.0.1'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ae1152f39..39795e5b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.1-SNAPSHOT +version = 1.0.1 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 88e3c714de94d1de4135c313c1f58b72c5613c45 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 13 Dec 2023 20:56:13 -0500 Subject: [PATCH 021/167] [Gradle Release Plugin] - new version commit: '1.0.2-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 39795e5b8..d98cf5da8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.1 +version = 1.0.2-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 1ed0242d1f298cf93d3666a754eb4bb4c5180c4c Mon Sep 17 00:00:00 2001 From: ashishkf <74931069+ashishkf@users.noreply.github.com> Date: Fri, 15 Dec 2023 01:50:26 -0800 Subject: [PATCH 022/167] Fix roaringbitmap - batchiterator's advanceIfNeeded to handle run lengths of zero (#691) --- .../org/roaringbitmap/RunBatchIterator.java | 9 +++++---- .../RoaringBitmapBatchIteratorTest.java | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java index 5aed07f95..159e3e2d9 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java @@ -60,14 +60,15 @@ public void advanceIfNeeded(char target) { do { int runStart = runs.getValue(run); int runLength = runs.getLength(run); - if (runStart <= target && runStart + runLength > target) { - cursor = target - runStart; - break; - } if (runStart > target) { cursor = 0; break; } + int offset = target - runStart; + if (offset <= runLength) { + cursor = offset; + break; + } ++run; cursor = 0; } while (run != runs.numberOfRuns()); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java index 98be641cb..6367b8b15 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java @@ -8,7 +8,10 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.roaringbitmap.buffer.MutableRoaringBitmap; +import java.util.Arrays; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -209,4 +212,19 @@ public void testBatchIteratorWithAdvanceIfNeeded() { assertEquals(batch[2], (3 << 16) + 10); } + @ParameterizedTest + @ValueSource(ints = {10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 24}) + public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24); + bitmap.runOptimize(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(number); + assertTrue(it.hasNext()); + int[] batch = new int[10]; + int n = it.nextBatch(batch); + int i = Arrays.binarySearch(batch, 0, n, number); + assertTrue(i >= 0, "key " + number + " not found"); + assertEquals(batch[i], number); + } + } From 16bb8310245829793fcbfaf10e1b6b3243d23be3 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:23:12 +0100 Subject: [PATCH 023/167] retired getContainer() removed (#708) From a8c6c4a52cc9dbc266f9acb9c32071d287d7ad4e Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:35:26 +0100 Subject: [PATCH 024/167] Code deduplication in operations over array containers when conversion from array containers to bitmap (#683) * code deduplication in ior() for array containers * code deduplication when converting to bitmap from array containers * use ixor() instead of xor() to avoid cloning --- .../org/roaringbitmap/ArrayContainer.java | 86 +-------- .../buffer/MappeableArrayContainer.java | 178 +----------------- 2 files changed, 16 insertions(+), 248 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index c3cea2c26..9bc050034 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -725,28 +725,8 @@ public boolean intersects(int minimum, int supremum) { @Override public Container ior(final ArrayContainer value2) { int totalCardinality = this.getCardinality() + value2.getCardinality(); - if (totalCardinality > DEFAULT_MAX_SIZE) {// it could be a bitmap! - BitmapContainer bc = new BitmapContainer(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = value2.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] |= (1L << v); - } - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] |= (1L << v); - } - bc.cardinality = 0; - for (long k : bc.bitmap) { - bc.cardinality += Long.bitCount(k); - } - if (bc.cardinality <= DEFAULT_MAX_SIZE) { - return bc.toArrayContainer(); - } else if (bc.isFull()) { - return RunContainer.full(); - } - return bc; + if (totalCardinality > DEFAULT_MAX_SIZE) { + return toBitmapContainer().lazyIOR(value2).repairAfterLazy(); } if (totalCardinality >= content.length) { int newCapacity = calculateCapacity(totalCardinality); @@ -969,28 +949,8 @@ int numberOfRuns() { public Container or(final ArrayContainer value2) { final ArrayContainer value1 = this; int totalCardinality = value1.getCardinality() + value2.getCardinality(); - if (totalCardinality > DEFAULT_MAX_SIZE) {// it could be a bitmap! - BitmapContainer bc = new BitmapContainer(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = value2.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] |= (1L << v); - } - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] |= (1L << v); - } - bc.cardinality = 0; - for (long k : bc.bitmap) { - bc.cardinality += Long.bitCount(k); - } - if (bc.cardinality <= DEFAULT_MAX_SIZE) { - return bc.toArrayContainer(); - } else if (bc.isFull()) { - return RunContainer.full(); - } - return bc; + if (totalCardinality > DEFAULT_MAX_SIZE) { + return toBitmapContainer().lazyIOR(value2).repairAfterLazy(); } ArrayContainer answer = new ArrayContainer(totalCardinality); answer.cardinality = @@ -1343,26 +1303,8 @@ public void writeExternal(ObjectOutput out) throws IOException { public Container xor(final ArrayContainer value2) { final ArrayContainer value1 = this; final int totalCardinality = value1.getCardinality() + value2.getCardinality(); - if (totalCardinality > DEFAULT_MAX_SIZE) {// it could be a bitmap! - BitmapContainer bc = new BitmapContainer(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = value2.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] ^= (1L << v); - } - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] ^= (1L << v); - } - bc.cardinality = 0; - for (long k : bc.bitmap) { - bc.cardinality += Long.bitCount(k); - } - if (bc.cardinality <= DEFAULT_MAX_SIZE) { - return bc.toArrayContainer(); - } - return bc; + if (totalCardinality > DEFAULT_MAX_SIZE) { + return toBitmapContainer().ixor(value2); } ArrayContainer answer = new ArrayContainer(totalCardinality); answer.cardinality = Util.unsignedExclusiveUnion2by2(value1.content, value1.getCardinality(), @@ -1499,20 +1441,8 @@ public void forAllInRange(char startValue, char endValue, final RelativeRangeCon protected Container lazyor(ArrayContainer value2) { final ArrayContainer value1 = this; int totalCardinality = value1.getCardinality() + value2.getCardinality(); - if (totalCardinality > ARRAY_LAZY_LOWERBOUND) {// it could be a bitmap! - BitmapContainer bc = new BitmapContainer(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = value2.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] |= (1L << v); - } - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content[k]; - final int i = (v) >>> 6; - bc.bitmap[i] |= (1L << v); - } - bc.cardinality = -1; - return bc; + if (totalCardinality > ARRAY_LAZY_LOWERBOUND) { + return toBitmapContainer().lazyIOR(value2); } ArrayContainer answer = new ArrayContainer(totalCardinality); answer.cardinality = diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index c3a9a6858..63122aae1 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -865,51 +865,8 @@ public boolean intersects(MappeableRunContainer x) { @Override public MappeableContainer ior(final MappeableArrayContainer value2) { final int totalCardinality = getCardinality() + value2.getCardinality(); - if (totalCardinality > DEFAULT_MAX_SIZE) {// it could be a bitmap! - final MappeableBitmapContainer bc = new MappeableBitmapContainer(); - if (!BufferUtil.isBackedBySimpleArray(bc.bitmap)) { - throw new RuntimeException("Should not happen. Internal bug."); - } - long[] bitArray = bc.bitmap.array(); - if (BufferUtil.isBackedBySimpleArray(value2.content)) { - char[] sarray = value2.content.array(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } else { - for (int k = 0; k < value2.cardinality; ++k) { - char v2 = value2.content.get(k); - final int i = (v2) >>> 6; - bitArray[i] |= (1L << v2); - } - } - if (BufferUtil.isBackedBySimpleArray(content)) { - char[] sarray = content.array(); - for (int k = 0; k < cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } else { - for (int k = 0; k < cardinality; ++k) { - char v = content.get(k); - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } - bc.cardinality = 0; - int len = bc.bitmap.limit(); - for (int index = 0; index < len; ++index) { - bc.cardinality += Long.bitCount(bitArray[index]); - } - if (bc.cardinality <= DEFAULT_MAX_SIZE) { - return bc.toArrayContainer(); - } else if (bc.isFull()) { - return MappeableRunContainer.full(); - } - return bc; + if (totalCardinality > DEFAULT_MAX_SIZE) { + return toBitmapContainer().lazyIOR(value2).repairAfterLazy(); } if (totalCardinality >= content.limit()) { int newCapacity = calculateCapacity(totalCardinality); @@ -1184,51 +1141,8 @@ int numberOfRuns() { public MappeableContainer or(final MappeableArrayContainer value2) { final MappeableArrayContainer value1 = this; final int totalCardinality = value1.getCardinality() + value2.getCardinality(); - if (totalCardinality > DEFAULT_MAX_SIZE) {// it could be a bitmap! - final MappeableBitmapContainer bc = new MappeableBitmapContainer(); - if (!BufferUtil.isBackedBySimpleArray(bc.bitmap)) { - throw new RuntimeException("Should not happen. Internal bug."); - } - long[] bitArray = bc.bitmap.array(); - if (BufferUtil.isBackedBySimpleArray(value2.content)) { - char[] sarray = value2.content.array(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } else { - for (int k = 0; k < value2.cardinality; ++k) { - char v2 = value2.content.get(k); - final int i = (v2) >>> 6; - bitArray[i] |= (1L << v2); - } - } - if (BufferUtil.isBackedBySimpleArray(this.content)) { - char[] sarray = this.content.array(); - for (int k = 0; k < this.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } else { - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content.get(k); - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } - bc.cardinality = 0; - int len = bc.bitmap.limit(); - for (int index = 0; index < len; ++index) { - bc.cardinality += Long.bitCount(bitArray[index]); - } - if (bc.cardinality <= DEFAULT_MAX_SIZE) { - return bc.toArrayContainer(); - } else if (bc.isFull()) { - return MappeableRunContainer.full(); - } - return bc; + if (totalCardinality > DEFAULT_MAX_SIZE) { + return toBitmapContainer().lazyIOR(value2).repairAfterLazy(); } final MappeableArrayContainer answer = new MappeableArrayContainer(totalCardinality); if (BufferUtil.isBackedBySimpleArray(value1.content) @@ -1253,42 +1167,8 @@ public MappeableContainer or(final MappeableArrayContainer value2) { protected MappeableContainer lazyor(final MappeableArrayContainer value2) { final MappeableArrayContainer value1 = this; final int totalCardinality = value1.getCardinality() + value2.getCardinality(); - if (totalCardinality > ARRAY_LAZY_LOWERBOUND) {// it could be a bitmap! - final MappeableBitmapContainer bc = new MappeableBitmapContainer(); - if (!BufferUtil.isBackedBySimpleArray(bc.bitmap)) { - throw new RuntimeException("Should not happen. Internal bug."); - } - long[] bitArray = bc.bitmap.array(); - if (BufferUtil.isBackedBySimpleArray(value2.content)) { - char[] sarray = value2.content.array(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } else { - for (int k = 0; k < value2.cardinality; ++k) { - char v2 = value2.content.get(k); - final int i = (v2) >>> 6; - bitArray[i] |= (1L << v2); - } - } - if (BufferUtil.isBackedBySimpleArray(this.content)) { - char[] sarray = this.content.array(); - for (int k = 0; k < this.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } else { - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content.get(k); - final int i = (v) >>> 6; - bitArray[i] |= (1L << v); - } - } - bc.cardinality = -1; - return bc; + if (totalCardinality > ARRAY_LAZY_LOWERBOUND) { + return toBitmapContainer().lazyIOR(value2); } final MappeableArrayContainer answer = new MappeableArrayContainer(totalCardinality); if (BufferUtil.isBackedBySimpleArray(value1.content) @@ -1694,50 +1574,8 @@ public void writeExternal(ObjectOutput out) throws IOException { public MappeableContainer xor(final MappeableArrayContainer value2) { final MappeableArrayContainer value1 = this; final int totalCardinality = value1.getCardinality() + value2.getCardinality(); - if (totalCardinality > DEFAULT_MAX_SIZE) {// it could be a bitmap! - final MappeableBitmapContainer bc = new MappeableBitmapContainer(); - if (!BufferUtil.isBackedBySimpleArray(bc.bitmap)) { - throw new RuntimeException("Should not happen. Internal bug."); - } - long[] bitArray = bc.bitmap.array(); - if (BufferUtil.isBackedBySimpleArray(value2.content)) { - char[] sarray = value2.content.array(); - for (int k = 0; k < value2.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] ^= (1L << v); - } - } else { - for (int k = 0; k < value2.cardinality; ++k) { - char v2 = value2.content.get(k); - final int i = (v2) >>> 6; - bitArray[i] ^= (1L << v2); - } - } - if (BufferUtil.isBackedBySimpleArray(this.content)) { - char[] sarray = this.content.array(); - for (int k = 0; k < this.cardinality; ++k) { - char v = sarray[k]; - final int i = (v) >>> 6; - bitArray[i] ^= (1L << v); - } - } else { - for (int k = 0; k < this.cardinality; ++k) { - char v = this.content.get(k); - final int i = (v) >>> 6; - bitArray[i] ^= (1L << v); - } - } - - bc.cardinality = 0; - int len = bc.bitmap.limit(); - for (int index = 0; index < len; ++index) { - bc.cardinality += Long.bitCount(bitArray[index]); - } - if (bc.cardinality <= DEFAULT_MAX_SIZE) { - return bc.toArrayContainer(); - } - return bc; + if (totalCardinality > DEFAULT_MAX_SIZE) { + return toBitmapContainer().ixor(value2); } final MappeableArrayContainer answer = new MappeableArrayContainer(totalCardinality); if (BufferUtil.isBackedBySimpleArray(value1.content) From fc882a83846de078f19af628aec1dcee1a407f02 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:45:39 +0100 Subject: [PATCH 025/167] Avoid repeated counting cardinality within call to addDigit() on bitmap slice index (#693) * use isEmpty() on bitmap instead of getCardinality() * not empty is correct From 9d7d35e936a73b0001bcd47277dea4768995d173 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:47:02 +0100 Subject: [PATCH 026/167] Addition status check using contains (#694) * avoid compute cardinality for run container using contains() instead * benchmark for optimized checkedAdd() * benchmark uses enums for testing scenarios From 492061d1f118e66ee6acbc8825c3f5e1359eefb5 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:48:17 +0100 Subject: [PATCH 027/167] Selection of top largest values in BSI optimized (#695) * benchmark for removal top values from bitmap * remove current value when iterating on bitmap works properly * use remove() to delete first K values From ac6a98de1126a3d523c9ed1f0ba74ac2d04e3ebe Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:50:21 +0100 Subject: [PATCH 028/167] AddOffset() optimization for array containers (#696) * addOffset() optimized for array containers * avoid use of local variable for optimized version * use of local variable variant is the most performant * renamed methods due to their confusing overloading --- .../src/main/java/org/roaringbitmap/Util.java | 140 ++++++---- .../org/roaringbitmap/buffer/BufferUtil.java | 154 ++++++----- .../org/roaringbitmap/AddOffsetBenchmark.java | 239 ++++++++++++++++++ 3 files changed, 419 insertions(+), 114 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java index d82ca0acc..2048e7834 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java @@ -30,67 +30,99 @@ public final class Util { * @return return an array made of two containers */ public static Container[] addOffset(Container source, char offsets) { - // could be a whole lot faster, this is a simple implementation if(source instanceof ArrayContainer) { - ArrayContainer c = (ArrayContainer) source; - ArrayContainer low = new ArrayContainer(c.cardinality); - ArrayContainer high = new ArrayContainer(c.cardinality); - for(int k = 0; k < c.cardinality; k++) { - int val = c.content[k]; - val += (int) (offsets); - if(val <= 0xFFFF) { - low.content[low.cardinality++] = (char) val; - } else { - high.content[high.cardinality++] = (char) val; - } - } - return new Container[] {low, high}; + return addOffsetArray((ArrayContainer) source, offsets); } else if (source instanceof BitmapContainer) { - BitmapContainer c = (BitmapContainer) source; - BitmapContainer low = new BitmapContainer(); - BitmapContainer high = new BitmapContainer(); - low.cardinality = -1; - high.cardinality = -1; - final int b = (int) (offsets) >>> 6; - final int i = (int) (offsets) % 64; - if(i == 0) { - System.arraycopy(c.bitmap, 0, low.bitmap, b, 1024 - b); - System.arraycopy(c.bitmap, 1024 - b, high.bitmap, 0, b ); - } else { - low.bitmap[b + 0] = c.bitmap[0] << i; - for(int k = 1; k < 1024 - b; k++) { - low.bitmap[b + k] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64-i)); - } - for(int k = 1024 - b; k < 1024 ; k++) { - high.bitmap[k - (1024 - b)] = - (c.bitmap[k] << i) - | (c.bitmap[k - 1] >>> (64-i)); - } - high.bitmap[b] = (c.bitmap[1024 - 1] >>> (64-i)); - } - return new Container[] {low.repairAfterLazy(), high.repairAfterLazy()}; + return addOffsetBitmap((BitmapContainer) source, offsets); } else if (source instanceof RunContainer) { - RunContainer input = (RunContainer) source; - RunContainer low = new RunContainer(); - RunContainer high = new RunContainer(); - for(int k = 0 ; k < input.nbrruns; k++) { - int val = (input.getValue(k)); - val += (int) (offsets); - int finalval = val + (input.getLength(k)); - if(val <= 0xFFFF) { - if(finalval <= 0xFFFF) { - low.smartAppend((char)val,input.getLength(k)); - } else { - low.smartAppend((char)val,(char)(0xFFFF-val)); - high.smartAppend((char) 0,(char)finalval); - } + return addOffsetRun((RunContainer) source, offsets); + } + throw new RuntimeException("unknown container type"); + } + + private static Container[] addOffsetArray(ArrayContainer source, char offsets) { + int splitIndex; + if (source.first() + offsets > 0xFFFF) { + splitIndex = 0; + } else if (source.last() + offsets < 0xFFFF) { + splitIndex = source.cardinality; + } else { + splitIndex = Util.unsignedBinarySearch(source.content, 0, source.cardinality, + (char) (0x10000 - offsets)); + if (splitIndex < 0) { + splitIndex = -splitIndex - 1; + } + } + + ArrayContainer low = splitIndex == 0 + ? new ArrayContainer() + : new ArrayContainer(splitIndex); + ArrayContainer high = source.cardinality - splitIndex == 0 + ? new ArrayContainer() + : new ArrayContainer(source.cardinality - splitIndex); + + int lowCardinality = 0; + for (int k = 0; k < splitIndex; k++) { + int val = source.content[k] + offsets; + low.content[lowCardinality++] = (char) val; + } + low.cardinality = lowCardinality; + + int highCardinality = 0; + for (int k = splitIndex; k < source.cardinality; k++) { + int val = source.content[k] + offsets; + high.content[highCardinality++] = (char) val; + } + high.cardinality = highCardinality; + + return new Container[]{low, high}; + } + + private static Container[] addOffsetBitmap(BitmapContainer source, char offsets) { + BitmapContainer c = source; + BitmapContainer low = new BitmapContainer(); + BitmapContainer high = new BitmapContainer(); + low.cardinality = -1; + high.cardinality = -1; + final int b = (int) offsets >>> 6; + final int i = (int) offsets % 64; + if(i == 0) { + System.arraycopy(c.bitmap, 0, low.bitmap, b, 1024 - b); + System.arraycopy(c.bitmap, 1024 - b, high.bitmap, 0, b); + } else { + low.bitmap[b] = c.bitmap[0] << i; + for(int k = 1; k < 1024 - b; k++) { + low.bitmap[b + k] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64 - i)); + } + for(int k = 1024 - b; k < 1024 ; k++) { + high.bitmap[k - (1024 - b)] = + (c.bitmap[k] << i) + | (c.bitmap[k - 1] >>> (64 - i)); + } + high.bitmap[b] = c.bitmap[1024 - 1] >>> (64 - i); + } + return new Container[] {low.repairAfterLazy(), high.repairAfterLazy()}; + } + + private static Container[] addOffsetRun(RunContainer source, char offsets) { + RunContainer input = source; + RunContainer low = new RunContainer(); + RunContainer high = new RunContainer(); + for(int k = 0 ; k < input.nbrruns; k++) { + int val = input.getValue(k) + offsets; + int finalval = val + input.getLength(k); + if(val <= 0xFFFF) { + if(finalval <= 0xFFFF) { + low.smartAppend((char) val, input.getLength(k)); } else { - high.smartAppend((char)val,input.getLength(k)); + low.smartAppend((char) val, (char) (0xFFFF - val)); + high.smartAppend((char) 0, (char) finalval); } + } else { + high.smartAppend((char) val, input.getLength(k)); } - return new Container[] {low, high}; } - throw new RuntimeException("unknown container type"); // never happens + return new Container[]{low, high}; } /** diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java index 80055274d..6421bf65a 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java @@ -31,74 +31,108 @@ public final class BufferUtil { * @return return an array made of two containers */ public static MappeableContainer[] addOffset(MappeableContainer source, char offsets) { - // could be a whole lot faster, this is a simple implementation if(source instanceof MappeableArrayContainer) { - MappeableArrayContainer c = (MappeableArrayContainer) source; - MappeableArrayContainer low = new MappeableArrayContainer(c.cardinality); - MappeableArrayContainer high = new MappeableArrayContainer(c.cardinality); - for(int k = 0; k < c.cardinality; k++) { - int val = (c.content.get(k)); - val += (int) (offsets); - if(val <= 0xFFFF) { - low.content.put(low.cardinality++, (char) val); - } else { - high.content.put(high.cardinality++, (char) val); - } - } - return new MappeableContainer[] {low, high}; + return addOffsetArray((MappeableArrayContainer) source, offsets); } else if (source instanceof MappeableBitmapContainer) { - MappeableBitmapContainer c = (MappeableBitmapContainer) source; - MappeableBitmapContainer low = new MappeableBitmapContainer(); - MappeableBitmapContainer high = new MappeableBitmapContainer(); - low.cardinality = -1; - high.cardinality = -1; - final int b = (int) (offsets) >>> 6; - final int i = (int) (offsets) % 64; - if(i == 0) { - for(int k = 0; k < 1024 - b; k++) { - low.bitmap.put(b + k, c.bitmap.get(k)); - } - for(int k = 1024 - b; k < 1024 ; k++) { - high.bitmap.put(k - (1024 - b),c.bitmap.get(k)); - } - } else { - low.bitmap.put(b + 0, c.bitmap.get(0) << i); - for(int k = 1; k < 1024 - b; k++) { - low.bitmap.put(b + k, (c.bitmap.get(k) << i) - | (c.bitmap.get(k - 1) >>> (64-i))); - } - for(int k = 1024 - b; k < 1024 ; k++) { - high.bitmap.put(k - (1024 - b), - (c.bitmap.get(k) << i) - | (c.bitmap.get(k - 1) >>> (64-i))); - } - high.bitmap.put(b, (c.bitmap.get(1024 - 1) >>> (64-i))); - } - return new MappeableContainer[] {low.repairAfterLazy(), high.repairAfterLazy()}; + return addOffsetBitmap((MappeableBitmapContainer) source, offsets); } else if (source instanceof MappeableRunContainer) { - MappeableRunContainer c = (MappeableRunContainer) source; - MappeableRunContainer low = new MappeableRunContainer(); - MappeableRunContainer high = new MappeableRunContainer(); - for(int k = 0 ; k < c.nbrruns; k++) { - int val = (c.getValue(k)); - val += (int) (offsets); - int finalval = val + (c.getLength(k)); - if(val <= 0xFFFF) { - if(finalval <= 0xFFFF) { - low.smartAppend((char)val,c.getLength(k)); - } else { - low.smartAppend((char)val,(char)(0xFFFF-val)); - high.smartAppend((char) 0,(char)finalval); - } + return addOffsetRun((MappeableRunContainer) source, offsets); + } + throw new RuntimeException("unknown container type"); // never happens + } + + private static MappeableContainer[] addOffsetArray(MappeableArrayContainer source, + char offsets) { + int splitIndex; + if (source.first() + offsets > 0xFFFF) { + splitIndex = 0; + } else if (source.last() + offsets < 0xFFFF) { + splitIndex = source.cardinality; + } else { + splitIndex = BufferUtil.unsignedBinarySearch(source.content, 0, source.cardinality, + (char) (0x10000 - offsets)); + if (splitIndex < 0) { + splitIndex = -splitIndex - 1; + } + } + MappeableArrayContainer low = splitIndex == 0 + ? new MappeableArrayContainer() + : new MappeableArrayContainer(splitIndex); + MappeableArrayContainer high = source.cardinality - splitIndex == 0 + ? new MappeableArrayContainer() + : new MappeableArrayContainer(source.cardinality - splitIndex); + + int lowCardinality = 0; + for (int k = 0; k < splitIndex; k++) { + int val = source.content.get(k) + offsets; + low.content.put(lowCardinality++, (char) val); + } + low.cardinality = lowCardinality; + + int highCardinality = 0; + for (int k = splitIndex; k < source.cardinality; k++) { + int val = source.content.get(k) + offsets; + high.content.put(highCardinality++, (char) val); + } + high.cardinality = highCardinality; + + return new MappeableContainer[]{low, high}; + } + + private static MappeableContainer[] addOffsetBitmap(MappeableBitmapContainer source, + char offsets) { + MappeableBitmapContainer c = source; + MappeableBitmapContainer low = new MappeableBitmapContainer(); + MappeableBitmapContainer high = new MappeableBitmapContainer(); + low.cardinality = -1; + high.cardinality = -1; + final int b = (int) offsets >>> 6; + final int i = (int) offsets % 64; + if (i == 0) { + for (int k = 0; k < 1024 - b; k++) { + low.bitmap.put(b + k, c.bitmap.get(k)); + } + for (int k = 1024 - b; k < 1024; k++) { + high.bitmap.put(k - (1024 - b), c.bitmap.get(k)); + } + } else { + //noinspection PointlessArithmeticExpression + low.bitmap.put(b + 0, c.bitmap.get(0) << i); + for (int k = 1; k < 1024 - b; k++) { + low.bitmap.put(b + k, (c.bitmap.get(k) << i) + | (c.bitmap.get(k - 1) >>> (64 - i))); + } + for (int k = 1024 - b; k < 1024; k++) { + high.bitmap.put(k - (1024 - b), + (c.bitmap.get(k) << i) + | (c.bitmap.get(k - 1) >>> (64 - i))); + } + high.bitmap.put(b, (c.bitmap.get(1024 - 1) >>> (64 - i))); + } + return new MappeableContainer[]{low.repairAfterLazy(), high.repairAfterLazy()}; + } + + private static MappeableContainer[] addOffsetRun(MappeableRunContainer source, char offsets) { + MappeableRunContainer c = source; + MappeableRunContainer low = new MappeableRunContainer(); + MappeableRunContainer high = new MappeableRunContainer(); + for (int k = 0; k < c.nbrruns; k++) { + int val = c.getValue(k); + val += offsets; + int finalval = val + c.getLength(k); + if (val <= 0xFFFF) { + if (finalval <= 0xFFFF) { + low.smartAppend((char) val, c.getLength(k)); } else { - high.smartAppend((char)val,c.getLength(k)); + low.smartAppend((char) val, (char) (0xFFFF - val)); + high.smartAppend((char) 0, (char) finalval); } + } else { + high.smartAppend((char) val, c.getLength(k)); } - return new MappeableContainer[] {low, high}; } - throw new RuntimeException("unknown container type"); // never happens + return new MappeableContainer[]{low, high}; } - /** * Find the smallest integer larger than pos such that array[pos]>= min. If none can be found, * return length. Based on code by O. Kaser. diff --git a/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java new file mode 100644 index 000000000..b7e2290cb --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java @@ -0,0 +1,239 @@ +package org.roaringbitmap; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 5000) +@Measurement(iterations = 10, timeUnit = TimeUnit.MILLISECONDS, time = 5000) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Benchmark) +@Fork(value = 1, jvmArgsPrepend = + { + "-XX:-TieredCompilation", + "-XX:+UseSerialGC", // "-XX:+UseParallelGC", + "-mx2G", + "-ms2G", + "-XX:+AlwaysPreTouch" + }) +public class AddOffsetBenchmark { + @Param({ + "ARRAY_ALL_IN_LOW", "ARRAY_HALF_TO_HALF", "ARRAY_ALL_SHIFTED_TO_HIGH", + // all variant provided for completeness only, original and current implementation are the same + // "RUN_ALL_IN_LOW", "RUN_HALF_TO_HALF", "RUN_ALL_SHIFTED_TO_HIGH", + // "BITMAP_ALL_IN_LOW", "BITMAP_HALF_TO_HALF", "BITMAP_ALL_SHIFTED_TO_HIGH", + // "BITMAP_HALF_TO_HALF_MULTIPLE_OF_LONG", "BITMAP_ALL_SHIFTED_TO_HIGH_MULTIPLE_OF_LONG", + }) + Scenario scenario; + + @SuppressWarnings("unused") + public enum Scenario { + RUN_ALL_IN_LOW(ContainerType.RUN, 0), + RUN_HALF_TO_HALF(ContainerType.RUN, 35000), + RUN_ALL_SHIFTED_TO_HIGH(ContainerType.RUN, 60000), + + ARRAY_ALL_IN_LOW(ContainerType.ARRAY, 0), + ARRAY_HALF_TO_HALF(ContainerType.ARRAY, 35000), + ARRAY_ALL_SHIFTED_TO_HIGH(ContainerType.ARRAY, 60000), + + BITMAP_ALL_IN_LOW(ContainerType.BITMAP, 0), + BITMAP_HALF_TO_HALF(ContainerType.BITMAP, 35000), + BITMAP_ALL_SHIFTED_TO_HIGH(ContainerType.BITMAP, 60000), + + BITMAP_HALF_TO_HALF_MULTIPLE_OF_LONG(ContainerType.BITMAP, 32768 + Long.SIZE * 32), // ~ 35000 + BITMAP_ALL_SHIFTED_TO_HIGH_MULTIPLE_OF_LONG(ContainerType.BITMAP, 65536 - Long.SIZE), + ; + + private final ContainerType containerType; + private final char offsets; + + Scenario(ContainerType containerType, int offsets) { + this.containerType = containerType; + this.offsets = (char) offsets; + } + + public ContainerType getContainerType() { + return containerType; + } + + public char getOffsets() { + return offsets; + } + + public Container createContainer() { + return containerType.createContainer(); + } + } + + public enum ContainerType { + RUN { + @Override + public Container createContainer() { + RunContainer rc = new RunContainer(); + for (int i = 0; i < numberOfValues; i++) { + rc.add(minValue + i * 2, minValue + i * 2 + 1); + } + return rc; + } + }, + BITMAP { + @Override + public Container createContainer() { + BitmapContainer bc = new BitmapContainer(); + for (int i = 0; i < numberOfValues; i++) { + bc.add((char) (minValue + i * 2)); + } + return bc; + } + }, ARRAY { + @Override + public Container createContainer() { + ArrayContainer ac = new ArrayContainer(); + for (int i = 0; i < numberOfValues; i++) { + ac.add((char) (minValue + i * 2)); + } + return ac; + } + }; + // value = minValue + i * 2 for i < numberOfValues, thus they lies in interval 20000 - 40000 + private static final int minValue = 20_000; + private static final int numberOfValues = 10000; + + public abstract Container createContainer(); + } + + public Container container; + public char offsets; + + + @Setup(Level.Invocation) + public void setUp() { + container = scenario.createContainer(); + offsets = scenario.getOffsets(); + } + + @Benchmark + public Container[] optimized() { + return Util.addOffset(container, offsets); + } + + @Benchmark + public Container[] optimizedFieldIncrement() { + if (container instanceof ArrayContainer) { + // only for comparison with optimized version + return addOffsetIncrementField((ArrayContainer) container, offsets); + } else { + return new Container[0]; + } + } + + @Benchmark + public Container[] original() { + return addOffsetOriginal(container, offsets); + } + + @SuppressWarnings({"RedundantCast", "PointlessArithmeticExpression", "GrazieInspection"}) + public static Container[] addOffsetOriginal(Container source, char offsets) { + // could be a whole lot faster, this is a simple implementation + if (source instanceof ArrayContainer) { + ArrayContainer c = (ArrayContainer) source; + ArrayContainer low = new ArrayContainer(c.cardinality); + ArrayContainer high = new ArrayContainer(c.cardinality); + for (int k = 0; k < c.cardinality; k++) { + int val = c.content[k]; + val += (int) (offsets); + if (val <= 0xFFFF) { + low.content[low.cardinality++] = (char) val; + } else { + high.content[high.cardinality++] = (char) val; + } + } + return new Container[]{low, high}; + } else if (source instanceof BitmapContainer) { + BitmapContainer c = (BitmapContainer) source; + BitmapContainer low = new BitmapContainer(); + BitmapContainer high = new BitmapContainer(); + low.cardinality = -1; + high.cardinality = -1; + final int b = (int) (offsets) >>> 6; + final int i = (int) (offsets) % 64; + if (i == 0) { + System.arraycopy(c.bitmap, 0, low.bitmap, b, 1024 - b); + System.arraycopy(c.bitmap, 1024 - b, high.bitmap, 0, b); + } else { + low.bitmap[b + 0] = c.bitmap[0] << i; + for (int k = 1; k < 1024 - b; k++) { + low.bitmap[b + k] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64 - i)); + } + for (int k = 1024 - b; k < 1024; k++) { + high.bitmap[k - (1024 - b)] = + (c.bitmap[k] << i) + | (c.bitmap[k - 1] >>> (64 - i)); + } + high.bitmap[b] = (c.bitmap[1024 - 1] >>> (64 - i)); + } + return new Container[]{low.repairAfterLazy(), high.repairAfterLazy()}; + } else if (source instanceof RunContainer) { + RunContainer input = (RunContainer) source; + RunContainer low = new RunContainer(); + RunContainer high = new RunContainer(); + for (int k = 0; k < input.nbrruns; k++) { + int val = (input.getValue(k)); + val += (int) (offsets); + int finalval = val + (input.getLength(k)); + if (val <= 0xFFFF) { + if (finalval <= 0xFFFF) { + low.smartAppend((char) val, input.getLength(k)); + } else { + low.smartAppend((char) val, (char) (0xFFFF - val)); + high.smartAppend((char) 0, (char) finalval); + } + } else { + high.smartAppend((char) val, input.getLength(k)); + } + } + return new Container[]{low, high}; + } + throw new RuntimeException("unknown container type"); // never happens + } + + private static Container[] addOffsetIncrementField(ArrayContainer source, char offsets) { + ArrayContainer low; + ArrayContainer high; + if (source.first() + offsets > 0xFFFF) { + low = new ArrayContainer(); + high = new ArrayContainer(source.cardinality); + for (int k = 0; k < source.cardinality; k++) { + int val = source.content[k] + offsets; + high.content[k] = (char) val; + } + high.cardinality = source.cardinality; + } else if (source.last() + offsets < 0xFFFF) { + low = new ArrayContainer(source.cardinality); + high = new ArrayContainer(); + for (int k = 0; k < source.cardinality; k++) { + int val = source.content[k] + offsets; + low.content[k] = (char) val; + } + low.cardinality = source.cardinality; + } else { + int splitIndex = Util.unsignedBinarySearch(source.content, 0, source.cardinality, + (char) ~offsets); + if (splitIndex < 0) { + splitIndex = -splitIndex - 1; + } + low = new ArrayContainer(splitIndex); + high = new ArrayContainer(source.cardinality - splitIndex); + for (int k = 0; k < splitIndex; k++) { + int val = source.content[k] + offsets; + low.content[low.cardinality++] = (char) val; + } + for (int k = splitIndex; k < source.cardinality; k++) { + int val = source.content[k] + offsets; + high.content[high.cardinality++] = (char) val; + } + } + return new Container[]{low, high}; + } +} \ No newline at end of file From 6d5dcff3527215ce6b50a67aa237523da2421692 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:51:30 +0100 Subject: [PATCH 029/167] avoid one negation (#697) --- .../src/main/java/org/roaringbitmap/RangeBitmap.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java index 9962418e6..39eee00a5 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java @@ -679,7 +679,7 @@ private long countRange(long threshold, boolean upper, RoaringBitmap context) { private void evaluateHorizontalSliceRange(long remaining, long threshold, long containerMask) { // most significant absent bit in the threshold for which there is no container; // everything before this is wasted work, so we just skip over the containers - int skip = 64 - Long.numberOfLeadingZeros(((~threshold & ~containerMask) & mask)); + int skip = 64 - Long.numberOfLeadingZeros((~(threshold | containerMask) & mask)); int slice = 0; if (skip > 0) { for (; slice < skip; ++slice) { @@ -1019,13 +1019,13 @@ private void evaluateHorizontalSlice(long containerMask, long remaining, long lo long upper) { // most significant absent bit in the threshold for which there is no container; // everything before this is wasted work, so we just skip over the containers - int skipLow = 64 - Long.numberOfLeadingZeros(((~lower & ~containerMask) & mask)); + int skipLow = 64 - Long.numberOfLeadingZeros((~(lower | containerMask) & mask)); if (skipLow == 64) { lower = 0L; } else if (skipLow > 0) { lower &= -(1L << skipLow); } - int skipHigh = 64 - Long.numberOfLeadingZeros(((~upper & ~containerMask) & mask)); + int skipHigh = 64 - Long.numberOfLeadingZeros((~(upper | containerMask) & mask)); if (skipHigh == 64) { upper = 0L; } else if (skipHigh > 0) { From c509d69d0b5d8a692f3b94976a131dcaaa2f9e52 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:51:59 +0100 Subject: [PATCH 030/167] integer overflow (#698) --- .../java/org/roaringbitmap/TestRoaringBitmap.java | 2 +- .../roaringbitmap/buffer/TestRoaringBitmap.java | 14 +++++++------- .../longlong/TestRoaring64NavigableMap.java | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java index c983489d0..cb601cf8f 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java @@ -1994,7 +1994,7 @@ public void orBigIntsTest() { rb.add(i); } - for (int i = 1 << 31 + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 5) { + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 5) { hs.add(i); rb2.add(i); } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java index d68faa6ab..27ef64ac2 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java @@ -1993,14 +1993,14 @@ public void flipTest7A() { // within 1 word, first container @Test public void flipTestBigInt() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); - rb.add( Integer.MAX_VALUE + 100000); - rb.add( Integer.MAX_VALUE + 100002); + rb.add((int) (Integer.MAX_VALUE + 100000L)); + rb.add((int) (Integer.MAX_VALUE + 100002L)); final MutableRoaringBitmap rb2 = MutableRoaringBitmap.flip(rb, Integer.MAX_VALUE+100001L , Integer.MAX_VALUE+200000L); assertEquals(99999, rb2.getCardinality()); - assertTrue(rb2.contains(Integer.MAX_VALUE+100000)); - assertFalse(rb2.contains(Integer.MAX_VALUE+100002)); - assertTrue(rb2.contains(Integer.MAX_VALUE+199999)); + assertTrue(rb2.contains((int) (Integer.MAX_VALUE + 100000L))); + assertFalse(rb2.contains((int) (Integer.MAX_VALUE + 100002L))); + assertTrue(rb2.contains((int) (Integer.MAX_VALUE + 199999L))); } @@ -3019,10 +3019,10 @@ public void testIteratorMapped() { public void testIteratorMappedBigInts() { MutableRoaringBitmap orb = new MutableRoaringBitmap(); for (int k = 0; k < 4000; ++k) { - orb.add((1<<32)+k); + orb.add((1 << 31) + k); } for (int k = 0; k < 1000; ++k) { - orb.add((1<<32)+k * 100); + orb.add((1 << 31) + k * 100); } MutableRoaringBitmap ocopy1 = new MutableRoaringBitmap(); for (int x : orb) { diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java index 6fd4dcb1e..6921d1e17 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java @@ -1516,11 +1516,11 @@ public void testLongSizeInBytes() { @Test public void testLazyOr() { - Roaring64NavigableMap map1 = Roaring64NavigableMap.bitmapOf(1 << 16, 1 << 18, 1 << 19, 1 << 33); + Roaring64NavigableMap map1 = Roaring64NavigableMap.bitmapOf(1 << 16, 1 << 18, 1 << 19, 1L << 33); map1.naivelazyor(Roaring64NavigableMap.bitmapOf(4, 7, 8, 9)); map1.naivelazyor(Roaring64NavigableMap.bitmapOf(1, 2, 3, 4, 5, 1 << 16, 1 << 17, 1 << 20)); map1.repairAfterLazy(); - Roaring64NavigableMap map2 = Roaring64NavigableMap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20 , 1 << 33); + Roaring64NavigableMap map2 = Roaring64NavigableMap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20 , 1L << 33); assertEquals(map2, map1); } From e7bfb1b4fd2c258de0c4f11939a31f68f2faa00a Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:53:23 +0100 Subject: [PATCH 031/167] bitwise and instead of conditional (#699) --- .../src/main/java/org/roaringbitmap/RangeBitmap.java | 8 ++++---- .../org/roaringbitmap/buffer/ImmutableRoaringArray.java | 2 +- .../org/roaringbitmap/buffer/MutableRoaringArray.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java index 39eee00a5..5c676b71b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java @@ -929,7 +929,7 @@ public RoaringBitmap compute(long lower, long upper) { bits = low.bits; } else { bits = low.bits; - for (int i = 0; i < bits.length & i < high.bits.length; i++) { + for (int i = 0; i < Math.min(bits.length, high.bits.length); i++) { bits[i] &= high.bits[i]; } } @@ -963,7 +963,7 @@ public long count(long lower, long upper) { } else if (high.full) { count += cardinalityInBitmapRange(low.bits, 0, remainder); } else { - for (int i = 0; i < low.bits.length & i < high.bits.length; i++) { + for (int i = 0; i < Math.min(low.bits.length, high.bits.length); i++) { high.bits[i] &= low.bits[i]; } count += cardinalityInBitmapRange(high.bits, 0, remainder); @@ -1001,7 +1001,7 @@ public long count(long lower, long upper, RoaringBitmap context) { } else if (high.full) { count += new BitmapContainer(low.bits, -1).andCardinality(container); } else { - for (int i = 0; i < low.bits.length & i < high.bits.length; i++) { + for (int i = 0; i < Math.min(low.bits.length, high.bits.length); i++) { high.bits[i] &= low.bits[i]; } count += new BitmapContainer(high.bits, -1).andCardinality(container); @@ -1337,7 +1337,7 @@ public void or(MappeableContainer container) { } public void and(MappeableContainer container) { - if (!empty & !container.isFull()) { + if (!empty && !container.isFull()) { container.andInto(bits); full = false; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java index a44d881fe..99d4d1999 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java @@ -275,7 +275,7 @@ public int getSizeInBytes() { @Override public boolean hasContainer() { - return 0 <= k & k < ImmutableRoaringArray.this.size; + return 0 <= k && k < ImmutableRoaringArray.this.size; } @Override diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java index 85fdffc9f..cf9948e71 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java @@ -500,7 +500,7 @@ public int getSizeInBytes() { @Override public boolean hasContainer() { - return 0 <= k & k < MutableRoaringArray.this.size; + return 0 <= k && k < MutableRoaringArray.this.size; } @Override From 769241f7b2e5b2955c5b64a62f7c196eeaa53ce2 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:55:28 +0100 Subject: [PATCH 032/167] Creation of range mask simplified (#700) * rangeMask simplification * rangeMask from number of slices simplification --- .../java/org/roaringbitmap/RangeBitmap.java | 4 +- .../org/roaringbitmap/RangeBitmapTest.java | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java index 5c676b71b..efb78ff46 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java @@ -75,7 +75,7 @@ public static RangeBitmap map(ByteBuffer buffer) { } int sliceCount = source.get() & 0xFF; int maxKey = source.getChar(); - long mask = sliceCount == 64 ? -1L : (1L << sliceCount) - 1; + long mask = -1L >>> (64 - sliceCount); byte bytesPerMask = (byte) ((sliceCount + 7) >>> 3); long maxRid = source.getInt() & 0xFFFFFFFFL; int masksOffset = source.position(); @@ -1609,7 +1609,7 @@ private Container containerForSlice(int sliceNumber) { */ private static long rangeMask(long maxValue) { int lz = Long.numberOfLeadingZeros(maxValue | 1); - return lz == 0 ? -1L : (1L << (64 - lz)) - 1; + return -1L >>> lz; } private static byte bytesPerMask(long maxValue) { diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java index bd8689ee5..bbe4f61f1 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java @@ -1054,4 +1054,56 @@ LongSupplier of(long seed, double... params) { abstract LongSupplier of(long seed, double... params); } + + private static long rangeMaskOriginal(long maxValue) { + int lz = Long.numberOfLeadingZeros(maxValue | 1); + return lz == 0 ? -1L : (1L << (64 - lz)) - 1; + } + + private static long rangeMaskOptimized(long maxValue) { + int lz = Long.numberOfLeadingZeros(maxValue | 1); + return -1L >>> lz; + } + + @Test + public void rangeMaskRandom() { + Random r = new Random(0); + for (int i = 0; i < 10_000; i++) { + long value = r.nextLong(); + assertEquals(rangeMaskOriginal(value), rangeMaskOptimized(value)); + } + } + @Test + public void rangeMaskExpressionSimplification() { + for (int lz = 0; lz < 64; lz++) { + long original = lz == 0 ? -1L : (1L << (64 - lz)) - 1; + long simplified = -1L >>> lz; + assertEquals(Long.toBinaryString(original), Long.toBinaryString(simplified), "lz=" + lz); + } + } + + private static long rangeMaskOriginal2(long sliceCount) { + return sliceCount == 64 ? -1L : (1L << sliceCount) - 1; + } + + private static long rangeMaskSimplified2(long sliceCount) { + return -1L >>> (64 - sliceCount); + } + + @Test + public void rangeMaskRandom2() { + Random r = new Random(0); + for (int i = 0; i < 10_000; i++) { + long value = (r.nextLong() & 63) + 1; // 1-64 are valid only + assertEquals(rangeMaskOriginal2(value), rangeMaskSimplified2(value), "" + value); + } + } + @Test + public void rangeMaskExpressionSimplification2() { + for (int sliceCount = 1; sliceCount <= 64; sliceCount++) { + long original = sliceCount == 64 ? -1L : (1L << sliceCount) - 1; + long simplified = -1L >>> (64 - sliceCount); + assertEquals(Long.toBinaryString(original), Long.toBinaryString(simplified), "sliceCount=" + sliceCount); + } + } } From 87a0309ac879596ca8b3a6358bb2f116d0c56e07 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 15:57:21 +0100 Subject: [PATCH 033/167] Avoid array reallocation (#701) * benchmark for deserialization mutable bitmaps * avoid long buffer duplication * avoid copy whole long array * avoid long buffer duplication --- .../org/roaringbitmap/BitmapContainer.java | 8 ++- .../buffer/MappeableBitmapContainer.java | 15 ++++-- .../buffer/MutableRoaringArray.java | 2 +- ...mapContainersDeserializationBenchmark.java | 54 +++++++++++++++++++ 4 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index 02a2feeaf..52cd96a4a 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -941,13 +941,11 @@ public Container limit(int maxcardinality) { } return ac; } - BitmapContainer bc = new BitmapContainer(maxcardinality, this.bitmap); + long[] newBitmap = new long[MAX_CAPACITY / 64]; + BitmapContainer bc = new BitmapContainer(newBitmap, maxcardinality); int s = (select(maxcardinality)); int usedwords = (s + 63) / 64; - int todelete = this.bitmap.length - usedwords; - for (int k = 0; k < todelete; ++k) { - bc.bitmap[bc.bitmap.length - 1 - k] = 0; - } + System.arraycopy(this.bitmap, 0, newBitmap, 0, usedwords); int lastword = s % 64; if (lastword != 0) { bc.bitmap[s / 64] &= (0xFFFFFFFFFFFFFFFFL >>> (64 - lastword)); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index b54f99a20..d9fd36693 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -1249,13 +1249,18 @@ public MappeableContainer limit(int maxcardinality) { } return ac; } - MappeableBitmapContainer bc = new MappeableBitmapContainer(maxcardinality, this.bitmap); + LongBuffer newBitmap = LongBuffer.allocate(MAX_CAPACITY / 64); + MappeableBitmapContainer bc = new MappeableBitmapContainer(newBitmap, maxcardinality); int s = (select(maxcardinality)); int usedwords = (s + 63) >>> 6; - int len = this.bitmap.limit(); - int todelete = len - usedwords; - for (int k = 0; k < todelete; ++k) { - bc.bitmap.put(len - 1 - k, 0); + if (this.isArrayBacked()) { + long[] source = this.bitmap.array(); + long[] dest = newBitmap.array(); + System.arraycopy(source, 0, dest, 0, usedwords); + } else { + for (int k = 0; k < usedwords; ++k) { + bc.bitmap.put(k, this.bitmap.get(k)); + } } int lastword = s % 64; if (lastword != 0) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java index cf9948e71..210f5f76a 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java @@ -394,7 +394,7 @@ public void deserialize(ByteBuffer bbf) { if (isBitmap[k]) { long[] array = new long[MappeableBitmapContainer.MAX_CAPACITY / 64]; buffer.asLongBuffer().get(array); - container = new MappeableBitmapContainer(cardinalities[k], LongBuffer.wrap(array)); + container = new MappeableBitmapContainer(LongBuffer.wrap(array), cardinalities[k]); buffer.position(buffer.position() + 1024 * 8); } else if (bitmapOfRunContainers != null && ((bitmapOfRunContainers[k / 8] & (1 << (k & 7))) != 0)) { diff --git a/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java new file mode 100644 index 000000000..e3e28085f --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java @@ -0,0 +1,54 @@ +package org.roaringbitmap.deserialization; + + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.roaringbitmap.buffer.MutableRoaringBitmap; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Warmup(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 5000) +@Measurement(iterations = 10, timeUnit = TimeUnit.MILLISECONDS, time = 5000) +@BenchmarkMode(Mode.Throughput) +public class BitmapContainersDeserializationBenchmark { + + private ByteBuffer buffer; + + @Setup + public void prepare() throws IOException { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + Random r = new Random(); + for (int containerIndex = 0; containerIndex < 1000; containerIndex++) { + for (int j = 0; j < 10_000; j++) { + int value = r.nextInt(65536); + bitmap.add(value + containerIndex * 65536); + } + } + byte[] x = serialise(bitmap); + buffer = ByteBuffer.allocate(x.length); + bitmap.serialize(buffer); + } + + @Benchmark + public void deserialize(Blackhole blackhole) throws IOException { + buffer.rewind(); + MutableRoaringBitmap l = new MutableRoaringBitmap(); + l.deserialize(buffer); + blackhole.consume(buffer); + } + + private static byte[] serialise(MutableRoaringBitmap input) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(input.serializedSizeInBytes()); + DataOutputStream dos = new DataOutputStream(bos)) { + input.serialize(dos); + return bos.toByteArray(); + } + } +} \ No newline at end of file From 7270c92cd19f7144f2d4ef170c7b43bd88faf003 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 16:02:25 +0100 Subject: [PATCH 034/167] Select from both sides (#703) * select from right if index is in upper half of cardinality * skip zeroes * benchmark for select from both sides * bugfix * variable name correction --- .../org/roaringbitmap/BitmapContainer.java | 36 ++++++++- .../buffer/MappeableBitmapContainer.java | 62 ++++++++++++++- .../bitmapcontainer/SelectBenchmark.java | 78 +++++++++++++++++++ 3 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index 52cd96a4a..face0de9c 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -1253,6 +1253,41 @@ public Container runOptimize() { @Override public char select(int j) { + if (//cardinality != -1 && // omitted as (-1>>>1) > j as j < (1<<16) + cardinality >>> 1 < j && j < cardinality) { + int leftover = cardinality - j; + for (int k = bitmap.length - 1; k >= 0; --k) { + long w = bitmap[k]; + if (w != 0) { + int bits = Long.bitCount(w); + if (bits >= leftover) { + return (char) (k * 64 + Util.select(w, bits - leftover)); + } + leftover -= bits; + } + } + } else { + int leftover = j; + for (int k = 0; k < bitmap.length; ++k) { + long w = bitmap[k]; + if (w != 0) { + int bits = Long.bitCount(bitmap[k]); + if (bits > leftover) { + return (char) (k * 64 + Util.select(bitmap[k], leftover)); + } + leftover -= bits; + } + } + } + throw new IllegalArgumentException("Insufficient cardinality."); + } + + /** TODO For comparison only, should be removed before merge. + * + * @param j ... + * @return ... + */ + public char selectOneSide(int j) { int leftover = j; for (int k = 0; k < bitmap.length; ++k) { int w = Long.bitCount(bitmap[k]); @@ -1263,7 +1298,6 @@ public char select(int j) { } throw new IllegalArgumentException("Insufficient cardinality."); } - @Override public void serialize(DataOutput out) throws IOException { // little endian diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index d9fd36693..18de4116b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -1702,6 +1702,67 @@ public MappeableContainer runOptimize() { @Override public char select(int j) { + if (BufferUtil.isBackedBySimpleArray(this.bitmap)) { + long[] b = this.bitmap.array(); + if (//cardinality != -1 && // omitted as (-1>>>1) > j as j < (1<<16) + cardinality >>> 1 < j && j < cardinality) { + int leftover = cardinality - j; + for (int k = b.length - 1; k >= 0; --k) { + long w = b[k]; + if (w != 0) { + int bits = Long.bitCount(w); + if (bits >= leftover) { + return (char) (k * 64 + Util.select(w, bits - leftover)); + } + leftover -= bits; + } + } + } else { + int leftover = j; + for (int k = 0; k < b.length; ++k) { + long w = b[k]; + if (w != 0) { + int bits = Long.bitCount(w); + if (bits > leftover) { + return (char) (k * 64 + Util.select(w, leftover)); + } + leftover -= bits; + } + } + } + } else { + int len = this.bitmap.limit(); + if (//cardinality != -1 && // (-1>>>1) > j as j < (1<<16) + cardinality >>> 1 < j && j < cardinality) { + int leftover = cardinality - j; + for (int k = len - 1; k >= 0; --k) { + int w = Long.bitCount(bitmap.get(k)); + if (w >= leftover) { + return (char) (k * 64 + Util.select(bitmap.get(k), w - leftover)); + } + leftover -= w; + } + } else { + int leftover = j; + for (int k = 0; k < len; ++k) { + long X = bitmap.get(k); + int w = Long.bitCount(X); + if (w > leftover) { + return (char) (k * 64 + Util.select(X, leftover)); + } + leftover -= w; + } + } + } + throw new IllegalArgumentException("Insufficient cardinality."); + } + + /** TODO For comparison only, should be removed before merge. + * + * @param j ... + * @return ... + */ + public char selectOneSide(int j) { int leftover = j; if (BufferUtil.isBackedBySimpleArray(this.bitmap)) { long[] b = this.bitmap.array(); @@ -1726,7 +1787,6 @@ public char select(int j) { } throw new IllegalArgumentException("Insufficient cardinality."); } - @Override public int serializedSizeInBytes() { return serializedSizeInBytes(0); diff --git a/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java new file mode 100644 index 000000000..dbb80ea45 --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java @@ -0,0 +1,78 @@ +package org.roaringbitmap.bitmapcontainer; + +import org.openjdk.jmh.annotations.*; +import org.roaringbitmap.BitmapContainer; +import org.roaringbitmap.buffer.MappeableBitmapContainer; + +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS, time = 1000) +@Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS, time = 1000) +public class SelectBenchmark { + + private BitmapContainer bc1; + private MappeableBitmapContainer mbc1; + + @Param({"100", "5000", "10000"}) + public int valuesCount; + + public char[] indexes; + + @Setup + public void setup() throws ExecutionException { + bc1 = new BitmapContainer(); + mbc1 = new MappeableBitmapContainer(); + indexes = new char[valuesCount]; + Random r = new Random(123); + for (int i = 0; i < valuesCount; i++) { + char value = (char) r.nextInt(Character.MAX_VALUE); + bc1.add(value); + mbc1.add(value); + } + int actualCardinality = bc1.getCardinality(); // some values can be inserted multiple times + for (int i = 0; i < actualCardinality; i++) { + indexes[i] = (char) r.nextInt(actualCardinality); + } + } + + @Benchmark + public long bitmapContainer_selectOneSide() { + long accumulator = 0; + for (int i = 0; i < bc1.getCardinality(); i++) { + accumulator += bc1.selectOneSide(indexes[i]); + } + return accumulator; + } + + @Benchmark + public long bitmapContainer_selectBothSides() { + long accumulator = 0; + for (int i = 0; i < bc1.getCardinality(); i++) { + accumulator += bc1.select(indexes[i]); + } + return accumulator; + } + + @Benchmark + public long mappeableBitmapContainer_selectOneSide() { + long accumulator = 0; + for (int i = 0; i < mbc1.getCardinality(); i++) { + accumulator += mbc1.selectOneSide(indexes[i]); + } + return accumulator; + } + + @Benchmark + public long mappeableBitmapContainer_selectBothSides() { + long accumulator = 0; + for (int i = 0; i < mbc1.getCardinality(); i++) { + accumulator += mbc1.select(indexes[i]); + } + return accumulator; + } +} From 8b386e9c00637c5d46d4b14abb0e61da43b8be8e Mon Sep 17 00:00:00 2001 From: xtonik Date: Sat, 27 Jan 2024 16:02:52 +0100 Subject: [PATCH 035/167] code for skipping containers deduplicated (#704) --- .../java/org/roaringbitmap/RangeBitmap.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java index efb78ff46..46086a307 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java @@ -468,9 +468,7 @@ public RoaringBitmap computePoint(long value, boolean negate, RoaringBitmap cont for (int prefix = 0; prefix <= maxContextKey && remaining > 0; prefix++) { long containerMask = getContainerMask(buffer, mPos, mask, bytesPerMask); if (prefix < contextArray.keys[contextPos]) { - for (int i = 0; i < Long.bitCount(containerMask); i++) { - skipContainer(); - } + skipContainers(containerMask); } else { int limit = Math.min((int) remaining, 0x10000); evaluateHorizontalSlicePoint(limit, value, containerMask); @@ -532,9 +530,7 @@ private long countPoint(long threshold, boolean negate, RoaringBitmap context) { int limit = Math.min(0x10000, (int) remaining); long containerMask = getContainerMask(buffer, mPos, mask, bytesPerMask); if (prefix < contextArray.keys[contextPos]) { - for (int i = 0; i < Long.bitCount(containerMask); i++) { - skipContainer(); - } + skipContainers(containerMask); } else { evaluateHorizontalSlicePoint(limit, threshold, containerMask); if (negate) { @@ -596,9 +592,7 @@ private RoaringBitmap computeRange(long threshold, boolean upper, RoaringBitmap for (int prefix = 0; prefix <= maxContextKey && remaining > 0; prefix++) { long containerMask = getContainerMask(buffer, mPos, mask, bytesPerMask); if (prefix < contextArray.keys[contextPos]) { - for (int i = 0; i < Long.bitCount(containerMask); i++) { - skipContainer(); - } + skipContainers(containerMask); } else { evaluateHorizontalSliceRange(remaining, threshold, containerMask); if (!upper) { @@ -658,9 +652,7 @@ private long countRange(long threshold, boolean upper, RoaringBitmap context) { for (int prefix = 0; prefix <= maxContextKey && remaining > 0; prefix++) { long containerMask = getContainerMask(buffer, mPos, mask, bytesPerMask); if (prefix < contextArray.keys[contextPos]) { - for (int i = 0; i < Long.bitCount(containerMask); i++) { - skipContainer(); - } + skipContainers(containerMask); } else { evaluateHorizontalSliceRange(remaining, threshold, containerMask); Container container = contextArray.values[contextPos]; @@ -900,6 +892,12 @@ private void skipContainer() { position += 3 + (size << (type == RUN ? 2 : 1)); } } + + private void skipContainers(long mask) { + for (int i = 0; i < Long.bitCount(mask); i++) { + skipContainer(); + } + } } private final class DoubleEvaluation { From 116cc6511a7810e0297b15d3373bdb4780e7e96e Mon Sep 17 00:00:00 2001 From: xtonik Date: Sun, 28 Jan 2024 18:04:01 +0100 Subject: [PATCH 036/167] fillArray() deduplicated, some its part removed as being dead code (#707) --- .../org/roaringbitmap/ArrayContainer.java | 2 +- .../org/roaringbitmap/BitmapContainer.java | 18 ---------- .../src/main/java/org/roaringbitmap/Util.java | 19 +++++++++++ .../buffer/MappeableArrayContainer.java | 2 +- .../buffer/MappeableBitmapContainer.java | 33 ------------------- 5 files changed, 21 insertions(+), 53 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index 9bc050034..0fe53625e 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -832,7 +832,7 @@ public Container limit(int maxcardinality) { void loadData(final BitmapContainer bitmapContainer) { this.cardinality = bitmapContainer.cardinality; - bitmapContainer.fillArray(content); + Util.fillArray(bitmapContainer.bitmap, content); } // for use in inot range known to be nonempty diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index face0de9c..7c2b25977 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -425,24 +425,6 @@ public boolean equals(Object o) { } - /** - * Fill the array with set bits - * - * @param array container (should be sufficiently large) - */ - void fillArray(final char[] array) { - int pos = 0; - int base = 0; - for (int k = 0; k < bitmap.length; ++k) { - long bitset = bitmap[k]; - while (bitset != 0) { - array[pos++] = (char) (base + numberOfTrailingZeros(bitset)); - bitset &= (bitset - 1); - } - base += 64; - } - } - @Override public void fillLeastSignificant16bits(int[] x, int i, int mask) { int pos = i; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java index 2048e7834..936b78eb7 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java @@ -1239,4 +1239,23 @@ public static void partialRadixSort(int[] data) { private Util() { } + + /** + * Fill the array with set bits + * + * @param bitmap source bitmap + * @param array container (should be sufficiently large) + */ + public static void fillArray(long[] bitmap, final char[] array) { + int pos = 0; + int base = 0; + for (int k = 0; k < bitmap.length; ++k) { + long bitset = bitmap[k]; + while (bitset != 0) { + array[pos++] = (char) (base + numberOfTrailingZeros(bitset)); + bitset &= (bitset - 1); + } + base += 64; + } + } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index 63122aae1..4a606cdc2 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -998,7 +998,7 @@ void loadData(final MappeableBitmapContainer bitmapContainer) { if (!BufferUtil.isBackedBySimpleArray(this.content)) { throw new RuntimeException("Should not happen. Internal bug."); } - bitmapContainer.fillArray(content.array()); + Util.fillArray(bitmapContainer.bitmap.array(), content.array()); } // for use in inot range known to be nonempty diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index 18de4116b..18a690595 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -450,39 +450,6 @@ public boolean equals(Object o) { return false; } - /** - * Fill the array with set bits - * - * @param array container (should be sufficiently large) - */ - void fillArray(final char[] array) { - int pos = 0; - if (BufferUtil.isBackedBySimpleArray(bitmap)) { - long[] b = bitmap.array(); - int base = 0; - for (int k = 0; k < b.length; ++k) { - long bitset = b[k]; - while (bitset != 0) { - array[pos++] = (char) (base + numberOfTrailingZeros(bitset)); - bitset &= (bitset - 1); - } - base += 64; - } - - } else { - int len = this.bitmap.limit(); - int base = 0; - for (int k = 0; k < len; ++k) { - long bitset = bitmap.get(k); - while (bitset != 0) { - array[pos++] = (char) (base + numberOfLeadingZeros(bitset)); - bitset &= (bitset - 1); - } - base += 64; - } - } - } - @Override public void fillLeastSignificant16bits(int[] x, int i, int mask) { int pos = i; From a81f12ca00c60175888dee5070dce88d25b3ec1d Mon Sep 17 00:00:00 2001 From: xtonik Date: Sun, 28 Jan 2024 18:05:55 +0100 Subject: [PATCH 037/167] Avoid useless computation in oNeilCompare() (#702) * avoid useless operations in oNeilCompare() * avoid instantiation unused empty bitmaps --- .../bsi/buffer/BitSliceIndexBase.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java index f867941da..036ad466c 100644 --- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java +++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java @@ -6,6 +6,7 @@ import org.roaringbitmap.IntIterator; import org.roaringbitmap.RoaringBitmap; import org.roaringbitmap.bsi.BitmapSliceIndex; +import org.roaringbitmap.bsi.BitmapSliceIndex.Operation; import org.roaringbitmap.bsi.Pair; import org.roaringbitmap.buffer.BufferFastAggregation; import org.roaringbitmap.buffer.ImmutableRoaringBitmap; @@ -191,23 +192,31 @@ private ImmutableRoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation ImmutableRoaringBitmap foundSet) { ImmutableRoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet; - MutableRoaringBitmap GT = new MutableRoaringBitmap(); - MutableRoaringBitmap LT = new MutableRoaringBitmap(); + MutableRoaringBitmap GT = operation == Operation.GT || operation == Operation.GE + ? new MutableRoaringBitmap() : null; + MutableRoaringBitmap LT = operation == Operation.LT || operation == Operation.LE + ? new MutableRoaringBitmap() : null; ImmutableRoaringBitmap EQ = this.ebM; for (int i = this.bitCount() - 1; i >= 0; i--) { int bit = (predicate >> i) & 1; if (bit == 1) { - LT = ImmutableRoaringBitmap.or(LT, ImmutableRoaringBitmap.andNot(EQ, this.bA[i])); + if (operation == Operation.LT || operation == Operation.LE) { + LT = ImmutableRoaringBitmap.or(LT, ImmutableRoaringBitmap.andNot(EQ, this.bA[i])); + } EQ = ImmutableRoaringBitmap.and(EQ, this.bA[i]); } else { - GT = ImmutableRoaringBitmap.or(GT, ImmutableRoaringBitmap.and(EQ, this.bA[i])); + if (operation == Operation.GT || operation == Operation.GE) { + GT = ImmutableRoaringBitmap.or(GT, ImmutableRoaringBitmap.and(EQ, this.bA[i])); + } EQ = ImmutableRoaringBitmap.andNot(EQ, this.bA[i]); } } - EQ = ImmutableRoaringBitmap.and(fixedFoundSet, EQ); + if (operation != Operation.LT && operation != Operation.GT) { + EQ = ImmutableRoaringBitmap.and(fixedFoundSet, EQ); + } switch (operation) { case EQ: return EQ; From 2786fbbda00e2022f32547da1082a506e71598d6 Mon Sep 17 00:00:00 2001 From: xtonik Date: Sun, 28 Jan 2024 18:06:20 +0100 Subject: [PATCH 038/167] Optimized check for value presence in run container (#705) * optimized run container's contains() with bitmap * optimized mappable run container's contains() with bitmap * test + benchmark for contains() * benchmark correction * benchmark correction * checkstyle * removed comparison for optimized contains() of (Mappeable)RunContainer --- .../java/org/roaringbitmap/RunContainer.java | 21 ++++++++++++---- .../buffer/MappeableRunContainer.java | 24 ++++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index 0c16aa5f7..eb7aa9b97 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -817,19 +817,30 @@ protected boolean contains(BitmapContainer bitmapContainer) { } final int runCount = numberOfRuns(); char ib = 0, ir = 0; + int start = getValue(ir); + int stop = start + getLength(ir); while(ib < bitmapContainer.bitmap.length && ir < runCount) { long w = bitmapContainer.bitmap[ib]; - while (w != 0 && ir < runCount) { - int start = (getValue(ir)); - int stop = start+ (getLength(ir)); - long t = w & -w; + while (true) { long r = ib * 64L + Long.numberOfTrailingZeros(w); if (r < start) { return false; } else if(r > stop) { ++ir; + if (ir == runCount) { + break; + } + w &= w - 1; + start = getValue(ir); + stop = start + getLength(ir); + } else if (ib * 64 + 64 < stop) { + ib = (char) (stop / 64); + w = bitmapContainer.bitmap[ib]; } else { - w ^= t; + w &= w - 1; + if (w == 0) { + break; + } } } if(w == 0) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index 630231f01..0be2d0069 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -2737,19 +2737,31 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) { } final int runCount = numberOfRuns(); char ib = 0, ir = 0; + int start = getValue(0); + int stop = start + getLength(0); while(ib < MappeableBitmapContainer.MAX_CAPACITY / 64 && ir < runCount) { long w = bitmapContainer.bitmap.get(ib); - while (w != 0 && ir < runCount) { - int start = (getValue(ir)); - int stop = start+ (getLength(ir)); - long t = w & -w; + while (true) { long r = ib * 64 + Long.numberOfTrailingZeros(w); if (r < start) { return false; - } else if(r > stop) { + } else if (r > stop) { ++ir; + if (ir == runCount) { + break; + } + w &= w - 1; + start = getValue(ir); + stop = start + getLength(ir); + + } else if (ib * 64 + 64 < stop) { + ib = (char) (stop / 64); + w = bitmapContainer.bitmap.get(ib); } else { - w ^= t; + w &= w - 1; + if (w == 0) { + break; + } } } if(w == 0) { From 028f3a5f40d08ade26724fad16e4fdf7256b46ea Mon Sep 17 00:00:00 2001 From: xtonik Date: Sun, 28 Jan 2024 18:07:10 +0100 Subject: [PATCH 039/167] Optimized creation of bitmap by range (#686) * more effective bitmapOf * unify coding way * more effective bitmapOf for buffered bitmap --- .../java/org/roaringbitmap/RoaringBitmap.java | 27 ++++++++++++- .../buffer/MutableRoaringBitmap.java | 31 +++++++++++++++ .../test/java/org/roaringbitmap/TestUtil.java | 22 +++++++++++ .../org/roaringbitmap/buffer/TestUtil.java | 22 +++++++++++ .../roaringbitmap/BitmapOfRangeBenchmark.java | 39 +++++++++++++++++++ 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 4f3fa11c6..71c5b4cb8 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -557,8 +557,31 @@ public static RoaringBitmap bitmapOfUnordered(final int... data) { * @see #add(long, long) */ public static RoaringBitmap bitmapOfRange(long min, long max) { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(min, max); + rangeSanityCheck(min, max); + if (min >= max) { + return new RoaringBitmap(); + } + final int hbStart = Util.highbits(min); + final int lbStart = Util.lowbits(min); + final int hbLast = Util.highbits(max - 1); + final int lbLast = Util.lowbits(max - 1); + + RoaringArray array = new RoaringArray(hbLast - hbStart + 1); + RoaringBitmap bitmap = new RoaringBitmap(array); + + int firstEnd = hbStart < hbLast ? 1 << 16 : lbLast + 1; + Container firstContainer = RunContainer.rangeOfOnes(lbStart, firstEnd); + bitmap.append((char) hbStart, firstContainer); + if (hbStart < hbLast) { + int i = hbStart + 1; + while (i < hbLast) { + Container runContainer = RunContainer.rangeOfOnes(0, 1 << 16); + bitmap.append((char) i, runContainer); + i++; + } + Container lastContainer = RunContainer.rangeOfOnes(0, lbLast + 1); + bitmap.append((char) hbLast, lastContainer); + } return bitmap; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java index 0d14472ab..902ab5dd4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java @@ -400,6 +400,37 @@ public static MutableRoaringBitmap bitmapOf(final int... dat) { } + /** + * @see #add(long, long) + */ + public static MutableRoaringBitmap bitmapOfRange(long min, long max) { + rangeSanityCheck(min, max); + if (min >= max) { + return new MutableRoaringBitmap(); + } + final int hbStart = BufferUtil.highbits(min); + final int lbStart = BufferUtil.lowbits(min); + final int hbLast = BufferUtil.highbits(max - 1); + final int lbLast = BufferUtil.lowbits(max - 1); + + MutableRoaringArray array = new MutableRoaringArray(hbLast - hbStart + 1); + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(array); + + int firstEnd = hbStart < hbLast ? 1 << 16 : lbLast + 1; + MappeableContainer firstContainer = MappeableContainer.rangeOfOnes(lbStart, firstEnd); + bitmap.append((char) hbStart, firstContainer); + if (hbStart < hbLast) { + int i = hbStart + 1; + while (i < hbLast) { + MappeableContainer runContainer = MappeableContainer. rangeOfOnes(0, 1 << 16); + bitmap.append((char) i, runContainer); + i++; + } + MappeableContainer lastContainer = MappeableContainer.rangeOfOnes(0, lbLast + 1); + bitmap.append((char) hbLast, lastContainer); + } + return bitmap; + } protected static void rangeSanityCheck(final long rangeStart, final long rangeEnd) { if (rangeStart < 0 || rangeStart > (1L << 32)-1) { diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestUtil.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestUtil.java index 9fd5ada5e..3b81180e4 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestUtil.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestUtil.java @@ -194,4 +194,26 @@ public void testIntersectBitmapWithArray(int[] set1, int[] set2) { assertEquals(expectedCardinality, cardinality); assertArrayEquals(referenceBitmap, bitmap); } + + @Test + public void bitmapOfRange() { + assertBitmapRange(0, 10);// begin of first container + assertBitmapRange(0, 1 << 16 - 1);// early full container + assertBitmapRange(0, 1 << 16);// full first container + assertBitmapRange(0, 1 << 16 + 1);// full first container + one value the second + assertBitmapRange(10, 1 << 16);// without first several integers + assertBitmapRange(1 << 16, (1 << 16) * 2);// full second container + assertBitmapRange(10, 100);// some integers inside interval + assertBitmapRange((1 << 16) - 5, (1 << 16) + 7); // first to second container + assertBitmapRange(0, 100_000); // more than one container + assertBitmapRange(100_000, 200_000);// second to third container + assertBitmapRange(200_000, 400_000);// more containers inside + } + + private static void assertBitmapRange(int start, int end) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOfRange(start, end); + assertEquals(end - start, bitmap.getCardinality()); + assertEquals(start, bitmap.first()); + assertEquals(end - 1, bitmap.last()); + } } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java index db70f4c07..eeceaa023 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java @@ -142,4 +142,26 @@ public void testIntersectBitmapWithArray(boolean direct, int[] set1, int[] set2) assertEquals(bitmap.get(i), referenceBitmap.get(i), "mismatch at " + i); } } + + @Test + public void bitmapOfRange() { + assertBitmapRange(0, 10);// begin of first container + assertBitmapRange(0, 1 << 16 - 1);// early full container + assertBitmapRange(0, 1 << 16);// full first container + assertBitmapRange(0, 1 << 16 + 1);// full first container + one value the second + assertBitmapRange(10, 1 << 16);// without first several integers + assertBitmapRange(1 << 16, (1 << 16) * 2);// full second container + assertBitmapRange(10, 100);// some integers inside interval + assertBitmapRange((1 << 16) - 5, (1 << 16) + 7); // first to second container + assertBitmapRange(0, 100_000); // more than one container + assertBitmapRange(100_000, 200_000);// second to third container + assertBitmapRange(200_000, 400_000);// more containers inside + } + + private static void assertBitmapRange(int start, int end) { + MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOfRange(start, end); + assertEquals(end - start, bitmap.getCardinality()); + assertEquals(start, bitmap.first()); + assertEquals(end - 1, bitmap.last()); + } } diff --git a/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java new file mode 100644 index 000000000..acfc63396 --- /dev/null +++ b/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java @@ -0,0 +1,39 @@ +package org.roaringbitmap; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 3, timeUnit = TimeUnit.MILLISECONDS, time = 1000) +@Measurement(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 1000) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Benchmark) +public class BitmapOfRangeBenchmark { + @Param({"0", // from the beginning + "100000" // from some offset + }) + int from; + + @Param({"10", + "100000", // ~ 100 kBi + "10000000",// ~ 10 MBi + }) + int length; + + @Benchmark + public RoaringBitmap original() { + return bitmapOfRangeOriginal(from, from + length); + } + + @Benchmark + public RoaringBitmap optimized() { + return RoaringBitmap.bitmapOfRange(from, from + length); + } + + public static RoaringBitmap bitmapOfRangeOriginal(long min, long max) { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(min, max); + return bitmap; + } +} \ No newline at end of file From 13d6566489a58f71ce79a60f66059941659c3114 Mon Sep 17 00:00:00 2001 From: Richard Startin Date: Fri, 8 Mar 2024 04:05:34 +0000 Subject: [PATCH 040/167] fix RangeBitmap#between bug in full section after empty section (#710) --- .../java/org/roaringbitmap/RangeBitmap.java | 40 +++++++++++++------ .../org/roaringbitmap/RangeBitmapTest.java | 30 +++++++++----- .../testdata/rangebitmap_regression.txt | 1 + 3 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 RoaringBitmap/src/test/resources/testdata/rangebitmap_regression.txt diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java index 46086a307..a47fe1c23 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java @@ -1288,16 +1288,14 @@ private static final class Bits { public void clear() { if (!empty) { Arrays.fill(bits, 0L); - empty = true; - full = false; + makeEmpty(); } } public void fill() { if (!full) { Arrays.fill(bits, -1L); - empty = false; - full = true; + makeFull(); } } @@ -1308,20 +1306,18 @@ public void reset(int boundary) { if (!empty) { resetBitmapRange(bits, boundary, 0x10000); } - empty = false; - full = false; + makeNonEmpty(); + makeNonFull(); } public void flip(int from, int to) { + Util.flipBitmapRange(bits, from, to); if (!full) { - Util.flipBitmapRange(bits, from, to); if (empty) { - empty = false; - full = true; + makeFull(); } } else { - full = false; - empty = true; + makeEmpty(); } } @@ -1330,16 +1326,34 @@ public void or(MappeableContainer container) { fill(); } else if (!full) { container.orInto(bits); - empty = false; + makeNonEmpty(); } } public void and(MappeableContainer container) { if (!empty && !container.isFull()) { container.andInto(bits); - full = false; + makeNonFull(); } } + + private void makeEmpty() { + this.empty = true; + this.full = false; + } + + private void makeNonEmpty() { + this.empty = false; + } + + private void makeFull() { + this.full = true; + this.empty = false; + } + + private void makeNonFull() { + this.full = false; + } } private static long getContainerMask(ByteBuffer buffer, int position, long mask, diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java index bbe4f61f1..4a5e46c8d 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java @@ -9,7 +9,10 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -43,8 +46,25 @@ @Execution(ExecutionMode.CONCURRENT) public class RangeBitmapTest { + @Test + public void betweenRegressionTest() throws IOException { + String[] lines = new String(Files.readAllBytes(Paths.get("src/test/resources/testdata/rangebitmap_regression.txt"))).split(","); + RangeBitmap.Appender appender = RangeBitmap.appender(2175288L); + for (String line : lines) { + appender.add(Long.parseLong(line)); + } + RangeBitmap bitmap = appender.build(); + for (int i = 0; i < 4; i++) { + long lowerTs = 263501 + i; + RoaringBitmap eqLower = bitmap.eq(lowerTs); // eq + RoaringBitmap eqUpper = bitmap.eq(lowerTs + 1); // eq + // [x,y] both inclusive, so it should be union of the two above + RoaringBitmap range = bitmap.between(lowerTs, lowerTs + 1); + assertEquals(RoaringBitmap.or(eqLower, eqUpper), range); + } + } + @ParameterizedTest - @Disabled("expensive - run on an ad hoc basis") @ValueSource(ints = {0, 0xFFFF, 0x10001, 100_000, 0x110001, 1_000_000}) public void testInsertContiguousValues(int size) { RangeBitmap.Appender appender = RangeBitmap.appender(size); @@ -72,7 +92,6 @@ public void testInsertContiguousValues(int size) { } @ParameterizedTest - @Disabled("expensive - run on an ad hoc basis") @ValueSource(ints = {0, 0xFFFF, 0x10001, 100_000, 0x110001, 1_000_000}) public void testInsertReversedContiguousValues(int size) { RangeBitmap.Appender appender = RangeBitmap.appender(size); @@ -281,7 +300,6 @@ public void testSerializeEmpty(long maxValue) { @ParameterizedTest @MethodSource("distributions") - @Disabled("expensive - run on an ad hoc basis") public void testAppenderReuseAfterClear(LongSupplier dist) { RangeBitmap.Appender appender = RangeBitmap.appender(10_000_000); long[] values = new long[100_000]; @@ -308,7 +326,6 @@ public void testAppenderReuseAfterClear(LongSupplier dist) { @ParameterizedTest @MethodSource("distributions") - @Disabled("expensive - run on an ad hoc basis") public void testConstructRelativeToMinValue(LongSupplier dist) { int[] values = IntStream.range(0, 1_000_000).map(i -> (int) dist.getAsLong()).toArray(); int min = IntStream.of(values).min().orElse(0); @@ -346,7 +363,6 @@ public static Stream distributions() { @ParameterizedTest @MethodSource("distributions") - @Disabled("expensive - run on an ad hoc basis") public void testAgainstReferenceImplementation(LongSupplier dist) { long maxValue = 10_000_000; ReferenceImplementation.Builder builder = ReferenceImplementation.builder(); @@ -370,7 +386,6 @@ public void testAgainstReferenceImplementation(LongSupplier dist) { @ParameterizedTest @MethodSource("distributions") @SuppressWarnings("unchecked") - @Disabled("expensive - run on an ad hoc basis") public void testAgainstPrecomputed(LongSupplier dist) { long maxValue = 10_000_000; ReferenceImplementation.Builder builder = ReferenceImplementation.builder(); @@ -412,7 +427,6 @@ public void testAgainstPrecomputed(LongSupplier dist) { @ParameterizedTest @MethodSource("distributions") - @Disabled("expensive - run on an ad hoc basis") public void testContextualRangeEvaluationAgainstNonContextual(LongSupplier dist) { long maxValue = 10_000_000; RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); @@ -442,7 +456,6 @@ public void testContextualRangeEvaluationAgainstNonContextual(LongSupplier dist) @ParameterizedTest @MethodSource("distributions") - @Disabled("expensive - run on an ad hoc basis") public void testDoubleEndedRangeEvaluationAgainstNonContextual(LongSupplier dist) { long maxValue = 10_000_000; RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); @@ -601,7 +614,6 @@ public void testBetween4() { @ParameterizedTest @MethodSource("distributions") - @Disabled("expensive - run on an ad hoc basis") public void testContextualBetweenCardinality(LongSupplier dist) { long maxValue = 10_000_000; RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); diff --git a/RoaringBitmap/src/test/resources/testdata/rangebitmap_regression.txt b/RoaringBitmap/src/test/resources/testdata/rangebitmap_regression.txt new file mode 100644 index 000000000..c25bace4d --- /dev/null +++ b/RoaringBitmap/src/test/resources/testdata/rangebitmap_regression.txt @@ -0,0 +1 @@ +140350,140350,140352,140353,140353,140370,140375,140379,140393,140396,140396,140397,140397,140401,140405,140405,140405,140405,140405,140406,140406,140406,140406,140406,140406,140406,140407,140407,140409,140410,140412,140412,140412,140412,140416,140417,140421,140425,140425,140425,140426,140427,140427,140428,140428,140430,140431,140432,140432,140432,140432,140432,140432,140433,140434,140434,140436,140442,140442,140443,140445,140445,140453,140453,140453,140453,140453,140453,140453,140454,140454,140454,140454,140454,140458,140458,140458,140458,140458,140458,140458,140458,140459,140459,140459,140461,140463,140465,140468,140468,140468,140469,140469,140471,140471,140472,140473,140474,140474,140475,140475,140477,140477,140478,140482,140482,140482,140482,140482,140482,140487,140487,140487,140487,140488,140489,140489,140496,140500,140500,140501,140502,140502,140502,140502,140503,140505,140506,140506,140506,140506,140507,140507,140509,140515,140515,140515,140516,140516,140519,140519,140520,140521,140521,140521,140521,140525,140526,140526,140527,140527,140527,140535,140536,140536,140537,140541,140541,140541,140543,140546,140546,140549,140549,140553,140553,140555,140558,140561,140563,140564,140565,140568,140575,140578,140592,140599,140599,140600,140600,140600,140600,140611,140614,140616,140617,140625,140625,140635,140635,140656,140669,140671,140672,140672,140672,140672,140672,140672,140672,140672,140672,140672,140674,140675,140675,140675,140677,140677,140681,140682,140682,140683,140683,140685,140687,140688,140689,140689,140699,140707,140714,140714,140714,140714,140714,140714,140714,140714,140715,140722,140722,140722,140730,140731,140734,140735,140739,140741,140753,140757,140757,140759,140759,140761,140763,140763,140764,140764,140764,140767,140771,140771,140772,140772,140774,140781,140786,140793,140793,140793,140793,140793,140793,140795,140795,140795,140795,140795,140795,140798,140800,140803,140804,140804,140807,140808,140813,140815,140815,140815,140815,140816,140817,140818,140818,140818,140819,140819,140821,140823,140827,140829,140829,140840,140845,140845,140845,140848,140850,140852,140853,140854,140854,140854,140854,140854,140857,140857,140858,140870,140870,140870,140870,140870,140870,140870,140870,140874,140876,140876,140879,140881,140883,140883,140883,140893,140893,140901,140903,140904,140905,140908,140908,140908,140908,140913,140920,140920,140920,140928,140929,140929,140929,140929,140929,140929,140930,140931,140941,140946,140946,140946,140946,140946,140946,140946,140946,140946,140952,140952,140952,140955,140968,140969,140970,140974,140974,140975,140975,140975,140977,140979,140979,140979,140979,140979,140979,140979,140979,140981,140981,140981,140981,140984,140987,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140988,140989,140990,140990,140990,140990,140992,140992,140992,140994,140994,140998,141004,141007,141014,141016,141016,141016,141016,141017,141018,141018,141025,141026,141026,141028,141037,141037,141037,141037,141048,141048,141055,141057,141065,141067,141067,141072,141072,141072,141072,141072,141072,141072,141072,141072,141072,141084,141084,141084,141084,141084,141084,141084,141084,141084,141085,141086,141086,141087,141088,141088,141089,141097,141097,141097,141097,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141098,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141099,141100,141100,141100,141100,141101,141101,141101,141101,141101,141101,141101,141101,141101,141101,141101,141101,141101,141102,141102,141102,141102,141102,141102,141102,141102,141102,141102,141102,141102,141102,141102,141103,141103,141103,141103,141103,141103,141104,141104,141104,141104,141104,141104,141104,141104,141104,141104,141104,141105,141106,141108,141108,141108,141108,141108,141109,141109,141109,141110,141110,141110,141110,141111,141112,141113,141113,141114,141114,141114,141114,141116,141117,141117,141118,141121,141121,141121,141122,141122,141122,141122,141123,141123,141124,141127,141127,141127,141128,141128,141128,141128,141128,141128,141128,141129,141131,141131,141131,141131,141131,141133,141133,141133,141133,141133,141135,141135,141135,141137,141139,141139,141139,141143,141144,141147,141147,141147,141147,141149,141149,141149,141154,141155,141155,141157,141157,141161,141162,141167,141167,141167,141168,141168,141168,141168,141168,141168,141168,141168,141168,141168,141168,141168,141169,141169,141169,141169,141169,141169,141169,141169,141169,141169,141169,141169,141169,141170,141170,141170,141170,141170,141170,141170,141170,141171,141172,141172,141176,141177,141177,141177,141178,141180,141180,141180,141180,141180,141180,141180,141180,141180,141180,141180,141183,141187,141187,141189,141189,141189,141190,141191,141191,141191,141195,141195,141195,141195,141195,141195,141195,141197,141197,141197,141197,141197,141197,141197,141197,141197,141197,141199,141200,141200,141200,141200,141200,141200,141200,141201,141202,141202,141202,141204,141204,141207,141207,141210,141212,141217,141220,141220,141221,141222,141224,141224,141225,141225,141225,141225,141225,141227,141230,141230,141230,141230,141230,141231,141240,141244,141244,141245,141245,141248,141254,141254,141254,141254,141264,141264,141264,141264,141267,141268,141269,141275,141275,141280,141281,141286,141287,141287,141287,141287,141287,141293,141293,141300,141305,141324,141324,141325,141330,141330,141336,141339,141342,141342,141343,141343,141344,141345,141346,141347,141348,141348,141348,141348,141349,141350,141357,141359,141359,141359,141360,141361,141367,141368,141368,141368,141370,141371,141372,141379,141381,141387,141394,141394,141395,141400,141400,141400,141401,141401,141402,141402,141411,141411,141411,141412,141415,141416,141416,141419,141423,141430,141431,141431,141435,141435,141438,141438,141438,141439,141439,141440,141440,141440,141441,141441,141441,141441,141443,141447,141447,141448,141448,141448,141448,141449,141449,141450,141452,141452,141455,141455,141455,141455,141457,141457,141457,141457,141458,141458,141460,141461,141461,141461,141461,141461,141461,141461,141463,141464,141467,141467,141473,141481,141481,141481,141481,141482,141482,141483,141483,141483,141484,141484,141484,141487,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141489,141490,141490,141495,141495,141495,141495,141497,141497,141500,141500,141506,141506,141507,141508,141509,141514,141514,141514,141514,141514,141517,141518,141518,141522,141524,141524,141528,141528,141529,141529,141530,141530,141532,141532,141533,141535,141535,141537,141537,141537,141537,141540,141540,141540,141540,141544,141544,141547,141547,141548,141548,141550,141551,141551,141551,141551,141554,141554,141556,141557,141557,141559,141559,141560,141563,141563,141563,141569,141571,141571,141571,141573,141576,141576,141576,141577,141577,141580,141582,141582,141583,141590,141594,141594,141595,141596,141609,141609,141618,141618,141621,141621,141622,141624,141625,141625,141625,141625,141625,141625,141625,141626,141627,141630,141630,141630,141635,141635,141636,141637,141640,141640,141640,141643,141643,141646,141646,141648,141650,141650,141650,141650,141652,141653,141653,141656,141659,141659,141659,141660,141663,141663,141668,141668,141671,141671,141672,141672,141672,141674,141676,141676,141685,141686,141686,141688,141690,141692,141693,141698,141702,141702,141703,141705,141707,141710,141713,141713,141713,141715,141715,141716,141718,141719,141719,141725,141725,141731,141731,141732,141732,141746,141746,141746,141746,141748,141750,141751,141753,141753,141753,141754,141755,141758,141765,141765,141767,141768,141770,141771,141778,141778,141778,141778,141783,141783,141791,141793,141802,141804,141808,141821,141824,141824,141831,141831,141832,141837,141841,141841,141847,141848,141848,141852,141852,141853,141853,141856,141858,141860,141864,141865,141869,141869,141869,141873,141876,141876,141876,141876,141876,141876,141876,141876,141876,141877,141882,141883,141888,141889,141892,141892,141894,141906,141911,141911,141911,141912,141915,141924,141927,141930,141936,141937,141937,141937,141941,141942,141942,141942,141942,141942,141942,141942,141945,141950,141950,141950,141950,141950,141950,141950,141950,141950,141950,141950,141951,141951,141951,141951,141951,141951,141952,141952,141953,141953,141957,141965,141965,141968,141972,141976,141977,141979,141980,141982,141982,141982,141982,141983,141984,141985,141989,141989,141990,141990,141997,141997,141999,141999,142003,142004,142004,142011,142017,142020,142020,142020,142020,142021,142023,142023,142023,142024,142025,142025,142029,142030,142034,142035,142035,142040,142040,142046,142047,142052,142053,142073,142073,142073,142075,142079,142086,142086,142096,142096,142096,142099,142108,142114,142115,142120,142121,142121,142125,142125,142127,142129,142136,142136,142136,142136,142136,142139,142141,142143,142143,142143,142143,142143,142143,142148,142149,142149,142149,142150,142150,142151,142151,142152,142152,142157,142159,142161,142161,142161,142163,142163,142171,142176,142176,142176,142177,142177,142187,142188,142188,142192,142192,142192,142192,142197,142203,142204,142205,142205,142205,142211,142211,142211,142217,142223,142232,142234,142234,142234,142234,142234,142245,142246,142249,142251,142254,142257,142257,142257,142257,142257,142260,142260,142260,142260,142260,142265,142270,142271,142272,142273,142273,142282,142295,142300,142300,142306,142306,142309,142310,142310,142344,142351,142353,142355,142360,142370,142371,142374,142376,142379,142379,142379,142379,142379,142379,142379,142379,142379,142379,142379,142380,142381,142386,142387,142387,142387,142390,142393,142394,142394,142395,142396,142397,142407,142410,142412,142412,142412,142412,142413,142416,142416,142419,142419,142422,142428,142432,142432,142435,142445,142449,142454,142454,142456,142456,142456,142456,142461,142468,142476,142478,142480,142482,142483,142483,142483,142484,142485,142489,142489,142490,142491,142493,142495,142498,142506,142515,142518,142523,142524,142524,142524,142524,142524,142524,142524,142527,142529,142531,142531,142532,142542,142544,142544,142544,142544,142544,142544,142545,142545,142545,142545,142545,142545,142546,142546,142546,142546,142546,142546,142547,142547,142547,142547,142547,142548,142548,142548,142549,142549,142549,142550,142550,142550,142550,142554,142555,142555,142555,142555,142555,142555,142555,142555,142555,142555,142555,142555,142555,142556,142556,142556,142556,142557,142557,142557,142560,142566,142568,142576,142577,142578,142593,142598,142598,142603,142606,142614,142614,142615,142617,142618,142619,142632,142634,142634,142634,142634,142636,142637,142637,142638,142638,142638,142638,142638,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142639,142640,142641,142641,142649,142651,142653,142653,142654,142654,142654,142661,142661,142662,142664,142665,142670,142670,142670,142670,142671,142673,142673,142673,142674,142674,142677,142679,142680,142680,142680,142680,142680,142680,142681,142681,142682,142683,142683,142683,142683,142684,142689,142689,142689,142689,142689,142691,142692,142692,142692,142692,142692,142695,142695,142695,142695,142696,142696,142696,142696,142696,142697,142697,142699,142699,142699,142699,142700,142701,142701,142702,142702,142702,142702,142703,142703,142703,142703,142703,142704,142704,142704,142704,142704,142704,142704,142705,142705,142705,142705,142707,142707,142707,142707,142707,142707,142707,142707,142707,142707,142708,142708,142708,142708,142708,142708,142708,142709,142709,142709,142709,142710,142710,142711,142711,142711,142712,142713,142714,142714,142714,142714,142715,142715,142716,142717,142719,142719,142720,142720,142720,142720,142720,142723,142724,142726,142727,142727,142728,142735,142735,142741,142742,142742,142746,142746,142748,142748,142748,142750,142750,142750,142750,142750,142758,142761,142761,142762,142764,142767,142768,142769,142769,142769,142769,142771,142773,142775,142776,142776,142776,142776,142776,142776,142776,142776,142777,142778,142778,142784,142792,142793,142797,142806,142807,142808,142809,142818,142818,142818,142818,142820,142828,142828,142841,142844,142847,142847,142851,142852,142854,142858,142859,142862,142862,142867,142868,142876,142882,142882,142884,142885,142885,142887,142887,142888,142888,142890,142891,142891,142893,142894,142896,142896,142897,142897,142898,142899,142902,142902,142903,142904,142904,142904,142904,142905,142906,142907,142909,142910,142911,142911,142911,142917,142922,142923,142924,142929,142933,142937,142940,142940,142941,142946,142949,142950,142951,142959,142964,142968,142968,142969,142975,142986,142988,142989,142989,142989,142991,142995,143003,143003,143009,143020,143020,143021,143024,143025,143025,143026,143026,143029,143036,143036,143036,143036,143036,143036,143036,143036,143038,143038,143038,143039,143044,143044,143044,143046,143047,143051,143059,143060,143062,143065,143079,143079,143079,143082,143083,143084,143084,143084,143084,143087,143087,143087,143087,143088,143090,143093,143094,143098,143100,143100,143102,143102,143103,143107,143107,143108,143111,143111,143111,143112,143112,143114,143114,143118,143118,143118,143118,143118,143118,143118,143118,143118,143118,143118,143118,143120,143122,143122,143128,143134,143134,143137,143137,143137,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143139,143142,143148,143152,143157,143158,143161,143169,143176,143182,143184,143187,143195,143195,143198,143198,143200,143214,143218,143218,143220,143223,143223,143223,143225,143225,143227,143232,143233,143235,143236,143236,143238,143246,143248,143248,143248,143250,143250,143250,143254,143257,143257,143257,143262,143268,143268,143268,143268,143268,143269,143276,143282,143288,143293,143294,143294,143297,143298,143298,143300,143300,143300,143306,143307,143308,143319,143321,143322,143322,143333,143337,143337,143338,143338,143339,143346,143347,143347,143348,143348,143348,143348,143353,143353,143353,143354,143355,143357,143359,143366,143374,143374,143374,143375,143378,143381,143381,143381,143381,143381,143381,143382,143382,143382,143382,143387,143387,143387,143387,143389,143389,143396,143398,143405,143407,143408,143410,143411,143411,143411,143416,143420,143425,143425,143431,143435,143441,143441,143443,143443,143444,143444,143445,143445,143445,143445,143447,143448,143448,143448,143448,143449,143449,143449,143450,143450,143451,143451,143451,143452,143453,143453,143466,143472,143479,143479,143480,143482,143483,143485,143494,143495,143495,143495,143502,143502,143502,143502,143502,143502,143502,143502,143502,143502,143502,143502,143502,143502,143503,143503,143507,143507,143510,143510,143510,143510,143510,143513,143513,143516,143518,143519,143521,143523,143523,143524,143524,143524,143524,143525,143532,143536,143541,143541,143542,143542,143542,143549,143551,143554,143554,143554,143556,143563,143564,143567,143571,143574,143578,143580,143583,143584,143584,143586,143586,143586,143586,143588,143590,143598,143610,143611,143611,143613,143617,143620,143621,143623,143623,143624,143624,143624,143624,143624,143625,143625,143630,143640,143643,143643,143643,143643,143643,143645,143645,143645,143646,143646,143647,143647,143653,143653,143659,143665,143668,143668,143670,143670,143670,143677,143678,143679,143681,143683,143701,143704,143704,143706,143709,143718,143718,143718,143718,143718,143718,143718,143718,143718,143718,143718,143718,143725,143725,143725,143725,143725,143725,143742,143749,143753,143753,143753,143755,143758,143763,143767,143770,143772,143774,143776,143778,143779,143780,143780,143784,143793,143793,143793,143794,143794,143796,143801,143804,143804,143805,143805,143806,143809,143809,143809,143809,143810,143810,143810,143810,143810,143810,143811,143811,143812,143812,143814,143814,143815,143815,143815,143815,143815,143818,143818,143818,143818,143821,143821,143821,143827,143827,143827,143832,143836,143836,143836,143847,143855,143857,143857,143857,143857,143861,143877,143881,143883,143887,143889,143889,143891,143891,143891,143891,143891,143894,143901,143901,143901,143901,143901,143901,143901,143901,143901,143901,143901,143904,143904,143904,143904,143904,143905,143906,143906,143907,143907,143907,143909,143910,143911,143911,143917,143917,143921,143921,143921,143921,143933,143933,143936,143939,143940,143940,143940,143940,143945,143945,143945,143947,143947,143947,143947,143947,143947,143949,143950,143951,143955,143955,143955,143955,143955,143955,143955,143955,143955,143955,143955,143955,143955,143955,143956,143956,143963,143968,143968,143971,143972,143984,143984,143987,143987,143988,143988,143988,143988,143989,143989,143990,143992,143992,143993,143995,144001,144004,144004,144005,144012,144013,144013,144013,144013,144015,144019,144020,144020,144023,144024,144025,144025,144028,144029,144029,144034,144040,144040,144040,144040,144048,144053,144055,144056,144056,144063,144065,144067,144071,144071,144071,144071,144071,144071,144071,144072,144073,144073,144073,144073,144079,144082,144082,144088,144092,144098,144101,144104,144105,144105,144105,144105,144105,144105,144105,144105,144110,144111,144111,144111,144113,144115,144115,144115,144118,144118,144121,144121,144122,144126,144126,144126,144126,144126,144129,144129,144129,144129,144129,144129,144131,144135,144135,144135,144135,144136,144136,144136,144136,144137,144137,144137,144137,144137,144145,144145,144145,144145,144145,144148,144151,144151,144151,144151,144151,144151,144151,144154,144154,144154,144154,144159,144159,144159,144159,144159,144159,144159,144159,144159,144159,144159,144159,144159,144159,144160,144160,144160,144166,144166,144167,144167,144167,144167,144167,144167,144167,144167,144168,144170,144174,144175,144179,144179,144179,144181,144182,144188,144189,144191,144194,144194,144194,144195,144195,144197,144199,144199,144199,144199,144202,144202,144202,144207,144210,144210,144210,144211,144225,144226,144226,144227,144230,144230,144230,144231,144234,144237,144237,144239,144239,144240,144243,144246,144246,144246,144248,144248,144248,144248,144249,144249,144250,144251,144253,144258,144258,144259,144259,144259,144259,144259,144259,144259,144259,144259,144261,144261,144266,144266,144266,144267,144272,144278,144278,144284,144286,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144290,144291,144296,144301,144304,144304,144305,144305,144306,144306,144306,144309,144309,144309,144311,144314,144314,144314,144315,144319,144323,144323,144323,144324,144325,144328,144328,144328,144328,144328,144329,144329,144334,144335,144335,144335,144341,144343,144346,144347,144349,144351,144351,144351,144351,144352,144352,144352,144352,144352,144354,144362,144362,144362,144367,144367,144367,144369,144370,144380,144381,144381,144381,144381,144385,144387,144390,144391,144392,144392,144394,144394,144395,144395,144395,144395,144396,144396,144398,144398,144398,144398,144399,144399,144399,144403,144406,144406,144406,144406,144406,144406,144407,144407,144407,144408,144408,144409,144411,144414,144415,144415,144415,144415,144416,144416,144419,144419,144419,144422,144422,144423,144423,144423,144426,144428,144428,144428,144428,144437,144437,144437,144437,144437,144441,144442,144445,144447,144447,144447,144447,144448,144448,144448,144448,144448,144448,144448,144448,144448,144450,144450,144450,144451,144453,144453,144454,144456,144459,144459,144461,144463,144466,144466,144466,144466,144466,144466,144466,144467,144471,144472,144472,144472,144472,144475,144477,144481,144494,144494,144499,144501,144501,144506,144506,144507,144510,144514,144517,144519,144520,144520,144520,144524,144527,144527,144529,144530,144530,144531,144531,144531,144533,144545,144545,144550,144550,144550,144551,144553,144553,144553,144553,144558,144559,144559,144560,144563,144565,144565,144565,144565,144565,144565,144565,144571,144575,144578,144583,144585,144587,144587,144592,144592,144595,144595,144595,144604,144604,144604,144612,144613,144613,144613,144613,144613,144613,144615,144618,144619,144619,144621,144621,144622,144623,144628,144630,144635,144639,144643,144647,144647,144648,144648,144651,144656,144656,144658,144660,144662,144668,144672,144674,144674,144674,144680,144681,144684,144692,144692,144692,144692,144692,144692,144692,144692,144692,144692,144692,144692,144693,144693,144697,144697,144697,144697,144697,144697,144697,144697,144697,144697,144701,144701,144701,144706,144707,144707,144707,144707,144712,144713,144713,144713,144713,144714,144714,144714,144714,144714,144714,144714,144715,144715,144717,144721,144727,144727,144735,144736,144736,144737,144741,144744,144745,144748,144749,144749,144754,144754,144754,144755,144758,144760,144760,144760,144761,144762,144765,144771,144776,144782,144782,144784,144785,144785,144789,144790,144793,144801,144812,144812,144812,144812,144812,144814,144816,144817,144819,144828,144832,144836,144838,144844,144847,144852,144852,144858,144858,144858,144858,144862,144862,144865,144865,144866,144867,144872,144873,144874,144876,144876,144879,144879,144879,144879,144879,144879,144882,144885,144885,144889,144898,144898,144901,144901,144901,144901,144902,144912,144918,144918,144919,144919,144919,144919,144926,144926,144926,144930,144930,144930,144931,144932,144943,144946,144950,144952,144965,144966,144970,144970,144972,144979,144979,144982,144992,144993,144993,145008,145009,145019,145023,145030,145032,145034,145034,145034,145034,145035,145037,145037,145039,145048,145051,145052,145054,145054,145054,145058,145067,145076,145077,145080,145081,145087,145089,145089,145089,145092,145092,145092,145094,145099,145100,145100,145100,145100,145100,145100,145100,145100,145102,145102,145103,145109,145116,145123,145124,145124,145129,145129,145130,145130,145130,145131,145133,145133,145133,145136,145139,145139,145143,145145,145155,145167,145167,145167,145168,145170,145172,145176,145176,145184,145193,145202,145205,145207,145208,145215,145222,145222,145222,145222,145222,145222,145222,145222,145224,145224,145237,145247,145247,145247,145247,145247,145252,145257,145257,145258,145260,145260,145260,145260,145260,145260,145260,145260,145263,145263,145263,145266,145273,145273,145276,145276,145276,145287,145288,145290,145292,145299,145299,145299,145299,145302,145302,145302,145302,145302,145303,145303,145305,145313,145326,145332,145338,145340,145340,145347,145347,145347,145354,145361,145361,145364,145364,145366,145369,145370,145373,145374,145374,145383,145386,145386,145386,145387,145388,145388,145388,145389,145389,145389,145390,145390,145391,145393,145395,145396,145396,145397,145404,145405,145405,145410,145410,145412,145412,145418,145418,145422,145424,145424,145424,145424,145425,145426,145426,145426,145426,145426,145427,145428,145429,145430,145430,145430,145430,145431,145431,145431,145431,145431,145431,145432,145432,145432,145433,145433,145436,145438,145440,145440,145441,145442,145442,145446,145446,145446,145447,145450,145450,145450,145455,145459,145466,145469,145469,145469,145471,145471,145471,145471,145471,145471,145473,145480,145480,145488,145489,145492,145492,145492,145499,145499,145499,145499,145499,145499,145499,145500,145500,145500,145500,145501,145502,145502,145502,145502,145505,145507,145507,145509,145512,145513,145517,145518,145518,145518,145519,145519,145519,145520,145524,145535,145535,145535,145536,145537,145539,145540,145540,145540,145540,145540,145540,145540,145542,145544,145544,145544,145547,145547,145547,145552,145552,145552,145553,145553,145553,145553,145555,145555,145555,145555,145555,145556,145556,145556,145556,145556,145556,145557,145559,145563,145565,145565,145568,145568,145568,145572,145573,145574,145574,145574,145574,145574,145574,145575,145577,145581,145583,145584,145585,145585,145585,145585,145588,145590,145590,145590,145592,145598,145603,145604,145608,145611,145611,145614,145623,145623,145623,145623,145623,145623,145623,145624,145627,145627,145628,145629,145630,145632,145632,145632,145632,145632,145633,145634,145635,145635,145636,145638,145642,145642,145643,145643,145643,145648,145648,145651,145652,145652,145652,145663,145663,145663,145668,145670,145671,145673,145673,145673,145673,145675,145677,145686,145690,145690,145691,145693,145693,145707,145719,145726,145726,145726,145726,145727,145728,145728,145731,145732,145733,145733,145733,145733,145739,145740,145742,145744,145746,145746,145746,145746,145746,145749,145749,145749,145749,145749,145749,145749,145753,145756,145756,145760,145761,145763,145763,145763,145767,145767,145769,145773,145774,145776,145781,145786,145791,145795,145799,145810,145815,145817,145822,145823,145823,145823,145823,145826,145832,145841,145841,145845,145846,145851,145856,145859,145864,145864,145867,145870,145870,145872,145875,145875,145875,145875,145877,145877,145877,145882,145884,145885,145887,145895,145897,145899,145900,145900,145900,145900,145900,145900,145900,145902,145903,145903,145903,145906,145907,145909,145913,145913,145913,145913,145913,145913,145913,145913,145913,145913,145938,145938,145948,145953,145960,145970,145974,145974,145974,145975,145976,145983,145983,145983,145985,145986,145988,145990,145994,146006,146009,146009,146015,146015,146019,146023,146023,146024,146030,146030,146030,146030,146030,146030,146031,146032,146034,146038,146044,146046,146046,146050,146050,146050,146051,146053,146054,146057,146057,146068,146073,146076,146082,146083,146083,146083,146086,146088,146088,146088,146088,146089,146089,146092,146098,146099,146099,146104,146105,146105,146110,146110,146112,146112,146113,146113,146113,146113,146115,146116,146117,146122,146131,146132,146135,146140,146140,146144,146144,146144,146144,146144,146146,146155,146159,146159,146159,146159,146161,146161,146161,146168,146174,146174,146175,146176,146179,146185,146185,146189,146201,146204,146207,146207,146207,146221,146224,146224,146225,146228,146228,146228,146228,146235,146237,146240,146241,146244,146246,146246,146246,146258,146260,146260,146260,146264,146264,146276,146276,146276,146276,146276,146277,146277,146277,146290,146293,146297,146297,146297,146297,146298,146299,146300,146300,146300,146300,146300,146308,146309,146309,146309,146309,146310,146312,146312,146312,146313,146317,146318,146318,146318,146319,146348,146350,146352,146371,146371,146371,146373,146373,146374,146376,146385,146388,146393,146393,146396,146397,146399,146414,146432,146434,146438,146441,146442,146446,146448,146448,146448,146448,146450,146450,146450,146450,146450,146450,146450,146453,146453,146455,146455,146457,146464,146464,146464,146464,146467,146467,146471,146472,146472,146480,146486,146487,146487,146489,146489,146490,146490,146499,146499,146499,146499,146499,146501,146502,146510,146519,146525,146525,146528,146529,146529,146531,146532,146532,146534,146536,146536,146536,146536,146538,146546,146546,146546,146550,146553,146562,146562,146562,146562,146568,146568,146568,146568,146568,146568,146568,146572,146572,146579,146581,146582,146582,146582,146582,146582,146584,146592,146600,146600,146600,146601,146617,146620,146621,146621,146621,146622,146622,146622,146622,146628,146628,146628,146631,146638,146646,146647,146647,146647,146647,146647,146647,146647,146648,146654,146656,146660,146660,146660,146660,146660,146660,146660,146660,146660,146660,146661,146662,146662,146662,146662,146664,146665,146671,146680,146682,146683,146683,146691,146692,146694,146697,146702,146703,146705,146707,146716,146717,146720,146721,146721,146722,146726,146727,146727,146727,146730,146730,146730,146730,146732,146732,146733,146737,146740,146746,146758,146774,146775,146782,146784,146784,146785,146785,146785,146785,146785,146785,146786,146786,146786,146786,146786,146786,146788,146800,146808,146808,146808,146814,146814,146814,146814,146814,146814,146814,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146820,146823,146828,146830,146833,146833,146833,146833,146833,146833,146833,146833,146833,146838,146838,146838,146838,146840,146840,146841,146841,146847,146847,146847,146850,146852,146859,146864,146865,146872,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146876,146878,146878,146880,146883,146883,146889,146889,146893,146896,146896,146897,146900,146900,146900,146901,146901,146901,146901,146903,146904,146905,146905,146906,146906,146906,146907,146907,146907,146907,146907,146907,146907,146907,146907,146908,146909,146909,146909,146909,146911,146911,146911,146911,146912,146912,146912,146913,146914,146916,146921,146921,146922,146922,146924,146924,146925,146925,146925,146925,146925,146926,146926,146930,146931,146931,146933,146935,146935,146937,146938,146940,146940,146940,146942,146946,146946,146946,146949,146950,146953,146959,146959,146959,146959,146959,146959,146959,146960,146967,146967,146967,146969,146979,146979,146980,146984,146985,146987,146987,146990,146991,146993,146993,146998,146999,146999,147002,147002,147004,147014,147015,147019,147019,147021,147024,147024,147026,147026,147027,147027,147027,147027,147031,147036,147038,147038,147040,147040,147042,147042,147042,147052,147052,147060,147060,147066,147070,147073,147075,147075,147077,147084,147084,147084,147084,147084,147084,147084,147085,147086,147089,147089,147104,147107,147110,147118,147119,147122,147123,147126,147128,147129,147129,147129,147130,147130,147133,147135,147135,147137,147141,147142,147148,147151,147161,147180,147180,147180,147180,147183,147184,147191,147191,147192,147206,147208,147214,147214,147218,147219,147219,147224,147238,147238,147242,147245,147246,147249,147249,147249,147254,147255,147255,147255,147255,147255,147259,147269,147269,147271,147271,147275,147281,147281,147282,147287,147287,147293,147293,147296,147296,147301,147305,147305,147311,147311,147313,147315,147319,147321,147327,147368,147368,147368,147368,147368,147368,147368,147371,147372,147372,147390,147391,147398,147398,147401,147402,147403,147413,147413,147413,147413,147413,147413,147418,147421,147426,147427,147429,147430,147431,147437,147437,147445,147447,147447,147455,147463,147463,147463,147478,147478,147478,147478,147478,147478,147478,147478,147484,147484,147485,147485,147485,147487,147492,147492,147492,147492,147494,147502,147504,147514,147525,147527,147531,147536,147536,147537,147537,147543,147543,147543,147550,147556,147558,147561,147561,147562,147562,147569,147569,147570,147578,147580,147582,147587,147607,147625,147625,147625,147625,147625,147625,147625,147625,147639,147641,147643,147646,147646,147649,147651,147651,147653,147657,147661,147663,147663,147663,147666,147669,147669,147674,147674,147683,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147684,147686,147686,147686,147687,147689,147689,147690,147690,147690,147691,147693,147695,147696,147698,147698,147698,147698,147698,147698,147699,147702,147702,147706,147706,147706,147706,147706,147706,147706,147706,147706,147706,147706,147706,147706,147708,147709,147709,147709,147709,147709,147709,147709,147709,147709,147709,147709,147709,147710,147711,147711,147712,147712,147712,147713,147713,147713,147713,147714,147714,147714,147714,147714,147714,147714,147715,147718,147719,147719,147720,147730,147732,147732,147737,147739,147741,147742,147742,147743,147743,147754,147755,147755,147756,147756,147756,147759,147759,147761,147762,147762,147765,147765,147768,147769,147770,147771,147773,147778,147779,147779,147779,147779,147780,147780,147780,147780,147780,147780,147781,147781,147782,147783,147784,147786,147786,147791,147791,147794,147794,147794,147794,147794,147795,147795,147797,147798,147798,147798,147798,147798,147798,147799,147799,147799,147799,147802,147802,147802,147802,147802,147802,147802,147802,147803,147803,147803,147804,147804,147815,147817,147817,147820,147820,147822,147824,147825,147825,147825,147825,147827,147829,147831,147833,147833,147837,147837,147843,147843,147846,147850,147850,147851,147852,147852,147852,147852,147852,147853,147853,147853,147853,147853,147853,147855,147855,147858,147860,147860,147862,147862,147867,147868,147871,147872,147880,147881,147884,147884,147884,147884,147884,147888,147888,147888,147888,147889,147890,147890,147891,147891,147891,147892,147894,147894,147894,147901,147901,147901,147901,147901,147902,147906,147907,147909,147910,147911,147913,147913,147916,147920,147920,147922,147924,147927,147928,147928,147930,147931,147931,147931,147931,147935,147936,147937,147938,147938,147938,147938,147949,147950,147950,147950,147955,147958,147960,147969,147969,147975,147975,147976,147978,147979,147984,147985,147985,147985,147988,147988,147988,147988,147992,147995,147995,147998,147998,148000,148002,148002,148002,148002,148002,148002,148005,148007,148007,148008,148009,148010,148010,148010,148010,148013,148013,148014,148015,148015,148015,148019,148019,148020,148020,148020,148020,148020,148020,148020,148025,148032,148032,148032,148034,148035,148038,148039,148043,148045,148045,148045,148046,148047,148053,148058,148070,148070,148070,148070,148070,148070,148072,148072,148076,148080,148082,148082,148086,148086,148087,148087,148088,148088,148089,148089,148089,148093,148094,148100,148100,148104,148104,148104,148107,148109,148120,148122,148123,148128,148143,148145,148145,148147,148148,148149,148149,148151,148151,148152,148154,148161,148162,148169,148169,148170,148170,148177,148181,148183,148183,148183,148183,148185,148189,148189,148197,148201,148201,148206,148209,148209,148209,148209,148209,148210,148211,148211,148212,148214,148214,148215,148216,148216,148216,148217,148218,148220,148221,148228,148228,148228,148228,148231,148231,148234,148234,148236,148237,148237,148237,148240,148248,148252,148252,148258,148261,148262,148262,148262,148264,148264,148264,148264,148265,148266,148267,148268,148273,148273,148273,148274,148276,148278,148279,148279,148283,148289,148292,148299,148299,148306,148306,148306,148306,148308,148309,148310,148311,148316,148318,148321,148327,148331,148331,148336,148338,148338,148338,148338,148339,148341,148341,148343,148354,148357,148359,148359,148375,148381,148386,148388,148388,148388,148389,148390,148390,148396,148401,148401,148401,148401,148402,148403,148403,148403,148403,148403,148404,148408,148411,148411,148411,148411,148411,148412,148415,148417,148418,148419,148437,148438,148438,148443,148443,148443,148447,148450,148450,148450,148459,148460,148460,148460,148469,148471,148473,148477,148477,148477,148477,148477,148477,148480,148480,148480,148482,148482,148482,148487,148487,148487,148487,148492,148497,148502,148506,148508,148508,148516,148516,148516,148516,148516,148516,148518,148518,148519,148527,148531,148531,148531,148554,148558,148569,148574,148592,148594,148612,148613,148616,148621,148624,148634,148636,148637,148645,148652,148656,148657,148660,148661,148670,148670,148670,148671,148674,148675,148676,148677,148680,148681,148683,148686,148690,148690,148705,148710,148717,148720,148721,148721,148725,148733,148733,148733,148738,148738,148738,148738,148738,148738,148738,148738,148738,148738,148742,148745,148756,148756,148756,148759,148759,148759,148762,148767,148767,148767,148768,148768,148768,148768,148771,148775,148778,148783,148787,148790,148801,148803,148813,148815,148817,148819,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148823,148825,148828,148830,148830,148830,148835,148851,148852,148858,148858,148862,148862,148862,148864,148866,148866,148866,148866,148866,148866,148866,148872,148874,148875,148875,148878,148879,148879,148879,148879,148885,148886,148887,148894,148894,148894,148897,148898,148898,148898,148898,148898,148898,148899,148899,148904,148906,148906,148906,148906,148906,148906,148907,148907,148912,148913,148914,148922,148922,148922,148923,148927,148927,148927,148928,148928,148928,148928,148928,148929,148929,148929,148929,148929,148930,148930,148930,148930,148930,148930,148931,148932,148932,148933,148933,148933,148933,148933,148936,148943,148948,148949,148949,148949,148951,148951,148951,148951,148952,148956,148956,148960,148960,148961,148963,148964,148964,148966,148966,148966,148966,148967,148969,148975,148976,148980,148980,148981,148984,148987,148994,148996,148997,149002,149002,149002,149003,149007,149010,149010,149011,149012,149012,149012,149015,149015,149018,149018,149019,149019,149019,149019,149019,149020,149020,149021,149023,149024,149028,149029,149029,149030,149030,149038,149038,149040,149040,149040,149041,149044,149044,149046,149046,149046,149047,149047,149049,149049,149049,149049,149051,149051,149051,149051,149051,149051,149052,149055,149059,149059,149059,149059,149063,149066,149066,149074,149075,149076,149078,149080,149080,149080,149082,149082,149083,149083,149083,149087,149087,149090,149091,149093,149099,149099,149099,149100,149101,149105,149107,149107,149108,149108,149108,149110,149110,149112,149116,149117,149117,149117,149117,149119,149122,149122,149123,149123,149126,149129,149130,149130,149133,149133,149135,149137,149139,149139,149145,149149,149155,149155,149159,149162,149162,149162,149166,149176,149184,149186,149197,149197,149197,149197,149215,149219,149219,149229,149229,149229,149230,149230,149230,149236,149238,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149239,149240,149240,149240,149240,149240,149243,149244,149247,149249,149249,149260,149269,149274,149275,149277,149279,149283,149285,149286,149289,149290,149291,149296,149299,149299,149299,149304,149312,149323,149326,149327,149327,149327,149327,149327,149328,149328,149329,149329,149332,149332,149333,149338,149338,149338,149338,149341,149344,149344,149349,149353,149353,149355,149359,149362,149362,149369,149380,149381,149381,149383,149386,149386,149386,149387,149388,149391,149391,149391,149391,149391,149391,149391,149391,149391,149397,149398,149404,149404,149406,149407,149407,149407,149407,149411,149411,149411,149411,149411,149411,149411,149422,149422,149422,149422,149424,149424,149424,149424,149424,149429,149436,149448,149450,149450,149463,149464,149465,149465,149465,149465,149466,149468,149468,149470,149470,149470,149471,149481,149489,149495,149511,149511,149511,149511,149521,149526,149527,149528,149528,149528,149529,149529,149529,149529,149529,149529,149529,149531,149531,149532,149535,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149542,149543,149543,149543,149546,149547,149548,149559,149561,149565,149575,149576,149581,149583,149586,149588,149594,149595,149597,149603,149603,149603,149609,149609,149609,149609,149609,149611,149612,149614,149615,149623,149624,149627,149630,149633,149635,149636,149638,149638,149640,149640,149641,149643,149644,149647,149648,149648,149650,149654,149654,149654,149657,149660,149661,149661,149662,149662,149663,149671,149674,149674,149674,149674,149691,149704,149717,149717,149719,149720,149721,149723,149723,149724,149725,149726,149726,149726,149729,149730,149731,149738,149738,149740,149740,149740,149741,149741,149742,149742,149742,149742,149743,149743,149743,149744,149745,149752,149752,149752,149757,149758,149764,149765,149765,149766,149768,149770,149777,149779,149780,149782,149782,149782,149790,149791,149791,149791,149793,149795,149795,149795,149795,149795,149796,149803,149803,149807,149811,149813,149819,149821,149824,149828,149829,149831,149833,149835,149837,149838,149842,149843,149844,149845,149848,149853,149855,149856,149857,149861,149863,149864,149864,149864,149870,149882,149882,149882,149882,149882,149882,149882,149882,149882,149882,149882,149882,149882,149896,149899,149901,149901,149904,149907,149907,149907,149907,149907,149907,149915,149915,149915,149916,149920,149921,149921,149921,149926,149933,149936,149942,149946,149961,149972,149974,149977,149979,149979,149980,149980,149980,149982,149983,149987,149989,149989,149997,149997,150001,150001,150001,150001,150004,150019,150022,150029,150030,150033,150033,150033,150034,150043,150045,150045,150046,150046,150046,150046,150046,150046,150046,150046,150046,150046,150046,150046,150046,150046,150053,150053,150060,150060,150060,150060,150060,150060,150060,150060,150068,150068,150068,150072,150082,150082,150082,150082,150082,150096,150096,150104,150109,150111,150125,150131,150134,150135,150135,150138,150138,150138,150138,150138,150139,150139,150140,150143,150145,150148,150148,150150,150151,150151,150159,150166,150166,150166,150166,150173,150176,150184,150186,150186,150186,150193,150196,150198,150199,150199,150199,150201,150208,150208,150208,150209,150212,150212,150214,150214,150220,150221,150228,150229,150229,150234,150235,150238,150256,150257,150258,150263,150266,150268,150269,150269,150275,150301,150307,150311,150318,150324,150327,150332,150348,150348,150348,150349,150349,150349,150353,150353,150361,150368,150368,150371,150375,150391,150392,150409,150414,150415,150415,150415,150415,150415,150415,150415,150417,150421,150422,150422,150422,150428,150428,150428,150430,150430,150433,150433,150433,150433,150434,150438,150439,150441,150443,150443,150446,150446,150449,150452,150475,150477,150477,150477,150480,150480,150480,150481,150492,150505,150506,150506,150514,150517,150517,150517,150518,150522,150522,150523,150523,150523,150523,150523,150523,150523,150523,150528,150533,150536,150536,150539,150539,150543,150547,150550,150553,150555,150555,150556,150557,150566,150566,150567,150572,150576,150576,150576,150576,150578,150579,150579,150580,150580,150580,150580,150580,150582,150587,150587,150590,150590,150590,150590,150590,150590,150590,150590,150591,150591,150594,150597,150600,150600,150600,150600,150600,150601,150601,150601,150604,150607,150609,150611,150612,150614,150614,150616,150616,150618,150618,150618,150620,150620,150629,150632,150634,150637,150647,150647,150647,150652,150656,150666,150668,150675,150675,150680,150680,150680,150681,150681,150681,150681,150684,150714,150732,150732,150732,150732,150732,150732,150732,150732,150732,150732,150732,150732,150734,150734,150734,150734,150734,150739,150742,150743,150743,150746,150751,150752,150754,150754,150754,150762,150766,150773,150773,150775,150775,150787,150795,150795,150795,150800,150800,150800,150808,150808,150808,150808,150809,150811,150811,150814,150814,150815,150816,150818,150818,150823,150824,150825,150825,150825,150825,150825,150831,150831,150831,150831,150831,150831,150833,150839,150845,150851,150852,150854,150858,150859,150861,150861,150861,150867,150867,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150868,150870,150875,150876,150884,150889,150889,150889,150893,150893,150898,150898,150899,150901,150901,150901,150906,150907,150907,150907,150907,150907,150907,150911,150916,150929,150929,150930,150931,150931,150931,150931,150931,150931,150931,150931,150931,150931,150931,150931,150931,150931,150931,150937,150938,150938,150948,150948,150948,150948,150948,150948,150948,150950,150950,150954,150955,150958,150958,150958,150962,150962,150962,150965,150967,150967,150969,150969,150972,150972,150973,150973,150973,150973,150973,150976,150978,150980,150980,150981,150981,150981,150983,150993,151004,151005,151005,151005,151005,151005,151005,151005,151013,151013,151013,151017,151021,151032,151032,151033,151044,151071,151077,151079,151079,151079,151079,151079,151079,151079,151079,151079,151079,151079,151082,151082,151082,151082,151082,151082,151082,151082,151082,151082,151088,151093,151096,151112,151113,151120,151120,151120,151120,151120,151120,151120,151120,151120,151120,151120,151120,151120,151120,151120,151121,151125,151139,151148,151148,151148,151151,151152,151153,151154,151173,151173,151173,151179,151180,151180,151185,151186,151187,151194,151198,151198,151204,151227,151229,151240,151252,151266,151266,151266,151266,151266,151266,151266,151266,151266,151296,151309,151314,151314,151314,151317,151318,151318,151318,151321,151322,151322,151330,151330,151330,151330,151335,151343,151354,151356,151358,151366,151366,151367,151367,151369,151369,151373,151377,151387,151389,151390,151390,151390,151390,151390,151391,151395,151395,151395,151396,151396,151410,151418,151421,151428,151433,151434,151434,151434,151434,151434,151434,151438,151445,151449,151454,151456,151459,151462,151462,151463,151464,151477,151477,151479,151485,151496,151498,151498,151500,151502,151506,151515,151515,151516,151529,151529,151529,151529,151529,151529,151532,151532,151532,151533,151533,151533,151534,151534,151534,151534,151534,151534,151535,151536,151536,151536,151537,151537,151537,151537,151537,151537,151537,151537,151537,151538,151538,151539,151539,151540,151540,151543,151543,151546,151549,151553,151554,151556,151556,151557,151557,151561,151563,151566,151568,151568,151568,151569,151571,151574,151578,151578,151578,151581,151581,151581,151582,151584,151584,151584,151584,151585,151585,151585,151586,151588,151596,151597,151597,151597,151597,151597,151598,151598,151598,151598,151598,151598,151604,151607,151609,151615,151615,151616,151618,151619,151620,151620,151620,151622,151631,151632,151632,151633,151634,151634,151634,151635,151641,151641,151641,151642,151643,151643,151643,151643,151644,151644,151644,151647,151652,151658,151660,151660,151660,151660,151663,151664,151665,151667,151668,151669,151669,151670,151670,151670,151672,151672,151672,151672,151672,151672,151672,151672,151672,151680,151680,151681,151681,151682,151682,151682,151682,151682,151682,151684,151685,151685,151686,151691,151691,151691,151693,151693,151693,151693,151693,151693,151693,151694,151694,151697,151697,151698,151703,151705,151710,151712,151712,151713,151714,151719,151720,151720,151722,151722,151722,151722,151723,151731,151735,151735,151736,151736,151737,151738,151742,151742,151742,151745,151745,151748,151749,151750,151750,151754,151756,151760,151760,151760,151760,151761,151761,151761,151764,151765,151766,151771,151772,151773,151773,151774,151774,151774,151776,151776,151786,151787,151787,151796,151796,151796,151796,151796,151796,151796,151802,151802,151805,151807,151807,151810,151820,151820,151822,151822,151822,151829,151845,151857,151881,151881,151881,151883,151883,151883,151883,151885,151885,151885,151885,151885,151885,151885,151886,151886,151886,151887,151893,151897,151897,151897,151897,151905,151908,151911,151911,151917,151925,151925,151930,151936,151938,151938,151938,151940,151942,151942,151942,151943,151943,151943,151943,151944,151946,151947,151947,151949,151954,151957,151958,151961,151963,151964,151964,151965,151965,151965,151967,151967,151969,151977,151979,151980,151980,151981,151983,151984,151984,151985,151985,151985,151985,151985,151989,151990,151990,151991,151993,151995,151997,151998,152000,152008,152008,152017,152019,152019,152021,152026,152026,152026,152027,152029,152030,152030,152031,152031,152032,152038,152038,152039,152041,152041,152048,152054,152060,152066,152080,152081,152084,152085,152091,152093,152101,152106,152106,152106,152111,152115,152116,152117,152118,152118,152135,152135,152135,152136,152137,152138,152140,152140,152145,152153,152156,152156,152156,152160,152161,152161,152161,152166,152167,152167,152168,152168,152170,152172,152173,152173,152176,152176,152176,152176,152177,152188,152191,152193,152194,152194,152200,152201,152201,152202,152202,152205,152205,152205,152205,152205,152205,152205,152205,152205,152205,152205,152205,152205,152205,152210,152210,152213,152213,152225,152226,152227,152227,152232,152233,152234,152234,152241,152242,152246,152247,152247,152247,152247,152247,152247,152250,152253,152255,152262,152263,152266,152266,152266,152268,152270,152272,152274,152274,152277,152278,152278,152279,152283,152283,152284,152285,152285,152285,152286,152287,152288,152291,152293,152293,152293,152295,152301,152301,152304,152310,152310,152313,152313,152314,152321,152321,152321,152321,152322,152325,152327,152330,152335,152338,152342,152347,152347,152347,152354,152354,152354,152354,152355,152355,152355,152360,152362,152364,152375,152376,152380,152380,152383,152387,152389,152395,152397,152398,152398,152407,152412,152414,152419,152419,152419,152419,152421,152421,152421,152424,152426,152434,152434,152437,152438,152444,152450,152451,152452,152461,152461,152474,152476,152482,152483,152486,152486,152488,152495,152495,152497,152498,152511,152518,152520,152521,152533,152537,152538,152538,152539,152546,152546,152549,152556,152558,152560,152566,152567,152575,152575,152575,152575,152576,152578,152579,152580,152583,152583,152590,152590,152597,152597,152601,152615,152622,152646,152646,152651,152651,152662,152666,152670,152675,152678,152685,152686,152692,152692,152692,152701,152702,152709,152709,152711,152711,152711,152713,152714,152714,152714,152714,152717,152718,152725,152729,152730,152730,152733,152734,152736,152737,152745,152745,152745,152745,152747,152747,152750,152757,152757,152757,152757,152757,152757,152758,152759,152759,152760,152766,152767,152770,152771,152774,152784,152785,152790,152790,152791,152797,152807,152807,152831,152831,152836,152867,152868,152870,152870,152870,152870,152870,152871,152877,152884,152884,152885,152894,152899,152899,152900,152900,152900,152900,152900,152900,152900,152912,152912,152912,152912,152912,152912,152912,152912,152913,152913,152913,152920,152924,152924,152924,152924,152927,152927,152927,152940,152945,152945,152946,152947,152947,152949,152950,152950,152962,152971,152981,152982,152985,152985,152987,152989,152993,153006,153013,153029,153031,153031,153038,153039,153045,153046,153046,153046,153047,153047,153047,153049,153052,153062,153062,153063,153080,153080,153080,153080,153080,153082,153083,153083,153083,153083,153089,153093,153097,153097,153098,153098,153098,153098,153098,153098,153098,153098,153099,153101,153101,153105,153105,153119,153120,153121,153122,153122,153127,153128,153128,153131,153134,153136,153141,153141,153141,153141,153143,153149,153149,153149,153149,153150,153150,153154,153154,153158,153158,153158,153158,153162,153165,153166,153166,153166,153170,153172,153177,153184,153197,153199,153203,153203,153204,153208,153208,153208,153208,153219,153223,153225,153225,153225,153225,153225,153225,153225,153225,153225,153225,153227,153232,153232,153234,153236,153241,153249,153256,153256,153270,153277,153287,153290,153294,153305,153307,153312,153322,153326,153341,153342,153348,153350,153351,153351,153352,153364,153364,153364,153366,153366,153366,153366,153366,153366,153366,153366,153369,153380,153380,153399,153405,153406,153406,153412,153412,153421,153423,153431,153432,153439,153442,153442,153442,153444,153445,153445,153445,153445,153445,153445,153445,153451,153453,153460,153467,153467,153475,153475,153475,153476,153476,153479,153482,153485,153486,153486,153492,153492,153496,153496,153502,153505,153505,153507,153507,153522,153528,153533,153539,153540,153541,153545,153546,153548,153548,153561,153564,153564,153564,153565,153567,153567,153572,153577,153577,153577,153579,153582,153588,153592,153598,153611,153619,153623,153623,153625,153625,153630,153630,153634,153636,153636,153640,153640,153641,153651,153659,153660,153666,153666,153666,153666,153666,153666,153666,153666,153673,153673,153673,153673,153673,153673,153675,153684,153685,153685,153688,153697,153706,153709,153709,153709,153710,153710,153710,153710,153711,153714,153722,153722,153722,153727,153736,153757,153784,153785,153785,153785,153787,153793,153794,153798,153798,153798,153798,153798,153799,153802,153806,153807,153807,153817,153817,153818,153818,153825,153825,153829,153832,153835,153837,153842,153845,153845,153845,153852,153856,153857,153857,153857,153857,153866,153866,153866,153870,153871,153871,153871,153871,153874,153874,153874,153874,153874,153875,153877,153878,153883,153886,153887,153889,153893,153894,153894,153896,153897,153903,153904,153907,153915,153917,153920,153920,153923,153923,153929,153934,153935,153935,153937,153941,153943,153951,153951,153955,153961,153962,153962,153963,153963,153963,153963,153963,153963,153963,153963,153964,153966,153966,153967,153972,153976,153976,153976,153976,153993,153998,154005,154007,154020,154021,154021,154021,154021,154022,154022,154022,154022,154024,154025,154026,154030,154032,154033,154035,154035,154036,154036,154042,154042,154042,154055,154056,154057,154059,154065,154069,154069,154069,154073,154078,154079,154084,154086,154086,154096,154096,154096,154099,154099,154104,154104,154106,154108,154112,154121,154121,154123,154123,154123,154123,154124,154124,154125,154125,154132,154136,154143,154144,154146,154148,154148,154148,154148,154149,154164,154169,154170,154173,154177,154180,154181,154189,154190,154195,154196,154216,154218,154230,154235,154242,154245,154245,154245,154248,154248,154248,154248,154250,154258,154259,154264,154264,154266,154269,154269,154269,154269,154269,154270,154270,154270,154270,154275,154279,154281,154293,154296,154302,154302,154302,154302,154302,154302,154309,154310,154310,154310,154319,154322,154329,154330,154330,154335,154339,154339,154343,154345,154346,154346,154346,154350,154354,154354,154354,154355,154357,154357,154360,154361,154361,154363,154366,154381,154381,154381,154383,154383,154384,154384,154384,154384,154385,154385,154385,154385,154385,154385,154389,154392,154392,154392,154392,154392,154396,154396,154398,154401,154401,154402,154407,154407,154407,154409,154409,154409,154409,154410,154410,154410,154410,154413,154413,154413,154415,154415,154418,154418,154419,154419,154419,154419,154419,154419,154419,154420,154421,154423,154423,154423,154425,154426,154428,154428,154432,154438,154440,154440,154441,154443,154446,154448,154448,154448,154449,154449,154452,154456,154458,154459,154459,154459,154459,154459,154459,154459,154459,154459,154464,154464,154466,154466,154467,154467,154467,154470,154470,154471,154471,154471,154473,154473,154473,154474,154474,154478,154478,154478,154480,154481,154482,154482,154483,154484,154484,154489,154489,154489,154491,154496,154497,154498,154498,154499,154500,154501,154513,154519,154520,154522,154522,154526,154526,154535,154536,154537,154537,154538,154538,154543,154555,154555,154556,154557,154558,154561,154562,154562,154565,154569,154569,154570,154571,154571,154572,154577,154588,154591,154591,154591,154592,154594,154595,154595,154599,154599,154602,154602,154605,154605,154605,154607,154608,154608,154609,154613,154620,154620,154622,154622,154622,154622,154622,154622,154624,154628,154630,154630,154631,154631,154636,154638,154641,154643,154645,154645,154647,154657,154660,154670,154671,154676,154676,154676,154676,154676,154676,154676,154676,154676,154676,154676,154676,154680,154683,154693,154698,154700,154708,154708,154708,154709,154709,154709,154710,154717,154723,154735,154735,154742,154743,154748,154748,154759,154761,154764,154764,154766,154767,154772,154772,154774,154774,154779,154781,154781,154781,154782,154784,154787,154788,154789,154793,154794,154795,154796,154797,154797,154801,154803,154803,154804,154822,154826,154826,154826,154826,154826,154830,154835,154840,154841,154843,154851,154856,154867,154871,154871,154871,154871,154871,154871,154871,154871,154871,154871,154871,154871,154871,154876,154879,154879,154880,154881,154883,154883,154883,154886,154887,154889,154889,154889,154890,154890,154890,154890,154892,154892,154898,154899,154902,154911,154911,154911,154912,154913,154921,154921,154923,154934,154935,154945,154951,154953,154958,154960,154961,154964,154964,154965,154965,154969,154969,154971,154971,154971,154972,154977,154981,154981,154990,154994,154994,154994,154995,154995,155003,155007,155013,155013,155016,155016,155016,155018,155022,155026,155033,155033,155033,155034,155037,155045,155047,155052,155052,155052,155052,155052,155052,155052,155052,155052,155052,155052,155055,155055,155056,155056,155058,155058,155060,155065,155065,155068,155073,155082,155082,155088,155089,155091,155091,155091,155091,155091,155093,155094,155096,155097,155099,155100,155101,155104,155107,155107,155107,155107,155107,155107,155107,155107,155111,155117,155117,155117,155117,155119,155119,155119,155119,155119,155119,155119,155122,155129,155129,155129,155129,155129,155129,155131,155143,155153,155163,155165,155165,155165,155168,155169,155171,155172,155173,155173,155173,155173,155174,155181,155185,155185,155190,155191,155192,155196,155197,155197,155197,155197,155197,155211,155214,155220,155221,155222,155222,155222,155223,155227,155227,155231,155231,155231,155234,155235,155236,155238,155243,155244,155247,155252,155253,155255,155257,155257,155268,155269,155277,155282,155282,155286,155286,155299,155307,155308,155309,155317,155330,155340,155340,155340,155341,155342,155343,155343,155346,155346,155346,155346,155346,155346,155346,155346,155346,155346,155346,155354,155355,155356,155356,155359,155361,155365,155367,155368,155368,155372,155374,155374,155376,155380,155381,155381,155382,155385,155388,155388,155390,155390,155391,155394,155396,155405,155405,155405,155410,155411,155412,155416,155417,155417,155419,155419,155419,155426,155427,155427,155430,155433,155435,155435,155436,155440,155445,155445,155445,155448,155485,155485,155486,155490,155491,155494,155496,155502,155514,155520,155520,155520,155534,155534,155537,155537,155537,155555,155556,155568,155574,155595,155596,155596,155596,155596,155597,155600,155610,155614,155615,155615,155618,155622,155629,155632,155634,155636,155645,155651,155653,155653,155655,155658,155659,155669,155679,155683,155683,155683,155683,155683,155683,155687,155687,155687,155687,155688,155688,155689,155689,155689,155692,155709,155718,155731,155739,155742,155742,155744,155744,155746,155749,155754,155755,155756,155758,155759,155761,155761,155761,155761,155761,155763,155763,155767,155773,155777,155778,155789,155789,155789,155794,155795,155796,155814,155822,155827,155827,155827,155833,155833,155833,155837,155839,155840,155840,155845,155845,155845,155845,155855,155855,155855,155855,155855,155857,155866,155870,155872,155872,155874,155876,155877,155882,155886,155890,155890,155894,155895,155898,155898,155898,155899,155899,155899,155899,155899,155899,155900,155909,155918,155920,155920,155920,155920,155920,155922,155922,155923,155929,155930,155930,155932,155932,155932,155932,155932,155932,155932,155933,155935,155935,155935,155935,155937,155937,155937,155937,155938,155938,155938,155938,155938,155939,155939,155939,155939,155939,155944,155944,155948,155952,155952,155956,155975,155975,155975,155984,155998,156001,156005,156005,156010,156013,156013,156018,156019,156022,156022,156023,156026,156034,156034,156034,156034,156034,156034,156036,156036,156039,156047,156050,156052,156053,156054,156055,156055,156055,156065,156066,156076,156085,156085,156085,156085,156085,156087,156087,156088,156091,156091,156094,156094,156094,156097,156097,156104,156108,156111,156116,156116,156116,156122,156124,156130,156130,156133,156134,156138,156139,156139,156139,156139,156139,156139,156139,156139,156139,156143,156145,156147,156154,156155,156155,156156,156156,156161,156172,156173,156173,156173,156180,156180,156180,156184,156193,156197,156202,156205,156208,156214,156217,156217,156221,156226,156231,156233,156234,156234,156234,156247,156247,156247,156251,156251,156251,156251,156253,156259,156259,156261,156268,156269,156269,156278,156278,156279,156281,156282,156282,156284,156286,156286,156286,156286,156288,156288,156290,156293,156294,156294,156305,156306,156306,156306,156306,156306,156306,156306,156306,156306,156306,156306,156307,156307,156308,156312,156317,156318,156318,156318,156329,156330,156331,156331,156331,156331,156334,156335,156336,156340,156340,156346,156346,156348,156348,156349,156349,156350,156351,156351,156354,156357,156360,156364,156373,156373,156373,156383,156388,156390,156399,156404,156409,156409,156409,156410,156410,156412,156414,156414,156414,156416,156427,156433,156433,156434,156434,156434,156434,156436,156437,156437,156441,156448,156448,156448,156451,156451,156451,156466,156481,156481,156488,156489,156490,156491,156493,156494,156494,156502,156507,156515,156520,156522,156522,156523,156525,156527,156532,156534,156540,156544,156544,156548,156548,156548,156552,156552,156561,156563,156563,156565,156567,156570,156570,156572,156574,156580,156581,156582,156582,156582,156582,156584,156587,156589,156592,156592,156594,156595,156595,156596,156599,156603,156610,156613,156613,156621,156621,156623,156623,156623,156623,156625,156625,156627,156627,156637,156642,156650,156652,156653,156653,156654,156654,156660,156665,156667,156675,156675,156675,156675,156675,156675,156675,156675,156675,156675,156675,156678,156679,156680,156681,156682,156682,156691,156692,156703,156708,156709,156711,156711,156718,156718,156718,156718,156718,156718,156718,156718,156718,156718,156719,156723,156729,156730,156734,156734,156734,156734,156737,156737,156737,156737,156737,156748,156749,156762,156762,156762,156767,156768,156768,156772,156787,156788,156788,156788,156791,156792,156794,156803,156803,156813,156814,156819,156820,156827,156829,156831,156833,156834,156835,156836,156836,156837,156838,156841,156842,156848,156848,156854,156855,156855,156860,156865,156872,156879,156879,156882,156883,156885,156889,156891,156891,156891,156892,156892,156892,156892,156899,156899,156900,156905,156910,156910,156913,156918,156926,156926,156926,156926,156936,156939,156939,156942,156942,156944,156944,156950,156954,156954,156954,156954,156954,156960,156960,156960,156960,156963,156964,156966,156966,156967,156968,156977,156979,156980,156980,156980,156981,156984,156984,156990,156995,156995,157005,157005,157007,157010,157010,157010,157010,157011,157011,157011,157011,157011,157011,157011,157011,157011,157013,157018,157025,157047,157055,157055,157058,157064,157064,157068,157072,157073,157075,157084,157084,157087,157094,157100,157103,157103,157103,157104,157104,157104,157107,157107,157110,157110,157110,157113,157113,157113,157115,157115,157115,157121,157121,157121,157122,157122,157122,157125,157125,157125,157135,157136,157137,157144,157144,157144,157144,157146,157153,157157,157160,157161,157162,157163,157165,157171,157171,157171,157171,157182,157188,157188,157191,157198,157198,157205,157205,157206,157212,157213,157215,157215,157219,157219,157219,157219,157219,157220,157220,157220,157220,157220,157222,157231,157233,157240,157242,157245,157246,157247,157247,157251,157254,157254,157255,157255,157257,157260,157263,157268,157279,157279,157282,157292,157295,157298,157300,157302,157305,157305,157305,157306,157308,157308,157308,157308,157308,157308,157308,157308,157308,157312,157313,157313,157313,157313,157313,157319,157319,157322,157323,157335,157335,157335,157335,157346,157348,157351,157351,157352,157352,157354,157354,157355,157355,157355,157357,157360,157361,157372,157374,157376,157379,157385,157396,157396,157396,157396,157396,157396,157396,157396,157396,157397,157397,157400,157404,157404,157404,157404,157404,157407,157408,157409,157410,157410,157411,157412,157412,157414,157414,157416,157419,157420,157421,157424,157424,157426,157431,157432,157434,157437,157444,157450,157451,157452,157452,157454,157454,157454,157456,157459,157463,157463,157463,157463,157463,157467,157468,157468,157470,157470,157474,157478,157487,157504,157505,157506,157506,157506,157508,157522,157522,157531,157537,157538,157541,157541,157541,157542,157548,157548,157548,157553,157553,157554,157554,157554,157554,157554,157556,157560,157575,157586,157595,157595,157595,157595,157597,157599,157601,157603,157603,157604,157604,157604,157605,157605,157607,157608,157613,157613,157613,157614,157619,157621,157623,157623,157623,157624,157625,157635,157635,157636,157637,157637,157638,157640,157640,157643,157651,157654,157654,157655,157655,157655,157655,157657,157661,157666,157673,157673,157674,157674,157674,157675,157679,157682,157687,157687,157689,157696,157701,157704,157707,157707,157714,157715,157715,157728,157730,157737,157738,157744,157747,157748,157748,157752,157753,157753,157753,157755,157755,157755,157756,157758,157758,157758,157759,157759,157762,157765,157766,157767,157767,157767,157769,157773,157774,157774,157792,157801,157806,157806,157808,157818,157820,157820,157823,157824,157826,157828,157829,157835,157839,157845,157854,157859,157862,157872,157874,157878,157880,157880,157881,157893,157896,157896,157899,157900,157902,157903,157908,157908,157908,157913,157916,157918,157920,157924,157928,157933,157936,157936,157954,157954,157954,157954,157954,157962,157963,157963,157963,157968,157968,157968,157975,157977,157977,157980,157981,157981,157981,157981,157981,157981,157981,157981,157981,157981,157981,157982,157984,157984,157984,157988,157995,157997,157997,157998,158003,158003,158003,158003,158003,158003,158005,158005,158005,158005,158005,158007,158013,158019,158022,158024,158026,158027,158028,158032,158038,158040,158049,158050,158050,158054,158054,158055,158056,158056,158059,158059,158059,158060,158060,158061,158062,158062,158062,158062,158062,158063,158063,158063,158063,158065,158066,158066,158066,158067,158073,158077,158078,158081,158081,158081,158085,158085,158085,158085,158085,158086,158088,158091,158095,158095,158095,158095,158095,158095,158098,158100,158104,158105,158109,158109,158110,158110,158110,158110,158110,158110,158110,158115,158117,158117,158117,158118,158119,158121,158122,158124,158128,158128,158133,158139,158139,158139,158140,158140,158143,158143,158144,158148,158153,158154,158154,158155,158155,158156,158156,158156,158157,158158,158163,158167,158171,158171,158177,158177,158177,158177,158180,158180,158181,158183,158183,158184,158189,158190,158191,158194,158205,158209,158209,158209,158210,158214,158214,158214,158214,158218,158218,158219,158219,158225,158227,158228,158230,158236,158239,158246,158250,158250,158251,158251,158251,158255,158255,158255,158255,158255,158256,158256,158259,158259,158259,158259,158261,158261,158261,158261,158263,158273,158274,158274,158277,158280,158285,158288,158289,158289,158289,158289,158290,158292,158292,158294,158294,158294,158294,158301,158303,158305,158305,158305,158305,158312,158318,158326,158337,158342,158342,158345,158345,158346,158348,158349,158355,158356,158356,158370,158377,158377,158393,158394,158394,158394,158396,158396,158400,158400,158400,158400,158400,158401,158402,158403,158403,158403,158406,158406,158407,158409,158415,158417,158417,158417,158419,158421,158421,158428,158428,158429,158430,158430,158432,158433,158437,158437,158437,158437,158441,158448,158448,158448,158448,158449,158449,158449,158449,158449,158449,158460,158464,158468,158469,158469,158469,158470,158470,158470,158470,158470,158470,158474,158474,158474,158488,158491,158491,158505,158506,158507,158507,158507,158515,158527,158530,158530,158533,158533,158533,158533,158533,158533,158533,158533,158533,158533,158533,158537,158538,158538,158538,158539,158539,158540,158540,158540,158540,158540,158540,158540,158542,158544,158547,158550,158557,158560,158561,158562,158562,158562,158562,158563,158565,158566,158568,158568,158569,158573,158578,158580,158580,158580,158580,158580,158581,158583,158584,158588,158596,158601,158602,158611,158617,158617,158617,158624,158628,158628,158633,158638,158638,158640,158641,158652,158652,158653,158653,158655,158655,158655,158657,158661,158667,158675,158678,158678,158682,158682,158687,158699,158702,158702,158702,158702,158708,158729,158736,158736,158737,158737,158766,158770,158770,158778,158778,158780,158781,158783,158787,158789,158789,158789,158791,158794,158797,158800,158810,158810,158820,158820,158820,158820,158839,158849,158863,158863,158873,158874,158876,158879,158883,158888,158889,158889,158889,158889,158890,158891,158891,158891,158893,158893,158893,158893,158901,158902,158902,158902,158902,158902,158904,158904,158908,158913,158913,158913,158914,158924,158929,158932,158936,158936,158938,158938,158942,158942,158942,158942,158942,158946,158948,158950,158950,158955,158955,158960,158960,158960,158960,158965,158965,158967,158967,158968,158972,158975,158976,158977,158977,158980,158980,158980,158980,158980,158984,158987,158990,158991,158995,158995,158995,158996,158998,159003,159007,159007,159011,159012,159012,159016,159017,159018,159024,159026,159031,159036,159037,159037,159037,159037,159037,159042,159046,159051,159055,159055,159055,159056,159056,159056,159056,159057,159057,159058,159059,159059,159062,159062,159065,159067,159068,159072,159077,159077,159077,159082,159084,159089,159094,159103,159109,159109,159109,159109,159109,159109,159109,159109,159113,159120,159133,159141,159143,159145,159145,159148,159148,159148,159152,159153,159154,159157,159159,159160,159160,159160,159160,159161,159164,159170,159170,159172,159181,159183,159183,159183,159184,159186,159186,159190,159190,159191,159196,159199,159199,159199,159202,159202,159202,159205,159209,159215,159218,159222,159228,159232,159232,159237,159237,159244,159245,159245,159245,159245,159254,159257,159259,159259,159263,159267,159270,159274,159278,159278,159281,159281,159283,159283,159283,159288,159288,159288,159288,159288,159288,159290,159290,159290,159291,159291,159291,159291,159291,159292,159292,159295,159301,159303,159303,159304,159304,159304,159304,159304,159306,159306,159311,159311,159311,159314,159314,159314,159314,159314,159316,159316,159316,159323,159324,159331,159344,159344,159347,159350,159350,159358,159372,159383,159383,159383,159383,159388,159389,159389,159393,159408,159408,159409,159416,159416,159416,159418,159422,159425,159440,159444,159451,159452,159454,159454,159454,159454,159454,159454,159460,159460,159460,159468,159476,159476,159483,159485,159492,159499,159500,159502,159524,159526,159530,159535,159536,159536,159536,159538,159540,159544,159547,159548,159548,159548,159549,159563,159573,159575,159576,159578,159578,159578,159578,159578,159578,159578,159578,159578,159578,159582,159583,159583,159586,159587,159598,159612,159612,159612,159612,159612,159615,159617,159618,159618,159620,159621,159621,159623,159642,159652,159665,159665,159665,159667,159667,159667,159671,159672,159672,159676,159676,159684,159689,159703,159708,159708,159711,159711,159711,159717,159721,159726,159730,159731,159731,159731,159732,159732,159732,159733,159734,159734,159734,159734,159737,159737,159737,159737,159738,159738,159741,159741,159741,159748,159750,159751,159751,159752,159752,159752,159753,159753,159754,159754,159755,159755,159755,159755,159755,159759,159759,159761,159761,159763,159763,159763,159764,159767,159767,159771,159774,159774,159774,159775,159775,159785,159786,159786,159789,159789,159791,159793,159794,159799,159799,159799,159800,159800,159801,159801,159802,159804,159806,159806,159810,159811,159811,159812,159812,159812,159813,159813,159815,159815,159820,159820,159821,159829,159837,159840,159840,159840,159846,159848,159849,159849,159850,159854,159854,159856,159856,159863,159868,159875,159875,159875,159878,159878,159879,159880,159881,159881,159881,159882,159892,159895,159895,159895,159895,159895,159895,159898,159900,159901,159906,159906,159906,159907,159911,159912,159913,159913,159915,159919,159924,159926,159926,159933,159933,159933,159933,159933,159934,159939,159943,159947,159947,159947,159947,159947,159947,159948,159951,159951,159951,159954,159965,159966,159967,159971,159971,159971,159971,159973,159974,159976,159977,159977,159980,159981,159982,159983,159983,159984,159989,159989,159990,159990,159992,159998,159999,159999,160000,160001,160001,160003,160005,160005,160008,160009,160012,160019,160019,160019,160021,160021,160022,160023,160025,160025,160036,160039,160046,160046,160047,160047,160049,160051,160052,160054,160056,160056,160059,160059,160060,160063,160064,160064,160064,160065,160068,160068,160071,160072,160072,160074,160076,160076,160076,160080,160085,160085,160087,160087,160088,160089,160089,160091,160091,160091,160091,160091,160097,160097,160101,160102,160104,160106,160106,160115,160119,160119,160130,160130,160131,160132,160145,160147,160147,160148,160149,160152,160152,160154,160156,160156,160157,160157,160157,160160,160162,160162,160164,160164,160164,160164,160165,160165,160165,160166,160167,160167,160167,160167,160167,160167,160167,160168,160169,160169,160169,160169,160169,160171,160171,160173,160173,160173,160173,160173,160176,160183,160183,160183,160183,160190,160190,160194,160195,160197,160197,160199,160199,160199,160200,160200,160200,160201,160201,160203,160215,160216,160216,160218,160224,160226,160226,160226,160226,160226,160226,160226,160226,160226,160226,160226,160226,160227,160227,160227,160227,160228,160228,160236,160238,160239,160241,160241,160242,160242,160242,160243,160243,160244,160244,160246,160248,160251,160258,160258,160258,160262,160264,160264,160264,160264,160264,160264,160265,160265,160267,160267,160267,160267,160272,160285,160288,160289,160290,160291,160291,160296,160301,160320,160320,160320,160320,160320,160320,160333,160333,160334,160334,160335,160336,160336,160338,160338,160340,160340,160340,160340,160340,160344,160344,160344,160345,160345,160346,160351,160356,160361,160364,160364,160365,160365,160365,160366,160367,160367,160367,160369,160369,160371,160371,160372,160374,160375,160378,160385,160385,160385,160388,160388,160388,160390,160390,160390,160390,160393,160396,160399,160399,160405,160408,160408,160409,160411,160411,160411,160411,160411,160411,160413,160414,160415,160418,160418,160419,160420,160421,160421,160422,160422,160425,160426,160427,160427,160427,160427,160428,160429,160429,160430,160430,160430,160430,160433,160433,160434,160435,160435,160437,160437,160437,160437,160437,160441,160443,160445,160445,160448,160450,160451,160451,160452,160452,160452,160452,160454,160461,160462,160462,160467,160468,160469,160469,160471,160471,160477,160477,160477,160477,160486,160487,160488,160488,160489,160489,160489,160489,160489,160489,160489,160489,160504,160504,160504,160506,160507,160507,160511,160511,160520,160520,160520,160520,160522,160522,160522,160522,160522,160522,160522,160523,160524,160526,160526,160526,160526,160526,160528,160532,160532,160536,160538,160541,160541,160541,160541,160546,160547,160549,160551,160554,160557,160557,160557,160557,160557,160557,160557,160567,160569,160569,160569,160569,160570,160572,160580,160580,160582,160589,160590,160595,160595,160595,160595,160595,160595,160595,160595,160597,160598,160604,160606,160610,160613,160619,160619,160619,160621,160625,160628,160630,160640,160640,160641,160641,160641,160645,160646,160648,160655,160655,160655,160656,160656,160657,160660,160662,160663,160663,160663,160663,160665,160670,160673,160680,160680,160682,160682,160685,160686,160686,160686,160686,160689,160689,160689,160689,160689,160690,160690,160690,160690,160690,160690,160690,160690,160690,160690,160690,160690,160690,160692,160692,160692,160692,160693,160693,160693,160693,160693,160693,160693,160693,160694,160694,160694,160694,160694,160694,160694,160694,160695,160695,160699,160699,160701,160701,160702,160704,160704,160708,160708,160708,160708,160708,160712,160712,160712,160712,160712,160713,160713,160713,160713,160713,160714,160714,160714,160715,160715,160715,160715,160715,160715,160715,160715,160715,160717,160718,160720,160721,160721,160721,160721,160723,160723,160725,160728,160728,160729,160730,160730,160730,160730,160731,160732,160733,160733,160733,160733,160733,160734,160737,160738,160739,160739,160739,160739,160742,160742,160745,160746,160747,160748,160748,160748,160748,160751,160753,160753,160753,160753,160755,160756,160756,160757,160758,160758,160759,160761,160761,160761,160767,160768,160769,160769,160770,160770,160771,160774,160774,160775,160777,160778,160779,160780,160782,160783,160785,160785,160786,160787,160788,160788,160788,160789,160789,160789,160789,160789,160789,160791,160793,160793,160795,160795,160796,160796,160797,160798,160798,160798,160799,160803,160803,160803,160803,160803,160803,160803,160805,160817,160817,160817,160818,160818,160818,160819,160819,160819,160819,160821,160821,160823,160823,160823,160824,160824,160827,160830,160831,160832,160832,160832,160832,160832,160834,160836,160836,160836,160836,160836,160836,160836,160836,160836,160836,160838,160838,160838,160839,160839,160839,160839,160839,160839,160839,160839,160839,160840,160840,160841,160841,160841,160841,160842,160843,160843,160843,160844,160844,160844,160847,160847,160847,160847,160849,160852,160852,160852,160853,160853,160858,160859,160859,160859,160860,160860,160865,160867,160870,160871,160871,160871,160874,160875,160877,160886,160886,160886,160899,160903,160907,160907,160907,160907,160907,160911,160911,160911,160916,160916,160917,160917,160917,160917,160917,160917,160919,160920,160927,160927,160927,160929,160932,160933,160937,160938,160938,160939,160939,160939,160940,160940,160940,160942,160942,160947,160949,160952,160952,160953,160953,160956,160957,160960,160960,160961,160962,160962,160965,160966,160966,160966,160967,160969,160969,160969,160969,160970,160974,160974,160975,160978,160979,160980,160982,160982,160982,160982,160982,160983,160987,160992,160999,160999,160999,160999,161002,161006,161007,161007,161007,161007,161012,161013,161022,161022,161022,161023,161027,161028,161028,161031,161033,161035,161035,161035,161036,161037,161040,161041,161041,161041,161041,161041,161041,161045,161045,161045,161049,161051,161051,161051,161052,161054,161057,161057,161057,161057,161059,161061,161062,161062,161062,161062,161063,161063,161069,161069,161071,161072,161072,161072,161074,161082,161083,161087,161093,161094,161094,161094,161099,161105,161106,161106,161111,161111,161111,161111,161111,161111,161117,161117,161120,161120,161120,161121,161121,161121,161123,161125,161126,161126,161128,161128,161130,161130,161134,161137,161139,161139,161139,161139,161141,161141,161141,161141,161141,161142,161142,161144,161144,161144,161145,161146,161146,161147,161156,161158,161158,161158,161158,161158,161158,161158,161158,161158,161160,161160,161160,161161,161165,161167,161179,161184,161185,161185,161186,161186,161196,161198,161198,161207,161207,161207,161210,161211,161211,161213,161215,161217,161217,161217,161218,161220,161222,161222,161222,161222,161222,161222,161222,161222,161222,161222,161223,161233,161234,161234,161234,161234,161234,161234,161234,161236,161239,161239,161239,161239,161241,161252,161252,161253,161255,161255,161260,161261,161266,161266,161266,161267,161273,161275,161277,161277,161278,161280,161280,161281,161284,161284,161288,161292,161293,161294,161295,161296,161300,161300,161300,161300,161300,161306,161307,161307,161307,161307,161307,161310,161310,161311,161312,161312,161317,161321,161321,161321,161321,161321,161321,161321,161321,161321,161324,161324,161327,161327,161328,161339,161352,161353,161356,161357,161358,161360,161361,161362,161365,161366,161366,161366,161366,161369,161369,161371,161371,161371,161372,161374,161382,161383,161383,161384,161388,161391,161394,161395,161395,161396,161396,161396,161397,161397,161401,161402,161402,161403,161403,161403,161403,161403,161403,161403,161403,161403,161403,161403,161404,161407,161409,161414,161414,161415,161415,161415,161416,161418,161418,161419,161424,161425,161425,161425,161428,161430,161432,161432,161432,161432,161437,161437,161437,161438,161443,161443,161443,161443,161443,161443,161443,161443,161444,161444,161444,161444,161447,161447,161447,161447,161447,161447,161447,161447,161447,161449,161449,161449,161451,161451,161451,161451,161451,161451,161451,161451,161451,161451,161451,161452,161452,161452,161452,161452,161454,161454,161454,161454,161455,161455,161455,161455,161457,161459,161461,161462,161462,161462,161462,161462,161462,161462,161462,161463,161464,161466,161468,161468,161470,161472,161473,161473,161473,161473,161473,161473,161473,161473,161475,161476,161476,161476,161479,161479,161480,161480,161480,161480,161480,161480,161480,161480,161480,161480,161480,161480,161481,161486,161491,161495,161499,161505,161505,161508,161508,161508,161508,161509,161510,161511,161513,161523,161524,161525,161530,161535,161539,161543,161543,161545,161545,161550,161552,161553,161553,161553,161553,161555,161556,161557,161558,161560,161560,161560,161563,161564,161564,161567,161567,161567,161567,161567,161567,161578,161580,161581,161583,161583,161584,161585,161585,161585,161585,161585,161585,161585,161585,161585,161585,161585,161589,161591,161595,161599,161599,161599,161601,161605,161605,161605,161605,161605,161606,161606,161606,161606,161611,161611,161613,161613,161617,161618,161618,161633,161637,161637,161637,161638,161638,161643,161644,161647,161647,161649,161650,161650,161650,161650,161650,161651,161652,161652,161654,161654,161654,161657,161657,161672,161672,161682,161682,161682,161684,161684,161703,161706,161711,161711,161716,161720,161733,161736,161737,161737,161738,161738,161738,161738,161738,161741,161743,161743,161743,161747,161747,161753,161753,161753,161754,161754,161756,161758,161758,161758,161758,161758,161758,161758,161758,161758,161758,161758,161758,161758,161758,161761,161761,161761,161762,161762,161764,161764,161765,161765,161765,161765,161766,161766,161773,161774,161776,161776,161778,161781,161782,161782,161784,161784,161784,161786,161786,161786,161786,161786,161789,161792,161792,161792,161792,161792,161792,161793,161800,161801,161802,161802,161802,161802,161802,161802,161804,161804,161812,161812,161812,161827,161835,161838,161838,161839,161839,161839,161840,161840,161844,161849,161851,161851,161851,161852,161855,161856,161857,161865,161865,161869,161875,161875,161875,161875,161875,161875,161875,161883,161883,161885,161885,161889,161890,161893,161893,161895,161899,161899,161899,161899,161899,161900,161902,161907,161907,161907,161907,161908,161908,161909,161911,161911,161911,161917,161917,161920,161920,161924,161928,161928,161929,161929,161934,161934,161934,161934,161937,161937,161937,161937,161937,161938,161939,161944,161945,161945,161947,161952,161952,161955,161957,161957,161957,161957,161957,161957,161958,161960,161961,161969,161972,161972,161983,161983,161985,161985,161985,161993,161995,161995,161997,161998,161998,161998,161998,161998,161998,161999,161999,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162000,162004,162011,162011,162013,162013,162013,162018,162018,162023,162023,162023,162023,162023,162023,162032,162033,162033,162033,162033,162035,162038,162038,162039,162039,162044,162045,162045,162045,162046,162049,162049,162060,162075,162078,162079,162079,162082,162082,162084,162084,162089,162089,162089,162090,162092,162104,162113,162113,162113,162113,162117,162119,162119,162121,162132,162139,162139,162139,162139,162139,162139,162145,162149,162151,162151,162151,162153,162153,162157,162163,162165,162165,162165,162165,162165,162165,162165,162165,162165,162165,162165,162165,162165,162165,162166,162166,162166,162173,162176,162179,162179,162179,162183,162183,162185,162185,162192,162193,162194,162198,162198,162198,162200,162201,162201,162201,162201,162201,162201,162203,162205,162208,162208,162208,162208,162208,162209,162211,162211,162212,162213,162219,162219,162219,162227,162227,162227,162227,162227,162228,162230,162230,162234,162238,162238,162238,162250,162250,162250,162252,162257,162257,162260,162263,162263,162263,162268,162272,162272,162272,162280,162283,162283,162294,162294,162295,162295,162299,162301,162302,162302,162309,162313,162314,162318,162319,162319,162319,162320,162321,162323,162323,162324,162324,162324,162325,162325,162325,162325,162327,162327,162327,162327,162330,162330,162330,162330,162331,162331,162341,162343,162344,162345,162348,162348,162351,162351,162366,162366,162369,162376,162377,162377,162378,162379,162379,162379,162383,162383,162384,162384,162386,162386,162390,162393,162394,162395,162400,162401,162404,162406,162407,162407,162407,162408,162408,162410,162410,162410,162410,162411,162411,162412,162414,162421,162421,162421,162421,162421,162425,162427,162427,162427,162427,162427,162427,162427,162427,162427,162427,162427,162427,162430,162435,162438,162439,162439,162440,162440,162445,162451,162453,162453,162453,162454,162461,162466,162466,162466,162466,162466,162481,162482,162482,162484,162488,162488,162497,162498,162502,162506,162506,162506,162506,162506,162511,162511,162511,162511,162511,162513,162519,162521,162521,162521,162524,162525,162525,162525,162525,162527,162528,162529,162530,162531,162533,162533,162536,162540,162540,162540,162540,162542,162544,162554,162554,162555,162557,162557,162557,162570,162573,162573,162574,162578,162580,162580,162583,162584,162584,162584,162587,162589,162593,162593,162595,162595,162596,162596,162598,162599,162600,162600,162600,162606,162610,162610,162610,162610,162611,162616,162623,162623,162628,162629,162630,162632,162633,162636,162636,162636,162637,162637,162639,162639,162639,162639,162640,162640,162642,162643,162643,162643,162643,162644,162646,162646,162646,162648,162648,162652,162653,162653,162654,162654,162661,162661,162661,162661,162668,162668,162668,162679,162688,162689,162690,162692,162695,162707,162707,162709,162709,162709,162709,162709,162709,162709,162709,162709,162709,162709,162709,162709,162709,162719,162719,162719,162719,162730,162734,162734,162737,162737,162737,162742,162746,162746,162750,162752,162753,162757,162758,162760,162766,162766,162768,162771,162771,162780,162783,162783,162784,162784,162784,162787,162787,162791,162791,162795,162795,162798,162798,162801,162805,162805,162806,162806,162806,162806,162806,162811,162816,162817,162819,162821,162823,162828,162829,162832,162835,162839,162843,162850,162859,162865,162869,162870,162870,162876,162878,162878,162878,162878,162878,162879,162879,162885,162887,162887,162889,162890,162890,162890,162893,162895,162896,162896,162897,162897,162898,162898,162898,162898,162900,162900,162901,162903,162906,162907,162907,162907,162942,162942,162950,162950,162950,162950,162950,162950,162950,162950,162950,162950,162950,162950,162950,162952,162952,162954,162954,162954,162960,162960,162960,162960,162960,162961,162961,162961,162961,162963,162967,162968,162968,162970,162976,162980,162982,162982,162984,162985,162985,162990,162992,162992,162992,162993,162993,162993,162993,162993,162994,162996,162996,162996,162996,162997,163004,163004,163004,163004,163004,163004,163004,163004,163004,163004,163004,163004,163004,163004,163007,163014,163019,163024,163031,163033,163035,163037,163037,163039,163039,163045,163046,163060,163063,163066,163082,163084,163086,163086,163086,163093,163097,163097,163106,163106,163108,163113,163115,163117,163118,163118,163121,163129,163142,163156,163160,163160,163163,163163,163163,163172,163178,163179,163179,163179,163179,163185,163186,163187,163192,163199,163200,163202,163206,163207,163207,163207,163210,163212,163220,163223,163223,163225,163234,163236,163236,163241,163246,163255,163255,163259,163259,163261,163261,163261,163261,163264,163264,163264,163275,163277,163277,163278,163278,163279,163280,163281,163281,163282,163282,163284,163284,163284,163284,163285,163285,163285,163285,163285,163285,163285,163286,163286,163289,163290,163290,163291,163292,163299,163301,163303,163303,163305,163305,163306,163307,163307,163312,163317,163318,163324,163325,163327,163331,163333,163333,163334,163341,163341,163341,163341,163343,163346,163351,163353,163358,163359,163360,163361,163369,163369,163369,163369,163369,163369,163369,163369,163369,163369,163369,163369,163370,163370,163370,163370,163370,163370,163370,163370,163370,163370,163373,163374,163375,163379,163379,163379,163379,163379,163381,163383,163383,163383,163383,163385,163389,163390,163392,163392,163393,163394,163396,163400,163400,163400,163400,163400,163404,163405,163405,163405,163405,163405,163406,163406,163406,163406,163408,163408,163409,163410,163411,163416,163416,163416,163416,163417,163418,163418,163419,163422,163422,163423,163423,163424,163425,163426,163427,163427,163435,163436,163436,163436,163439,163439,163439,163440,163442,163446,163449,163451,163451,163453,163456,163456,163457,163460,163461,163464,163464,163468,163477,163478,163482,163485,163487,163488,163490,163496,163497,163497,163506,163506,163506,163506,163506,163509,163515,163519,163519,163521,163527,163532,163534,163538,163544,163545,163547,163547,163547,163547,163548,163551,163551,163553,163553,163553,163555,163556,163557,163558,163558,163558,163558,163559,163560,163561,163561,163563,163563,163566,163566,163576,163577,163578,163579,163580,163581,163581,163581,163583,163584,163592,163595,163607,163607,163607,163612,163615,163616,163618,163621,163622,163622,163622,163622,163622,163623,163623,163625,163631,163631,163632,163632,163632,163632,163632,163632,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163633,163634,163635,163635,163635,163635,163640,163642,163647,163649,163650,163651,163654,163656,163656,163658,163659,163659,163662,163662,163664,163666,163667,163669,163674,163674,163675,163676,163676,163676,163677,163677,163677,163679,163679,163679,163679,163680,163680,163680,163680,163680,163680,163680,163681,163684,163684,163684,163685,163685,163685,163686,163686,163691,163692,163692,163692,163694,163695,163695,163706,163707,163708,163709,163710,163710,163711,163713,163714,163716,163717,163718,163719,163720,163721,163728,163729,163730,163731,163734,163734,163735,163735,163736,163736,163736,163736,163737,163737,163738,163738,163738,163738,163740,163740,163740,163740,163741,163742,163742,163748,163750,163753,163756,163759,163759,163759,163761,163761,163763,163766,163770,163770,163770,163775,163776,163780,163781,163781,163781,163781,163781,163781,163781,163781,163781,163781,163781,163781,163781,163785,163787,163797,163800,163800,163800,163800,163800,163800,163800,163800,163801,163804,163805,163808,163808,163809,163812,163815,163820,163824,163824,163826,163827,163827,163827,163831,163832,163838,163839,163839,163839,163839,163851,163855,163855,163862,163867,163869,163870,163872,163877,163881,163887,163889,163893,163893,163896,163901,163904,163905,163907,163907,163907,163912,163912,163916,163917,163919,163926,163928,163928,163928,163928,163928,163936,163936,163938,163939,163939,163950,163960,163960,163960,163960,163960,163961,163962,163962,163962,163962,163963,163963,163963,163963,163963,163965,163970,163977,163980,163980,163980,163980,163984,163992,163992,163994,163994,163994,164002,164004,164006,164007,164007,164029,164034,164049,164050,164059,164059,164059,164059,164059,164059,164063,164064,164064,164070,164070,164073,164074,164077,164079,164079,164079,164079,164079,164080,164080,164080,164084,164088,164089,164089,164089,164092,164092,164093,164093,164093,164104,164107,164107,164118,164118,164127,164127,164136,164140,164140,164140,164141,164141,164141,164141,164143,164148,164161,164165,164167,164175,164176,164177,164179,164181,164181,164181,164181,164181,164184,164186,164191,164205,164207,164207,164212,164216,164217,164217,164222,164233,164242,164244,164247,164254,164254,164255,164255,164255,164266,164267,164267,164267,164267,164267,164267,164267,164267,164267,164267,164267,164272,164287,164287,164287,164288,164289,164289,164291,164297,164305,164305,164305,164307,164307,164307,164313,164320,164327,164327,164331,164344,164353,164353,164353,164353,164354,164354,164354,164354,164356,164358,164359,164362,164365,164365,164370,164370,164370,164370,164370,164372,164372,164373,164374,164377,164382,164382,164382,164382,164382,164386,164386,164387,164388,164392,164394,164397,164397,164407,164407,164407,164408,164414,164415,164422,164422,164436,164441,164446,164446,164446,164446,164446,164446,164447,164454,164457,164462,164464,164467,164480,164489,164506,164508,164508,164509,164512,164516,164520,164522,164524,164525,164528,164528,164533,164535,164542,164545,164545,164545,164548,164548,164552,164554,164554,164559,164560,164563,164563,164580,164583,164583,164584,164584,164606,164607,164607,164608,164621,164622,164623,164624,164625,164628,164630,164630,164630,164632,164633,164633,164633,164636,164638,164645,164645,164650,164655,164659,164675,164682,164682,164686,164688,164688,164688,164691,164695,164695,164701,164701,164703,164704,164704,164705,164707,164707,164717,164719,164719,164727,164736,164736,164741,164744,164744,164744,164744,164748,164753,164754,164754,164757,164757,164757,164758,164758,164758,164758,164758,164761,164761,164762,164762,164762,164762,164762,164762,164762,164762,164766,164767,164770,164776,164781,164785,164789,164795,164797,164798,164798,164798,164798,164799,164802,164802,164803,164804,164804,164804,164807,164807,164808,164808,164818,164818,164825,164828,164829,164837,164842,164843,164844,164846,164877,164878,164882,164888,164888,164888,164894,164901,164903,164904,164904,164905,164905,164907,164907,164908,164911,164915,164925,164937,164939,164946,164946,164947,164949,164949,164957,164958,164958,164958,164958,164959,164959,164959,164959,164959,164959,164959,164959,164959,164959,164959,164959,164960,164960,164961,164963,164963,164964,164964,164964,164965,164965,164965,164968,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164970,164978,164979,164980,164982,164990,164993,165000,165000,165002,165004,165004,165004,165004,165006,165006,165007,165007,165007,165007,165007,165007,165008,165009,165009,165010,165013,165013,165017,165017,165018,165019,165019,165020,165020,165020,165020,165020,165020,165023,165023,165023,165030,165030,165030,165031,165031,165035,165035,165035,165037,165037,165037,165037,165037,165042,165047,165048,165054,165054,165059,165059,165065,165066,165069,165072,165074,165076,165076,165077,165080,165085,165085,165085,165086,165088,165092,165093,165094,165096,165100,165102,165104,165105,165107,165107,165107,165109,165109,165109,165112,165114,165119,165120,165122,165124,165124,165124,165126,165128,165128,165130,165138,165139,165139,165139,165139,165139,165140,165140,165140,165142,165146,165147,165151,165153,165155,165160,165160,165161,165161,165161,165161,165161,165164,165165,165174,165174,165175,165179,165180,165180,165181,165182,165183,165183,165183,165184,165185,165185,165185,165187,165190,165195,165195,165196,165198,165199,165199,165199,165200,165200,165200,165200,165201,165204,165204,165205,165206,165209,165209,165209,165209,165210,165210,165210,165210,165210,165210,165210,165211,165214,165214,165214,165215,165216,165218,165221,165223,165225,165227,165231,165231,165236,165240,165242,165247,165247,165247,165247,165251,165252,165255,165258,165258,165258,165258,165258,165258,165259,165261,165261,165265,165265,165268,165269,165269,165281,165285,165288,165292,165294,165294,165294,165294,165296,165300,165306,165307,165310,165313,165315,165317,165321,165323,165324,165330,165330,165332,165332,165332,165332,165332,165334,165334,165334,165334,165334,165334,165336,165336,165336,165336,165337,165338,165340,165350,165350,165353,165354,165358,165359,165363,165363,165367,165373,165374,165374,165375,165376,165378,165379,165379,165380,165383,165383,165383,165386,165386,165387,165390,165390,165391,165393,165394,165400,165404,165412,165413,165413,165414,165416,165417,165417,165417,165417,165417,165419,165422,165425,165428,165433,165433,165433,165433,165433,165434,165434,165434,165434,165434,165436,165436,165436,165438,165439,165439,165439,165441,165443,165445,165446,165446,165452,165462,165462,165462,165464,165467,165471,165471,165472,165473,165473,165478,165478,165481,165483,165485,165486,165488,165490,165490,165492,165492,165492,165493,165493,165493,165493,165493,165493,165493,165493,165493,165493,165494,165494,165494,165497,165498,165498,165507,165507,165512,165513,165513,165526,165527,165528,165533,165535,165535,165537,165543,165545,165554,165559,165559,165559,165559,165559,165559,165559,165560,165560,165560,165560,165569,165569,165569,165569,165573,165576,165576,165576,165582,165582,165593,165596,165598,165611,165611,165611,165612,165612,165614,165615,165617,165618,165618,165618,165618,165618,165618,165618,165618,165618,165618,165618,165618,165618,165618,165618,165620,165624,165628,165628,165643,165645,165645,165645,165646,165647,165647,165656,165664,165664,165664,165665,165668,165674,165674,165677,165684,165684,165684,165685,165687,165689,165695,165695,165700,165706,165707,165707,165713,165713,165714,165714,165719,165719,165719,165720,165720,165720,165721,165721,165721,165721,165723,165723,165729,165729,165729,165741,165742,165743,165743,165744,165744,165756,165756,165756,165758,165758,165758,165765,165779,165779,165779,165781,165781,165781,165786,165786,165786,165786,165786,165786,165786,165787,165789,165789,165790,165792,165795,165798,165802,165807,165807,165809,165811,165813,165813,165815,165816,165816,165822,165822,165822,165825,165825,165827,165827,165827,165827,165828,165828,165828,165828,165830,165835,165835,165835,165835,165835,165835,165836,165836,165836,165838,165839,165839,165839,165840,165840,165842,165842,165843,165844,165851,165852,165852,165852,165852,165852,165852,165853,165853,165854,165854,165857,165857,165857,165859,165859,165859,165860,165861,165861,165861,165861,165861,165861,165861,165861,165865,165866,165867,165867,165873,165875,165877,165877,165879,165881,165882,165882,165882,165882,165882,165882,165882,165882,165882,165885,165889,165891,165891,165892,165896,165896,165899,165901,165902,165903,165904,165904,165907,165912,165913,165913,165913,165914,165915,165918,165921,165921,165921,165922,165922,165922,165923,165923,165924,165925,165927,165928,165929,165929,165932,165932,165933,165937,165939,165943,165943,165949,165949,165950,165950,165952,165952,165954,165955,165955,165955,165955,165955,165955,165962,165965,165967,165968,165968,165969,165971,165971,165971,165971,165982,165982,165986,165987,165987,165987,165987,165988,165988,165988,165988,165993,165994,165994,165994,165994,166000,166001,166001,166004,166005,166007,166010,166010,166011,166011,166013,166014,166014,166014,166014,166014,166014,166015,166015,166015,166015,166016,166016,166030,166033,166033,166033,166034,166034,166039,166049,166049,166051,166051,166054,166054,166059,166073,166077,166077,166077,166079,166080,166080,166083,166084,166095,166101,166102,166102,166108,166111,166112,166113,166113,166114,166115,166115,166115,166121,166121,166121,166122,166126,166128,166129,166134,166140,166141,166142,166143,166144,166147,166147,166147,166150,166150,166150,166150,166156,166158,166165,166165,166170,166172,166173,166173,166175,166175,166177,166193,166193,166203,166203,166214,166214,166214,166217,166218,166226,166227,166227,166227,166228,166231,166231,166231,166231,166232,166239,166240,166240,166241,166242,166244,166244,166251,166256,166261,166265,166266,166266,166266,166266,166273,166274,166277,166279,166287,166291,166293,166295,166297,166297,166297,166298,166298,166298,166303,166303,166303,166305,166309,166309,166310,166310,166312,166312,166312,166312,166313,166313,166313,166313,166314,166315,166315,166318,166323,166323,166326,166326,166328,166329,166330,166330,166331,166334,166335,166335,166335,166337,166337,166339,166339,166339,166339,166339,166339,166339,166339,166340,166342,166342,166342,166342,166342,166349,166357,166357,166359,166359,166364,166364,166365,166365,166367,166367,166367,166367,166367,166367,166372,166372,166372,166374,166374,166379,166384,166384,166385,166387,166396,166396,166397,166397,166399,166402,166402,166402,166402,166403,166404,166409,166410,166410,166410,166413,166413,166413,166420,166427,166452,166452,166457,166457,166457,166458,166460,166460,166462,166462,166462,166462,166462,166463,166464,166464,166466,166467,166467,166467,166471,166471,166475,166476,166477,166477,166486,166488,166488,166490,166491,166491,166491,166491,166499,166499,166504,166504,166504,166504,166504,166508,166508,166508,166511,166513,166515,166515,166523,166525,166530,166530,166531,166533,166534,166534,166534,166539,166542,166547,166551,166551,166560,166580,166589,166590,166590,166590,166590,166590,166590,166590,166590,166597,166603,166605,166607,166607,166609,166609,166609,166609,166609,166609,166609,166609,166612,166613,166613,166614,166615,166615,166629,166631,166638,166641,166644,166646,166648,166654,166662,166664,166664,166674,166680,166681,166682,166686,166690,166694,166694,166706,166710,166713,166713,166715,166722,166722,166728,166731,166736,166737,166741,166742,166744,166752,166756,166782,166782,166783,166783,166784,166784,166787,166788,166798,166799,166804,166805,166806,166807,166808,166808,166810,166813,166813,166819,166819,166822,166823,166824,166825,166825,166825,166827,166835,166836,166836,166836,166838,166839,166839,166839,166842,166844,166850,166861,166864,166865,166865,166877,166879,166884,166884,166895,166895,166897,166897,166897,166898,166904,166904,166904,166907,166913,166914,166914,166915,166926,166929,166930,166932,166932,166932,166934,166936,166939,166939,166941,166944,166944,166945,166948,166948,166957,166957,166962,166962,166966,166972,166985,166991,166993,166993,167008,167008,167012,167013,167013,167013,167017,167017,167035,167036,167036,167036,167037,167040,167041,167053,167054,167054,167059,167059,167061,167061,167074,167075,167076,167080,167080,167080,167087,167095,167096,167100,167100,167108,167113,167113,167113,167121,167122,167123,167126,167128,167129,167132,167138,167139,167139,167139,167145,167150,167151,167153,167163,167163,167163,167164,167164,167164,167166,167170,167170,167177,167181,167185,167206,167209,167214,167214,167215,167215,167215,167218,167219,167219,167227,167228,167229,167229,167242,167243,167255,167256,167259,167263,167264,167271,167275,167283,167289,167295,167313,167314,167318,167325,167325,167327,167329,167329,167329,167329,167329,167329,167329,167329,167329,167329,167329,167329,167330,167332,167342,167349,167349,167353,167353,167366,167373,167373,167377,167379,167380,167380,167392,167401,167408,167408,167408,167408,167409,167409,167411,167412,167413,167413,167413,167414,167420,167420,167420,167429,167437,167437,167437,167443,167443,167443,167443,167443,167457,167457,167457,167464,167464,167473,167476,167478,167480,167505,167510,167513,167513,167513,167513,167513,167513,167515,167519,167519,167527,167541,167543,167544,167545,167549,167550,167551,167559,167559,167559,167566,167569,167570,167570,167570,167574,167574,167576,167579,167587,167589,167595,167595,167598,167601,167613,167613,167614,167614,167629,167629,167629,167636,167650,167650,167650,167651,167653,167657,167657,167657,167657,167658,167660,167665,167667,167675,167677,167678,167682,167685,167685,167686,167686,167691,167694,167694,167694,167700,167705,167708,167713,167713,167713,167713,167713,167716,167717,167728,167732,167734,167734,167736,167737,167740,167742,167743,167744,167752,167763,167765,167768,167769,167778,167784,167785,167794,167795,167796,167800,167800,167800,167800,167803,167803,167813,167813,167819,167819,167837,167846,167851,167851,167859,167862,167866,167867,167867,167867,167869,167870,167872,167872,167879,167891,167891,167892,167895,167896,167903,167913,167913,167916,167920,167921,167921,167921,167921,167922,167922,167925,167925,167927,167928,167928,167928,167928,167932,167932,167934,167938,167949,167950,167953,167955,167955,167963,167963,167964,167972,167972,167972,167972,167972,167974,167975,167978,167979,167979,167980,167988,167989,167995,167995,168013,168023,168032,168035,168035,168035,168036,168044,168051,168052,168053,168059,168062,168062,168063,168066,168066,168067,168067,168067,168070,168070,168070,168070,168071,168074,168075,168078,168081,168083,168084,168084,168093,168093,168097,168097,168099,168099,168100,168100,168100,168103,168105,168106,168110,168114,168114,168116,168119,168119,168156,168156,168156,168156,168156,168160,168160,168160,168162,168162,168162,168162,168162,168166,168166,168166,168166,168166,168166,168166,168170,168170,168171,168179,168186,168188,168193,168200,168201,168209,168211,168215,168215,168221,168224,168224,168230,168230,168233,168233,168233,168233,168233,168237,168240,168244,168249,168259,168261,168289,168295,168304,168308,168308,168309,168309,168309,168309,168312,168314,168314,168314,168320,168323,168325,168333,168341,168345,168355,168361,168362,168372,168387,168387,168387,168387,168387,168395,168404,168405,168406,168414,168414,168417,168422,168422,168441,168455,168456,168457,168457,168461,168474,168480,168485,168491,168492,168496,168497,168500,168500,168500,168502,168512,168514,168515,168520,168521,168524,168524,168524,168526,168536,168536,168536,168536,168539,168554,168554,168554,168558,168563,168566,168575,168583,168590,168590,168591,168596,168597,168597,168597,168597,168597,168598,168608,168611,168612,168612,168613,168615,168615,168617,168631,168634,168645,168649,168649,168656,168663,168670,168674,168674,168678,168678,168695,168699,168701,168705,168705,168705,168709,168710,168710,168712,168714,168721,168722,168722,168730,168734,168735,168740,168740,168742,168742,168743,168752,168753,168753,168760,168768,168770,168772,168772,168773,168773,168776,168776,168777,168779,168780,168780,168783,168784,168784,168787,168787,168787,168787,168787,168789,168789,168792,168792,168792,168795,168799,168804,168807,168811,168814,168817,168823,168827,168834,168835,168837,168848,168848,168848,168854,168880,168881,168884,168892,168895,168896,168896,168901,168902,168913,168913,168921,168922,168923,168925,168939,168940,168940,168940,168940,168945,168947,168948,168949,168951,168955,168957,168957,168957,168957,168957,168961,168961,168962,168962,168964,168976,168977,168977,168977,168977,168977,168977,168977,168978,168980,168988,168989,168999,169004,169004,169006,169014,169014,169015,169017,169023,169023,169024,169026,169029,169031,169031,169031,169031,169043,169043,169046,169046,169046,169046,169046,169046,169046,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169048,169055,169056,169056,169056,169057,169059,169065,169073,169077,169077,169079,169080,169084,169092,169105,169105,169105,169105,169108,169114,169114,169114,169115,169115,169117,169118,169120,169120,169120,169120,169120,169120,169120,169121,169122,169122,169122,169124,169124,169125,169125,169125,169125,169125,169125,169125,169125,169126,169126,169126,169126,169127,169127,169127,169127,169127,169127,169127,169128,169132,169132,169132,169132,169132,169132,169133,169133,169133,169133,169133,169133,169133,169133,169134,169134,169134,169135,169135,169135,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169137,169138,169138,169138,169142,169143,169143,169143,169143,169143,169147,169147,169151,169154,169155,169156,169156,169158,169159,169159,169160,169162,169166,169167,169168,169169,169170,169170,169170,169170,169171,169175,169175,169175,169175,169175,169175,169175,169176,169176,169176,169177,169177,169177,169178,169178,169178,169179,169179,169180,169180,169182,169182,169182,169183,169183,169183,169185,169185,169187,169187,169189,169189,169189,169191,169191,169192,169192,169192,169192,169192,169192,169193,169193,169193,169194,169194,169194,169194,169194,169195,169197,169198,169198,169203,169204,169204,169205,169210,169211,169211,169214,169216,169219,169220,169223,169225,169232,169232,169234,169236,169239,169239,169239,169241,169241,169241,169241,169241,169241,169242,169243,169244,169246,169246,169246,169246,169246,169246,169246,169246,169246,169246,169247,169251,169252,169253,169253,169260,169261,169261,169261,169261,169264,169264,169266,169266,169270,169270,169272,169273,169275,169281,169284,169284,169287,169287,169292,169300,169303,169306,169306,169306,169306,169312,169314,169314,169314,169316,169321,169321,169323,169331,169331,169331,169334,169336,169342,169342,169342,169342,169345,169351,169355,169355,169355,169356,169356,169356,169365,169365,169365,169366,169370,169371,169371,169371,169379,169379,169382,169389,169393,169397,169397,169399,169402,169402,169402,169403,169409,169409,169409,169412,169412,169412,169412,169412,169412,169412,169412,169412,169412,169413,169413,169414,169416,169419,169419,169420,169433,169434,169434,169441,169450,169459,169463,169471,169472,169472,169481,169481,169485,169486,169490,169495,169498,169501,169505,169508,169508,169512,169514,169514,169514,169516,169517,169529,169529,169529,169538,169538,169539,169543,169543,169543,169548,169551,169559,169561,169564,169565,169565,169565,169569,169583,169584,169584,169584,169584,169584,169584,169584,169585,169585,169585,169603,169603,169603,169605,169614,169615,169619,169627,169637,169637,169655,169655,169655,169655,169655,169658,169659,169666,169673,169678,169686,169686,169689,169689,169689,169690,169690,169692,169695,169699,169701,169704,169705,169709,169712,169714,169714,169714,169714,169714,169717,169717,169718,169722,169730,169734,169735,169741,169745,169749,169755,169755,169755,169758,169761,169761,169761,169763,169763,169763,169764,169764,169764,169764,169764,169764,169764,169764,169764,169764,169764,169766,169768,169768,169768,169780,169788,169792,169792,169795,169795,169795,169795,169795,169795,169795,169795,169795,169795,169795,169795,169795,169795,169798,169809,169813,169813,169813,169822,169822,169824,169825,169826,169828,169829,169830,169836,169836,169836,169837,169837,169837,169837,169837,169843,169843,169843,169843,169843,169845,169849,169849,169849,169849,169851,169853,169854,169869,169870,169870,169870,169876,169876,169876,169879,169880,169880,169880,169883,169883,169883,169883,169883,169883,169889,169892,169901,169903,169903,169903,169906,169906,169910,169914,169914,169917,169918,169926,169932,169935,169936,169940,169942,169943,169943,169943,169954,169959,169977,169978,169980,169982,169983,169987,169989,169993,169993,169996,170000,170011,170013,170016,170025,170025,170026,170039,170040,170042,170042,170042,170045,170048,170050,170052,170053,170054,170055,170059,170064,170065,170067,170071,170073,170079,170080,170083,170083,170083,170085,170086,170087,170087,170095,170096,170099,170100,170100,170105,170105,170105,170111,170111,170113,170114,170114,170115,170117,170122,170127,170135,170137,170137,170138,170138,170138,170141,170147,170151,170153,170169,170173,170177,170177,170177,170177,170178,170180,170181,170184,170191,170193,170195,170195,170195,170195,170195,170195,170201,170204,170207,170208,170210,170210,170214,170214,170214,170214,170214,170231,170232,170232,170232,170232,170240,170245,170251,170258,170258,170261,170261,170263,170264,170265,170265,170267,170267,170273,170274,170276,170279,170283,170293,170297,170297,170299,170303,170309,170309,170313,170314,170315,170315,170316,170316,170316,170318,170326,170326,170326,170326,170326,170327,170329,170330,170330,170336,170336,170336,170337,170338,170338,170339,170343,170356,170358,170363,170367,170373,170374,170381,170387,170390,170390,170390,170391,170401,170414,170414,170418,170426,170426,170431,170435,170444,170448,170448,170450,170452,170452,170452,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170457,170466,170474,170474,170474,170480,170485,170486,170487,170489,170492,170499,170502,170506,170507,170508,170514,170514,170518,170518,170518,170518,170518,170518,170519,170521,170522,170522,170522,170522,170523,170526,170529,170529,170529,170529,170534,170534,170538,170538,170549,170553,170559,170562,170562,170562,170562,170562,170569,170577,170584,170585,170585,170586,170586,170586,170588,170588,170590,170592,170594,170594,170599,170600,170600,170600,170600,170600,170600,170600,170600,170607,170611,170612,170613,170613,170614,170622,170622,170622,170622,170622,170626,170629,170629,170630,170642,170642,170649,170653,170653,170664,170670,170673,170684,170687,170687,170692,170696,170696,170700,170700,170700,170700,170700,170700,170700,170700,170700,170700,170700,170700,170700,170700,170700,170702,170707,170708,170712,170713,170713,170713,170713,170715,170715,170716,170717,170723,170723,170724,170724,170724,170734,170736,170737,170737,170743,170744,170747,170748,170750,170750,170755,170758,170759,170759,170761,170761,170762,170766,170780,170780,170797,170801,170802,170809,170814,170814,170814,170814,170816,170817,170820,170820,170820,170820,170820,170820,170833,170835,170836,170838,170839,170839,170845,170845,170859,170859,170862,170864,170864,170877,170877,170877,170880,170882,170890,170891,170891,170897,170897,170897,170899,170900,170903,170907,170913,170913,170915,170923,170924,170924,170924,170929,170930,170935,170938,170938,170943,170943,170947,170948,170949,170950,170951,170951,170951,170951,170953,170961,170963,170963,170963,170968,170969,170970,170973,170986,170987,170988,170988,170988,170994,170995,170996,170999,170999,171001,171001,171002,171003,171003,171005,171005,171005,171005,171005,171005,171005,171005,171006,171007,171008,171008,171008,171008,171008,171008,171014,171014,171014,171014,171014,171014,171014,171014,171022,171023,171025,171030,171033,171033,171037,171038,171038,171038,171039,171039,171039,171039,171039,171039,171039,171039,171041,171041,171044,171048,171049,171056,171056,171064,171070,171074,171074,171084,171084,171084,171086,171086,171086,171086,171088,171091,171094,171098,171099,171099,171099,171099,171105,171106,171113,171114,171114,171118,171134,171134,171134,171139,171143,171143,171156,171156,171156,171156,171156,171156,171156,171166,171170,171173,171174,171178,171178,171183,171185,171186,171186,171187,171190,171190,171198,171199,171203,171203,171203,171204,171213,171214,171219,171220,171222,171222,171224,171225,171228,171232,171232,171235,171237,171237,171237,171237,171241,171243,171245,171250,171252,171261,171263,171266,171268,171268,171273,171273,171273,171274,171278,171280,171280,171281,171281,171281,171281,171281,171282,171284,171284,171287,171293,171296,171296,171296,171296,171296,171301,171301,171307,171307,171309,171310,171313,171314,171314,171316,171319,171319,171319,171323,171324,171324,171324,171324,171326,171332,171339,171341,171346,171347,171353,171353,171353,171353,171353,171359,171359,171359,171360,171360,171361,171369,171376,171383,171383,171383,171385,171388,171393,171395,171396,171396,171396,171397,171398,171398,171398,171399,171399,171404,171413,171415,171415,171415,171415,171418,171418,171418,171430,171434,171434,171438,171438,171446,171446,171446,171447,171447,171447,171447,171447,171449,171451,171454,171457,171457,171465,171465,171466,171470,171477,171479,171480,171484,171484,171484,171484,171484,171487,171488,171491,171491,171494,171498,171499,171499,171499,171500,171500,171502,171505,171507,171509,171512,171513,171513,171513,171513,171513,171513,171514,171514,171514,171515,171518,171518,171518,171521,171526,171526,171526,171526,171526,171528,171528,171529,171530,171530,171530,171531,171531,171531,171532,171532,171533,171533,171533,171537,171537,171537,171537,171538,171538,171539,171539,171539,171539,171539,171539,171539,171542,171543,171543,171543,171543,171543,171543,171543,171543,171544,171544,171545,171547,171547,171547,171547,171547,171547,171548,171548,171549,171549,171549,171549,171550,171557,171558,171558,171558,171560,171561,171562,171563,171564,171569,171572,171576,171577,171578,171578,171578,171579,171579,171581,171581,171581,171581,171581,171581,171591,171596,171598,171598,171599,171600,171604,171604,171604,171606,171606,171607,171607,171608,171608,171608,171608,171608,171608,171608,171608,171608,171608,171608,171608,171609,171609,171609,171609,171614,171614,171616,171616,171616,171616,171617,171617,171618,171618,171618,171618,171619,171619,171619,171619,171619,171620,171621,171621,171621,171622,171622,171622,171622,171627,171629,171632,171635,171635,171635,171636,171636,171636,171636,171636,171636,171637,171638,171639,171640,171640,171640,171640,171640,171641,171642,171644,171645,171646,171656,171656,171656,171656,171656,171656,171656,171657,171657,171657,171657,171660,171662,171673,171676,171676,171678,171680,171681,171681,171683,171683,171684,171697,171697,171697,171697,171697,171698,171703,171703,171704,171704,171704,171707,171713,171713,171714,171714,171717,171722,171722,171722,171722,171728,171729,171729,171730,171735,171735,171735,171735,171735,171736,171736,171736,171740,171741,171745,171745,171746,171747,171747,171752,171753,171753,171753,171753,171753,171753,171753,171753,171754,171754,171755,171756,171756,171756,171756,171759,171760,171761,171762,171762,171763,171763,171765,171768,171770,171770,171770,171770,171770,171771,171771,171772,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171780,171782,171786,171786,171788,171789,171792,171793,171793,171796,171796,171802,171802,171803,171807,171807,171807,171813,171814,171815,171815,171819,171819,171819,171822,171822,171822,171827,171827,171828,171831,171833,171833,171833,171834,171835,171838,171839,171839,171840,171842,171843,171846,171857,171859,171869,171869,171872,171883,171890,171890,171891,171891,171893,171898,171898,171898,171898,171898,171898,171898,171898,171900,171906,171906,171906,171909,171914,171914,171917,171920,171921,171922,171922,171923,171923,171925,171925,171927,171927,171936,171937,171938,171938,171938,171938,171938,171938,171938,171939,171941,171941,171941,171942,171942,171944,171946,171946,171946,171949,171949,171949,171949,171951,171951,171951,171953,171955,171957,171957,171961,171961,171963,171964,171967,171968,171968,171971,171973,171974,171975,171975,171975,171983,171983,171985,171989,171989,171989,171989,171989,171989,171989,171991,171992,171992,171999,172002,172003,172005,172006,172008,172013,172014,172015,172016,172017,172018,172018,172021,172021,172022,172024,172026,172026,172026,172026,172026,172026,172026,172028,172037,172038,172039,172039,172040,172040,172046,172046,172047,172052,172053,172056,172057,172058,172058,172061,172062,172066,172069,172069,172074,172076,172078,172083,172091,172091,172091,172092,172093,172093,172093,172093,172093,172094,172094,172094,172094,172096,172100,172100,172101,172101,172104,172107,172108,172112,172113,172113,172113,172115,172117,172117,172118,172118,172119,172120,172124,172126,172126,172127,172129,172129,172130,172132,172132,172132,172133,172136,172136,172136,172140,172140,172140,172146,172149,172149,172151,172151,172151,172155,172156,172156,172161,172170,172179,172180,172184,172184,172184,172191,172192,172192,172195,172197,172201,172201,172207,172208,172214,172214,172214,172214,172214,172240,172251,172251,172254,172255,172257,172259,172260,172263,172265,172269,172270,172271,172274,172274,172274,172274,172275,172277,172280,172280,172281,172281,172281,172282,172282,172284,172293,172296,172298,172299,172301,172301,172304,172307,172313,172314,172314,172315,172315,172316,172316,172317,172319,172322,172324,172328,172328,172330,172330,172331,172332,172332,172332,172332,172332,172332,172351,172359,172363,172364,172364,172366,172369,172370,172374,172375,172376,172385,172385,172385,172385,172385,172386,172386,172386,172386,172390,172390,172391,172393,172395,172397,172397,172397,172397,172397,172408,172410,172410,172410,172413,172413,172414,172418,172422,172427,172427,172428,172431,172437,172446,172448,172456,172456,172456,172457,172458,172463,172466,172474,172476,172481,172481,172481,172485,172488,172493,172495,172495,172495,172498,172498,172499,172501,172501,172501,172504,172504,172504,172508,172509,172514,172514,172514,172514,172514,172514,172514,172518,172525,172526,172533,172533,172541,172546,172547,172548,172554,172554,172558,172558,172564,172566,172567,172570,172573,172577,172577,172578,172584,172588,172590,172590,172596,172599,172599,172599,172599,172599,172604,172606,172606,172606,172606,172606,172609,172609,172611,172612,172613,172613,172613,172613,172613,172618,172623,172623,172623,172625,172625,172641,172643,172643,172643,172646,172647,172656,172656,172657,172665,172665,172667,172667,172679,172679,172679,172679,172687,172694,172695,172695,172695,172696,172696,172696,172697,172699,172702,172702,172707,172709,172710,172714,172714,172714,172714,172726,172727,172730,172738,172740,172740,172740,172740,172740,172753,172755,172755,172755,172757,172758,172758,172758,172758,172758,172762,172766,172767,172781,172783,172789,172801,172811,172811,172811,172811,172813,172814,172814,172814,172814,172814,172814,172816,172816,172816,172822,172827,172828,172829,172829,172829,172829,172830,172830,172830,172830,172831,172831,172842,172844,172855,172859,172864,172865,172869,172870,172870,172876,172898,172903,172904,172911,172911,172911,172913,172914,172914,172914,172914,172914,172914,172914,172914,172914,172914,172914,172914,172915,172916,172921,172922,172925,172929,172929,172929,172935,172935,172935,172935,172937,172943,172944,172945,172946,172948,172958,172965,172969,172970,172970,172975,172981,172981,172982,172985,172987,172987,172987,172987,172987,172987,172987,172987,172987,172994,172994,172994,172997,173000,173000,173000,173000,173002,173002,173002,173002,173002,173002,173003,173003,173006,173010,173011,173013,173013,173013,173014,173016,173016,173016,173016,173017,173022,173023,173027,173037,173037,173039,173040,173044,173048,173059,173059,173061,173063,173063,173064,173064,173076,173076,173080,173082,173084,173084,173084,173084,173084,173084,173084,173087,173087,173090,173090,173091,173098,173103,173103,173106,173112,173112,173114,173114,173114,173114,173114,173116,173117,173117,173117,173117,173122,173125,173125,173125,173126,173128,173131,173131,173135,173135,173138,173141,173142,173142,173142,173142,173142,173143,173143,173145,173148,173149,173149,173149,173151,173151,173156,173157,173167,173171,173171,173177,173180,173184,173187,173199,173199,173203,173205,173209,173213,173213,173213,173213,173215,173215,173226,173226,173231,173234,173235,173237,173237,173238,173240,173240,173240,173240,173259,173272,173278,173289,173295,173295,173295,173295,173295,173296,173300,173302,173313,173313,173314,173314,173317,173320,173321,173321,173321,173321,173335,173342,173342,173345,173345,173346,173346,173346,173346,173346,173347,173349,173353,173356,173361,173373,173377,173379,173381,173381,173385,173385,173396,173400,173401,173403,173403,173403,173406,173407,173410,173413,173413,173414,173415,173417,173417,173417,173417,173417,173417,173421,173422,173425,173425,173425,173437,173437,173437,173437,173437,173437,173437,173438,173438,173439,173440,173443,173443,173443,173446,173446,173451,173456,173457,173463,173473,173476,173479,173483,173483,173483,173504,173504,173505,173505,173513,173513,173513,173513,173513,173523,173523,173523,173532,173532,173532,173532,173532,173533,173533,173535,173535,173536,173540,173544,173544,173544,173550,173553,173559,173559,173561,173564,173566,173573,173573,173576,173577,173578,173579,173596,173600,173603,173607,173609,173614,173620,173621,173624,173627,173630,173634,173634,173638,173638,173638,173638,173639,173639,173639,173639,173639,173640,173644,173644,173645,173645,173652,173652,173654,173667,173671,173671,173672,173672,173672,173676,173677,173677,173680,173682,173687,173689,173689,173696,173698,173698,173702,173702,173702,173702,173702,173702,173702,173705,173714,173726,173726,173726,173726,173727,173733,173733,173734,173735,173735,173735,173735,173735,173735,173735,173735,173735,173735,173736,173736,173736,173736,173736,173736,173737,173737,173738,173738,173738,173738,173738,173738,173739,173739,173739,173739,173739,173739,173739,173739,173739,173741,173741,173742,173742,173742,173744,173744,173745,173745,173745,173745,173745,173745,173745,173746,173746,173747,173750,173751,173755,173757,173759,173760,173760,173764,173766,173767,173773,173775,173775,173778,173779,173779,173779,173780,173780,173780,173780,173783,173784,173784,173784,173785,173785,173785,173785,173785,173785,173785,173785,173785,173786,173786,173786,173786,173787,173787,173787,173787,173787,173787,173788,173788,173789,173789,173789,173790,173790,173790,173790,173792,173792,173794,173794,173796,173796,173797,173798,173800,173800,173800,173800,173800,173800,173800,173800,173800,173800,173800,173800,173804,173804,173804,173804,173808,173808,173808,173808,173808,173808,173808,173808,173808,173808,173810,173810,173812,173812,173813,173813,173813,173813,173813,173813,173813,173813,173815,173815,173818,173818,173819,173819,173819,173819,173819,173819,173819,173819,173819,173819,173820,173823,173823,173828,173829,173829,173832,173832,173832,173832,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173833,173837,173839,173839,173839,173839,173841,173842,173842,173843,173843,173843,173844,173844,173844,173845,173845,173845,173845,173845,173845,173846,173847,173852,173853,173853,173853,173853,173853,173853,173854,173854,173854,173854,173855,173856,173856,173856,173856,173856,173856,173856,173856,173856,173856,173856,173856,173856,173856,173856,173860,173860,173861,173862,173864,173865,173865,173865,173865,173865,173865,173865,173865,173866,173866,173866,173866,173866,173868,173869,173870,173870,173871,173871,173871,173871,173874,173878,173879,173882,173883,173886,173890,173891,173891,173891,173891,173891,173892,173896,173896,173896,173898,173899,173899,173899,173899,173901,173901,173901,173904,173907,173907,173911,173911,173912,173912,173912,173912,173914,173914,173917,173917,173917,173919,173919,173919,173922,173922,173926,173927,173931,173931,173934,173941,173941,173941,173941,173941,173943,173943,173944,173944,173945,173946,173946,173946,173952,173955,173956,173956,173957,173957,173957,173957,173962,173962,173968,173968,173968,173970,173971,173971,173972,173972,173972,173973,173973,173973,173975,173979,173979,173982,173983,173983,173985,173986,173987,173988,173990,173990,173993,173993,173994,173994,173994,173994,173994,173994,173995,173996,173996,173996,173996,173997,173997,173997,173997,174001,174003,174003,174005,174005,174008,174008,174008,174012,174016,174016,174017,174022,174025,174026,174026,174026,174026,174026,174026,174026,174026,174026,174028,174030,174032,174032,174032,174032,174032,174034,174034,174034,174038,174038,174038,174039,174041,174045,174046,174047,174049,174049,174055,174057,174061,174065,174065,174069,174069,174073,174073,174073,174074,174082,174083,174086,174101,174101,174106,174108,174108,174108,174108,174109,174109,174109,174109,174109,174111,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174113,174115,174115,174115,174115,174117,174117,174118,174118,174118,174118,174118,174119,174119,174119,174119,174120,174121,174122,174124,174124,174124,174127,174127,174128,174139,174144,174145,174147,174150,174150,174151,174151,174154,174154,174159,174160,174162,174165,174165,174165,174166,174169,174169,174169,174171,174174,174176,174176,174176,174176,174176,174176,174178,174180,174181,174181,174183,174185,174185,174188,174188,174188,174188,174188,174188,174188,174188,174189,174189,174189,174189,174189,174191,174191,174191,174201,174201,174201,174207,174207,174209,174214,174218,174220,174220,174227,174227,174229,174232,174232,174237,174237,174237,174242,174242,174242,174243,174244,174245,174254,174254,174254,174258,174258,174259,174259,174259,174261,174261,174263,174265,174265,174265,174268,174269,174269,174269,174269,174269,174270,174270,174272,174272,174272,174272,174272,174272,174272,174274,174274,174274,174274,174274,174283,174283,174294,174302,174305,174306,174307,174307,174307,174307,174307,174314,174314,174314,174314,174315,174316,174316,174318,174318,174318,174318,174318,174325,174325,174333,174333,174333,174337,174339,174339,174342,174342,174345,174360,174369,174372,174372,174375,174376,174378,174378,174379,174379,174379,174379,174379,174379,174379,174381,174382,174383,174384,174384,174386,174386,174386,174386,174386,174387,174390,174390,174390,174395,174408,174411,174411,174411,174413,174423,174424,174424,174424,174424,174424,174424,174424,174424,174424,174424,174424,174424,174426,174426,174428,174433,174433,174439,174444,174444,174451,174451,174451,174451,174453,174454,174461,174461,174461,174461,174462,174464,174464,174466,174466,174466,174466,174466,174469,174471,174473,174476,174477,174479,174479,174480,174484,174484,174485,174485,174485,174485,174491,174495,174499,174499,174500,174501,174501,174501,174501,174506,174511,174511,174511,174513,174516,174523,174531,174537,174543,174543,174543,174545,174546,174546,174546,174546,174554,174554,174554,174554,174554,174554,174554,174555,174556,174557,174558,174558,174558,174558,174558,174562,174563,174563,174563,174563,174563,174563,174563,174563,174563,174564,174565,174567,174570,174570,174570,174571,174573,174574,174575,174576,174578,174583,174583,174583,174583,174588,174598,174598,174598,174598,174598,174598,174608,174614,174614,174614,174614,174622,174622,174628,174629,174629,174629,174630,174630,174631,174634,174634,174643,174643,174649,174650,174650,174657,174657,174657,174658,174661,174661,174661,174661,174663,174665,174665,174666,174666,174666,174666,174669,174673,174673,174675,174678,174686,174686,174686,174686,174686,174691,174693,174693,174693,174694,174696,174702,174708,174710,174711,174711,174711,174718,174721,174722,174727,174729,174739,174743,174753,174753,174753,174753,174758,174758,174758,174762,174766,174766,174772,174772,174773,174778,174781,174782,174784,174786,174793,174798,174801,174801,174805,174809,174811,174811,174817,174817,174817,174818,174819,174822,174822,174824,174824,174825,174827,174827,174829,174829,174833,174834,174836,174837,174839,174841,174842,174844,174845,174845,174845,174845,174847,174851,174851,174851,174854,174861,174867,174869,174875,174876,174885,174885,174903,174903,174915,174917,174917,174917,174917,174922,174922,174922,174924,174924,174932,174935,174935,174936,174938,174938,174939,174943,174943,174943,174944,174944,174950,174951,174951,174955,174956,174964,174965,174965,174970,174970,174970,174974,174975,174975,174975,174980,174986,174986,174986,174990,174991,174994,175005,175005,175005,175005,175009,175011,175014,175025,175025,175036,175036,175036,175038,175038,175038,175038,175038,175039,175046,175047,175048,175048,175048,175048,175048,175048,175048,175051,175053,175053,175053,175057,175059,175061,175062,175062,175062,175064,175064,175066,175072,175073,175078,175078,175082,175082,175085,175085,175088,175095,175100,175100,175100,175101,175105,175105,175105,175111,175111,175120,175122,175137,175139,175141,175155,175158,175158,175158,175158,175158,175160,175162,175162,175166,175166,175168,175168,175169,175169,175169,175169,175172,175175,175176,175176,175176,175176,175182,175182,175184,175187,175188,175191,175191,175191,175194,175196,175203,175203,175210,175212,175222,175222,175222,175222,175222,175222,175222,175224,175225,175225,175226,175226,175226,175226,175226,175226,175226,175226,175234,175234,175241,175241,175246,175246,175259,175262,175265,175265,175265,175265,175265,175265,175265,175266,175267,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175269,175271,175280,175283,175283,175283,175283,175283,175283,175283,175283,175283,175283,175283,175283,175283,175283,175283,175284,175284,175284,175286,175286,175286,175286,175286,175291,175295,175297,175297,175297,175297,175297,175297,175297,175297,175299,175299,175301,175302,175303,175311,175312,175312,175312,175312,175312,175312,175313,175317,175317,175317,175320,175321,175321,175321,175324,175327,175334,175334,175335,175335,175335,175335,175343,175343,175343,175345,175346,175346,175346,175346,175346,175347,175347,175349,175352,175353,175355,175356,175357,175357,175357,175357,175360,175362,175362,175365,175365,175366,175366,175367,175367,175371,175371,175372,175372,175372,175372,175372,175381,175383,175383,175386,175390,175390,175390,175394,175397,175401,175401,175401,175401,175401,175401,175401,175404,175404,175404,175404,175404,175404,175404,175404,175405,175405,175407,175407,175407,175407,175407,175408,175409,175411,175411,175411,175413,175413,175413,175414,175417,175418,175420,175420,175420,175420,175420,175420,175423,175433,175436,175437,175444,175445,175447,175452,175452,175452,175452,175457,175457,175458,175460,175469,175469,175469,175470,175470,175470,175470,175470,175470,175472,175477,175477,175477,175483,175483,175483,175483,175483,175484,175485,175485,175489,175493,175493,175493,175498,175500,175504,175504,175504,175509,175509,175510,175511,175512,175515,175515,175518,175518,175518,175518,175518,175518,175518,175518,175524,175524,175536,175537,175538,175539,175539,175539,175540,175540,175540,175543,175544,175545,175547,175548,175549,175551,175551,175551,175556,175556,175556,175556,175557,175557,175557,175557,175557,175557,175557,175560,175565,175565,175565,175565,175565,175571,175586,175586,175586,175586,175586,175588,175588,175589,175592,175595,175595,175595,175611,175611,175611,175615,175616,175616,175616,175616,175632,175632,175645,175645,175645,175646,175652,175662,175662,175664,175664,175664,175666,175666,175666,175666,175666,175666,175666,175675,175682,175682,175688,175689,175689,175690,175690,175690,175690,175690,175690,175690,175690,175695,175695,175696,175696,175696,175696,175697,175699,175699,175699,175701,175704,175707,175707,175708,175708,175711,175715,175715,175719,175721,175724,175727,175730,175732,175738,175742,175746,175750,175752,175757,175757,175757,175759,175768,175768,175769,175769,175769,175770,175771,175773,175773,175774,175777,175780,175783,175783,175784,175789,175790,175795,175796,175796,175796,175800,175800,175802,175802,175802,175810,175812,175812,175812,175812,175816,175817,175817,175822,175823,175827,175837,175837,175839,175843,175843,175843,175843,175847,175848,175849,175849,175851,175851,175851,175851,175851,175852,175852,175852,175852,175852,175852,175855,175855,175858,175860,175867,175875,175885,175886,175886,175886,175894,175894,175900,175911,175911,175911,175911,175911,175914,175919,175920,175921,175924,175925,175929,175931,175939,175939,175939,175942,175942,175943,175943,175943,175950,175950,175950,175961,175961,175961,175961,175961,175963,175966,175966,175966,175966,175967,175968,175971,175977,175977,175977,175977,175977,175977,175977,175977,175977,175978,175978,175980,175981,175981,175981,175981,175982,175982,175982,175982,175982,175982,175982,175982,175985,175988,175988,175988,175988,175988,175988,175988,175988,175988,175990,175992,175995,175998,176001,176001,176002,176002,176004,176007,176008,176009,176009,176009,176009,176010,176011,176011,176016,176021,176022,176022,176022,176022,176022,176022,176022,176022,176024,176033,176035,176035,176039,176042,176044,176046,176048,176050,176054,176056,176057,176057,176059,176071,176071,176080,176083,176083,176090,176090,176090,176090,176091,176091,176098,176098,176099,176101,176103,176106,176110,176110,176110,176114,176114,176114,176114,176115,176115,176115,176117,176119,176119,176119,176120,176123,176126,176128,176132,176133,176133,176134,176137,176138,176138,176139,176141,176141,176141,176141,176141,176141,176142,176142,176143,176143,176143,176143,176143,176144,176144,176144,176144,176147,176147,176147,176153,176155,176157,176157,176161,176161,176161,176165,176169,176171,176171,176171,176172,176173,176173,176174,176178,176179,176181,176181,176182,176184,176184,176184,176186,176190,176194,176201,176202,176202,176202,176206,176210,176212,176213,176213,176213,176213,176213,176214,176214,176214,176214,176214,176214,176214,176214,176214,176214,176214,176215,176216,176224,176224,176234,176238,176238,176240,176240,176244,176247,176251,176251,176252,176252,176252,176252,176253,176253,176257,176257,176257,176257,176257,176257,176261,176261,176261,176262,176266,176266,176266,176266,176266,176266,176266,176266,176273,176277,176278,176278,176281,176281,176284,176293,176294,176298,176299,176301,176301,176302,176302,176302,176302,176302,176302,176303,176303,176303,176303,176303,176303,176303,176303,176305,176305,176305,176305,176306,176307,176308,176308,176314,176314,176316,176316,176318,176318,176318,176318,176318,176318,176318,176318,176318,176321,176321,176322,176323,176332,176332,176332,176332,176332,176332,176332,176332,176333,176337,176337,176341,176351,176353,176353,176353,176356,176356,176356,176357,176357,176361,176365,176365,176370,176370,176372,176372,176373,176373,176379,176383,176383,176389,176394,176406,176406,176406,176414,176418,176423,176427,176432,176445,176450,176453,176456,176461,176461,176464,176464,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176465,176466,176466,176466,176466,176466,176468,176468,176468,176468,176468,176468,176468,176468,176469,176469,176471,176471,176472,176472,176472,176473,176475,176478,176479,176480,176480,176480,176480,176480,176480,176480,176480,176480,176480,176480,176480,176482,176482,176483,176483,176483,176483,176483,176483,176484,176485,176485,176485,176485,176485,176486,176486,176486,176486,176486,176486,176487,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176488,176489,176489,176489,176489,176489,176489,176490,176490,176491,176491,176493,176493,176493,176493,176493,176493,176494,176495,176495,176495,176495,176495,176495,176495,176495,176495,176495,176495,176495,176495,176497,176498,176498,176500,176500,176500,176500,176500,176500,176502,176502,176502,176502,176502,176502,176503,176505,176505,176505,176505,176506,176507,176507,176507,176509,176509,176509,176509,176509,176509,176510,176511,176512,176513,176513,176513,176513,176516,176516,176516,176516,176516,176516,176517,176517,176517,176520,176520,176520,176520,176520,176521,176526,176527,176527,176527,176527,176527,176529,176531,176532,176532,176534,176537,176537,176537,176537,176537,176537,176537,176537,176538,176539,176540,176542,176543,176543,176547,176547,176547,176549,176551,176551,176551,176551,176551,176551,176552,176554,176554,176554,176554,176554,176555,176555,176556,176559,176562,176563,176563,176563,176563,176564,176565,176566,176566,176567,176569,176570,176570,176570,176571,176571,176571,176574,176574,176576,176580,176582,176582,176585,176588,176588,176588,176588,176588,176588,176589,176592,176592,176592,176592,176592,176594,176598,176600,176602,176602,176602,176602,176602,176602,176605,176607,176609,176609,176609,176609,176610,176612,176615,176617,176617,176617,176621,176621,176621,176623,176623,176628,176629,176629,176633,176633,176634,176636,176636,176636,176636,176636,176637,176646,176648,176651,176652,176652,176653,176653,176654,176657,176657,176657,176658,176658,176658,176658,176658,176663,176665,176666,176667,176673,176674,176674,176676,176677,176677,176677,176678,176678,176680,176680,176680,176682,176682,176682,176683,176686,176686,176693,176694,176696,176696,176696,176696,176696,176696,176699,176701,176702,176702,176703,176706,176711,176711,176711,176719,176720,176723,176723,176740,176740,176740,176742,176742,176746,176754,176760,176760,176761,176761,176766,176767,176768,176771,176772,176773,176773,176774,176777,176781,176787,176787,176787,176787,176787,176792,176792,176792,176796,176797,176798,176798,176799,176802,176802,176804,176806,176808,176808,176808,176808,176808,176808,176808,176808,176808,176808,176808,176808,176808,176809,176809,176809,176809,176813,176813,176813,176813,176816,176821,176821,176821,176822,176822,176822,176828,176830,176838,176839,176846,176852,176852,176852,176852,176854,176857,176860,176861,176861,176861,176867,176867,176867,176869,176869,176869,176869,176870,176870,176870,176870,176882,176882,176882,176882,176885,176885,176899,176899,176899,176899,176902,176907,176907,176910,176910,176911,176911,176920,176921,176922,176922,176922,176922,176922,176922,176922,176922,176922,176923,176924,176924,176927,176927,176929,176929,176936,176938,176941,176952,176953,176957,176957,176958,176958,176960,176967,176967,176967,176967,176967,176969,176970,176971,176971,176971,176971,176973,176976,176976,176976,176976,176976,176977,176979,176979,176979,176983,176983,176983,176983,176983,176983,176983,176983,176989,176989,176990,176990,176995,176995,176996,176996,176997,176998,177000,177002,177002,177003,177003,177003,177003,177003,177005,177007,177007,177007,177010,177011,177011,177011,177011,177012,177012,177012,177013,177013,177019,177023,177023,177026,177026,177026,177026,177026,177026,177029,177042,177043,177043,177045,177050,177050,177050,177050,177050,177050,177050,177050,177050,177050,177051,177051,177051,177051,177054,177054,177055,177055,177056,177056,177056,177056,177057,177057,177064,177064,177064,177064,177064,177064,177064,177071,177081,177081,177084,177084,177094,177095,177095,177095,177095,177095,177095,177111,177111,177111,177111,177111,177111,177111,177112,177116,177116,177117,177117,177117,177117,177117,177117,177117,177118,177118,177121,177121,177121,177123,177123,177123,177125,177125,177125,177125,177125,177125,177126,177129,177131,177131,177131,177131,177131,177131,177132,177132,177145,177149,177149,177151,177151,177152,177152,177153,177159,177159,177166,177166,177174,177176,177181,177182,177184,177185,177190,177199,177199,177199,177199,177200,177205,177205,177207,177208,177209,177209,177209,177210,177210,177210,177211,177211,177214,177215,177215,177215,177215,177215,177217,177217,177220,177220,177220,177220,177221,177223,177224,177224,177228,177228,177230,177231,177232,177234,177234,177235,177236,177252,177252,177254,177257,177258,177258,177258,177258,177258,177264,177264,177264,177264,177264,177268,177272,177272,177272,177272,177272,177272,177273,177273,177278,177279,177284,177284,177284,177284,177284,177284,177284,177284,177285,177285,177288,177291,177291,177293,177298,177298,177304,177305,177307,177307,177307,177308,177308,177308,177311,177314,177316,177317,177320,177323,177329,177329,177329,177330,177332,177335,177337,177340,177340,177340,177340,177341,177341,177341,177341,177341,177341,177341,177341,177342,177342,177342,177343,177343,177343,177343,177343,177343,177343,177343,177343,177344,177344,177344,177344,177344,177344,177344,177344,177344,177344,177344,177347,177348,177349,177352,177352,177353,177353,177353,177354,177354,177356,177358,177358,177362,177364,177374,177386,177386,177387,177387,177387,177394,177394,177394,177394,177394,177394,177394,177394,177396,177397,177399,177399,177399,177400,177400,177400,177401,177401,177407,177409,177409,177410,177412,177412,177412,177412,177413,177413,177416,177416,177416,177416,177419,177419,177419,177420,177424,177424,177424,177425,177425,177425,177425,177425,177430,177432,177432,177432,177434,177435,177435,177435,177435,177437,177437,177437,177437,177437,177438,177439,177439,177439,177440,177446,177452,177452,177452,177453,177454,177454,177454,177457,177464,177465,177465,177466,177466,177466,177466,177466,177466,177467,177468,177473,177474,177474,177474,177474,177474,177477,177480,177480,177480,177480,177480,177480,177484,177484,177487,177491,177500,177500,177507,177507,177507,177507,177507,177511,177511,177511,177513,177520,177520,177520,177520,177520,177526,177527,177527,177527,177528,177528,177529,177530,177531,177531,177533,177533,177535,177535,177535,177536,177537,177537,177537,177539,177539,177539,177539,177539,177539,177539,177540,177542,177546,177549,177549,177549,177549,177549,177549,177549,177549,177549,177549,177549,177549,177549,177550,177553,177554,177554,177554,177554,177554,177556,177556,177560,177560,177560,177560,177560,177560,177560,177562,177563,177566,177566,177566,177567,177567,177568,177571,177571,177572,177572,177572,177572,177572,177572,177576,177576,177580,177584,177590,177593,177594,177594,177601,177602,177611,177611,177611,177614,177614,177614,177614,177614,177614,177614,177619,177643,177646,177647,177653,177654,177654,177655,177656,177658,177659,177659,177660,177660,177664,177664,177671,177671,177671,177680,177683,177686,177686,177686,177695,177698,177699,177700,177701,177712,177712,177712,177712,177712,177716,177721,177725,177730,177730,177737,177737,177738,177739,177739,177741,177746,177749,177751,177751,177752,177752,177752,177755,177759,177761,177761,177761,177761,177761,177761,177763,177766,177766,177766,177766,177769,177770,177770,177770,177770,177770,177770,177771,177772,177772,177775,177775,177775,177775,177776,177776,177776,177776,177777,177777,177777,177783,177783,177783,177784,177784,177788,177788,177793,177797,177799,177799,177799,177800,177801,177801,177801,177801,177805,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177811,177815,177819,177823,177823,177824,177824,177827,177827,177830,177832,177840,177840,177840,177844,177852,177852,177852,177852,177853,177855,177857,177858,177858,177858,177868,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177869,177870,177870,177870,177870,177870,177870,177870,177870,177870,177870,177870,177872,177873,177873,177873,177873,177877,177880,177880,177880,177880,177881,177881,177883,177884,177884,177884,177884,177884,177886,177886,177886,177887,177888,177888,177893,177893,177894,177894,177894,177894,177895,177895,177895,177895,177895,177897,177898,177899,177905,177905,177905,177905,177907,177907,177913,177914,177914,177920,177924,177929,177929,177930,177930,177931,177933,177933,177933,177934,177934,177934,177934,177936,177939,177940,177941,177941,177942,177943,177943,177943,177943,177943,177943,177946,177947,177947,177948,177948,177948,177949,177949,177949,177949,177950,177950,177952,177953,177955,177955,177956,177956,177961,177961,177962,177966,177966,177967,177968,177972,177973,177973,177974,177974,177974,177978,177978,177981,177984,177984,177986,177986,177995,177995,177999,177999,178000,178002,178008,178012,178012,178012,178014,178015,178017,178017,178020,178020,178020,178020,178027,178028,178028,178028,178028,178030,178034,178034,178036,178039,178039,178042,178042,178043,178043,178046,178049,178051,178051,178051,178054,178054,178056,178056,178059,178059,178059,178060,178061,178062,178062,178064,178065,178065,178065,178065,178065,178065,178065,178065,178065,178065,178065,178066,178066,178066,178066,178066,178066,178066,178066,178067,178067,178067,178067,178067,178067,178067,178067,178067,178067,178068,178071,178071,178071,178074,178076,178077,178079,178084,178086,178088,178092,178092,178093,178094,178096,178097,178097,178100,178107,178107,178108,178110,178110,178111,178111,178111,178111,178114,178120,178120,178123,178124,178130,178130,178130,178130,178133,178133,178133,178138,178140,178140,178140,178140,178140,178144,178144,178148,178152,178152,178154,178154,178158,178158,178158,178161,178161,178165,178167,178168,178172,178184,178184,178184,178184,178185,178191,178193,178196,178199,178211,178211,178214,178218,178218,178225,178228,178228,178228,178228,178228,178230,178230,178230,178230,178231,178235,178235,178235,178235,178235,178241,178242,178243,178247,178249,178250,178252,178253,178253,178253,178253,178253,178256,178256,178257,178259,178259,178260,178262,178262,178262,178264,178264,178265,178265,178267,178268,178268,178268,178269,178270,178280,178280,178282,178284,178285,178286,178286,178286,178286,178286,178288,178288,178290,178290,178291,178291,178291,178291,178291,178291,178291,178294,178294,178294,178294,178294,178298,178299,178305,178305,178305,178305,178305,178305,178306,178306,178308,178311,178311,178317,178317,178317,178325,178326,178332,178332,178332,178337,178337,178337,178337,178338,178338,178338,178338,178341,178341,178341,178341,178342,178343,178345,178346,178347,178348,178348,178348,178348,178350,178350,178353,178353,178353,178353,178353,178354,178354,178359,178359,178360,178360,178360,178360,178360,178366,178368,178368,178373,178373,178377,178379,178384,178384,178392,178392,178397,178400,178401,178401,178401,178401,178405,178405,178405,178405,178405,178405,178405,178405,178406,178406,178406,178407,178408,178408,178408,178411,178411,178411,178412,178412,178412,178414,178414,178414,178422,178422,178422,178422,178424,178425,178425,178425,178425,178425,178425,178425,178427,178427,178428,178429,178436,178449,178452,178458,178458,178458,178466,178471,178473,178473,178478,178480,178480,178480,178480,178485,178487,178489,178489,178489,178489,178491,178495,178495,178500,178510,178510,178514,178516,178522,178531,178536,178542,178542,178542,178542,178543,178543,178543,178543,178545,178545,178546,178546,178546,178548,178550,178553,178556,178556,178556,178558,178560,178561,178566,178571,178573,178573,178575,178576,178576,178576,178577,178581,178587,178587,178587,178587,178587,178589,178595,178597,178604,178604,178605,178605,178606,178610,178612,178612,178612,178612,178612,178612,178621,178621,178623,178625,178625,178626,178627,178627,178628,178628,178628,178628,178628,178628,178628,178629,178629,178633,178634,178636,178639,178639,178644,178650,178653,178653,178653,178653,178656,178657,178663,178663,178663,178665,178666,178676,178676,178679,178681,178683,178683,178683,178686,178693,178693,178697,178699,178699,178699,178701,178701,178702,178702,178702,178703,178703,178703,178705,178707,178707,178707,178707,178710,178710,178710,178710,178710,178710,178710,178710,178710,178710,178711,178711,178711,178711,178711,178711,178712,178712,178716,178716,178717,178717,178719,178719,178719,178719,178719,178719,178719,178720,178720,178720,178720,178721,178721,178722,178723,178724,178724,178728,178728,178728,178728,178730,178730,178731,178731,178733,178733,178736,178737,178742,178742,178742,178743,178743,178743,178749,178749,178749,178753,178753,178753,178753,178753,178754,178754,178754,178756,178756,178756,178756,178756,178756,178756,178756,178756,178757,178757,178757,178758,178758,178759,178760,178762,178762,178762,178763,178763,178763,178763,178763,178763,178763,178763,178763,178763,178763,178763,178763,178764,178764,178764,178765,178768,178769,178770,178771,178773,178773,178773,178773,178775,178775,178775,178775,178775,178777,178780,178780,178780,178781,178781,178781,178782,178783,178783,178783,178786,178787,178787,178787,178790,178790,178790,178791,178791,178792,178792,178792,178792,178792,178792,178792,178795,178799,178800,178800,178800,178801,178802,178804,178807,178807,178807,178807,178810,178811,178811,178812,178812,178813,178813,178813,178813,178813,178816,178818,178819,178830,178835,178841,178843,178843,178843,178850,178850,178850,178851,178857,178861,178863,178864,178866,178866,178866,178866,178866,178866,178867,178867,178867,178867,178867,178867,178867,178867,178868,178868,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178869,178870,178870,178870,178871,178871,178871,178871,178871,178871,178871,178872,178873,178873,178874,178874,178875,178876,178878,178879,178879,178879,178879,178880,178882,178883,178883,178883,178883,178883,178885,178885,178887,178887,178887,178891,178895,178897,178898,178898,178898,178898,178899,178899,178900,178901,178902,178904,178904,178904,178906,178910,178910,178911,178912,178912,178914,178914,178919,178926,178927,178933,178933,178934,178935,178939,178941,178942,178943,178943,178943,178943,178945,178946,178947,178950,178952,178952,178952,178953,178955,178955,178957,178958,178959,178966,178966,178966,178981,178981,178981,178981,178982,178982,178990,178990,178992,178994,178997,178997,179001,179001,179006,179006,179007,179007,179012,179015,179015,179015,179017,179020,179024,179030,179031,179031,179036,179037,179039,179040,179040,179041,179041,179041,179041,179041,179046,179047,179047,179047,179047,179048,179049,179051,179051,179052,179053,179054,179057,179057,179057,179057,179057,179057,179058,179058,179058,179058,179063,179063,179063,179069,179073,179073,179075,179075,179079,179079,179084,179090,179090,179097,179098,179104,179108,179108,179116,179117,179117,179127,179127,179127,179127,179127,179140,179140,179141,179142,179142,179142,179142,179144,179144,179144,179149,179155,179158,179161,179166,179175,179175,179179,179183,179184,179184,179186,179199,179199,179199,179199,179199,179210,179211,179211,179215,179217,179226,179234,179238,179238,179240,179244,179245,179245,179245,179253,179254,179257,179259,179266,179266,179266,179269,179275,179277,179277,179277,179282,179286,179301,179301,179301,179301,179303,179307,179311,179311,179314,179320,179321,179323,179331,179335,179342,179342,179342,179342,179346,179346,179347,179349,179351,179351,179351,179351,179354,179354,179356,179356,179356,179367,179367,179369,179371,179373,179379,179382,179382,179382,179382,179383,179384,179384,179384,179385,179385,179388,179388,179388,179388,179388,179389,179396,179398,179400,179403,179403,179403,179406,179407,179407,179410,179412,179413,179416,179416,179416,179418,179425,179425,179425,179425,179425,179426,179427,179427,179427,179431,179431,179436,179438,179440,179444,179444,179448,179452,179457,179460,179462,179463,179464,179468,179476,179481,179484,179487,179489,179489,179492,179496,179500,179510,179511,179511,179511,179511,179515,179519,179524,179529,179529,179529,179538,179539,179539,179539,179539,179541,179544,179544,179544,179547,179550,179551,179551,179553,179555,179555,179558,179559,179560,179560,179560,179566,179566,179566,179568,179569,179573,179582,179583,179583,179584,179584,179585,179586,179590,179592,179592,179594,179601,179601,179601,179601,179601,179602,179602,179606,179606,179609,179610,179611,179613,179616,179618,179625,179626,179626,179629,179632,179636,179638,179645,179654,179654,179655,179657,179657,179657,179660,179660,179660,179662,179667,179667,179667,179668,179670,179670,179672,179672,179684,179684,179684,179692,179696,179697,179698,179720,179723,179730,179743,179744,179744,179744,179746,179746,179756,179756,179756,179760,179760,179763,179765,179767,179769,179771,179771,179771,179776,179777,179782,179782,179782,179783,179783,179785,179785,179787,179795,179796,179799,179800,179800,179803,179807,179807,179807,179809,179809,179811,179811,179811,179814,179815,179835,179839,179839,179839,179841,179841,179841,179841,179848,179848,179849,179850,179851,179851,179852,179852,179852,179855,179855,179856,179858,179859,179859,179859,179863,179863,179868,179868,179878,179882,179883,179883,179883,179883,179883,179883,179883,179883,179883,179883,179883,179883,179883,179883,179883,179885,179885,179891,179891,179891,179901,179901,179901,179907,179907,179907,179907,179907,179907,179907,179909,179911,179911,179911,179911,179915,179915,179915,179920,179920,179920,179924,179924,179924,179924,179926,179927,179928,179929,179929,179929,179929,179930,179930,179930,179930,179930,179930,179930,179930,179930,179932,179932,179936,179936,179936,179936,179936,179936,179936,179938,179940,179940,179940,179940,179940,179940,179941,179941,179941,179942,179946,179946,179947,179948,179951,179954,179954,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179955,179956,179959,179960,179962,179964,179970,179971,179974,179975,179975,179982,179984,179984,179984,179984,179993,179994,179994,179996,180012,180015,180026,180026,180026,180030,180031,180034,180037,180038,180039,180043,180043,180044,180044,180049,180050,180050,180051,180053,180062,180063,180070,180073,180074,180074,180074,180074,180074,180074,180074,180075,180085,180086,180086,180086,180086,180088,180095,180102,180111,180111,180114,180114,180123,180124,180125,180125,180127,180127,180128,180128,180128,180128,180128,180131,180131,180137,180138,180139,180139,180140,180140,180142,180143,180146,180146,180146,180147,180151,180152,180152,180152,180153,180154,180154,180156,180156,180156,180157,180157,180157,180158,180159,180159,180159,180161,180161,180161,180162,180162,180163,180164,180169,180173,180177,180182,180184,180184,180184,180184,180184,180184,180194,180198,180198,180199,180199,180199,180199,180202,180205,180205,180205,180205,180205,180208,180208,180208,180209,180209,180209,180209,180209,180210,180210,180210,180210,180210,180210,180210,180210,180210,180211,180213,180213,180216,180219,180225,180225,180228,180236,180241,180251,180251,180251,180252,180257,180257,180257,180257,180257,180257,180257,180258,180262,180264,180265,180265,180270,180271,180272,180272,180272,180281,180281,180281,180282,180282,180283,180283,180286,180287,180288,180288,180289,180292,180292,180294,180294,180294,180294,180294,180294,180294,180294,180295,180295,180296,180300,180300,180300,180300,180300,180301,180301,180301,180306,180306,180307,180307,180310,180311,180314,180314,180314,180318,180322,180323,180323,180333,180334,180334,180350,180358,180365,180368,180369,180374,180377,180378,180382,180386,180398,180398,180398,180398,180398,180398,180400,180400,180400,180405,180412,180420,180420,180420,180421,180421,180421,180421,180424,180430,180432,180432,180440,180450,180451,180452,180452,180452,180457,180460,180463,180465,180466,180467,180468,180470,180470,180470,180470,180473,180473,180473,180473,180473,180474,180477,180477,180477,180477,180481,180482,180482,180482,180482,180483,180483,180483,180483,180483,180483,180484,180484,180484,180484,180485,180485,180485,180487,180487,180487,180487,180487,180489,180489,180490,180490,180490,180491,180491,180491,180493,180493,180496,180496,180497,180498,180498,180498,180498,180498,180498,180498,180499,180499,180499,180499,180500,180500,180500,180501,180505,180505,180505,180505,180505,180505,180507,180507,180507,180507,180507,180507,180509,180509,180509,180509,180511,180511,180511,180511,180511,180511,180515,180516,180516,180518,180519,180521,180521,180521,180521,180521,180521,180522,180522,180522,180522,180524,180524,180524,180525,180526,180526,180526,180526,180528,180529,180529,180529,180529,180531,180531,180533,180534,180534,180535,180535,180535,180535,180535,180535,180535,180535,180535,180535,180536,180539,180540,180540,180542,180542,180545,180545,180547,180548,180548,180549,180552,180552,180552,180552,180552,180552,180552,180552,180554,180556,180556,180556,180556,180557,180557,180557,180557,180557,180557,180558,180558,180558,180558,180562,180563,180567,180573,180573,180574,180576,180576,180579,180583,180589,180589,180589,180589,180589,180589,180589,180589,180589,180590,180590,180590,180590,180596,180596,180596,180596,180597,180599,180600,180600,180603,180603,180607,180607,180607,180607,180609,180609,180611,180611,180616,180624,180625,180628,180629,180633,180635,180643,180643,180646,180646,180646,180649,180652,180655,180660,180661,180666,180671,180675,180675,180675,180675,180675,180675,180675,180675,180675,180675,180675,180675,180678,180680,180681,180681,180681,180681,180681,180683,180683,180685,180686,180686,180686,180689,180694,180697,180699,180706,180707,180713,180718,180720,180724,180725,180725,180733,180738,180738,180739,180739,180739,180739,180739,180749,180759,180762,180762,180764,180778,180778,180778,180779,180780,180782,180782,180788,180788,180788,180788,180788,180789,180789,180792,180792,180797,180797,180797,180812,180814,180834,180836,180850,180851,180851,180851,180851,180851,180853,180855,180855,180866,180867,180868,180868,180870,180872,180872,180876,180876,180876,180878,180879,180879,180884,180884,180884,180890,180890,180890,180890,180893,180893,180894,180901,180904,180906,180908,180908,180908,180908,180910,180912,180913,180913,180913,180916,180916,180920,180921,180924,180930,180930,180936,180936,180936,180937,180937,180937,180937,180938,180943,180943,180943,180944,180944,180944,180944,180944,180947,180950,180951,180951,180951,180952,180952,180954,180955,180957,180958,180958,180958,180958,180958,180958,180961,180961,180963,180965,180965,180965,180965,180967,180973,180977,180978,180991,180992,180992,180992,180993,180993,180993,180993,180993,180993,181005,181015,181020,181025,181042,181042,181045,181045,181046,181046,181047,181047,181051,181051,181052,181052,181052,181052,181052,181052,181052,181052,181054,181055,181056,181056,181056,181057,181058,181060,181060,181062,181062,181062,181062,181062,181062,181062,181062,181063,181063,181063,181063,181063,181064,181064,181064,181065,181065,181065,181065,181066,181066,181066,181066,181066,181066,181068,181068,181068,181068,181069,181069,181070,181070,181070,181070,181070,181072,181072,181073,181073,181074,181075,181075,181076,181076,181078,181079,181079,181080,181081,181081,181084,181086,181086,181087,181090,181091,181096,181098,181099,181099,181101,181106,181107,181107,181107,181116,181121,181122,181122,181122,181122,181124,181128,181128,181129,181130,181133,181134,181135,181138,181142,181142,181142,181145,181146,181146,181146,181146,181149,181150,181151,181151,181154,181154,181154,181155,181157,181157,181164,181165,181175,181179,181179,181179,181179,181179,181179,181179,181179,181179,181179,181183,181185,181189,181189,181189,181192,181194,181194,181194,181195,181195,181199,181199,181199,181199,181199,181199,181199,181199,181199,181199,181199,181199,181199,181200,181200,181200,181200,181200,181200,181200,181200,181200,181200,181200,181201,181201,181201,181201,181201,181202,181202,181203,181203,181203,181203,181203,181204,181205,181205,181205,181205,181206,181206,181206,181207,181209,181209,181210,181210,181214,181214,181214,181214,181215,181215,181216,181216,181218,181218,181218,181222,181223,181223,181223,181224,181224,181224,181224,181224,181225,181225,181225,181225,181225,181226,181226,181227,181227,181227,181227,181227,181228,181228,181229,181229,181229,181230,181230,181230,181231,181231,181231,181231,181231,181231,181232,181232,181232,181232,181232,181232,181233,181234,181235,181235,181235,181235,181238,181238,181240,181242,181242,181243,181244,181244,181246,181248,181250,181250,181251,181252,181253,181254,181255,181255,181255,181258,181259,181259,181260,181260,181263,181266,181267,181269,181270,181270,181270,181270,181270,181271,181271,181271,181271,181271,181271,181271,181271,181271,181272,181272,181272,181272,181272,181272,181272,181273,181273,181273,181273,181273,181273,181273,181273,181273,181273,181273,181273,181273,181274,181275,181275,181275,181275,181275,181275,181277,181277,181277,181281,181281,181283,181284,181284,181284,181285,181294,181295,181295,181295,181295,181295,181296,181296,181296,181296,181298,181306,181307,181308,181309,181309,181309,181310,181310,181310,181310,181317,181318,181323,181328,181328,181328,181330,181345,181345,181345,181345,181349,181349,181349,181350,181351,181357,181361,181362,181363,181363,181365,181365,181365,181365,181366,181368,181368,181368,181368,181369,181370,181371,181372,181372,181374,181376,181376,181382,181385,181387,181389,181397,181397,181398,181404,181410,181413,181421,181424,181424,181424,181424,181424,181424,181426,181426,181426,181426,181432,181435,181435,181436,181440,181446,181449,181449,181449,181451,181451,181451,181451,181455,181458,181464,181467,181476,181476,181477,181477,181478,181479,181479,181481,181481,181481,181481,181482,181482,181482,181484,181484,181484,181485,181486,181486,181486,181486,181488,181488,181488,181489,181489,181489,181489,181491,181492,181492,181493,181494,181494,181497,181498,181508,181513,181513,181515,181519,181519,181519,181519,181519,181519,181519,181519,181521,181521,181524,181527,181528,181534,181534,181534,181536,181548,181556,181558,181558,181561,181561,181561,181569,181573,181579,181586,181589,181593,181597,181600,181602,181606,181606,181607,181608,181611,181614,181615,181617,181620,181624,181628,181632,181636,181640,181643,181643,181643,181653,181656,181658,181660,181661,181662,181662,181662,181666,181670,181672,181681,181681,181686,181687,181687,181687,181687,181687,181687,181687,181687,181687,181688,181688,181688,181693,181696,181704,181706,181706,181709,181709,181710,181712,181712,181715,181715,181716,181717,181718,181722,181722,181722,181723,181728,181728,181728,181728,181728,181731,181732,181735,181739,181739,181746,181748,181748,181748,181748,181748,181748,181748,181748,181748,181748,181752,181752,181754,181754,181754,181754,181755,181763,181765,181766,181766,181766,181767,181775,181789,181792,181796,181796,181800,181816,181823,181823,181823,181824,181826,181836,181836,181837,181838,181838,181841,181844,181845,181845,181845,181845,181845,181851,181857,181858,181864,181865,181867,181873,181873,181873,181873,181873,181873,181873,181873,181874,181874,181874,181876,181876,181877,181877,181881,181882,181891,181891,181892,181895,181895,181899,181900,181902,181905,181912,181913,181914,181915,181921,181921,181921,181921,181921,181921,181922,181923,181926,181927,181928,181931,181931,181933,181938,181940,181942,181944,181944,181944,181946,181959,181962,181966,181966,181966,181969,181971,181973,181975,181984,181985,181992,181993,181996,182011,182016,182019,182027,182029,182035,182037,182040,182040,182040,182040,182040,182041,182041,182042,182042,182044,182045,182049,182052,182052,182052,182052,182053,182053,182053,182053,182053,182053,182054,182054,182054,182054,182054,182054,182055,182055,182055,182056,182057,182060,182066,182066,182066,182066,182066,182067,182069,182071,182073,182073,182075,182075,182075,182079,182079,182096,182102,182104,182108,182108,182108,182116,182117,182117,182118,182118,182121,182125,182126,182127,182127,182127,182130,182137,182145,182149,182154,182154,182154,182156,182158,182158,182158,182159,182160,182163,182164,182167,182168,182168,182169,182170,182178,182179,182180,182183,182183,182183,182183,182183,182192,182192,182193,182195,182196,182196,182200,182203,182204,182204,182204,182204,182210,182213,182213,182213,182215,182215,182215,182217,182220,182220,182225,182231,182236,182238,182238,182238,182249,182250,182250,182253,182254,182256,182256,182258,182258,182266,182267,182267,182267,182271,182273,182273,182273,182273,182273,182274,182274,182274,182274,182276,182279,182281,182285,182285,182291,182295,182296,182297,182297,182306,182307,182308,182318,182318,182318,182318,182318,182321,182321,182323,182329,182331,182333,182335,182338,182340,182342,182344,182352,182354,182354,182354,182354,182354,182355,182355,182355,182356,182356,182356,182356,182357,182357,182358,182360,182361,182363,182363,182363,182365,182371,182374,182376,182376,182376,182377,182377,182377,182379,182382,182386,182393,182398,182398,182398,182398,182398,182398,182398,182398,182398,182406,182412,182418,182418,182420,182421,182421,182421,182422,182424,182425,182427,182434,182436,182446,182450,182458,182463,182463,182472,182480,182482,182484,182485,182488,182489,182494,182494,182494,182494,182494,182498,182502,182520,182520,182520,182526,182526,182526,182528,182530,182536,182546,182546,182547,182548,182554,182570,182573,182575,182587,182590,182590,182590,182590,182590,182590,182591,182592,182592,182592,182592,182592,182592,182593,182593,182593,182593,182602,182602,182602,182602,182602,182602,182602,182605,182605,182605,182606,182607,182607,182607,182607,182609,182615,182621,182630,182630,182630,182630,182630,182636,182639,182639,182640,182641,182643,182647,182651,182656,182658,182666,182667,182667,182667,182667,182670,182670,182678,182678,182678,182694,182696,182696,182706,182711,182713,182719,182723,182723,182723,182735,182741,182744,182746,182749,182766,182770,182770,182770,182771,182775,182778,182797,182802,182809,182809,182820,182825,182830,182830,182834,182845,182848,182849,182860,182863,182863,182863,182863,182865,182865,182865,182865,182865,182867,182867,182867,182876,182877,182877,182877,182877,182897,182897,182901,182906,182912,182915,182915,182916,182916,182924,182925,182931,182936,182938,182943,182944,182944,182951,182953,182961,182966,182968,182973,182976,182976,182976,182977,182985,182987,182987,182987,182987,182993,182993,182998,183003,183006,183006,183006,183006,183006,183006,183013,183017,183017,183017,183017,183022,183023,183026,183028,183029,183029,183031,183037,183045,183050,183051,183058,183058,183058,183058,183060,183060,183060,183060,183061,183064,183065,183065,183073,183073,183073,183075,183075,183078,183082,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183083,183086,183086,183087,183093,183093,183095,183095,183095,183096,183097,183097,183098,183098,183103,183103,183103,183104,183107,183112,183120,183121,183121,183127,183132,183140,183144,183146,183148,183148,183155,183161,183161,183164,183170,183172,183174,183174,183174,183177,183177,183179,183185,183191,183191,183197,183205,183209,183214,183226,183226,183228,183230,183236,183242,183243,183243,183254,183254,183261,183264,183269,183272,183272,183273,183273,183274,183274,183277,183277,183277,183281,183282,183292,183297,183299,183300,183302,183306,183306,183306,183306,183314,183322,183330,183342,183349,183350,183352,183354,183358,183364,183364,183364,183364,183364,183364,183364,183373,183374,183382,183382,183386,183388,183393,183399,183404,183406,183412,183420,183422,183424,183428,183434,183435,183437,183438,183440,183442,183442,183448,183451,183451,183461,183462,183465,183466,183468,183468,183468,183468,183468,183470,183470,183470,183473,183474,183479,183482,183485,183485,183485,183485,183489,183489,183492,183495,183499,183503,183507,183511,183515,183516,183516,183517,183517,183517,183517,183517,183519,183528,183529,183530,183535,183540,183549,183554,183563,183563,183564,183569,183569,183572,183576,183577,183578,183581,183581,183582,183583,183583,183583,183583,183583,183583,183583,183583,183583,183583,183588,183590,183591,183594,183594,183594,183596,183596,183597,183599,183604,183604,183604,183604,183604,183607,183614,183614,183615,183615,183615,183617,183618,183620,183626,183627,183627,183630,183630,183633,183640,183644,183648,183652,183652,183654,183660,183660,183661,183662,183662,183662,183664,183667,183668,183669,183674,183674,183674,183676,183676,183676,183676,183676,183676,183676,183676,183676,183680,183685,183686,183686,183690,183691,183694,183695,183702,183711,183714,183715,183722,183736,183736,183746,183751,183759,183768,183768,183771,183778,183780,183784,183791,183792,183795,183796,183799,183812,183816,183816,183826,183826,183832,183832,183832,183834,183835,183837,183838,183845,183849,183850,183853,183859,183863,183864,183870,183874,183877,183880,183884,183886,183893,183896,183898,183904,183906,183920,183921,183923,183925,183925,183926,183929,183930,183930,183931,183931,183931,183931,183931,183931,183936,183944,183944,183946,183946,183946,183950,183952,183952,183953,183953,183953,183959,183973,183975,183976,183976,183976,183976,183976,183986,183988,183990,183992,183994,183994,184000,184001,184001,184001,184001,184009,184009,184011,184018,184018,184023,184027,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184029,184031,184033,184035,184035,184035,184035,184038,184038,184038,184040,184043,184044,184047,184052,184052,184053,184053,184058,184058,184058,184059,184061,184062,184070,184071,184071,184071,184071,184071,184072,184074,184077,184077,184079,184079,184080,184080,184080,184080,184080,184086,184086,184086,184086,184086,184086,184088,184093,184093,184093,184094,184094,184098,184098,184100,184109,184111,184111,184111,184111,184111,184111,184111,184111,184111,184111,184111,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184121,184122,184122,184122,184122,184123,184123,184123,184123,184123,184123,184123,184123,184123,184124,184124,184124,184124,184125,184125,184125,184125,184126,184127,184127,184128,184128,184129,184129,184133,184134,184138,184141,184142,184143,184148,184152,184154,184156,184156,184156,184156,184156,184156,184156,184156,184156,184156,184156,184156,184156,184156,184159,184164,184164,184164,184164,184164,184166,184168,184168,184168,184168,184168,184168,184169,184180,184181,184182,184183,184183,184183,184185,184185,184187,184187,184187,184187,184187,184188,184189,184189,184191,184192,184192,184192,184195,184195,184195,184195,184195,184197,184198,184198,184198,184200,184201,184201,184202,184204,184205,184205,184206,184206,184211,184212,184214,184216,184220,184220,184221,184223,184226,184226,184227,184232,184232,184232,184232,184232,184232,184232,184232,184232,184232,184232,184232,184232,184232,184232,184243,184248,184248,184248,184253,184254,184255,184255,184255,184255,184255,184258,184259,184259,184260,184261,184263,184263,184270,184273,184276,184276,184278,184278,184278,184279,184279,184280,184280,184280,184280,184280,184281,184282,184282,184283,184284,184284,184284,184284,184285,184285,184287,184293,184293,184299,184301,184302,184302,184302,184311,184319,184319,184319,184320,184320,184320,184320,184323,184324,184324,184324,184327,184327,184327,184327,184327,184327,184327,184330,184334,184338,184338,184340,184340,184340,184340,184342,184343,184343,184344,184344,184349,184353,184353,184355,184356,184356,184356,184356,184356,184357,184359,184366,184366,184370,184375,184376,184377,184377,184380,184382,184384,184384,184386,184388,184389,184391,184393,184393,184393,184394,184397,184398,184398,184398,184399,184401,184403,184403,184403,184403,184403,184403,184403,184405,184406,184412,184413,184418,184418,184419,184421,184421,184421,184424,184424,184425,184425,184432,184432,184438,184440,184441,184441,184441,184441,184441,184442,184443,184444,184444,184444,184447,184447,184451,184451,184451,184457,184457,184458,184465,184465,184474,184477,184485,184489,184489,184497,184497,184501,184501,184501,184501,184503,184507,184507,184511,184511,184511,184511,184521,184522,184524,184527,184534,184536,184538,184539,184540,184545,184545,184548,184548,184550,184550,184562,184562,184562,184562,184562,184562,184562,184562,184562,184566,184566,184566,184566,184566,184566,184566,184566,184567,184567,184567,184568,184569,184569,184569,184569,184573,184573,184573,184573,184573,184576,184576,184576,184577,184584,184584,184592,184597,184599,184601,184609,184615,184617,184620,184629,184636,184636,184642,184642,184642,184646,184649,184649,184651,184651,184653,184653,184654,184659,184659,184664,184666,184667,184681,184688,184690,184698,184712,184713,184713,184715,184722,184730,184733,184737,184739,184739,184739,184739,184741,184742,184744,184745,184745,184745,184745,184751,184751,184751,184751,184756,184756,184762,184765,184767,184767,184768,184769,184769,184777,184789,184791,184794,184795,184795,184795,184795,184795,184795,184798,184798,184798,184798,184798,184798,184799,184806,184807,184811,184811,184812,184812,184813,184813,184815,184816,184817,184821,184822,184823,184823,184823,184823,184823,184824,184833,184834,184834,184837,184838,184854,184857,184859,184859,184859,184860,184870,184876,184877,184877,184880,184882,184884,184884,184884,184890,184894,184894,184894,184894,184894,184894,184898,184898,184899,184899,184900,184900,184901,184907,184911,184911,184918,184920,184920,184920,184922,184931,184931,184936,184939,184939,184941,184945,184945,184948,184948,184948,184948,184948,184948,184948,184949,184954,184954,184954,184955,184961,184961,184965,184965,184966,184966,184966,184966,184967,184972,184972,184973,184973,184973,184973,184973,184975,184978,184979,184980,184982,184987,184987,184987,184987,184987,184989,184989,184989,184990,184991,184991,184994,184994,184995,184995,184995,184995,184996,184996,185000,185000,185000,185003,185012,185015,185016,185017,185018,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185021,185022,185022,185022,185022,185022,185024,185024,185024,185024,185024,185025,185025,185025,185025,185025,185025,185025,185025,185025,185027,185027,185028,185030,185030,185030,185030,185030,185030,185030,185030,185032,185035,185036,185038,185041,185041,185041,185044,185046,185052,185057,185058,185064,185064,185065,185073,185077,185077,185077,185077,185077,185077,185077,185081,185081,185082,185086,185093,185093,185095,185095,185104,185108,185116,185117,185118,185125,185126,185126,185132,185135,185141,185142,185143,185149,185151,185156,185156,185156,185157,185157,185163,185165,185173,185175,185178,185180,185184,185186,185187,185187,185191,185200,185203,185208,185217,185217,185219,185225,185234,185235,185239,185252,185259,185265,185265,185271,185275,185278,185278,185278,185278,185279,185279,185279,185280,185280,185282,185286,185286,185287,185287,185298,185301,185304,185307,185308,185310,185312,185312,185317,185319,185320,185320,185323,185329,185331,185332,185335,185335,185335,185338,185338,185342,185342,185342,185342,185342,185342,185342,185342,185342,185342,185342,185342,185343,185343,185343,185343,185347,185347,185347,185353,185353,185356,185357,185358,185363,185368,185368,185369,185371,185372,185372,185372,185372,185373,185373,185376,185376,185379,185379,185380,185380,185380,185399,185399,185399,185399,185403,185404,185404,185404,185407,185411,185418,185422,185424,185426,185432,185433,185435,185442,185445,185445,185448,185452,185456,185464,185472,185472,185474,185475,185478,185479,185487,185497,185500,185500,185500,185500,185500,185500,185500,185500,185502,185504,185507,185510,185524,185525,185526,185532,185532,185533,185540,185541,185542,185542,185546,185546,185546,185546,185546,185550,185552,185554,185557,185560,185564,185565,185567,185572,185575,185576,185577,185580,185585,185586,185587,185590,185592,185595,185596,185597,185598,185598,185600,185602,185608,185615,185616,185621,185622,185630,185630,185630,185632,185633,185634,185635,185636,185636,185636,185636,185636,185636,185636,185636,185636,185636,185636,185640,185641,185641,185641,185643,185643,185647,185650,185650,185650,185653,185655,185655,185655,185655,185655,185655,185655,185655,185655,185655,185655,185657,185657,185663,185664,185664,185664,185664,185669,185669,185669,185671,185679,185692,185693,185695,185699,185709,185711,185719,185719,185723,185727,185727,185727,185729,185729,185734,185737,185745,185746,185746,185752,185759,185762,185765,185766,185768,185768,185776,185776,185778,185780,185781,185782,185789,185794,185796,185805,185807,185814,185814,185814,185814,185814,185814,185824,185829,185831,185831,185834,185834,185842,185843,185847,185847,185847,185849,185857,185857,185858,185858,185858,185860,185866,185868,185871,185877,185877,185878,185880,185885,185885,185885,185887,185887,185887,185887,185888,185893,185899,185900,185901,185908,185913,185922,185922,185923,185924,185925,185930,185931,185938,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185939,185943,185948,185949,185953,185953,185953,185953,185953,185957,185957,185961,185962,185966,185966,185967,185967,185967,185969,185972,185972,185977,185977,185978,185979,185979,185980,185981,185981,185983,185983,185986,185996,185998,186000,186004,186004,186005,186008,186010,186014,186014,186015,186018,186024,186033,186037,186037,186037,186037,186037,186037,186037,186037,186037,186041,186042,186043,186046,186047,186048,186049,186050,186054,186054,186054,186054,186055,186057,186057,186057,186057,186057,186057,186068,186068,186069,186069,186069,186076,186078,186087,186090,186091,186092,186094,186096,186097,186098,186098,186100,186101,186115,186118,186118,186118,186118,186118,186118,186119,186122,186122,186122,186123,186123,186125,186126,186128,186128,186129,186131,186132,186133,186138,186138,186143,186143,186144,186147,186148,186148,186148,186148,186151,186152,186158,186162,186164,186174,186174,186174,186178,186185,186187,186187,186188,186189,186194,186194,186201,186213,186213,186213,186214,186216,186218,186218,186218,186218,186218,186218,186218,186221,186221,186222,186223,186223,186223,186223,186223,186223,186223,186223,186229,186233,186235,186236,186241,186242,186245,186250,186250,186253,186256,186256,186256,186261,186261,186270,186270,186270,186271,186274,186281,186282,186289,186290,186290,186298,186302,186302,186302,186311,186313,186313,186313,186320,186320,186320,186323,186323,186324,186326,186327,186327,186327,186327,186329,186331,186332,186333,186333,186336,186348,186350,186353,186356,186356,186366,186373,186378,186379,186380,186392,186392,186395,186400,186407,186408,186413,186416,186416,186416,186416,186416,186416,186416,186416,186416,186416,186419,186419,186419,186422,186422,186422,186422,186422,186422,186422,186423,186426,186427,186434,186442,186442,186443,186443,186445,186446,186451,186454,186456,186456,186457,186457,186457,186463,186464,186467,186467,186469,186469,186469,186469,186470,186472,186475,186477,186480,186482,186482,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186487,186488,186490,186491,186496,186498,186505,186505,186513,186514,186519,186520,186520,186520,186520,186522,186522,186524,186525,186525,186527,186527,186527,186529,186529,186536,186537,186539,186539,186542,186543,186544,186544,186544,186544,186544,186550,186550,186553,186553,186556,186559,186563,186566,186567,186567,186572,186578,186578,186580,186583,186585,186586,186589,186590,186591,186594,186599,186599,186599,186602,186602,186603,186604,186604,186611,186613,186613,186613,186618,186618,186618,186620,186620,186620,186620,186622,186629,186634,186634,186636,186642,186642,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186643,186648,186651,186652,186654,186654,186655,186655,186655,186655,186656,186656,186656,186656,186656,186656,186657,186657,186657,186657,186657,186659,186661,186662,186663,186663,186663,186663,186664,186664,186665,186666,186666,186666,186666,186666,186666,186666,186668,186668,186670,186672,186673,186673,186673,186673,186673,186673,186674,186675,186676,186677,186677,186678,186679,186680,186680,186682,186683,186683,186683,186683,186683,186683,186683,186684,186684,186684,186686,186686,186687,186687,186688,186688,186688,186688,186688,186691,186692,186693,186694,186696,186696,186696,186697,186697,186698,186699,186699,186699,186701,186702,186702,186702,186702,186702,186702,186703,186703,186703,186703,186703,186703,186703,186703,186704,186704,186704,186704,186704,186704,186704,186705,186705,186705,186705,186706,186706,186706,186706,186706,186707,186707,186707,186709,186710,186710,186710,186711,186711,186711,186711,186713,186713,186713,186713,186714,186715,186718,186718,186719,186721,186721,186732,186732,186733,186736,186737,186739,186740,186740,186743,186744,186745,186745,186745,186745,186746,186747,186747,186747,186747,186747,186749,186752,186752,186753,186757,186758,186759,186761,186764,186764,186767,186769,186771,186772,186772,186772,186773,186773,186778,186791,186798,186801,186809,186809,186809,186809,186809,186809,186810,186818,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186826,186834,186834,186834,186846,186846,186851,186858,186876,186879,186886,186887,186887,186887,186890,186893,186896,186896,186896,186900,186902,186902,186903,186918,186921,186922,186926,186926,186931,186931,186931,186931,186931,186933,186933,186933,186933,186933,186933,186933,186933,186933,186934,186934,186934,186935,186935,186937,186937,186938,186938,186940,186942,186943,186946,186946,186946,186946,186946,186953,186961,186963,186964,186965,186966,186980,186985,186991,186991,186991,186991,186991,186991,186991,186991,186992,186992,186994,186995,186996,186996,186996,186996,186996,187000,187006,187011,187014,187016,187024,187032,187032,187033,187036,187036,187036,187036,187036,187036,187036,187036,187041,187047,187047,187048,187052,187056,187058,187060,187060,187060,187062,187062,187062,187062,187063,187075,187083,187092,187096,187097,187098,187099,187099,187100,187104,187106,187110,187110,187110,187110,187110,187110,187110,187110,187110,187111,187114,187114,187122,187122,187130,187131,187133,187134,187134,187138,187138,187138,187144,187149,187163,187163,187181,187182,187183,187186,187189,187194,187194,187194,187199,187199,187200,187200,187201,187202,187205,187209,187212,187214,187225,187232,187240,187240,187240,187240,187245,187247,187249,187249,187254,187254,187266,187271,187274,187274,187274,187277,187277,187281,187283,187286,187286,187288,187289,187289,187291,187291,187292,187292,187292,187295,187295,187295,187297,187298,187298,187300,187301,187301,187302,187307,187309,187309,187313,187314,187316,187316,187316,187316,187318,187322,187322,187324,187326,187328,187329,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187342,187344,187344,187345,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187346,187358,187359,187359,187361,187362,187364,187364,187366,187374,187375,187375,187381,187382,187405,187416,187420,187425,187426,187434,187435,187439,187440,187446,187449,187453,187458,187458,187466,187475,187476,187476,187477,187477,187478,187478,187488,187488,187488,187488,187488,187489,187497,187498,187503,187504,187507,187517,187519,187519,187520,187520,187520,187521,187521,187521,187521,187524,187525,187525,187525,187528,187528,187528,187529,187530,187530,187530,187531,187531,187533,187534,187534,187534,187534,187534,187535,187535,187535,187535,187536,187536,187536,187536,187537,187538,187538,187538,187538,187538,187538,187539,187540,187540,187540,187540,187540,187540,187540,187541,187542,187542,187542,187543,187544,187544,187544,187544,187547,187547,187547,187547,187548,187548,187549,187550,187564,187569,187569,187572,187573,187579,187579,187580,187587,187590,187591,187604,187604,187604,187605,187607,187616,187616,187617,187620,187621,187628,187629,187629,187629,187631,187635,187643,187644,187644,187644,187644,187644,187644,187644,187644,187644,187644,187644,187644,187644,187644,187645,187646,187647,187648,187648,187648,187648,187648,187648,187649,187650,187650,187650,187651,187651,187653,187653,187653,187653,187654,187657,187657,187660,187660,187667,187671,187671,187671,187671,187675,187675,187675,187675,187675,187675,187675,187675,187675,187675,187675,187676,187677,187678,187679,187679,187679,187682,187683,187683,187686,187691,187693,187695,187695,187695,187695,187695,187695,187695,187695,187696,187696,187697,187697,187701,187703,187714,187715,187718,187719,187719,187725,187725,187725,187727,187727,187727,187727,187727,187727,187727,187729,187730,187732,187732,187743,187745,187746,187746,187746,187746,187746,187751,187753,187753,187753,187753,187753,187753,187753,187753,187753,187755,187755,187755,187762,187765,187767,187767,187769,187771,187774,187776,187777,187781,187781,187781,187781,187783,187783,187784,187784,187785,187785,187785,187785,187785,187785,187785,187785,187785,187787,187788,187788,187789,187789,187789,187789,187789,187789,187789,187790,187791,187792,187792,187793,187794,187794,187795,187795,187796,187798,187798,187798,187798,187798,187799,187799,187799,187802,187808,187811,187813,187817,187818,187819,187821,187823,187834,187836,187842,187844,187844,187844,187846,187848,187848,187848,187848,187848,187854,187854,187857,187858,187860,187861,187861,187861,187861,187862,187863,187863,187866,187866,187869,187871,187871,187872,187872,187873,187875,187875,187878,187880,187880,187880,187886,187888,187888,187890,187890,187892,187892,187892,187893,187893,187893,187893,187895,187895,187895,187895,187895,187895,187903,187905,187905,187905,187907,187907,187907,187909,187913,187914,187914,187914,187915,187916,187916,187916,187916,187916,187916,187916,187916,187916,187916,187916,187916,187916,187916,187916,187917,187917,187917,187917,187917,187917,187918,187918,187918,187918,187920,187922,187922,187922,187922,187922,187922,187922,187922,187927,187930,187931,187933,187933,187936,187937,187938,187938,187943,187945,187945,187945,187949,187950,187950,187952,187956,187956,187957,187961,187964,187964,187964,187966,187966,187966,187966,187967,187968,187969,187969,187969,187970,187972,187975,187975,187977,187978,187978,187978,187978,187978,187978,187978,187978,187978,187979,187981,187981,187981,187982,187982,187982,187984,187985,187986,187986,187986,187986,187986,187988,187992,187992,187995,187995,187996,187998,188003,188003,188005,188005,188005,188006,188006,188009,188011,188013,188013,188013,188015,188015,188017,188018,188020,188021,188021,188021,188021,188021,188021,188021,188021,188021,188021,188022,188023,188023,188024,188024,188024,188024,188024,188025,188025,188025,188025,188025,188027,188027,188027,188038,188038,188040,188040,188040,188040,188040,188040,188042,188042,188042,188042,188043,188043,188044,188046,188046,188046,188046,188046,188046,188048,188048,188049,188049,188051,188053,188053,188053,188057,188058,188060,188062,188062,188062,188062,188062,188062,188062,188062,188064,188064,188064,188066,188066,188066,188071,188071,188072,188074,188074,188075,188078,188079,188079,188079,188079,188079,188079,188079,188079,188079,188083,188084,188084,188085,188086,188089,188091,188091,188091,188095,188095,188096,188100,188105,188107,188107,188115,188115,188116,188117,188118,188119,188123,188135,188138,188143,188146,188146,188146,188146,188146,188147,188147,188149,188153,188153,188154,188159,188160,188161,188161,188161,188161,188166,188168,188173,188179,188185,188185,188185,188185,188186,188187,188188,188189,188189,188194,188194,188196,188196,188196,188196,188197,188202,188202,188204,188204,188205,188205,188205,188205,188211,188211,188212,188212,188212,188213,188213,188213,188214,188220,188222,188222,188225,188230,188234,188234,188234,188234,188234,188236,188236,188242,188242,188245,188245,188249,188251,188251,188253,188253,188254,188256,188256,188256,188256,188256,188256,188262,188269,188269,188272,188283,188290,188295,188296,188297,188302,188304,188306,188307,188307,188309,188309,188312,188312,188315,188319,188320,188322,188331,188340,188340,188341,188347,188354,188354,188356,188356,188356,188356,188357,188358,188358,188359,188362,188363,188370,188372,188372,188376,188378,188378,188380,188380,188380,188380,188380,188380,188380,188382,188383,188385,188385,188385,188385,188387,188392,188392,188393,188393,188394,188394,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188395,188396,188396,188397,188398,188399,188399,188400,188403,188403,188408,188409,188409,188409,188412,188415,188420,188423,188424,188429,188433,188438,188438,188440,188440,188441,188441,188442,188442,188444,188445,188447,188451,188451,188451,188451,188451,188451,188452,188454,188454,188455,188455,188456,188457,188459,188460,188460,188460,188460,188460,188461,188462,188464,188464,188466,188467,188468,188469,188470,188474,188476,188479,188479,188479,188479,188479,188480,188480,188480,188480,188482,188482,188484,188484,188484,188484,188484,188493,188493,188495,188495,188495,188496,188497,188497,188497,188497,188498,188499,188500,188500,188501,188502,188503,188506,188506,188512,188512,188512,188515,188515,188518,188522,188522,188522,188522,188523,188526,188533,188533,188534,188534,188535,188535,188535,188535,188535,188536,188536,188536,188536,188536,188536,188536,188536,188537,188537,188537,188537,188537,188538,188538,188540,188541,188544,188546,188546,188546,188546,188546,188547,188550,188550,188550,188550,188553,188555,188555,188555,188555,188555,188555,188555,188555,188555,188558,188560,188560,188561,188562,188562,188562,188562,188562,188563,188566,188566,188567,188568,188568,188568,188569,188570,188570,188570,188570,188574,188578,188578,188579,188579,188580,188581,188581,188581,188582,188582,188584,188584,188587,188588,188588,188588,188588,188588,188592,188594,188594,188594,188595,188596,188596,188604,188604,188604,188604,188604,188604,188604,188604,188605,188605,188607,188609,188611,188611,188612,188612,188612,188616,188617,188618,188620,188621,188626,188626,188626,188627,188627,188639,188646,188646,188647,188648,188648,188648,188652,188653,188657,188657,188660,188660,188692,188692,188692,188700,188704,188704,188704,188704,188704,188713,188713,188715,188715,188715,188715,188718,188721,188721,188722,188722,188729,188729,188729,188730,188730,188730,188734,188735,188737,188737,188737,188737,188737,188737,188737,188740,188740,188740,188741,188742,188742,188748,188753,188753,188753,188755,188755,188761,188766,188770,188775,188777,188787,188793,188793,188797,188797,188800,188806,188806,188813,188814,188817,188823,188824,188826,188827,188827,188828,188833,188833,188835,188835,188835,188835,188837,188838,188841,188843,188843,188843,188843,188843,188844,188844,188845,188846,188846,188848,188849,188849,188849,188849,188850,188852,188852,188854,188854,188856,188859,188860,188861,188861,188861,188865,188865,188865,188865,188865,188865,188865,188865,188865,188866,188866,188866,188866,188867,188867,188867,188867,188870,188870,188870,188874,188875,188878,188878,188878,188880,188880,188883,188884,188884,188884,188884,188884,188887,188890,188895,188895,188895,188896,188900,188901,188901,188906,188907,188907,188907,188907,188907,188916,188917,188917,188917,188920,188926,188930,188930,188930,188931,188931,188931,188931,188931,188934,188935,188936,188942,188943,188943,188944,188948,188948,188955,188955,188956,188957,188957,188957,188957,188957,188957,188957,188957,188959,188963,188965,188976,188976,188976,188976,188976,188976,188976,188976,188976,188976,188976,188976,188976,188977,188977,188977,188978,188979,188981,188981,188982,188986,188988,188988,188988,188988,188988,188988,188988,188989,188989,188989,188990,188990,188990,188990,188998,188999,188999,188999,189004,189004,189004,189006,189010,189010,189010,189010,189010,189010,189011,189011,189011,189012,189013,189014,189022,189031,189033,189037,189037,189042,189047,189048,189059,189070,189073,189081,189085,189087,189088,189088,189094,189107,189113,189114,189124,189124,189126,189126,189129,189129,189133,189133,189134,189134,189134,189134,189135,189135,189136,189137,189137,189138,189138,189138,189138,189138,189139,189139,189144,189145,189146,189146,189146,189146,189147,189147,189147,189150,189152,189152,189154,189156,189156,189157,189159,189159,189159,189159,189159,189159,189160,189160,189160,189160,189162,189162,189164,189166,189169,189170,189170,189170,189176,189177,189177,189178,189178,189178,189178,189178,189178,189178,189178,189178,189179,189182,189186,189186,189186,189186,189189,189189,189190,189190,189192,189194,189194,189195,189195,189198,189207,189207,189207,189208,189208,189208,189208,189208,189208,189208,189211,189211,189211,189213,189215,189219,189219,189225,189226,189226,189227,189241,189246,189252,189258,189258,189258,189258,189263,189265,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189268,189269,189269,189269,189269,189269,189271,189273,189273,189273,189276,189277,189278,189288,189288,189288,189288,189288,189288,189288,189288,189288,189288,189288,189288,189292,189292,189292,189292,189295,189303,189304,189304,189304,189313,189313,189319,189320,189325,189326,189326,189326,189331,189331,189331,189332,189334,189335,189335,189338,189338,189338,189339,189341,189342,189347,189348,189350,189352,189354,189354,189354,189355,189356,189358,189359,189359,189367,189368,189368,189369,189369,189377,189377,189377,189377,189381,189381,189381,189381,189381,189381,189387,189387,189388,189389,189400,189404,189410,189410,189423,189428,189431,189435,189437,189437,189440,189440,189442,189445,189445,189446,189446,189452,189454,189455,189455,189457,189457,189461,189461,189461,189466,189466,189467,189470,189471,189471,189471,189472,189472,189473,189473,189473,189473,189473,189473,189474,189474,189476,189476,189477,189477,189484,189486,189487,189490,189491,189494,189494,189495,189495,189495,189498,189505,189510,189510,189512,189516,189516,189516,189516,189519,189519,189519,189519,189519,189520,189520,189522,189525,189526,189526,189530,189530,189530,189530,189530,189530,189534,189540,189540,189540,189543,189551,189551,189552,189557,189557,189557,189557,189557,189560,189560,189561,189561,189561,189561,189561,189563,189563,189564,189564,189564,189566,189586,189586,189593,189604,189605,189610,189611,189613,189616,189629,189633,189633,189640,189640,189640,189653,189653,189654,189654,189655,189658,189661,189661,189661,189661,189664,189664,189664,189665,189668,189668,189668,189668,189671,189674,189674,189675,189675,189675,189675,189675,189675,189676,189678,189680,189680,189682,189683,189683,189683,189683,189683,189683,189683,189685,189695,189696,189699,189704,189707,189708,189715,189715,189720,189724,189725,189726,189729,189730,189731,189731,189733,189735,189735,189737,189739,189740,189740,189740,189740,189740,189741,189741,189744,189746,189746,189746,189746,189747,189748,189750,189753,189753,189753,189753,189753,189753,189753,189753,189754,189754,189756,189756,189759,189761,189761,189761,189761,189761,189761,189761,189761,189761,189761,189762,189762,189762,189762,189762,189762,189764,189767,189770,189772,189772,189781,189781,189781,189781,189781,189781,189781,189781,189783,189787,189787,189787,189787,189787,189787,189787,189787,189787,189791,189791,189791,189793,189794,189794,189794,189796,189796,189796,189804,189808,189809,189809,189809,189819,189820,189821,189824,189824,189824,189824,189830,189830,189830,189830,189830,189830,189830,189831,189831,189833,189833,189833,189833,189833,189833,189834,189835,189837,189842,189847,189847,189854,189861,189862,189863,189865,189874,189875,189876,189876,189883,189885,189887,189888,189888,189889,189896,189899,189903,189904,189908,189909,189912,189919,189919,189919,189919,189925,189927,189927,189927,189927,189927,189927,189927,189927,189927,189928,189930,189930,189936,189943,189943,189943,189943,189943,189943,189948,189948,189948,189948,189948,189948,189949,189953,189953,189957,189957,189963,189964,189965,189965,189970,189971,189972,189972,189972,189976,189976,189976,189976,189976,189976,189976,189976,189976,189976,189976,189979,189979,189979,189979,189979,189981,189987,189987,189988,189990,189994,189996,190001,190001,190004,190007,190007,190007,190009,190009,190011,190013,190014,190014,190014,190014,190016,190016,190016,190023,190025,190029,190031,190037,190038,190041,190041,190041,190041,190041,190051,190053,190054,190055,190057,190057,190057,190057,190059,190059,190059,190059,190059,190067,190070,190073,190077,190078,190082,190083,190085,190086,190090,190090,190092,190093,190093,190093,190094,190094,190097,190097,190097,190098,190099,190100,190100,190100,190100,190100,190101,190101,190103,190103,190103,190103,190103,190105,190105,190110,190112,190112,190112,190115,190122,190123,190125,190127,190129,190131,190131,190134,190134,190135,190140,190141,190143,190143,190147,190150,190151,190152,190153,190156,190158,190164,190165,190165,190181,190181,190183,190183,190183,190193,190204,190204,190219,190220,190236,190237,190242,190242,190243,190249,190249,190253,190261,190277,190285,190285,190289,190290,190291,190292,190292,190296,190302,190305,190305,190305,190310,190310,190310,190310,190313,190314,190316,190321,190333,190333,190335,190335,190345,190347,190347,190348,190349,190350,190351,190355,190362,190365,190369,190369,190369,190370,190371,190371,190373,190375,190378,190390,190391,190391,190395,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190396,190399,190401,190410,190410,190410,190410,190410,190410,190432,190434,190439,190455,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190458,190463,190463,190463,190463,190463,190466,190469,190469,190472,190472,190477,190477,190481,190481,190486,190486,190488,190488,190489,190492,190493,190493,190497,190497,190499,190503,190504,190505,190505,190505,190508,190509,190512,190513,190515,190519,190520,190522,190522,190529,190530,190531,190531,190532,190532,190532,190532,190532,190535,190535,190539,190539,190539,190539,190543,190545,190548,190548,190548,190549,190555,190558,190573,190573,190573,190573,190574,190574,190576,190577,190578,190578,190580,190580,190580,190580,190581,190581,190587,190587,190587,190587,190589,190589,190591,190591,190592,190592,190592,190593,190593,190593,190593,190600,190600,190600,190600,190600,190600,190600,190600,190600,190603,190603,190603,190603,190603,190603,190603,190603,190604,190604,190604,190604,190604,190604,190604,190604,190604,190604,190604,190604,190604,190605,190605,190605,190605,190605,190605,190605,190605,190605,190606,190607,190607,190608,190608,190608,190608,190608,190609,190609,190612,190612,190612,190613,190613,190620,190620,190620,190620,190620,190620,190621,190621,190625,190626,190627,190627,190633,190636,190636,190636,190636,190636,190636,190636,190636,190636,190638,190639,190639,190639,190639,190639,190639,190640,190640,190644,190645,190645,190648,190650,190650,190651,190651,190653,190658,190658,190660,190660,190660,190661,190661,190664,190665,190667,190667,190667,190667,190667,190667,190667,190667,190669,190681,190681,190683,190685,190687,190687,190699,190699,190700,190700,190702,190704,190708,190711,190713,190714,190717,190717,190717,190719,190719,190719,190719,190719,190720,190722,190725,190725,190726,190735,190738,190741,190744,190748,190749,190750,190751,190751,190752,190752,190755,190755,190756,190757,190758,190760,190760,190760,190760,190760,190761,190761,190762,190762,190763,190764,190764,190764,190766,190766,190768,190771,190772,190772,190772,190772,190772,190772,190775,190776,190776,190776,190776,190776,190776,190779,190781,190784,190784,190786,190790,190790,190790,190790,190791,190791,190791,190791,190800,190804,190809,190810,190814,190815,190823,190823,190836,190836,190837,190842,190842,190844,190845,190846,190846,190846,190846,190847,190848,190848,190849,190849,190853,190856,190856,190856,190858,190862,190863,190864,190865,190865,190866,190867,190868,190870,190871,190871,190872,190873,190874,190875,190878,190880,190880,190881,190882,190883,190883,190883,190883,190883,190883,190883,190884,190885,190885,190885,190885,190885,190885,190886,190886,190887,190894,190895,190895,190895,190897,190897,190897,190902,190907,190910,190910,190911,190913,190913,190913,190913,190913,190914,190914,190923,190928,190928,190928,190932,190942,190945,190946,190948,190953,190956,190956,190962,190968,190969,190975,190975,190976,190977,190977,190978,190990,190990,190990,190990,190990,190993,190993,190994,190994,190995,190995,190996,190996,190996,190996,190996,191003,191003,191005,191005,191012,191012,191021,191021,191025,191027,191028,191041,191042,191046,191049,191052,191053,191053,191058,191062,191069,191072,191085,191085,191085,191085,191085,191085,191086,191086,191086,191086,191098,191106,191111,191111,191120,191122,191125,191125,191125,191139,191140,191142,191146,191150,191151,191151,191151,191151,191151,191155,191156,191157,191160,191161,191161,191161,191161,191162,191162,191162,191163,191163,191163,191164,191164,191164,191165,191165,191166,191166,191169,191169,191169,191169,191172,191173,191173,191175,191175,191175,191176,191177,191177,191177,191177,191186,191186,191186,191186,191186,191186,191186,191186,191189,191189,191191,191202,191203,191215,191216,191216,191225,191234,191235,191235,191236,191237,191240,191241,191241,191242,191257,191261,191264,191264,191264,191275,191276,191277,191280,191281,191281,191281,191282,191284,191288,191290,191295,191302,191308,191308,191308,191309,191310,191313,191313,191313,191313,191316,191316,191316,191316,191316,191323,191323,191333,191333,191333,191333,191333,191333,191336,191340,191342,191344,191351,191351,191352,191352,191355,191357,191359,191365,191368,191370,191370,191372,191372,191375,191379,191379,191379,191389,191390,191390,191390,191392,191393,191401,191402,191409,191414,191419,191419,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191421,191422,191422,191422,191422,191422,191422,191422,191423,191423,191425,191425,191425,191428,191428,191428,191428,191429,191429,191429,191429,191430,191431,191431,191431,191433,191434,191436,191437,191437,191437,191438,191438,191440,191440,191440,191440,191440,191440,191440,191440,191440,191441,191443,191443,191443,191443,191445,191446,191446,191447,191449,191449,191449,191450,191450,191453,191453,191453,191453,191453,191453,191454,191454,191454,191456,191456,191459,191460,191461,191461,191461,191462,191466,191466,191466,191467,191467,191467,191468,191469,191469,191471,191471,191471,191472,191472,191474,191477,191479,191479,191479,191479,191479,191479,191479,191479,191479,191479,191481,191481,191481,191481,191481,191482,191482,191484,191484,191486,191488,191489,191489,191490,191490,191491,191491,191491,191491,191491,191491,191491,191491,191491,191495,191495,191495,191496,191496,191496,191496,191497,191497,191497,191497,191497,191497,191505,191506,191506,191506,191506,191506,191507,191507,191507,191507,191507,191511,191511,191512,191512,191513,191513,191513,191513,191514,191515,191515,191517,191521,191521,191525,191525,191525,191528,191530,191532,191532,191532,191532,191533,191533,191534,191536,191536,191536,191536,191536,191536,191536,191539,191542,191542,191542,191545,191545,191545,191545,191545,191546,191547,191548,191548,191549,191554,191554,191554,191556,191559,191559,191564,191566,191568,191572,191572,191572,191573,191574,191574,191574,191574,191574,191575,191576,191576,191577,191577,191578,191579,191586,191587,191587,191590,191590,191590,191596,191598,191598,191599,191599,191599,191599,191599,191599,191602,191603,191603,191605,191607,191609,191609,191610,191613,191613,191613,191619,191619,191623,191623,191627,191630,191631,191638,191638,191638,191638,191643,191648,191649,191649,191649,191650,191650,191650,191653,191654,191656,191657,191660,191661,191662,191662,191664,191667,191671,191674,191674,191674,191675,191678,191678,191678,191680,191680,191680,191680,191680,191680,191682,191685,191688,191689,191689,191689,191690,191690,191694,191695,191701,191701,191702,191703,191703,191703,191703,191703,191705,191707,191707,191707,191710,191712,191712,191712,191713,191716,191716,191719,191721,191721,191721,191730,191732,191735,191739,191740,191741,191742,191743,191749,191750,191751,191751,191756,191765,191766,191766,191766,191768,191770,191770,191777,191783,191786,191791,191806,191807,191807,191817,191820,191821,191829,191831,191835,191842,191847,191847,191850,191852,191853,191857,191866,191878,191878,191878,191878,191880,191880,191886,191886,191886,191886,191886,191886,191886,191892,191908,191912,191920,191920,191920,191920,191920,191920,191920,191920,191920,191920,191920,191920,191920,191921,191922,191923,191925,191926,191926,191926,191926,191926,191927,191927,191928,191931,191932,191932,191932,191932,191932,191932,191932,191933,191933,191933,191933,191933,191933,191933,191933,191934,191934,191943,191944,191944,191944,191944,191944,191947,191951,191959,191963,191971,191973,191973,191974,191974,191974,191976,191976,191976,191976,191976,191977,191977,191977,191978,191979,191979,191979,191981,191984,191986,191987,191987,191987,191991,191993,191995,191997,192010,192016,192016,192016,192016,192017,192028,192030,192034,192038,192038,192040,192043,192043,192044,192046,192054,192054,192061,192061,192061,192061,192061,192063,192069,192071,192078,192081,192081,192082,192082,192085,192086,192086,192086,192088,192098,192098,192101,192102,192102,192106,192109,192114,192121,192121,192133,192134,192144,192144,192144,192145,192165,192165,192165,192165,192167,192169,192173,192175,192178,192180,192185,192193,192200,192200,192200,192204,192210,192211,192211,192216,192220,192220,192223,192230,192231,192235,192236,192236,192246,192246,192246,192249,192249,192250,192254,192256,192266,192267,192268,192268,192282,192282,192282,192282,192282,192282,192282,192284,192284,192284,192284,192287,192287,192287,192290,192293,192294,192298,192299,192301,192303,192304,192308,192312,192312,192312,192312,192312,192312,192313,192313,192313,192314,192314,192314,192314,192314,192314,192316,192316,192323,192330,192331,192342,192350,192357,192357,192374,192382,192385,192385,192389,192392,192392,192393,192398,192401,192401,192401,192401,192401,192401,192404,192415,192418,192425,192427,192436,192446,192448,192448,192448,192451,192454,192465,192472,192476,192486,192486,192486,192486,192502,192502,192511,192511,192514,192520,192523,192523,192523,192536,192536,192536,192541,192541,192541,192550,192553,192553,192553,192553,192553,192553,192553,192555,192560,192560,192560,192563,192563,192563,192563,192563,192563,192563,192563,192563,192563,192567,192577,192577,192577,192582,192597,192598,192598,192598,192598,192605,192617,192620,192623,192638,192657,192662,192665,192665,192667,192667,192668,192681,192689,192689,192690,192691,192694,192698,192703,192710,192714,192718,192719,192720,192721,192729,192729,192729,192729,192729,192729,192729,192729,192729,192729,192737,192742,192743,192745,192747,192749,192749,192749,192751,192753,192753,192753,192753,192759,192759,192759,192759,192765,192780,192786,192790,192797,192797,192799,192811,192811,192816,192827,192830,192830,192830,192830,192830,192830,192830,192832,192833,192833,192834,192834,192834,192834,192837,192850,192851,192852,192852,192853,192853,192860,192860,192860,192862,192884,192893,192893,192898,192905,192907,192911,192912,192925,192929,192930,192936,192947,192950,192950,192950,192950,192952,192953,192955,192956,192965,192966,192967,192981,192988,192988,192993,193001,193004,193007,193009,193009,193009,193009,193011,193012,193012,193019,193021,193023,193023,193024,193024,193024,193029,193037,193041,193043,193043,193049,193052,193054,193054,193055,193067,193067,193067,193071,193077,193082,193087,193089,193091,193094,193096,193096,193113,193114,193120,193129,193133,193139,193139,193143,193145,193145,193145,193148,193162,193170,193170,193181,193181,193187,193187,193187,193187,193187,193187,193187,193187,193187,193187,193189,193191,193191,193200,193201,193201,193201,193201,193201,193215,193215,193217,193221,193223,193223,193230,193243,193243,193251,193256,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193265,193267,193267,193271,193286,193286,193294,193296,193299,193308,193312,193312,193312,193323,193327,193327,193329,193331,193333,193344,193349,193367,193367,193367,193370,193370,193373,193379,193382,193383,193383,193395,193395,193396,193396,193396,193396,193396,193396,193396,193396,193403,193407,193412,193412,193417,193420,193426,193426,193428,193445,193445,193452,193452,193468,193489,193489,193502,193502,193502,193503,193503,193505,193505,193509,193509,193514,193514,193529,193530,193531,193538,193541,193542,193547,193547,193547,193553,193555,193555,193591,193599,193599,193599,193599,193599,193601,193601,193601,193603,193606,193606,193607,193607,193607,193607,193610,193624,193625,193625,193629,193640,193640,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193659,193660,193660,193660,193660,193663,193663,193668,193670,193670,193674,193677,193677,193677,193684,193699,193709,193715,193718,193725,193725,193725,193725,193725,193725,193735,193735,193738,193744,193747,193747,193747,193749,193750,193750,193750,193752,193752,193755,193757,193770,193770,193770,193770,193770,193770,193770,193770,193770,193770,193770,193771,193772,193775,193776,193776,193776,193777,193777,193777,193778,193778,193779,193779,193782,193787,193787,193789,193792,193795,193797,193797,193797,193799,193799,193811,193814,193814,193814,193814,193816,193816,193817,193818,193818,193828,193828,193828,193828,193828,193832,193833,193833,193836,193836,193842,193872,193877,193878,193880,193880,193881,193881,193882,193887,193887,193887,193887,193887,193887,193887,193887,193888,193888,193888,193888,193888,193888,193888,193888,193894,193896,193898,193900,193903,193903,193903,193907,193911,193915,193922,193927,193933,193936,193940,193940,193941,193957,193958,193962,193973,193975,193981,193981,193985,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193988,193991,193992,193993,193994,193998,194003,194007,194007,194007,194010,194010,194012,194013,194014,194014,194015,194015,194015,194015,194016,194019,194019,194019,194022,194025,194025,194030,194032,194033,194033,194035,194036,194036,194036,194040,194040,194040,194040,194040,194040,194045,194046,194046,194048,194051,194051,194056,194059,194060,194073,194074,194074,194074,194084,194087,194089,194089,194089,194089,194090,194091,194093,194095,194095,194095,194100,194100,194106,194108,194108,194108,194110,194117,194119,194119,194119,194131,194131,194131,194131,194131,194133,194137,194146,194146,194147,194153,194153,194154,194155,194157,194157,194157,194164,194164,194168,194168,194168,194169,194180,194191,194207,194213,194216,194221,194221,194221,194223,194226,194226,194226,194231,194233,194236,194240,194240,194244,194244,194245,194245,194252,194263,194267,194271,194275,194281,194283,194283,194286,194286,194289,194289,194290,194298,194299,194303,194305,194307,194308,194311,194324,194326,194330,194331,194338,194347,194352,194353,194353,194354,194360,194363,194365,194367,194370,194378,194384,194397,194397,194402,194403,194406,194407,194411,194412,194412,194412,194418,194418,194426,194438,194451,194456,194467,194468,194472,194476,194476,194500,194500,194500,194500,194500,194500,194500,194502,194502,194502,194503,194503,194503,194503,194503,194503,194504,194505,194505,194506,194506,194515,194522,194523,194543,194545,194545,194545,194556,194564,194564,194572,194583,194586,194592,194595,194609,194623,194623,194625,194625,194625,194628,194637,194647,194647,194647,194650,194653,194658,194661,194665,194667,194671,194671,194671,194671,194671,194678,194681,194684,194684,194684,194685,194686,194688,194689,194690,194690,194691,194697,194700,194701,194715,194727,194733,194734,194737,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194739,194742,194746,194750,194752,194753,194753,194754,194758,194760,194762,194762,194762,194762,194762,194762,194762,194762,194762,194766,194767,194767,194767,194768,194770,194771,194771,194771,194781,194781,194781,194794,194802,194803,194804,194804,194807,194814,194814,194816,194820,194832,194832,194837,194844,194851,194858,194868,194868,194868,194869,194870,194876,194876,194882,194885,194896,194900,194902,194903,194908,194908,194910,194914,194914,194920,194924,194927,194929,194938,194946,194946,194948,194951,194953,194954,194954,194960,194963,194964,194969,194969,194969,194972,194977,194983,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194988,194995,194995,194995,195005,195015,195026,195026,195027,195028,195028,195029,195029,195030,195033,195033,195033,195033,195033,195044,195047,195049,195052,195052,195052,195053,195055,195056,195058,195059,195059,195059,195061,195061,195062,195064,195072,195082,195084,195084,195084,195084,195084,195084,195084,195084,195084,195093,195101,195107,195107,195112,195118,195122,195122,195126,195126,195133,195146,195147,195158,195158,195158,195158,195171,195172,195174,195178,195179,195179,195195,195198,195202,195207,195213,195217,195217,195217,195217,195222,195229,195242,195250,195256,195258,195258,195261,195261,195271,195274,195277,195277,195277,195278,195278,195278,195288,195300,195300,195300,195302,195309,195309,195311,195314,195314,195314,195316,195331,195332,195333,195342,195344,195345,195349,195353,195354,195357,195370,195376,195377,195378,195388,195388,195388,195389,195394,195394,195396,195396,195396,195400,195402,195402,195415,195416,195416,195416,195422,195428,195432,195435,195444,195444,195445,195456,195461,195464,195464,195467,195468,195468,195469,195469,195469,195470,195472,195473,195474,195476,195476,195476,195476,195476,195477,195483,195485,195489,195493,195498,195503,195504,195506,195506,195516,195516,195516,195519,195526,195527,195547,195549,195555,195555,195555,195575,195576,195577,195580,195580,195581,195581,195581,195581,195581,195581,195582,195584,195584,195584,195585,195586,195593,195594,195594,195594,195596,195596,195597,195598,195605,195609,195612,195613,195613,195613,195613,195613,195615,195618,195618,195622,195623,195629,195629,195632,195638,195640,195641,195643,195650,195650,195650,195650,195653,195655,195655,195656,195660,195665,195665,195667,195682,195682,195682,195682,195682,195682,195684,195686,195688,195688,195688,195688,195688,195688,195688,195688,195688,195688,195688,195688,195688,195688,195689,195690,195692,195693,195694,195695,195698,195698,195698,195703,195707,195707,195709,195717,195718,195727,195737,195737,195737,195757,195765,195771,195775,195786,195787,195798,195803,195803,195811,195825,195829,195833,195837,195844,195849,195861,195865,195892,195896,195898,195899,195912,195923,195924,195925,195938,195938,195938,195938,195938,195938,195940,195944,195947,195947,195947,195950,195961,195964,195964,195965,195966,195970,195971,195971,195973,195976,195977,195978,195981,195981,195984,195986,195987,195998,195998,196000,196000,196000,196001,196002,196012,196017,196017,196024,196026,196027,196030,196030,196042,196050,196051,196055,196073,196073,196076,196084,196085,196085,196104,196108,196109,196116,196123,196128,196136,196136,196136,196136,196141,196145,196145,196148,196148,196149,196150,196151,196164,196178,196191,196193,196193,196193,196194,196194,196196,196196,196196,196200,196201,196205,196205,196209,196210,196210,196210,196216,196217,196218,196221,196221,196222,196222,196222,196232,196233,196234,196234,196235,196238,196238,196239,196239,196239,196239,196239,196241,196241,196241,196242,196242,196242,196242,196243,196244,196244,196244,196244,196244,196247,196247,196247,196248,196250,196250,196250,196251,196251,196251,196251,196251,196252,196252,196252,196252,196252,196253,196253,196258,196258,196259,196260,196261,196261,196261,196261,196262,196263,196263,196266,196267,196268,196269,196270,196270,196271,196271,196271,196272,196273,196274,196275,196275,196275,196277,196278,196279,196279,196279,196281,196282,196282,196282,196282,196283,196283,196283,196283,196283,196286,196286,196286,196286,196288,196288,196288,196288,196288,196288,196290,196292,196292,196292,196292,196292,196292,196293,196293,196293,196293,196294,196294,196294,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196295,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196296,196297,196297,196297,196297,196297,196297,196297,196297,196297,196298,196298,196298,196298,196298,196298,196298,196299,196299,196299,196300,196300,196300,196300,196302,196302,196302,196302,196302,196302,196302,196302,196302,196303,196308,196308,196308,196308,196308,196308,196310,196310,196310,196311,196312,196312,196312,196312,196312,196312,196312,196312,196312,196312,196312,196312,196312,196312,196312,196313,196313,196313,196314,196315,196315,196315,196315,196315,196315,196315,196316,196316,196317,196317,196317,196317,196317,196317,196317,196317,196317,196317,196319,196319,196319,196319,196319,196319,196321,196321,196321,196321,196321,196321,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196322,196323,196323,196323,196323,196323,196323,196325,196325,196327,196327,196327,196327,196327,196329,196329,196329,196329,196329,196329,196334,196334,196334,196334,196335,196335,196337,196337,196337,196338,196339,196339,196339,196339,196339,196339,196339,196342,196343,196343,196344,196348,196348,196348,196352,196352,196353,196357,196359,196360,196363,196369,196371,196371,196372,196372,196376,196377,196378,196378,196381,196381,196384,196384,196384,196385,196387,196387,196387,196389,196390,196390,196390,196390,196392,196394,196395,196395,196395,196395,196395,196395,196395,196396,196397,196398,196400,196401,196401,196414,196414,196414,196414,196417,196418,196418,196418,196418,196418,196418,196419,196423,196425,196425,196425,196425,196425,196427,196427,196427,196427,196427,196427,196427,196427,196427,196427,196427,196428,196428,196430,196430,196431,196431,196431,196431,196431,196431,196431,196431,196432,196432,196432,196433,196433,196433,196433,196433,196433,196433,196433,196435,196435,196435,196436,196437,196438,196438,196438,196439,196439,196442,196442,196443,196443,196445,196448,196448,196450,196450,196451,196451,196453,196453,196453,196453,196463,196468,196477,196480,196480,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196481,196483,196483,196483,196487,196487,196489,196490,196490,196493,196494,196494,196494,196495,196495,196495,196497,196498,196500,196501,196501,196501,196510,196510,196510,196510,196510,196511,196513,196515,196515,196515,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196517,196518,196518,196518,196519,196522,196525,196525,196525,196525,196526,196526,196526,196527,196527,196527,196527,196527,196527,196527,196534,196543,196543,196543,196543,196543,196543,196543,196544,196544,196547,196547,196550,196551,196551,196552,196553,196555,196555,196555,196555,196557,196558,196559,196559,196559,196560,196563,196563,196563,196566,196566,196566,196567,196567,196567,196568,196575,196577,196578,196578,196578,196588,196593,196593,196598,196598,196600,196606,196609,196610,196614,196614,196614,196614,196614,196614,196614,196614,196614,196614,196614,196617,196617,196620,196621,196621,196625,196626,196628,196631,196632,196632,196634,196642,196642,196643,196645,196650,196661,196662,196663,196664,196666,196667,196669,196670,196670,196687,196690,196693,196693,196693,196693,196693,196693,196694,196697,196700,196700,196705,196707,196710,196718,196719,196719,196719,196720,196721,196722,196724,196729,196730,196731,196732,196732,196732,196734,196734,196738,196741,196744,196744,196745,196746,196748,196752,196752,196752,196752,196754,196755,196755,196755,196755,196757,196757,196771,196779,196783,196786,196786,196786,196786,196786,196790,196790,196800,196806,196808,196811,196812,196816,196818,196828,196834,196834,196834,196834,196838,196844,196846,196849,196850,196852,196853,196858,196858,196875,196875,196876,196876,196876,196886,196888,196893,196893,196897,196913,196914,196914,196914,196916,196916,196916,196938,196939,196957,196958,196960,196963,196968,196969,196969,196985,196988,196989,196990,196991,196991,196992,196992,196992,196995,196995,196995,196995,196995,196998,196999,197002,197006,197008,197008,197008,197008,197008,197008,197008,197008,197008,197008,197009,197009,197014,197015,197024,197024,197024,197024,197032,197037,197041,197048,197048,197053,197054,197054,197054,197054,197057,197058,197065,197065,197065,197067,197067,197068,197073,197073,197074,197077,197077,197079,197080,197082,197092,197099,197104,197105,197112,197112,197112,197126,197135,197136,197146,197146,197147,197157,197158,197158,197158,197158,197158,197158,197160,197166,197167,197167,197186,197186,197186,197186,197189,197191,197193,197194,197197,197199,197199,197202,197203,197207,197207,197211,197237,197245,197248,197249,197259,197269,197269,197269,197282,197295,197301,197301,197317,197317,197326,197336,197336,197337,197340,197350,197350,197350,197350,197351,197351,197351,197360,197364,197364,197365,197373,197375,197375,197375,197376,197382,197383,197383,197383,197383,197383,197383,197383,197383,197383,197383,197383,197383,197383,197383,197383,197387,197390,197410,197415,197417,197417,197421,197424,197427,197427,197427,197427,197431,197431,197431,197431,197432,197436,197436,197438,197439,197440,197443,197443,197443,197444,197448,197452,197453,197455,197455,197455,197455,197457,197465,197471,197471,197475,197476,197476,197481,197481,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197482,197484,197485,197485,197489,197490,197491,197491,197493,197501,197506,197509,197513,197513,197513,197513,197513,197513,197521,197521,197523,197525,197533,197535,197535,197535,197535,197535,197535,197535,197538,197540,197541,197553,197556,197563,197563,197563,197566,197566,197570,197570,197571,197576,197576,197576,197578,197584,197592,197592,197592,197593,197593,197593,197593,197593,197595,197598,197600,197605,197613,197613,197613,197613,197622,197636,197636,197641,197641,197641,197641,197641,197641,197641,197641,197641,197641,197641,197646,197649,197650,197651,197652,197652,197652,197654,197654,197654,197654,197655,197658,197662,197662,197662,197664,197665,197666,197667,197667,197667,197667,197667,197667,197667,197667,197667,197669,197670,197674,197674,197674,197676,197676,197698,197704,197714,197714,197715,197715,197715,197715,197715,197715,197715,197715,197719,197719,197722,197727,197746,197753,197764,197775,197781,197789,197790,197793,197793,197793,197793,197793,197793,197793,197793,197797,197800,197801,197801,197801,197801,197801,197802,197802,197807,197811,197811,197811,197811,197811,197815,197815,197815,197817,197824,197824,197824,197824,197824,197824,197824,197824,197825,197827,197827,197827,197827,197827,197827,197828,197829,197835,197858,197861,197869,197872,197872,197872,197877,197880,197882,197882,197882,197884,197884,197885,197885,197886,197889,197889,197890,197893,197901,197904,197907,197907,197907,197911,197912,197912,197912,197914,197914,197919,197922,197923,197923,197924,197924,197924,197924,197928,197928,197933,197938,197938,197941,197944,197956,197956,197956,197959,197963,197965,197972,197973,197973,197981,197994,198000,198000,198006,198006,198007,198014,198019,198019,198023,198026,198027,198032,198034,198034,198034,198034,198034,198034,198035,198035,198037,198038,198038,198038,198038,198039,198039,198039,198039,198039,198039,198039,198039,198039,198041,198041,198041,198041,198041,198041,198043,198043,198043,198044,198048,198048,198049,198049,198049,198049,198049,198054,198056,198057,198066,198074,198077,198085,198085,198085,198085,198087,198089,198091,198097,198107,198111,198111,198111,198111,198112,198128,198130,198131,198136,198151,198159,198162,198170,198170,198173,198175,198175,198178,198178,198178,198178,198190,198190,198192,198202,198202,198204,198215,198218,198218,198220,198220,198220,198223,198223,198223,198225,198227,198227,198231,198233,198235,198236,198236,198240,198240,198242,198244,198244,198244,198246,198248,198249,198249,198251,198257,198271,198271,198271,198271,198276,198282,198282,198283,198284,198285,198286,198286,198287,198287,198288,198292,198295,198295,198297,198297,198300,198303,198304,198305,198307,198320,198324,198324,198337,198338,198339,198339,198342,198342,198348,198348,198349,198357,198363,198368,198370,198371,198373,198374,198379,198379,198379,198379,198385,198389,198389,198391,198391,198391,198393,198393,198393,198394,198394,198394,198397,198399,198399,198399,198403,198403,198403,198403,198403,198403,198403,198406,198406,198407,198407,198407,198407,198407,198409,198409,198409,198409,198409,198410,198412,198412,198412,198412,198412,198412,198412,198412,198413,198413,198413,198413,198414,198414,198416,198416,198417,198417,198417,198417,198417,198417,198417,198422,198422,198424,198426,198435,198435,198438,198444,198446,198446,198449,198456,198462,198462,198469,198471,198472,198472,198473,198473,198473,198473,198488,198498,198499,198507,198507,198507,198507,198507,198510,198510,198510,198510,198510,198514,198514,198515,198515,198515,198515,198518,198519,198523,198524,198524,198524,198530,198530,198530,198530,198533,198534,198534,198534,198534,198534,198534,198534,198535,198540,198545,198552,198555,198557,198562,198565,198565,198572,198572,198572,198593,198594,198599,198608,198609,198614,198614,198615,198621,198621,198622,198622,198631,198642,198642,198644,198645,198646,198647,198648,198648,198651,198653,198657,198663,198663,198663,198669,198669,198674,198674,198674,198674,198674,198674,198677,198677,198677,198678,198681,198681,198681,198682,198685,198692,198692,198692,198692,198692,198698,198699,198699,198699,198699,198699,198699,198701,198701,198701,198705,198705,198705,198707,198714,198715,198715,198716,198719,198719,198722,198724,198730,198731,198743,198749,198750,198750,198750,198775,198780,198781,198783,198783,198798,198798,198798,198800,198801,198801,198801,198801,198801,198803,198803,198811,198813,198821,198825,198825,198825,198825,198826,198826,198827,198828,198832,198832,198832,198832,198832,198832,198832,198832,198832,198832,198832,198833,198834,198834,198835,198835,198850,198850,198856,198857,198858,198858,198858,198862,198862,198864,198864,198867,198868,198870,198874,198874,198875,198877,198877,198877,198877,198878,198882,198886,198896,198898,198909,198909,198914,198914,198914,198914,198914,198914,198914,198914,198914,198921,198922,198922,198922,198922,198923,198926,198930,198930,198934,198942,198942,198946,198956,198956,198957,198958,198959,198960,198960,198960,198960,198960,198960,198960,198960,198960,198960,198961,198964,198967,198967,198968,198974,198975,198976,198985,198997,198997,198997,199014,199029,199032,199043,199043,199043,199043,199047,199047,199053,199053,199056,199056,199058,199061,199065,199069,199070,199070,199084,199088,199089,199089,199089,199091,199091,199091,199094,199098,199099,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199100,199103,199104,199104,199107,199107,199107,199108,199109,199111,199117,199119,199119,199119,199121,199122,199123,199124,199126,199127,199133,199134,199135,199147,199148,199156,199158,199166,199166,199173,199177,199180,199181,199181,199187,199190,199193,199194,199197,199200,199209,199213,199217,199223,199224,199226,199231,199239,199239,199245,199245,199245,199252,199254,199261,199261,199261,199261,199261,199261,199261,199261,199261,199261,199264,199264,199264,199273,199276,199277,199280,199284,199321,199323,199337,199343,199343,199343,199343,199344,199346,199346,199346,199346,199346,199346,199346,199347,199349,199350,199351,199352,199353,199353,199353,199353,199354,199356,199358,199360,199366,199371,199374,199389,199389,199392,199392,199396,199397,199400,199403,199412,199412,199415,199416,199418,199419,199419,199419,199422,199423,199425,199425,199436,199447,199447,199456,199470,199473,199478,199484,199487,199487,199487,199493,199498,199501,199508,199510,199510,199510,199510,199514,199531,199531,199531,199531,199531,199531,199531,199531,199531,199531,199538,199540,199543,199550,199551,199552,199552,199552,199552,199553,199553,199553,199553,199554,199554,199558,199558,199558,199558,199563,199575,199576,199579,199579,199579,199579,199587,199587,199591,199594,199594,199609,199609,199613,199614,199614,199615,199616,199618,199618,199618,199619,199619,199620,199620,199620,199620,199620,199620,199621,199621,199624,199625,199625,199628,199628,199629,199629,199630,199644,199644,199645,199646,199646,199653,199654,199657,199658,199658,199659,199659,199659,199659,199659,199662,199662,199662,199662,199664,199667,199670,199673,199673,199677,199681,199681,199682,199682,199684,199686,199686,199728,199729,199729,199730,199730,199731,199731,199731,199738,199738,199738,199739,199739,199740,199742,199744,199744,199744,199744,199746,199752,199754,199756,199757,199757,199759,199759,199759,199759,199759,199764,199765,199786,199786,199786,199789,199789,199790,199797,199799,199799,199800,199800,199801,199801,199802,199804,199806,199813,199814,199815,199815,199815,199815,199815,199815,199817,199817,199818,199820,199820,199822,199822,199826,199833,199833,199833,199836,199842,199850,199852,199852,199852,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199857,199860,199860,199865,199865,199866,199871,199874,199876,199876,199879,199881,199881,199883,199883,199883,199883,199883,199883,199883,199888,199889,199889,199890,199891,199895,199899,199899,199900,199904,199904,199904,199905,199905,199906,199907,199909,199910,199912,199915,199916,199918,199921,199921,199923,199924,199924,199924,199924,199924,199926,199927,199929,199929,199931,199931,199932,199937,199939,199939,199940,199940,199940,199940,199941,199941,199941,199941,199941,199941,199944,199944,199944,199944,199944,199948,199948,199948,199948,199949,199949,199950,199952,199952,199952,199952,199953,199954,199955,199958,199961,199962,199964,199967,199967,199967,199967,199967,199967,199967,199967,199967,199967,199967,199968,199968,199968,199970,199971,199971,199971,199971,199971,199973,199973,199973,199975,199975,199975,199975,199977,199977,199980,199980,199983,199983,199983,199983,199984,199985,199988,199989,199992,199994,199995,199998,199998,199998,200000,200000,200003,200004,200004,200004,200005,200005,200006,200008,200008,200008,200009,200009,200012,200016,200017,200020,200021,200021,200021,200026,200027,200030,200032,200033,200034,200040,200042,200042,200043,200050,200056,200057,200058,200064,200064,200066,200066,200066,200066,200066,200066,200066,200074,200076,200077,200079,200079,200079,200079,200079,200081,200081,200083,200083,200084,200085,200087,200087,200087,200087,200088,200090,200090,200092,200092,200092,200092,200096,200097,200112,200113,200117,200117,200117,200117,200117,200117,200117,200117,200117,200122,200125,200125,200129,200129,200129,200129,200129,200129,200129,200131,200131,200133,200134,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200141,200142,200150,200150,200150,200150,200153,200153,200154,200155,200156,200157,200160,200160,200162,200165,200166,200167,200167,200168,200169,200171,200181,200182,200184,200186,200191,200192,200192,200200,200200,200200,200200,200200,200202,200202,200203,200203,200203,200206,200208,200209,200209,200210,200212,200212,200218,200219,200225,200228,200231,200234,200239,200244,200246,200246,200246,200250,200250,200250,200250,200251,200255,200255,200256,200256,200256,200257,200257,200257,200258,200259,200259,200260,200264,200264,200265,200265,200265,200265,200267,200267,200267,200272,200272,200273,200292,200299,200301,200303,200303,200303,200304,200304,200304,200305,200305,200305,200305,200305,200305,200305,200307,200307,200307,200307,200307,200307,200308,200317,200323,200325,200327,200328,200329,200329,200329,200334,200334,200337,200341,200342,200342,200348,200352,200352,200352,200352,200352,200352,200353,200353,200355,200356,200356,200356,200361,200363,200363,200363,200364,200364,200364,200364,200366,200366,200366,200366,200366,200367,200368,200371,200371,200371,200374,200377,200384,200385,200385,200392,200392,200408,200408,200408,200408,200412,200414,200425,200438,200441,200443,200451,200457,200457,200457,200458,200458,200459,200459,200460,200461,200461,200464,200466,200471,200472,200474,200479,200480,200481,200483,200484,200484,200485,200495,200496,200496,200496,200496,200496,200503,200504,200508,200508,200511,200512,200513,200515,200517,200517,200517,200517,200517,200517,200519,200521,200521,200521,200524,200525,200526,200526,200529,200531,200535,200535,200536,200537,200538,200538,200538,200538,200538,200539,200539,200539,200542,200542,200545,200547,200547,200548,200548,200548,200548,200548,200551,200552,200552,200552,200552,200552,200555,200557,200557,200559,200560,200560,200561,200563,200563,200569,200572,200578,200578,200578,200578,200581,200587,200589,200589,200594,200594,200596,200597,200600,200602,200604,200610,200611,200611,200611,200612,200612,200616,200618,200618,200626,200628,200630,200630,200630,200630,200630,200632,200639,200640,200648,200649,200658,200658,200670,200677,200694,200694,200700,200701,200708,200708,200708,200720,200720,200724,200732,200732,200732,200744,200745,200746,200756,200758,200758,200764,200766,200771,200773,200773,200778,200780,200782,200782,200782,200782,200782,200784,200784,200784,200790,200800,200801,200801,200804,200809,200809,200809,200812,200816,200824,200830,200832,200833,200839,200839,200850,200851,200854,200862,200866,200867,200867,200872,200876,200881,200892,200892,200892,200892,200896,200896,200901,200904,200904,200905,200905,200905,200907,200909,200916,200917,200919,200919,200920,200927,200927,200931,200939,200941,200941,200945,200945,200946,200960,200960,200962,200964,200967,200967,200972,200978,200978,200981,200986,200993,201019,201020,201020,201020,201021,201025,201031,201032,201032,201032,201034,201036,201037,201049,201050,201051,201051,201051,201051,201051,201051,201051,201063,201064,201065,201065,201072,201073,201076,201076,201076,201078,201078,201083,201087,201090,201090,201096,201097,201101,201101,201102,201103,201115,201115,201115,201115,201115,201115,201115,201119,201122,201122,201126,201138,201151,201152,201153,201153,201160,201160,201163,201167,201173,201191,201202,201202,201211,201211,201211,201211,201211,201211,201211,201211,201211,201224,201231,201239,201242,201242,201249,201252,201252,201252,201253,201254,201255,201257,201263,201269,201270,201292,201292,201307,201307,201307,201307,201307,201307,201308,201312,201322,201322,201326,201326,201326,201326,201326,201326,201326,201326,201326,201326,201326,201326,201333,201341,201351,201358,201362,201363,201366,201366,201370,201372,201377,201381,201383,201386,201386,201391,201399,201404,201404,201404,201405,201407,201411,201415,201421,201421,201429,201429,201437,201437,201437,201437,201437,201437,201437,201437,201437,201437,201437,201437,201437,201437,201446,201446,201446,201449,201453,201453,201455,201464,201466,201467,201467,201471,201471,201471,201471,201474,201477,201477,201478,201478,201479,201494,201494,201505,201515,201525,201526,201526,201527,201529,201529,201530,201530,201531,201533,201553,201555,201557,201564,201595,201595,201607,201621,201626,201626,201632,201632,201633,201634,201634,201634,201635,201635,201636,201638,201638,201639,201639,201641,201649,201650,201651,201652,201652,201655,201664,201668,201668,201668,201671,201674,201675,201675,201680,201680,201680,201680,201683,201683,201688,201688,201689,201695,201696,201696,201704,201713,201715,201715,201715,201715,201721,201722,201723,201726,201733,201736,201748,201748,201748,201748,201748,201748,201748,201748,201749,201753,201758,201762,201762,201770,201771,201775,201775,201783,201783,201783,201783,201784,201785,201785,201788,201790,201791,201794,201794,201794,201794,201797,201802,201802,201802,201810,201810,201811,201814,201816,201816,201816,201819,201822,201828,201828,201828,201833,201834,201845,201845,201847,201850,201850,201850,201852,201853,201855,201855,201855,201861,201867,201871,201888,201890,201891,201894,201894,201913,201914,201914,201914,201914,201914,201914,201914,201916,201918,201923,201923,201923,201925,201942,201944,201947,201950,201950,201953,201954,201956,201956,201956,201959,201962,201962,201978,201980,201984,201984,201989,201995,201995,202000,202013,202017,202023,202025,202028,202037,202050,202051,202054,202054,202056,202056,202058,202077,202079,202083,202084,202088,202092,202093,202099,202108,202120,202128,202128,202139,202141,202146,202146,202148,202150,202153,202155,202158,202160,202176,202176,202176,202176,202178,202178,202179,202180,202181,202189,202192,202197,202198,202199,202202,202206,202206,202207,202207,202210,202210,202210,202212,202212,202213,202214,202220,202220,202223,202230,202230,202230,202230,202230,202230,202230,202236,202236,202236,202237,202237,202237,202237,202243,202245,202246,202249,202252,202253,202253,202255,202256,202257,202261,202268,202268,202280,202280,202281,202281,202281,202281,202281,202290,202290,202296,202313,202324,202332,202337,202355,202355,202355,202369,202374,202378,202391,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202396,202409,202410,202427,202429,202430,202431,202443,202443,202451,202451,202451,202451,202453,202454,202455,202455,202455,202455,202456,202456,202457,202457,202459,202459,202460,202460,202461,202461,202461,202462,202467,202467,202467,202471,202475,202480,202480,202482,202483,202483,202503,202504,202506,202508,202526,202526,202531,202538,202538,202538,202538,202538,202554,202559,202559,202564,202565,202574,202575,202576,202578,202581,202581,202584,202586,202586,202586,202586,202586,202586,202586,202589,202592,202599,202600,202601,202610,202610,202610,202611,202611,202612,202624,202624,202624,202624,202629,202630,202630,202633,202633,202633,202633,202633,202633,202633,202634,202634,202634,202636,202644,202651,202655,202655,202655,202676,202676,202681,202681,202681,202681,202686,202689,202691,202697,202700,202700,202700,202700,202700,202703,202708,202708,202715,202729,202732,202734,202734,202736,202737,202738,202738,202738,202739,202739,202739,202739,202739,202740,202740,202740,202740,202741,202742,202742,202743,202744,202744,202745,202746,202746,202746,202746,202746,202746,202746,202746,202747,202747,202747,202747,202747,202751,202751,202751,202751,202752,202752,202752,202752,202752,202755,202757,202761,202762,202764,202767,202769,202777,202777,202780,202780,202787,202789,202789,202795,202795,202810,202813,202813,202813,202813,202813,202815,202827,202830,202832,202832,202832,202848,202848,202848,202850,202850,202850,202850,202850,202850,202850,202850,202850,202850,202850,202850,202850,202852,202852,202852,202853,202853,202853,202853,202853,202853,202854,202854,202854,202855,202855,202855,202856,202856,202858,202858,202859,202859,202859,202861,202861,202864,202867,202869,202869,202871,202871,202872,202875,202877,202883,202890,202891,202891,202891,202892,202894,202903,202903,202906,202906,202906,202909,202910,202913,202916,202924,202926,202931,202932,202936,202938,202938,202938,202940,202945,202948,202948,202950,202951,202953,202954,202954,202955,202957,202960,202960,202964,202964,202964,202967,202967,202968,202968,202968,202968,202968,202973,202974,202974,202976,202980,202980,202981,202981,202981,202981,202981,202982,202982,202982,202983,202984,202984,202986,202987,202987,202987,202987,202987,202987,202987,202987,202987,202988,202988,202990,202990,202991,202992,202992,202992,202992,202993,202994,202996,202997,202998,202998,202998,202998,202998,202998,202998,202998,203004,203007,203009,203009,203009,203010,203011,203011,203013,203013,203016,203030,203031,203034,203036,203047,203049,203050,203051,203051,203053,203053,203053,203053,203056,203056,203057,203057,203057,203058,203061,203063,203063,203064,203067,203068,203069,203070,203080,203083,203086,203088,203097,203097,203097,203097,203099,203099,203100,203103,203105,203112,203121,203121,203121,203127,203128,203128,203130,203130,203135,203136,203138,203138,203138,203138,203138,203138,203139,203140,203141,203141,203142,203142,203144,203144,203146,203151,203152,203161,203161,203161,203172,203175,203180,203183,203183,203185,203187,203189,203189,203191,203195,203205,203213,203213,203213,203216,203220,203223,203223,203223,203223,203223,203223,203223,203225,203225,203230,203231,203233,203234,203237,203237,203237,203237,203237,203238,203238,203238,203239,203239,203239,203239,203240,203240,203240,203242,203243,203244,203246,203246,203247,203247,203249,203251,203253,203255,203256,203258,203263,203263,203263,203263,203266,203266,203268,203268,203268,203268,203268,203268,203269,203269,203276,203279,203279,203279,203286,203287,203287,203289,203291,203293,203299,203299,203300,203300,203301,203301,203301,203302,203306,203309,203309,203315,203315,203315,203317,203317,203317,203319,203323,203323,203323,203326,203326,203329,203333,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203335,203338,203339,203341,203347,203347,203347,203347,203351,203352,203352,203352,203352,203352,203354,203354,203355,203356,203356,203356,203357,203357,203357,203363,203364,203364,203364,203364,203364,203364,203364,203364,203365,203368,203368,203369,203369,203369,203372,203372,203372,203372,203372,203372,203373,203375,203377,203378,203378,203381,203381,203384,203384,203384,203384,203384,203385,203385,203386,203387,203388,203388,203390,203393,203394,203396,203397,203399,203400,203402,203402,203402,203402,203402,203404,203407,203417,203423,203423,203431,203438,203438,203438,203438,203438,203443,203443,203443,203444,203456,203457,203458,203464,203467,203467,203476,203477,203483,203484,203486,203487,203487,203487,203499,203501,203506,203506,203508,203509,203509,203512,203512,203515,203518,203520,203523,203527,203531,203532,203532,203532,203532,203533,203533,203533,203534,203538,203538,203538,203538,203539,203539,203542,203542,203543,203544,203544,203544,203547,203547,203550,203550,203550,203550,203550,203552,203554,203557,203558,203565,203574,203574,203574,203593,203600,203600,203601,203603,203603,203603,203603,203607,203607,203612,203612,203613,203615,203621,203626,203626,203629,203629,203637,203637,203640,203640,203640,203640,203640,203640,203640,203640,203640,203640,203642,203646,203648,203651,203652,203656,203656,203656,203656,203664,203664,203672,203682,203683,203683,203683,203689,203703,203704,203707,203713,203715,203725,203727,203729,203732,203741,203744,203744,203745,203750,203759,203760,203760,203761,203761,203764,203765,203765,203767,203767,203768,203768,203770,203778,203778,203778,203778,203782,203782,203782,203782,203782,203782,203782,203782,203782,203784,203793,203795,203795,203795,203795,203796,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203797,203798,203801,203804,203804,203804,203810,203813,203815,203817,203819,203819,203825,203826,203826,203829,203833,203836,203837,203840,203844,203854,203854,203854,203854,203854,203859,203859,203865,203870,203870,203883,203893,203897,203897,203897,203902,203903,203909,203909,203912,203917,203917,203917,203921,203921,203921,203930,203930,203930,203930,203930,203931,203933,203940,203946,203948,203948,203948,203950,203962,203964,203964,203964,203969,203971,203971,203972,203972,203972,203980,203982,203988,203988,203988,203996,203998,204001,204004,204014,204019,204023,204035,204037,204037,204043,204049,204052,204056,204059,204059,204062,204066,204067,204067,204070,204072,204072,204072,204074,204074,204075,204076,204077,204079,204080,204080,204081,204081,204084,204084,204084,204084,204087,204088,204091,204110,204113,204114,204120,204127,204131,204134,204140,204144,204144,204144,204146,204147,204148,204152,204156,204156,204159,204160,204171,204173,204181,204193,204198,204206,204209,204218,204219,204219,204222,204222,204224,204227,204229,204231,204238,204242,204248,204251,204254,204255,204256,204269,204270,204271,204271,204271,204272,204272,204274,204276,204276,204279,204279,204281,204286,204295,204295,204298,204298,204298,204299,204307,204316,204316,204317,204320,204321,204321,204322,204329,204329,204330,204341,204342,204351,204351,204351,204351,204351,204353,204354,204354,204354,204354,204354,204354,204357,204367,204370,204376,204377,204377,204388,204392,204396,204403,204411,204414,204417,204420,204420,204420,204422,204425,204426,204427,204429,204430,204434,204434,204434,204437,204439,204441,204441,204447,204449,204449,204450,204452,204453,204453,204454,204458,204458,204458,204458,204460,204463,204464,204465,204468,204473,204473,204473,204474,204477,204477,204479,204482,204488,204491,204491,204491,204497,204503,204510,204513,204513,204519,204519,204519,204525,204529,204532,204538,204549,204550,204552,204554,204554,204554,204554,204556,204559,204560,204561,204561,204561,204563,204565,204579,204581,204582,204585,204587,204587,204592,204595,204596,204596,204599,204602,204608,204610,204614,204614,204614,204616,204620,204620,204620,204620,204631,204631,204634,204639,204643,204643,204643,204643,204644,204646,204651,204651,204652,204659,204661,204661,204662,204662,204665,204665,204668,204668,204668,204676,204680,204697,204700,204700,204700,204710,204710,204710,204710,204712,204719,204722,204724,204724,204724,204726,204728,204731,204739,204742,204745,204746,204750,204752,204752,204755,204759,204768,204770,204770,204773,204781,204784,204784,204784,204787,204787,204787,204787,204787,204795,204795,204796,204801,204807,204808,204810,204811,204817,204832,204833,204835,204847,204848,204852,204852,204854,204859,204865,204865,204865,204865,204871,204872,204879,204886,204893,204893,204895,204904,204906,204908,204911,204911,204911,204913,204913,204919,204919,204919,204919,204919,204923,204927,204930,204930,204930,204930,204931,204931,204931,204931,204931,204931,204931,204938,204941,204944,204946,204948,204949,204953,204953,204955,204956,204956,204961,204963,204963,204966,204966,204966,204969,204970,204973,204973,204979,204990,204994,204994,205003,205007,205011,205011,205012,205014,205025,205025,205025,205025,205026,205032,205034,205048,205049,205051,205052,205052,205052,205052,205052,205056,205058,205058,205067,205069,205072,205074,205081,205085,205085,205085,205086,205095,205097,205123,205123,205123,205125,205132,205136,205146,205147,205149,205160,205160,205169,205171,205171,205171,205171,205171,205174,205174,205185,205186,205192,205197,205199,205201,205224,205224,205227,205243,205244,205245,205245,205245,205245,205250,205250,205250,205252,205264,205271,205272,205272,205272,205274,205280,205280,205280,205280,205280,205280,205283,205284,205284,205284,205287,205287,205287,205287,205288,205298,205300,205301,205306,205306,205306,205306,205306,205307,205308,205309,205309,205309,205309,205312,205312,205314,205315,205316,205319,205321,205322,205333,205340,205340,205340,205340,205340,205342,205351,205351,205354,205354,205354,205355,205355,205359,205361,205368,205369,205372,205373,205381,205382,205382,205384,205387,205388,205399,205405,205409,205412,205415,205417,205417,205417,205417,205417,205421,205421,205421,205421,205422,205428,205429,205433,205439,205442,205445,205445,205451,205458,205459,205461,205469,205472,205473,205475,205477,205482,205483,205487,205487,205497,205497,205499,205501,205502,205504,205504,205505,205507,205510,205513,205529,205530,205546,205551,205553,205553,205556,205556,205559,205562,205570,205583,205583,205583,205608,205609,205614,205618,205621,205621,205622,205622,205627,205627,205631,205631,205634,205635,205635,205635,205637,205640,205642,205651,205657,205657,205658,205667,205668,205668,205668,205670,205672,205673,205673,205675,205677,205682,205687,205688,205691,205710,205717,205720,205722,205722,205722,205732,205734,205740,205750,205750,205750,205750,205756,205756,205759,205761,205761,205761,205763,205763,205766,205772,205775,205775,205775,205777,205777,205777,205784,205784,205784,205785,205787,205791,205791,205791,205791,205791,205791,205793,205796,205808,205825,205825,205825,205827,205827,205827,205827,205827,205827,205827,205827,205827,205827,205827,205829,205831,205839,205840,205842,205845,205850,205851,205860,205875,205875,205876,205882,205883,205889,205899,205901,205914,205921,205925,205927,205934,205937,205937,205937,205948,205950,205950,205953,205955,205955,205955,205955,205955,205956,205960,205960,205960,205968,205972,205974,205975,205982,205984,205984,205984,205984,205984,205996,205997,205997,205998,206002,206003,206005,206006,206007,206008,206010,206012,206023,206029,206029,206029,206031,206031,206040,206041,206045,206050,206057,206057,206058,206058,206058,206058,206058,206058,206063,206063,206067,206070,206070,206070,206070,206073,206078,206082,206084,206090,206090,206090,206095,206102,206105,206107,206107,206109,206110,206111,206127,206127,206127,206127,206128,206134,206136,206136,206136,206136,206136,206136,206136,206136,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206141,206146,206153,206153,206156,206159,206160,206165,206171,206171,206171,206172,206174,206176,206176,206177,206178,206211,206211,206211,206224,206227,206239,206249,206257,206282,206282,206283,206287,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206293,206294,206294,206294,206313,206320,206324,206324,206326,206326,206328,206334,206334,206335,206347,206347,206347,206347,206347,206351,206351,206351,206351,206351,206352,206352,206352,206355,206355,206355,206355,206355,206355,206366,206368,206368,206372,206373,206373,206373,206378,206384,206385,206385,206390,206392,206402,206402,206413,206417,206417,206417,206425,206425,206429,206441,206442,206444,206444,206446,206449,206449,206454,206461,206461,206461,206461,206461,206461,206461,206461,206461,206461,206468,206472,206473,206473,206475,206481,206484,206484,206484,206484,206485,206485,206485,206485,206485,206495,206500,206500,206500,206500,206500,206510,206510,206510,206510,206520,206524,206524,206524,206524,206530,206530,206530,206530,206530,206534,206536,206537,206537,206541,206546,206569,206569,206569,206572,206572,206572,206576,206577,206583,206583,206583,206583,206584,206584,206584,206584,206586,206586,206586,206590,206597,206597,206598,206603,206611,206629,206634,206634,206634,206634,206634,206636,206643,206645,206645,206648,206648,206652,206654,206654,206654,206661,206677,206678,206681,206681,206685,206686,206689,206692,206696,206697,206706,206711,206713,206724,206747,206757,206759,206763,206764,206767,206769,206776,206778,206778,206778,206825,206826,206828,206836,206851,206855,206856,206856,206856,206856,206871,206882,206882,206882,206882,206883,206889,206898,206898,206921,206931,206931,206934,206934,206941,206948,206948,206957,206959,206960,206960,206963,206970,206970,206973,206973,206973,206976,206978,206978,206978,206981,206981,206981,206981,206982,206982,206985,206985,206985,206986,206989,207000,207006,207009,207010,207010,207012,207014,207014,207018,207020,207021,207023,207028,207033,207052,207055,207059,207062,207066,207074,207074,207075,207075,207075,207086,207090,207107,207110,207110,207110,207110,207110,207110,207112,207114,207116,207118,207128,207135,207143,207155,207155,207155,207155,207155,207155,207155,207155,207155,207157,207157,207168,207168,207169,207170,207175,207181,207204,207214,207226,207226,207226,207226,207230,207242,207242,207242,207243,207243,207243,207243,207243,207243,207243,207243,207243,207243,207243,207243,207243,207243,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207244,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207245,207246,207246,207246,207246,207246,207246,207246,207247,207247,207247,207248,207248,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207249,207250,207250,207250,207250,207250,207251,207251,207251,207251,207251,207251,207251,207252,207252,207252,207252,207252,207252,207252,207253,207253,207254,207255,207257,207259,207259,207259,207259,207259,207259,207259,207259,207259,207260,207260,207260,207260,207260,207261,207263,207263,207263,207264,207264,207264,207264,207264,207264,207264,207264,207267,207271,207271,207272,207272,207272,207272,207274,207274,207274,207274,207274,207279,207279,207279,207281,207281,207281,207281,207283,207284,207284,207284,207285,207287,207287,207287,207287,207287,207288,207292,207292,207292,207292,207292,207293,207293,207295,207296,207296,207301,207301,207301,207304,207306,207308,207308,207308,207311,207312,207312,207312,207314,207314,207314,207314,207314,207314,207314,207314,207314,207314,207314,207315,207315,207315,207316,207317,207317,207324,207326,207327,207327,207328,207334,207334,207334,207336,207339,207340,207340,207343,207347,207347,207348,207349,207349,207350,207351,207351,207354,207355,207355,207356,207356,207356,207358,207359,207359,207359,207359,207359,207359,207360,207361,207362,207362,207364,207366,207366,207366,207366,207366,207366,207366,207366,207368,207370,207370,207375,207375,207375,207375,207377,207377,207382,207382,207387,207387,207399,207399,207405,207414,207418,207420,207422,207425,207425,207427,207427,207427,207428,207428,207428,207428,207429,207429,207432,207432,207433,207435,207435,207435,207436,207441,207441,207442,207443,207445,207445,207445,207445,207445,207446,207446,207446,207450,207452,207452,207452,207454,207454,207460,207462,207464,207468,207470,207470,207476,207478,207480,207485,207492,207500,207501,207501,207501,207501,207503,207510,207510,207510,207510,207514,207515,207523,207528,207528,207528,207528,207530,207538,207538,207542,207542,207542,207542,207551,207553,207554,207554,207554,207559,207559,207560,207561,207562,207564,207564,207565,207575,207575,207583,207583,207590,207591,207594,207594,207597,207611,207612,207613,207613,207615,207615,207619,207620,207626,207631,207632,207632,207632,207633,207633,207633,207633,207633,207633,207633,207633,207633,207633,207633,207635,207635,207636,207642,207642,207642,207644,207647,207648,207648,207650,207651,207655,207656,207656,207657,207658,207663,207666,207666,207667,207667,207667,207672,207682,207682,207689,207690,207697,207697,207716,207716,207716,207716,207718,207720,207724,207725,207725,207725,207725,207726,207728,207729,207729,207729,207732,207734,207740,207746,207755,207758,207758,207758,207760,207762,207766,207770,207770,207771,207771,207771,207771,207771,207775,207775,207775,207782,207784,207785,207786,207788,207788,207788,207788,207791,207791,207792,207792,207792,207795,207797,207806,207807,207809,207811,207811,207816,207819,207822,207823,207828,207828,207828,207831,207833,207836,207837,207842,207848,207849,207849,207851,207856,207857,207857,207857,207857,207857,207857,207857,207857,207858,207858,207862,207862,207863,207863,207864,207868,207869,207869,207870,207870,207872,207872,207875,207878,207882,207887,207888,207891,207894,207896,207897,207914,207915,207926,207928,207928,207928,207930,207931,207931,207933,207933,207934,207935,207935,207937,207938,207944,207948,207949,207949,207949,207955,207955,207962,207963,207971,207973,207977,207984,207987,207992,207993,207993,207993,207994,207994,207994,207994,207994,207994,207997,207997,207997,207997,207997,207998,208000,208023,208028,208028,208028,208030,208030,208034,208041,208042,208046,208054,208057,208058,208083,208083,208083,208083,208095,208095,208121,208121,208123,208137,208137,208137,208137,208137,208137,208137,208137,208137,208137,208137,208153,208153,208157,208157,208157,208162,208162,208163,208166,208171,208173,208183,208183,208183,208185,208185,208185,208185,208186,208186,208188,208188,208190,208190,208198,208205,208210,208211,208221,208221,208221,208225,208225,208226,208230,208235,208235,208235,208237,208241,208241,208248,208250,208251,208251,208251,208258,208260,208262,208274,208276,208279,208281,208281,208285,208291,208311,208313,208318,208319,208322,208327,208328,208333,208335,208344,208344,208344,208351,208360,208362,208366,208366,208385,208385,208389,208397,208401,208403,208403,208403,208403,208408,208416,208421,208421,208421,208421,208421,208423,208423,208424,208424,208426,208428,208440,208443,208443,208447,208447,208447,208447,208447,208447,208447,208447,208447,208447,208447,208449,208449,208449,208451,208451,208451,208451,208451,208451,208451,208451,208452,208452,208452,208454,208470,208473,208475,208475,208485,208494,208494,208495,208495,208503,208512,208520,208528,208531,208547,208553,208553,208554,208555,208555,208560,208560,208560,208562,208564,208579,208579,208583,208586,208596,208636,208636,208636,208637,208639,208646,208647,208648,208649,208649,208654,208654,208654,208654,208654,208662,208670,208670,208671,208673,208673,208673,208675,208676,208682,208682,208684,208687,208689,208691,208692,208694,208703,208706,208706,208706,208716,208716,208719,208719,208747,208754,208759,208759,208759,208766,208766,208767,208768,208776,208776,208781,208782,208782,208786,208807,208807,208807,208818,208822,208846,208849,208850,208856,208856,208856,208858,208861,208864,208865,208867,208867,208871,208873,208874,208874,208882,208888,208890,208890,208892,208906,208907,208914,208914,208914,208914,208915,208923,208923,208924,208929,208935,208936,208936,208940,208943,208948,208948,208948,208948,208958,208958,208960,208960,208961,208961,208967,208968,208972,208981,208986,208987,208989,208990,208993,208999,209000,209002,209009,209013,209016,209026,209032,209034,209038,209038,209038,209038,209047,209055,209055,209055,209055,209059,209064,209067,209067,209068,209069,209072,209076,209078,209081,209093,209095,209098,209101,209104,209106,209108,209108,209108,209108,209109,209109,209113,209113,209113,209115,209117,209120,209120,209126,209131,209132,209135,209140,209152,209160,209165,209178,209187,209188,209199,209205,209208,209210,209211,209222,209228,209229,209231,209234,209236,209236,209241,209244,209245,209245,209246,209246,209246,209247,209247,209249,209249,209249,209250,209253,209254,209254,209255,209258,209258,209258,209258,209258,209258,209260,209261,209269,209283,209283,209293,209295,209299,209299,209307,209318,209322,209325,209325,209333,209333,209333,209333,209333,209333,209333,209333,209333,209336,209337,209338,209338,209355,209357,209371,209380,209382,209392,209396,209396,209403,209408,209411,209411,209411,209412,209414,209418,209418,209418,209418,209418,209418,209429,209429,209429,209431,209432,209433,209435,209450,209457,209459,209472,209482,209482,209482,209482,209482,209482,209482,209482,209484,209485,209497,209501,209504,209506,209506,209507,209512,209514,209514,209515,209517,209519,209519,209523,209524,209539,209547,209553,209553,209553,209553,209556,209557,209561,209563,209563,209563,209563,209563,209563,209563,209563,209563,209563,209563,209563,209563,209563,209565,209568,209577,209577,209580,209580,209580,209581,209582,209584,209585,209588,209588,209591,209591,209592,209594,209594,209598,209606,209607,209614,209614,209615,209615,209615,209615,209615,209626,209626,209631,209631,209636,209640,209644,209647,209650,209650,209664,209678,209683,209683,209683,209683,209690,209702,209708,209708,209712,209714,209715,209716,209723,209724,209727,209736,209754,209758,209758,209762,209769,209770,209773,209773,209776,209777,209777,209777,209791,209792,209793,209793,209793,209795,209795,209798,209801,209804,209806,209823,209825,209845,209845,209850,209850,209852,209852,209853,209854,209854,209855,209861,209872,209875,209875,209875,209886,209886,209887,209887,209887,209887,209890,209893,209893,209893,209893,209893,209893,209893,209893,209904,209905,209911,209920,209921,209921,209922,209924,209927,209933,209934,209935,209935,209936,209936,209941,209941,209944,209944,209952,209952,209953,209954,209959,209960,209970,209978,209989,209993,210007,210011,210015,210017,210026,210028,210038,210040,210041,210043,210046,210046,210048,210049,210057,210060,210062,210064,210064,210064,210066,210069,210072,210072,210072,210073,210073,210075,210090,210094,210097,210101,210113,210120,210139,210139,210139,210139,210139,210139,210139,210140,210141,210150,210150,210165,210167,210171,210172,210173,210176,210179,210180,210188,210188,210188,210188,210188,210188,210188,210188,210191,210191,210191,210191,210193,210193,210193,210193,210199,210208,210210,210212,210213,210213,210214,210214,210214,210218,210222,210223,210226,210233,210235,210237,210241,210244,210245,210245,210247,210248,210248,210254,210255,210257,210257,210258,210258,210259,210259,210259,210260,210260,210263,210266,210266,210266,210268,210268,210276,210279,210280,210280,210280,210282,210282,210286,210288,210288,210288,210288,210289,210289,210291,210292,210292,210292,210292,210292,210294,210294,210302,210305,210305,210308,210309,210310,210312,210312,210312,210312,210317,210317,210317,210317,210317,210319,210328,210328,210332,210332,210333,210335,210336,210338,210338,210338,210338,210341,210341,210341,210342,210342,210344,210347,210350,210350,210350,210353,210353,210359,210364,210367,210368,210371,210373,210375,210375,210378,210381,210386,210386,210389,210389,210389,210391,210391,210391,210391,210394,210396,210397,210397,210399,210400,210402,210406,210411,210411,210413,210415,210417,210424,210424,210427,210427,210430,210430,210436,210436,210436,210436,210441,210441,210441,210445,210445,210445,210445,210447,210447,210448,210450,210450,210451,210452,210452,210452,210452,210454,210456,210456,210463,210463,210464,210465,210472,210473,210473,210474,210479,210479,210479,210492,210501,210501,210501,210501,210501,210507,210507,210507,210511,210515,210518,210518,210523,210524,210525,210528,210528,210528,210528,210528,210535,210540,210541,210544,210550,210552,210552,210552,210552,210553,210554,210554,210556,210557,210557,210557,210558,210560,210562,210563,210566,210566,210575,210578,210581,210584,210592,210593,210595,210597,210603,210607,210608,210614,210614,210614,210614,210614,210617,210617,210628,210628,210628,210631,210632,210632,210632,210639,210640,210640,210643,210643,210644,210644,210644,210644,210644,210644,210645,210645,210645,210645,210645,210648,210648,210655,210656,210657,210658,210658,210659,210663,210663,210663,210663,210663,210663,210671,210671,210671,210674,210674,210674,210674,210679,210683,210685,210686,210686,210686,210687,210688,210688,210695,210695,210695,210695,210695,210697,210697,210697,210697,210697,210697,210697,210697,210698,210698,210700,210702,210711,210711,210718,210727,210728,210728,210728,210737,210739,210739,210739,210740,210740,210740,210742,210743,210743,210743,210743,210743,210744,210746,210746,210750,210750,210750,210750,210750,210751,210751,210751,210760,210770,210780,210792,210794,210796,210797,210798,210799,210799,210801,210807,210807,210807,210807,210807,210810,210811,210811,210811,210814,210814,210814,210814,210821,210826,210826,210826,210826,210831,210831,210831,210831,210831,210831,210840,210840,210840,210840,210840,210840,210844,210844,210846,210846,210853,210853,210854,210854,210858,210858,210858,210858,210858,210860,210862,210862,210878,210879,210879,210883,210884,210884,210884,210885,210892,210895,210897,210897,210900,210900,210901,210901,210903,210904,210907,210917,210921,210921,210924,210924,210928,210931,210931,210931,210933,210940,210940,210946,210946,210946,210946,210946,210946,210952,210966,210969,210973,210975,210976,210976,210979,210985,210987,210987,210987,210988,210988,210988,210988,210988,210988,210988,210988,210989,210991,210991,210991,210991,210999,211007,211008,211011,211011,211014,211019,211027,211031,211031,211037,211038,211038,211038,211051,211051,211056,211056,211056,211057,211057,211057,211057,211057,211057,211057,211057,211057,211057,211057,211058,211058,211065,211069,211087,211091,211100,211100,211100,211106,211107,211109,211111,211111,211111,211123,211129,211131,211133,211133,211136,211138,211142,211143,211147,211150,211152,211152,211152,211154,211156,211156,211156,211162,211172,211175,211180,211180,211183,211183,211183,211183,211189,211197,211211,211231,211236,211242,211242,211242,211242,211245,211251,211256,211257,211257,211269,211271,211271,211283,211286,211286,211289,211289,211289,211289,211289,211295,211299,211301,211302,211302,211307,211307,211307,211311,211311,211311,211321,211321,211321,211325,211329,211330,211332,211332,211339,211339,211339,211341,211341,211346,211348,211348,211348,211348,211348,211348,211353,211353,211353,211354,211355,211355,211355,211355,211358,211359,211361,211365,211365,211367,211367,211367,211367,211367,211367,211367,211367,211369,211370,211372,211373,211373,211376,211380,211380,211383,211385,211391,211409,211411,211412,211412,211412,211412,211412,211412,211412,211412,211412,211413,211415,211415,211421,211424,211425,211433,211434,211434,211434,211434,211434,211435,211435,211435,211444,211454,211463,211463,211466,211480,211480,211480,211493,211494,211494,211494,211494,211494,211495,211496,211500,211501,211506,211510,211518,211520,211520,211530,211531,211531,211531,211544,211545,211546,211547,211548,211548,211548,211549,211552,211556,211556,211556,211556,211556,211556,211556,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211558,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211559,211560,211560,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211561,211562,211562,211562,211564,211564,211564,211564,211564,211564,211564,211564,211565,211565,211566,211566,211567,211568,211568,211568,211568,211568,211568,211572,211573,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211574,211575,211575,211576,211576,211578,211578,211579,211579,211582,211583,211585,211586,211586,211586,211586,211586,211586,211587,211589,211589,211589,211590,211590,211592,211592,211592,211592,211592,211592,211593,211595,211595,211596,211597,211599,211599,211600,211600,211601,211601,211602,211602,211602,211603,211603,211603,211605,211608,211608,211608,211610,211612,211612,211614,211614,211615,211615,211615,211615,211617,211617,211618,211629,211630,211630,211630,211630,211630,211630,211631,211631,211632,211632,211634,211634,211635,211635,211635,211635,211636,211636,211638,211638,211639,211639,211641,211642,211642,211644,211647,211650,211650,211651,211652,211652,211652,211654,211654,211656,211657,211662,211662,211662,211666,211666,211666,211666,211669,211670,211671,211671,211675,211681,211682,211682,211682,211683,211684,211685,211685,211685,211687,211687,211687,211687,211688,211688,211691,211693,211694,211697,211701,211702,211704,211705,211706,211707,211708,211708,211708,211709,211709,211711,211711,211711,211714,211714,211714,211716,211717,211717,211718,211718,211719,211719,211719,211719,211719,211719,211720,211721,211721,211722,211724,211725,211732,211732,211738,211738,211744,211751,211752,211752,211754,211754,211754,211756,211757,211757,211757,211757,211757,211760,211760,211761,211761,211761,211761,211762,211766,211767,211770,211772,211772,211772,211772,211772,211782,211785,211789,211790,211791,211793,211798,211798,211799,211799,211801,211809,211809,211821,211821,211828,211828,211831,211835,211839,211840,211840,211840,211840,211841,211842,211842,211842,211842,211843,211843,211843,211849,211850,211850,211852,211852,211853,211858,211858,211860,211861,211862,211863,211863,211866,211872,211879,211882,211882,211882,211882,211882,211886,211886,211886,211886,211896,211896,211896,211897,211897,211898,211898,211900,211900,211900,211906,211907,211911,211911,211911,211912,211912,211914,211915,211918,211919,211919,211924,211924,211924,211924,211924,211925,211925,211925,211925,211925,211929,211929,211929,211929,211930,211930,211930,211930,211930,211930,211931,211933,211936,211938,211938,211938,211938,211942,211942,211942,211942,211952,211952,211952,211952,211952,211952,211952,211952,211952,211952,211953,211953,211956,211956,211956,211958,211958,211963,211964,211965,211965,211966,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211971,211972,211975,211981,211982,211982,211982,211997,212001,212001,212007,212007,212008,212008,212011,212011,212011,212011,212013,212018,212019,212020,212020,212022,212023,212024,212024,212029,212030,212033,212034,212035,212041,212042,212045,212045,212046,212046,212046,212047,212052,212052,212053,212053,212054,212054,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212055,212057,212057,212057,212057,212057,212057,212057,212058,212058,212065,212065,212065,212065,212066,212069,212072,212073,212073,212073,212074,212074,212074,212074,212074,212074,212076,212077,212077,212079,212080,212080,212080,212080,212080,212080,212081,212084,212084,212087,212087,212092,212093,212094,212094,212095,212096,212102,212102,212102,212103,212103,212103,212105,212107,212108,212108,212115,212118,212118,212118,212124,212136,212136,212137,212142,212142,212148,212148,212148,212148,212148,212148,212148,212151,212151,212157,212158,212158,212159,212159,212160,212160,212161,212161,212161,212161,212163,212166,212173,212173,212173,212173,212174,212174,212174,212174,212175,212176,212178,212178,212180,212181,212187,212188,212188,212188,212188,212188,212188,212191,212193,212194,212194,212194,212194,212194,212194,212195,212195,212195,212195,212195,212200,212205,212210,212210,212210,212210,212211,212211,212211,212211,212213,212219,212224,212228,212231,212233,212233,212233,212234,212235,212235,212238,212239,212239,212239,212239,212239,212239,212241,212242,212242,212242,212242,212243,212243,212243,212243,212245,212245,212245,212247,212247,212248,212249,212251,212251,212251,212252,212256,212256,212256,212256,212259,212259,212259,212259,212259,212260,212260,212260,212263,212265,212266,212266,212266,212266,212269,212270,212272,212273,212274,212276,212280,212284,212284,212284,212284,212288,212290,212290,212291,212294,212298,212299,212299,212306,212306,212306,212306,212306,212306,212306,212306,212306,212307,212309,212309,212311,212311,212311,212311,212311,212311,212315,212315,212320,212321,212322,212326,212326,212336,212355,212355,212356,212357,212357,212357,212360,212360,212360,212360,212370,212373,212373,212375,212384,212384,212390,212398,212406,212420,212420,212428,212430,212430,212430,212430,212430,212431,212436,212441,212441,212441,212441,212449,212450,212455,212455,212455,212455,212455,212455,212455,212455,212455,212455,212455,212458,212458,212459,212462,212473,212473,212476,212476,212476,212486,212498,212502,212502,212511,212511,212513,212513,212513,212514,212517,212518,212518,212518,212518,212518,212518,212520,212522,212524,212524,212528,212531,212533,212534,212538,212539,212539,212539,212539,212539,212540,212542,212548,212548,212551,212552,212552,212556,212558,212558,212566,212566,212571,212572,212572,212572,212574,212575,212575,212576,212577,212577,212577,212577,212577,212578,212583,212583,212583,212583,212583,212583,212585,212585,212586,212588,212589,212590,212590,212590,212591,212592,212597,212599,212599,212599,212599,212601,212603,212605,212606,212606,212608,212608,212608,212611,212611,212613,212613,212621,212621,212622,212622,212623,212623,212626,212627,212628,212630,212630,212645,212645,212647,212647,212647,212649,212652,212657,212657,212659,212668,212673,212673,212673,212684,212684,212685,212685,212685,212687,212688,212689,212689,212697,212699,212702,212704,212711,212711,212711,212711,212714,212717,212718,212719,212720,212743,212743,212743,212746,212748,212750,212754,212759,212759,212760,212761,212761,212761,212761,212761,212761,212763,212763,212763,212764,212769,212786,212790,212790,212794,212794,212794,212802,212802,212803,212805,212805,212811,212811,212811,212812,212812,212812,212812,212812,212812,212812,212812,212815,212815,212820,212820,212820,212820,212820,212824,212824,212824,212826,212829,212829,212832,212834,212834,212838,212838,212839,212839,212839,212839,212841,212841,212841,212841,212841,212841,212843,212843,212847,212849,212851,212851,212852,212853,212854,212854,212854,212854,212854,212855,212856,212856,212856,212858,212859,212859,212859,212861,212863,212863,212866,212866,212866,212866,212866,212866,212866,212866,212866,212867,212867,212870,212870,212870,212871,212872,212882,212885,212889,212889,212889,212889,212889,212889,212891,212891,212892,212892,212892,212892,212892,212892,212892,212894,212894,212894,212895,212895,212895,212895,212895,212895,212896,212899,212899,212899,212899,212900,212900,212900,212901,212901,212901,212901,212903,212905,212905,212905,212905,212905,212905,212905,212905,212906,212906,212908,212909,212913,212914,212914,212914,212915,212918,212918,212918,212920,212922,212922,212922,212922,212922,212922,212922,212923,212923,212924,212924,212924,212924,212925,212926,212928,212930,212931,212933,212933,212942,212942,212947,212950,212950,212951,212951,212952,212954,212958,212961,212973,212975,212975,212975,212979,212979,212979,212980,212980,212984,212990,212993,212997,213003,213004,213010,213010,213013,213013,213017,213020,213020,213021,213023,213025,213025,213028,213028,213028,213028,213029,213033,213035,213035,213038,213039,213043,213045,213045,213046,213057,213057,213057,213066,213066,213066,213068,213072,213074,213082,213082,213082,213083,213083,213083,213083,213083,213083,213083,213083,213083,213083,213083,213083,213086,213087,213088,213089,213089,213091,213096,213099,213102,213102,213112,213119,213119,213124,213127,213130,213139,213139,213147,213150,213152,213152,213152,213156,213163,213165,213166,213167,213167,213168,213169,213173,213174,213176,213180,213183,213183,213183,213183,213190,213190,213190,213191,213191,213193,213193,213201,213201,213201,213202,213202,213203,213207,213207,213207,213207,213207,213207,213208,213208,213211,213211,213211,213212,213212,213215,213217,213218,213218,213219,213221,213221,213221,213224,213225,213226,213226,213226,213226,213226,213226,213229,213229,213229,213243,213244,213244,213244,213248,213250,213251,213252,213254,213254,213255,213255,213257,213260,213262,213262,213265,213265,213269,213271,213272,213272,213272,213277,213281,213281,213282,213282,213282,213282,213282,213284,213285,213286,213287,213289,213292,213292,213293,213293,213295,213304,213306,213307,213311,213315,213316,213319,213319,213319,213319,213322,213322,213323,213325,213325,213327,213327,213327,213328,213334,213334,213337,213337,213339,213339,213339,213342,213342,213342,213342,213343,213345,213349,213354,213356,213357,213359,213359,213370,213371,213373,213376,213378,213380,213382,213385,213386,213386,213386,213386,213386,213391,213392,213392,213395,213411,213411,213411,213412,213412,213416,213416,213416,213417,213418,213436,213439,213440,213440,213440,213447,213451,213451,213452,213452,213462,213466,213466,213466,213471,213471,213473,213473,213479,213480,213481,213481,213485,213493,213495,213499,213500,213505,213506,213507,213507,213507,213508,213511,213511,213511,213512,213512,213512,213519,213523,213527,213529,213529,213529,213529,213529,213529,213533,213533,213544,213545,213546,213546,213546,213547,213547,213547,213548,213548,213548,213549,213551,213552,213552,213552,213554,213555,213555,213556,213556,213556,213558,213559,213561,213562,213564,213566,213566,213567,213567,213567,213571,213571,213577,213579,213582,213583,213583,213589,213589,213589,213590,213596,213596,213608,213609,213613,213616,213616,213616,213616,213630,213630,213631,213631,213631,213631,213631,213631,213631,213631,213642,213644,213646,213650,213660,213667,213671,213671,213672,213673,213677,213686,213686,213686,213686,213686,213688,213690,213690,213690,213702,213711,213711,213712,213712,213712,213712,213712,213716,213728,213729,213730,213732,213732,213732,213732,213732,213736,213738,213738,213741,213746,213746,213747,213747,213747,213747,213753,213753,213753,213753,213753,213753,213753,213753,213753,213756,213757,213758,213759,213766,213766,213766,213769,213769,213769,213770,213771,213773,213773,213774,213779,213781,213781,213781,213782,213784,213785,213786,213787,213789,213799,213801,213806,213808,213810,213818,213828,213828,213841,213841,213842,213843,213843,213843,213844,213850,213850,213852,213852,213853,213857,213860,213860,213869,213871,213871,213871,213871,213871,213871,213871,213871,213871,213871,213872,213873,213873,213873,213877,213879,213879,213882,213884,213895,213895,213899,213901,213903,213913,213913,213913,213913,213913,213914,213916,213917,213924,213926,213928,213942,213942,213943,213943,213943,213946,213954,213957,213957,213957,213960,213960,213960,213961,213961,213961,213976,213976,213979,213982,213985,213986,213987,213999,213999,213999,214000,214002,214003,214003,214003,214011,214014,214017,214024,214031,214034,214039,214039,214051,214051,214056,214066,214069,214073,214082,214084,214091,214091,214091,214092,214096,214101,214104,214105,214105,214105,214106,214107,214111,214111,214111,214111,214111,214112,214112,214112,214112,214112,214112,214116,214117,214124,214128,214131,214140,214145,214154,214154,214154,214158,214158,214161,214161,214161,214161,214161,214163,214165,214165,214166,214173,214173,214173,214173,214174,214176,214176,214176,214179,214179,214179,214179,214179,214180,214180,214183,214187,214187,214187,214187,214189,214189,214189,214190,214190,214190,214190,214190,214190,214191,214191,214191,214191,214191,214191,214191,214191,214191,214191,214192,214192,214192,214192,214192,214192,214192,214192,214192,214192,214192,214192,214193,214193,214193,214193,214194,214195,214196,214196,214196,214196,214197,214197,214200,214200,214200,214200,214202,214202,214202,214202,214202,214202,214203,214203,214203,214205,214206,214207,214207,214207,214209,214209,214209,214209,214211,214211,214213,214215,214217,214217,214217,214218,214218,214221,214221,214225,214225,214225,214225,214225,214225,214227,214227,214227,214233,214233,214235,214239,214239,214239,214240,214240,214240,214240,214240,214242,214242,214242,214242,214243,214243,214245,214246,214246,214247,214249,214254,214254,214257,214258,214258,214258,214258,214258,214259,214260,214260,214260,214261,214261,214261,214264,214264,214264,214264,214264,214271,214271,214271,214271,214271,214271,214272,214274,214275,214275,214275,214275,214278,214281,214281,214283,214283,214283,214284,214286,214286,214289,214290,214291,214291,214291,214292,214293,214296,214307,214307,214308,214308,214311,214311,214312,214314,214314,214324,214328,214328,214328,214328,214328,214328,214328,214328,214328,214328,214329,214332,214333,214334,214335,214336,214338,214339,214341,214343,214344,214348,214348,214352,214352,214352,214352,214353,214354,214355,214358,214362,214363,214365,214365,214365,214365,214366,214368,214373,214379,214384,214384,214394,214399,214399,214401,214408,214408,214408,214409,214411,214414,214417,214419,214419,214419,214425,214433,214437,214438,214439,214445,214445,214445,214449,214452,214452,214453,214456,214457,214460,214462,214467,214467,214468,214468,214469,214472,214473,214476,214478,214479,214483,214485,214486,214489,214491,214491,214491,214491,214491,214491,214492,214493,214495,214496,214496,214496,214497,214497,214497,214497,214497,214497,214497,214500,214501,214501,214501,214501,214501,214501,214501,214505,214509,214514,214515,214517,214518,214520,214521,214521,214521,214521,214521,214521,214521,214521,214522,214522,214522,214526,214527,214530,214532,214533,214533,214536,214538,214538,214538,214539,214539,214539,214541,214541,214541,214542,214542,214545,214545,214545,214547,214549,214549,214549,214549,214553,214554,214554,214554,214554,214554,214554,214555,214557,214558,214558,214560,214560,214560,214560,214560,214568,214570,214571,214576,214580,214581,214584,214585,214585,214585,214585,214587,214591,214591,214597,214598,214607,214611,214612,214612,214614,214617,214617,214619,214620,214622,214623,214625,214628,214629,214631,214639,214639,214639,214640,214642,214644,214645,214651,214651,214651,214652,214655,214655,214655,214656,214656,214656,214656,214657,214657,214658,214658,214658,214658,214658,214658,214661,214667,214667,214667,214667,214667,214667,214668,214668,214674,214676,214676,214679,214679,214681,214681,214681,214681,214683,214683,214688,214690,214693,214697,214697,214697,214698,214698,214698,214698,214698,214698,214698,214698,214700,214701,214701,214702,214704,214706,214709,214711,214711,214717,214717,214718,214719,214719,214719,214719,214719,214719,214719,214719,214719,214719,214727,214730,214733,214741,214741,214743,214751,214754,214754,214754,214756,214756,214756,214756,214756,214756,214756,214756,214756,214756,214756,214756,214757,214758,214763,214763,214766,214771,214773,214773,214773,214774,214783,214783,214783,214787,214788,214790,214790,214790,214791,214792,214794,214795,214796,214799,214799,214799,214799,214801,214801,214801,214801,214801,214803,214803,214803,214803,214803,214808,214808,214809,214812,214812,214812,214812,214812,214812,214813,214813,214813,214813,214813,214813,214813,214813,214813,214813,214813,214813,214816,214816,214817,214817,214820,214820,214820,214820,214824,214825,214826,214828,214830,214830,214831,214831,214831,214831,214832,214832,214832,214834,214834,214837,214837,214837,214837,214838,214838,214838,214838,214838,214839,214839,214841,214841,214841,214841,214843,214843,214844,214844,214844,214845,214848,214850,214851,214853,214854,214854,214854,214854,214856,214857,214858,214859,214859,214859,214859,214859,214861,214861,214866,214866,214866,214867,214867,214869,214869,214869,214870,214874,214876,214876,214876,214877,214877,214877,214882,214886,214886,214886,214891,214892,214892,214894,214894,214894,214895,214897,214897,214897,214897,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214898,214904,214905,214908,214908,214911,214918,214920,214921,214922,214924,214928,214935,214938,214938,214940,214945,214946,214946,214947,214951,214951,214952,214952,214956,214956,214959,214960,214962,214962,214983,214985,214985,214985,214988,214988,214988,214988,214989,214990,214990,214990,214990,214991,214992,214992,214996,214997,214997,214998,214998,215001,215001,215001,215001,215001,215001,215003,215003,215005,215005,215005,215005,215006,215006,215007,215007,215007,215008,215008,215008,215012,215013,215013,215013,215014,215014,215015,215015,215015,215015,215016,215024,215025,215025,215025,215026,215026,215026,215026,215026,215026,215026,215026,215026,215026,215032,215037,215037,215042,215047,215047,215049,215050,215050,215050,215050,215059,215063,215064,215068,215069,215070,215070,215073,215073,215074,215079,215083,215087,215091,215093,215095,215095,215095,215099,215099,215101,215101,215102,215102,215103,215103,215103,215103,215105,215108,215110,215110,215110,215111,215120,215120,215132,215132,215132,215147,215149,215150,215153,215153,215153,215154,215156,215162,215166,215168,215169,215175,215175,215175,215175,215176,215178,215178,215183,215184,215186,215195,215195,215196,215197,215197,215200,215201,215201,215202,215203,215203,215203,215204,215206,215207,215207,215207,215208,215209,215209,215211,215217,215217,215217,215235,215235,215235,215235,215239,215239,215241,215241,215242,215243,215243,215244,215247,215252,215252,215252,215252,215258,215260,215266,215266,215270,215271,215272,215273,215274,215274,215274,215274,215276,215276,215277,215277,215277,215277,215277,215277,215278,215285,215285,215285,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215287,215296,215296,215297,215297,215297,215299,215300,215300,215304,215304,215304,215306,215306,215307,215312,215313,215313,215315,215316,215316,215316,215316,215319,215319,215319,215319,215320,215321,215325,215331,215338,215339,215345,215345,215345,215351,215351,215351,215352,215352,215353,215355,215356,215356,215357,215360,215360,215362,215367,215367,215367,215367,215368,215373,215373,215373,215376,215376,215376,215376,215376,215376,215380,215380,215381,215381,215381,215382,215384,215384,215388,215389,215390,215396,215400,215418,215418,215428,215441,215441,215441,215441,215442,215443,215444,215451,215454,215456,215457,215457,215464,215464,215475,215482,215482,215482,215483,215483,215483,215486,215486,215486,215486,215486,215487,215487,215487,215487,215487,215489,215494,215494,215494,215494,215496,215496,215497,215497,215497,215497,215498,215498,215499,215499,215499,215500,215502,215504,215506,215509,215509,215511,215511,215514,215514,215514,215514,215514,215514,215516,215516,215522,215522,215522,215522,215522,215531,215552,215552,215553,215553,215553,215556,215562,215562,215567,215567,215567,215573,215573,215573,215573,215574,215575,215582,215582,215582,215585,215585,215592,215592,215592,215592,215592,215592,215592,215592,215592,215592,215594,215602,215602,215602,215602,215602,215607,215607,215607,215607,215611,215617,215620,215625,215625,215627,215628,215628,215629,215632,215632,215639,215639,215639,215639,215641,215641,215644,215646,215646,215646,215649,215651,215652,215652,215658,215658,215658,215662,215662,215663,215666,215666,215670,215671,215672,215672,215672,215672,215675,215675,215678,215678,215678,215678,215678,215679,215679,215679,215679,215679,215680,215680,215680,215680,215680,215682,215683,215684,215690,215690,215691,215693,215695,215695,215698,215699,215705,215707,215718,215719,215719,215720,215720,215729,215732,215733,215733,215733,215735,215736,215740,215740,215740,215740,215742,215746,215752,215753,215753,215766,215776,215778,215780,215782,215786,215789,215792,215793,215796,215798,215803,215811,215811,215816,215817,215817,215817,215817,215817,215817,215819,215819,215819,215820,215820,215820,215820,215821,215822,215822,215822,215828,215831,215833,215834,215837,215838,215838,215839,215840,215842,215845,215846,215848,215848,215849,215849,215849,215850,215850,215850,215850,215850,215850,215850,215850,215850,215850,215850,215850,215850,215850,215852,215852,215857,215861,215864,215864,215864,215864,215866,215867,215868,215868,215868,215873,215873,215876,215876,215881,215882,215884,215884,215887,215891,215893,215895,215895,215895,215895,215895,215895,215896,215899,215899,215903,215904,215906,215906,215911,215911,215911,215916,215916,215919,215922,215922,215922,215922,215927,215930,215932,215932,215933,215933,215937,215937,215939,215942,215947,215948,215948,215948,215952,215952,215956,215956,215956,215957,215960,215960,215960,215960,215960,215960,215965,215965,215965,215970,215972,215972,215973,215973,215973,215974,215974,215975,215975,215975,215978,215978,215984,215986,215986,215986,215986,215987,215989,215989,215989,215989,215989,215989,215989,215989,215990,215990,215990,215990,215990,215990,215991,215994,215994,215994,215995,215996,215996,215997,215997,215997,215999,216002,216003,216003,216003,216003,216007,216007,216010,216012,216016,216020,216020,216029,216031,216031,216036,216042,216045,216048,216057,216060,216060,216066,216070,216073,216075,216075,216076,216085,216086,216089,216090,216091,216094,216100,216102,216102,216103,216103,216112,216118,216120,216133,216133,216138,216145,216150,216151,216151,216153,216153,216153,216153,216153,216153,216153,216156,216158,216158,216158,216158,216159,216160,216160,216160,216164,216164,216164,216166,216166,216166,216166,216166,216167,216169,216173,216174,216179,216181,216181,216184,216184,216184,216184,216185,216185,216185,216187,216187,216189,216190,216190,216192,216192,216192,216192,216192,216195,216197,216198,216199,216201,216201,216203,216206,216211,216212,216213,216218,216218,216218,216218,216218,216218,216222,216222,216222,216222,216222,216222,216233,216233,216233,216233,216233,216233,216238,216253,216253,216253,216256,216259,216259,216266,216270,216270,216270,216271,216271,216272,216272,216272,216283,216283,216292,216295,216299,216299,216300,216303,216304,216306,216310,216311,216314,216321,216321,216322,216322,216322,216323,216324,216324,216328,216328,216328,216328,216328,216328,216329,216329,216329,216330,216330,216330,216330,216330,216331,216331,216332,216336,216338,216338,216338,216342,216342,216342,216343,216343,216346,216348,216348,216348,216348,216353,216357,216371,216384,216384,216384,216386,216386,216386,216387,216387,216387,216387,216388,216397,216399,216401,216402,216403,216408,216408,216408,216408,216408,216408,216408,216408,216415,216431,216436,216438,216445,216449,216454,216455,216455,216455,216455,216455,216455,216455,216455,216455,216455,216456,216456,216456,216456,216456,216456,216456,216456,216456,216456,216456,216457,216458,216462,216464,216464,216465,216465,216465,216466,216466,216466,216467,216467,216467,216467,216467,216468,216468,216468,216468,216471,216476,216476,216476,216476,216476,216479,216482,216488,216488,216488,216492,216498,216499,216501,216502,216503,216503,216505,216505,216505,216506,216508,216508,216508,216508,216508,216508,216513,216513,216513,216513,216516,216518,216518,216518,216518,216519,216519,216522,216522,216527,216530,216532,216533,216533,216534,216534,216534,216534,216535,216536,216536,216538,216538,216538,216539,216539,216540,216542,216542,216542,216546,216546,216548,216551,216551,216552,216552,216552,216552,216554,216556,216556,216556,216556,216556,216556,216557,216558,216559,216563,216564,216569,216569,216571,216573,216573,216574,216574,216574,216574,216577,216579,216580,216580,216582,216582,216582,216583,216583,216583,216584,216584,216589,216589,216591,216592,216597,216600,216606,216606,216606,216606,216606,216606,216606,216608,216611,216613,216616,216616,216617,216617,216617,216617,216617,216620,216620,216620,216620,216622,216622,216622,216622,216622,216622,216622,216622,216622,216622,216622,216624,216627,216627,216628,216629,216630,216631,216633,216633,216633,216636,216636,216636,216636,216641,216641,216641,216644,216644,216644,216647,216649,216650,216650,216650,216650,216655,216655,216665,216665,216665,216666,216679,216686,216686,216686,216686,216688,216688,216696,216696,216696,216696,216696,216696,216696,216696,216696,216704,216705,216712,216715,216715,216715,216719,216720,216724,216724,216724,216727,216732,216734,216739,216739,216739,216739,216739,216742,216742,216743,216749,216751,216751,216753,216755,216755,216755,216766,216776,216782,216782,216782,216782,216785,216786,216788,216789,216796,216796,216796,216801,216801,216802,216804,216806,216806,216808,216811,216811,216811,216812,216813,216820,216822,216822,216825,216826,216834,216836,216836,216836,216837,216837,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216840,216844,216844,216851,216852,216857,216858,216868,216868,216871,216873,216873,216878,216879,216885,216885,216888,216888,216891,216893,216893,216895,216897,216897,216897,216897,216902,216902,216903,216903,216903,216903,216905,216905,216905,216908,216908,216910,216910,216910,216910,216910,216910,216910,216910,216913,216913,216916,216916,216916,216917,216917,216917,216918,216918,216918,216923,216923,216924,216924,216925,216925,216925,216925,216925,216925,216926,216928,216929,216929,216929,216929,216929,216930,216932,216936,216937,216937,216938,216942,216942,216942,216944,216944,216944,216944,216944,216949,216952,216954,216954,216954,216954,216954,216954,216955,216955,216959,216959,216959,216959,216960,216960,216961,216961,216963,216964,216964,216964,216964,216964,216965,216965,216966,216966,216969,216970,216971,216972,216972,216972,216972,216972,216973,216978,216978,216978,216978,216979,216979,216986,216987,216993,216999,217001,217007,217012,217013,217013,217015,217025,217027,217027,217030,217033,217033,217034,217034,217034,217034,217034,217034,217037,217037,217038,217038,217039,217039,217039,217041,217042,217043,217043,217043,217043,217043,217043,217044,217044,217045,217045,217046,217046,217046,217047,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217049,217050,217050,217050,217050,217050,217050,217050,217051,217051,217051,217053,217054,217054,217055,217055,217056,217058,217058,217059,217059,217060,217060,217060,217062,217062,217062,217064,217066,217068,217072,217082,217084,217084,217085,217086,217088,217098,217100,217100,217100,217100,217100,217107,217108,217111,217111,217111,217114,217119,217128,217128,217129,217135,217138,217143,217152,217157,217157,217157,217159,217159,217163,217163,217163,217170,217170,217173,217173,217173,217175,217183,217183,217185,217185,217186,217203,217205,217205,217205,217208,217210,217211,217211,217211,217211,217213,217213,217213,217213,217214,217222,217222,217231,217241,217241,217241,217243,217243,217243,217248,217248,217257,217261,217261,217264,217266,217280,217295,217295,217308,217311,217311,217314,217314,217315,217315,217316,217316,217316,217316,217316,217319,217323,217325,217328,217329,217330,217339,217339,217339,217346,217348,217350,217351,217352,217360,217361,217361,217363,217366,217366,217366,217366,217366,217367,217367,217368,217368,217369,217369,217369,217370,217370,217371,217376,217378,217379,217380,217380,217381,217381,217382,217384,217384,217384,217384,217384,217388,217389,217391,217391,217391,217391,217395,217395,217396,217399,217399,217399,217399,217399,217399,217399,217401,217406,217406,217406,217407,217410,217411,217412,217412,217414,217418,217419,217423,217423,217423,217424,217424,217425,217426,217426,217428,217430,217431,217432,217437,217437,217438,217438,217441,217441,217441,217441,217441,217441,217441,217442,217442,217442,217443,217443,217444,217444,217444,217446,217447,217447,217447,217447,217450,217450,217451,217452,217452,217454,217454,217457,217457,217457,217457,217459,217459,217459,217459,217459,217459,217459,217459,217462,217462,217464,217464,217464,217465,217465,217465,217465,217465,217465,217465,217466,217466,217467,217471,217472,217472,217472,217478,217479,217483,217483,217483,217483,217483,217484,217485,217487,217491,217492,217493,217493,217493,217494,217494,217494,217494,217494,217494,217498,217500,217501,217505,217506,217508,217508,217510,217523,217528,217529,217529,217530,217532,217539,217539,217540,217541,217542,217542,217542,217544,217544,217544,217544,217544,217544,217545,217545,217545,217545,217545,217545,217545,217545,217545,217546,217548,217549,217555,217555,217557,217558,217558,217560,217560,217562,217562,217562,217568,217569,217569,217571,217571,217571,217573,217573,217573,217577,217579,217580,217583,217583,217585,217585,217585,217590,217591,217591,217591,217591,217591,217593,217593,217594,217601,217611,217611,217611,217611,217611,217611,217614,217621,217621,217622,217623,217623,217623,217623,217623,217624,217625,217626,217626,217627,217627,217627,217627,217628,217628,217628,217632,217639,217639,217639,217639,217646,217646,217647,217650,217650,217652,217652,217653,217657,217657,217658,217658,217658,217666,217677,217685,217685,217685,217687,217699,217699,217710,217710,217710,217710,217710,217710,217711,217711,217711,217714,217714,217718,217718,217723,217723,217723,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217726,217730,217738,217744,217744,217744,217744,217744,217746,217746,217749,217750,217754,217754,217754,217756,217756,217757,217757,217757,217759,217768,217771,217771,217772,217772,217773,217775,217776,217776,217776,217782,217785,217785,217790,217790,217790,217794,217798,217798,217798,217798,217806,217807,217809,217809,217809,217812,217818,217823,217825,217825,217825,217825,217825,217825,217825,217825,217825,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217828,217829,217829,217829,217829,217830,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217831,217834,217834,217834,217834,217834,217834,217834,217834,217834,217834,217834,217834,217834,217835,217835,217835,217836,217836,217836,217836,217836,217836,217836,217836,217836,217837,217837,217837,217838,217838,217838,217840,217840,217841,217842,217842,217842,217843,217843,217843,217843,217844,217844,217844,217844,217844,217845,217845,217845,217845,217845,217845,217845,217845,217848,217848,217848,217848,217848,217848,217848,217849,217849,217849,217849,217849,217849,217849,217850,217851,217851,217851,217852,217853,217854,217854,217855,217855,217856,217856,217856,217857,217857,217857,217857,217858,217860,217861,217861,217861,217862,217862,217862,217862,217862,217862,217862,217862,217862,217862,217862,217862,217862,217862,217862,217864,217866,217866,217866,217866,217866,217866,217866,217866,217866,217866,217866,217866,217866,217866,217867,217867,217867,217868,217868,217868,217869,217871,217872,217873,217876,217876,217877,217877,217877,217877,217877,217877,217877,217877,217877,217878,217879,217879,217880,217880,217880,217880,217880,217881,217881,217881,217882,217882,217882,217883,217883,217883,217884,217884,217884,217884,217885,217887,217887,217887,217887,217887,217887,217888,217890,217891,217891,217891,217891,217891,217891,217891,217892,217893,217893,217893,217893,217893,217895,217895,217895,217895,217895,217895,217898,217898,217898,217899,217899,217902,217902,217903,217904,217904,217905,217905,217905,217905,217905,217905,217906,217906,217906,217908,217908,217908,217908,217909,217911,217911,217911,217911,217913,217913,217914,217915,217915,217915,217917,217920,217920,217920,217920,217920,217920,217921,217921,217921,217922,217922,217924,217924,217924,217924,217924,217925,217925,217925,217925,217925,217927,217928,217930,217930,217932,217934,217937,217937,217937,217938,217938,217939,217939,217939,217939,217939,217939,217939,217939,217939,217939,217939,217939,217940,217940,217940,217940,217940,217943,217944,217945,217945,217945,217945,217946,217947,217948,217949,217951,217951,217951,217951,217951,217951,217951,217952,217955,217955,217955,217956,217956,217956,217956,217956,217957,217957,217958,217959,217963,217964,217965,217966,217969,217971,217971,217971,217971,217971,217971,217971,217971,217971,217971,217971,217971,217971,217972,217972,217972,217973,217973,217973,217974,217979,217980,217980,217980,217980,217980,217983,217983,217983,217984,217984,217984,217984,217985,217986,217986,217988,217988,217988,217989,217990,217991,217991,217993,217993,217993,217993,217994,217994,217994,217994,217994,217994,217994,217994,217994,217995,217995,217995,217995,217996,217997,217997,217997,217997,217997,217997,217997,217998,217998,217998,217998,217998,218000,218000,218002,218002,218002,218003,218003,218004,218006,218006,218006,218007,218008,218008,218008,218009,218009,218011,218011,218012,218015,218015,218015,218015,218016,218017,218024,218028,218030,218032,218033,218033,218034,218034,218037,218037,218039,218040,218040,218040,218040,218040,218040,218040,218041,218041,218043,218043,218044,218051,218052,218055,218056,218058,218058,218061,218062,218063,218064,218067,218068,218071,218071,218071,218071,218075,218075,218078,218082,218082,218082,218086,218086,218086,218086,218086,218086,218087,218087,218087,218087,218087,218088,218090,218090,218090,218090,218091,218092,218093,218095,218097,218097,218099,218099,218100,218100,218100,218100,218105,218108,218111,218111,218111,218111,218113,218116,218120,218120,218120,218123,218125,218125,218126,218131,218131,218131,218131,218131,218134,218134,218135,218137,218137,218142,218142,218142,218144,218152,218155,218159,218160,218162,218162,218167,218168,218169,218169,218169,218169,218171,218171,218173,218175,218181,218189,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218190,218198,218200,218206,218218,218218,218228,218234,218234,218237,218237,218247,218252,218252,218252,218252,218252,218252,218258,218260,218270,218270,218276,218276,218285,218287,218291,218294,218295,218308,218310,218312,218317,218317,218320,218321,218323,218323,218324,218324,218325,218330,218333,218333,218333,218337,218339,218342,218345,218359,218361,218361,218374,218374,218374,218375,218375,218375,218375,218375,218375,218376,218376,218380,218382,218385,218385,218385,218385,218385,218387,218387,218387,218390,218390,218390,218390,218390,218392,218395,218395,218395,218397,218398,218403,218403,218403,218403,218404,218406,218410,218413,218414,218416,218418,218424,218429,218433,218439,218444,218447,218457,218461,218461,218461,218463,218466,218470,218470,218470,218471,218472,218473,218473,218473,218477,218477,218478,218487,218487,218491,218497,218504,218512,218517,218532,218536,218544,218544,218544,218555,218556,218556,218558,218561,218563,218569,218573,218590,218594,218597,218599,218599,218601,218610,218617,218617,218622,218625,218626,218636,218637,218638,218639,218645,218649,218649,218652,218652,218658,218658,218658,218663,218663,218676,218676,218676,218676,218684,218685,218685,218685,218689,218689,218689,218689,218689,218689,218689,218689,218689,218692,218693,218695,218696,218698,218702,218703,218725,218738,218738,218738,218738,218738,218738,218738,218744,218749,218750,218752,218754,218757,218757,218757,218758,218761,218761,218761,218761,218761,218765,218765,218765,218765,218765,218765,218766,218778,218780,218786,218791,218791,218791,218791,218797,218805,218806,218808,218809,218813,218813,218814,218817,218817,218834,218838,218838,218838,218838,218838,218838,218839,218839,218839,218853,218856,218868,218870,218871,218871,218871,218880,218882,218884,218884,218885,218885,218885,218885,218885,218887,218890,218890,218891,218891,218891,218891,218891,218891,218892,218892,218896,218898,218898,218899,218899,218899,218904,218904,218906,218912,218915,218916,218916,218921,218924,218924,218924,218924,218924,218924,218924,218924,218924,218924,218924,218926,218927,218927,218927,218927,218928,218931,218933,218933,218933,218934,218934,218941,218946,218946,218946,218946,218946,218955,218955,218957,218957,218960,218963,218964,218966,218966,218967,218967,218967,218967,218970,218973,218973,218973,218977,218977,218979,218981,218982,218985,218985,218989,218990,218990,218991,218995,218995,218995,218999,219000,219003,219009,219009,219011,219013,219017,219017,219018,219020,219021,219021,219022,219022,219028,219029,219032,219032,219032,219032,219032,219035,219035,219037,219037,219037,219039,219040,219040,219042,219044,219044,219044,219044,219044,219044,219044,219044,219044,219047,219048,219049,219049,219053,219053,219053,219053,219053,219053,219053,219058,219058,219058,219058,219058,219059,219059,219062,219062,219062,219064,219064,219064,219065,219065,219065,219066,219071,219072,219073,219073,219073,219076,219076,219076,219078,219078,219080,219080,219080,219080,219080,219082,219082,219082,219083,219083,219083,219086,219086,219086,219089,219090,219093,219093,219094,219094,219095,219096,219096,219096,219096,219096,219097,219097,219097,219097,219097,219097,219101,219101,219103,219104,219104,219104,219104,219105,219105,219106,219107,219107,219109,219109,219110,219110,219110,219112,219112,219114,219115,219115,219116,219118,219118,219118,219118,219118,219118,219118,219118,219118,219119,219119,219120,219120,219121,219122,219122,219124,219124,219124,219124,219125,219125,219125,219126,219126,219127,219127,219128,219128,219129,219129,219131,219132,219134,219136,219136,219137,219137,219137,219140,219143,219143,219144,219145,219146,219147,219149,219149,219149,219152,219152,219152,219153,219153,219153,219153,219153,219154,219154,219154,219155,219155,219155,219155,219156,219156,219156,219156,219156,219156,219156,219156,219157,219157,219157,219157,219159,219159,219159,219159,219160,219160,219161,219162,219163,219163,219168,219169,219171,219172,219174,219176,219177,219177,219177,219178,219178,219182,219183,219184,219185,219186,219188,219191,219195,219196,219197,219197,219201,219201,219201,219201,219202,219203,219203,219204,219204,219205,219205,219205,219205,219205,219206,219206,219206,219206,219207,219208,219208,219208,219208,219209,219209,219209,219209,219209,219209,219210,219211,219211,219214,219214,219214,219214,219214,219214,219214,219214,219215,219215,219215,219215,219217,219217,219219,219221,219223,219223,219225,219226,219226,219226,219226,219227,219227,219227,219227,219229,219229,219229,219229,219229,219230,219235,219235,219235,219236,219238,219239,219242,219243,219243,219243,219245,219246,219247,219247,219249,219254,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219255,219256,219256,219256,219256,219256,219256,219256,219256,219256,219256,219257,219257,219258,219259,219259,219259,219259,219259,219259,219259,219262,219262,219262,219262,219262,219262,219263,219264,219269,219271,219271,219271,219271,219271,219273,219276,219276,219276,219280,219280,219280,219280,219280,219280,219280,219280,219280,219280,219281,219283,219284,219287,219289,219289,219292,219292,219292,219295,219296,219297,219300,219301,219301,219301,219301,219302,219302,219302,219303,219303,219303,219303,219303,219306,219307,219308,219311,219311,219311,219311,219313,219313,219313,219313,219313,219313,219313,219320,219320,219320,219320,219320,219323,219323,219323,219323,219323,219327,219327,219328,219328,219330,219330,219331,219331,219334,219335,219337,219338,219340,219343,219343,219343,219343,219343,219347,219347,219347,219347,219347,219347,219347,219349,219349,219349,219351,219352,219352,219357,219358,219359,219360,219360,219360,219367,219368,219371,219372,219372,219375,219375,219376,219377,219379,219380,219380,219381,219383,219384,219384,219388,219391,219395,219398,219401,219404,219405,219406,219406,219414,219414,219414,219414,219414,219414,219414,219414,219414,219414,219414,219415,219415,219417,219417,219422,219422,219422,219426,219426,219426,219426,219426,219426,219429,219435,219435,219435,219435,219435,219438,219439,219440,219440,219440,219444,219447,219448,219449,219451,219459,219459,219459,219460,219462,219464,219464,219464,219465,219465,219469,219469,219471,219471,219473,219473,219473,219473,219473,219473,219473,219477,219478,219478,219480,219480,219480,219480,219484,219486,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219487,219489,219489,219491,219491,219491,219491,219491,219493,219495,219498,219501,219501,219501,219502,219502,219503,219503,219503,219503,219503,219504,219506,219508,219511,219514,219514,219518,219519,219519,219519,219519,219519,219519,219519,219519,219519,219519,219528,219528,219528,219532,219532,219534,219534,219534,219534,219540,219541,219541,219541,219541,219541,219541,219543,219543,219545,219546,219550,219550,219558,219558,219558,219558,219561,219563,219565,219565,219565,219565,219565,219565,219565,219566,219566,219569,219579,219580,219580,219581,219581,219581,219581,219581,219581,219581,219581,219585,219585,219588,219596,219596,219597,219597,219597,219597,219601,219610,219610,219610,219613,219613,219616,219621,219621,219621,219624,219624,219626,219626,219626,219629,219629,219629,219633,219636,219636,219636,219638,219639,219647,219647,219647,219647,219647,219647,219647,219647,219648,219648,219649,219650,219650,219651,219651,219651,219652,219652,219657,219658,219658,219660,219660,219660,219660,219660,219661,219661,219661,219661,219661,219661,219661,219665,219667,219668,219679,219683,219683,219684,219684,219684,219684,219684,219684,219684,219684,219684,219685,219685,219689,219693,219696,219711,219711,219711,219713,219714,219719,219719,219719,219719,219719,219719,219719,219719,219719,219721,219724,219737,219739,219741,219744,219746,219752,219752,219754,219756,219757,219757,219759,219761,219767,219769,219772,219785,219786,219794,219799,219806,219812,219817,219817,219817,219817,219820,219820,219820,219823,219823,219823,219823,219823,219830,219840,219840,219849,219851,219853,219853,219854,219855,219855,219861,219861,219861,219862,219865,219867,219872,219872,219872,219879,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219880,219881,219881,219881,219881,219881,219881,219881,219881,219881,219881,219882,219882,219882,219882,219882,219882,219882,219882,219882,219882,219882,219882,219882,219883,219883,219884,219884,219884,219884,219885,219885,219885,219885,219885,219885,219885,219885,219885,219885,219885,219885,219885,219886,219886,219886,219886,219886,219886,219886,219886,219886,219886,219886,219886,219887,219887,219887,219887,219887,219887,219887,219887,219887,219887,219887,219887,219887,219887,219887,219888,219888,219888,219888,219888,219889,219890,219890,219891,219893,219894,219894,219894,219894,219894,219896,219896,219900,219900,219901,219901,219901,219901,219901,219902,219902,219902,219903,219903,219903,219904,219904,219904,219904,219905,219905,219905,219905,219905,219905,219907,219907,219907,219907,219907,219907,219909,219909,219910,219910,219910,219910,219910,219910,219911,219911,219911,219911,219912,219913,219913,219913,219914,219914,219915,219915,219915,219916,219918,219919,219919,219919,219919,219919,219919,219919,219921,219921,219923,219925,219925,219925,219928,219933,219934,219937,219938,219938,219939,219939,219939,219941,219941,219941,219944,219946,219946,219950,219951,219951,219951,219951,219951,219951,219953,219953,219953,219953,219953,219953,219953,219953,219953,219953,219954,219954,219954,219954,219956,219958,219959,219964,219965,219968,219969,219969,219970,219971,219971,219972,219972,219983,219983,219987,219987,219987,219989,219994,219994,219996,219996,219998,219998,220000,220000,220003,220003,220006,220007,220009,220011,220014,220014,220014,220014,220014,220014,220015,220015,220015,220015,220015,220015,220015,220016,220016,220016,220021,220023,220024,220024,220025,220025,220027,220027,220027,220027,220027,220027,220028,220028,220028,220029,220030,220030,220034,220036,220036,220036,220037,220037,220039,220040,220043,220044,220044,220044,220044,220045,220051,220051,220051,220051,220051,220051,220051,220051,220051,220052,220052,220052,220052,220052,220053,220054,220054,220055,220055,220056,220056,220056,220057,220058,220060,220060,220063,220063,220063,220063,220063,220063,220063,220065,220070,220073,220083,220085,220085,220085,220085,220085,220085,220085,220085,220085,220085,220085,220086,220086,220088,220089,220091,220091,220092,220092,220093,220093,220093,220094,220096,220098,220098,220099,220099,220100,220102,220102,220106,220107,220107,220107,220108,220108,220108,220110,220111,220111,220113,220113,220120,220120,220120,220120,220120,220120,220120,220124,220124,220127,220129,220134,220134,220134,220140,220140,220144,220145,220145,220149,220151,220151,220151,220151,220155,220155,220155,220155,220155,220155,220155,220155,220155,220155,220160,220160,220160,220167,220167,220167,220168,220168,220168,220168,220173,220173,220173,220174,220176,220176,220177,220184,220184,220184,220184,220184,220185,220185,220192,220194,220209,220209,220215,220218,220223,220226,220226,220229,220229,220229,220229,220229,220229,220229,220233,220233,220233,220234,220235,220235,220235,220243,220243,220248,220251,220252,220252,220252,220253,220253,220255,220256,220256,220256,220256,220258,220260,220266,220267,220267,220271,220272,220272,220272,220272,220272,220272,220272,220272,220272,220272,220274,220274,220274,220274,220275,220286,220286,220290,220290,220291,220295,220296,220296,220299,220299,220301,220301,220302,220302,220307,220307,220311,220318,220324,220326,220326,220326,220326,220327,220330,220330,220330,220330,220332,220332,220337,220339,220339,220344,220346,220347,220347,220347,220347,220348,220348,220349,220350,220351,220351,220351,220351,220354,220354,220354,220354,220355,220356,220358,220358,220358,220358,220358,220358,220359,220359,220360,220361,220362,220363,220365,220365,220366,220366,220366,220366,220366,220368,220371,220372,220372,220372,220375,220375,220375,220375,220375,220375,220375,220375,220375,220376,220376,220377,220379,220379,220379,220379,220379,220380,220381,220381,220381,220381,220383,220384,220385,220385,220385,220386,220387,220387,220388,220389,220389,220389,220391,220393,220393,220396,220398,220398,220398,220399,220399,220399,220399,220399,220399,220399,220399,220399,220399,220399,220399,220400,220400,220402,220402,220403,220403,220404,220404,220404,220405,220405,220406,220406,220407,220407,220407,220407,220408,220410,220410,220410,220410,220411,220411,220412,220413,220413,220413,220413,220413,220416,220416,220416,220417,220417,220418,220418,220418,220419,220419,220419,220419,220419,220420,220420,220420,220420,220420,220420,220421,220423,220424,220425,220425,220425,220426,220426,220426,220428,220429,220431,220431,220431,220432,220432,220432,220432,220432,220435,220435,220435,220435,220443,220443,220449,220449,220449,220452,220452,220453,220454,220454,220454,220454,220456,220459,220462,220462,220462,220464,220465,220468,220468,220470,220470,220470,220470,220471,220473,220475,220475,220481,220483,220483,220483,220484,220484,220484,220485,220485,220485,220486,220486,220486,220486,220486,220490,220491,220492,220492,220492,220493,220493,220493,220493,220494,220494,220498,220498,220498,220498,220498,220498,220498,220498,220498,220498,220499,220499,220500,220500,220501,220501,220504,220504,220505,220505,220507,220508,220508,220509,220509,220509,220511,220511,220512,220512,220512,220512,220513,220514,220514,220516,220516,220516,220521,220521,220522,220522,220522,220524,220525,220526,220526,220526,220526,220528,220529,220529,220529,220529,220532,220533,220533,220533,220534,220534,220534,220534,220540,220540,220540,220540,220541,220541,220541,220541,220543,220543,220543,220543,220543,220544,220544,220545,220545,220545,220545,220545,220545,220545,220546,220547,220548,220548,220548,220551,220551,220552,220553,220553,220553,220553,220553,220553,220554,220557,220557,220557,220557,220559,220559,220559,220559,220559,220559,220560,220560,220560,220561,220561,220561,220561,220562,220565,220565,220565,220565,220565,220566,220566,220566,220566,220567,220567,220567,220567,220567,220567,220567,220569,220570,220570,220572,220572,220572,220576,220577,220577,220577,220577,220581,220582,220582,220583,220583,220583,220583,220585,220585,220587,220587,220587,220587,220587,220589,220590,220591,220593,220593,220595,220595,220595,220595,220595,220596,220596,220598,220598,220600,220600,220600,220600,220600,220600,220601,220604,220605,220606,220607,220607,220607,220607,220607,220607,220607,220607,220608,220609,220609,220611,220611,220611,220613,220613,220615,220615,220615,220616,220616,220616,220616,220616,220616,220616,220617,220617,220617,220617,220617,220618,220620,220626,220628,220628,220628,220634,220642,220647,220647,220647,220648,220650,220650,220651,220651,220651,220657,220658,220662,220662,220662,220662,220662,220662,220662,220662,220662,220663,220663,220663,220666,220666,220666,220667,220667,220667,220667,220667,220667,220668,220668,220668,220668,220669,220670,220671,220673,220674,220674,220681,220681,220681,220681,220682,220683,220683,220683,220683,220683,220694,220700,220700,220700,220700,220700,220704,220705,220705,220705,220705,220706,220706,220706,220706,220706,220708,220708,220714,220717,220721,220726,220727,220728,220728,220728,220731,220731,220731,220731,220731,220732,220734,220741,220742,220742,220742,220742,220743,220747,220747,220749,220749,220754,220754,220754,220754,220755,220755,220755,220755,220757,220758,220760,220760,220762,220762,220762,220762,220762,220763,220763,220763,220764,220764,220764,220764,220764,220764,220764,220764,220764,220764,220764,220764,220766,220767,220771,220771,220772,220772,220772,220772,220772,220772,220772,220773,220773,220773,220774,220776,220777,220777,220777,220777,220778,220778,220779,220779,220779,220781,220781,220781,220785,220785,220785,220785,220785,220785,220785,220785,220785,220790,220791,220792,220792,220797,220797,220799,220799,220799,220802,220804,220806,220813,220820,220828,220830,220830,220830,220841,220841,220843,220843,220843,220845,220846,220849,220849,220849,220849,220849,220849,220849,220849,220852,220853,220860,220861,220862,220862,220862,220862,220862,220862,220864,220864,220868,220869,220869,220869,220869,220869,220870,220871,220872,220872,220873,220874,220875,220875,220876,220879,220879,220880,220880,220881,220881,220881,220882,220884,220884,220886,220890,220890,220893,220893,220893,220893,220896,220897,220897,220898,220901,220903,220904,220904,220907,220908,220908,220911,220913,220915,220922,220922,220930,220931,220939,220939,220939,220945,220945,220946,220947,220949,220952,220952,220952,220955,220957,220957,220957,220963,220963,220963,220966,220966,220970,220970,220970,220971,220971,220973,220984,220984,220988,220999,220999,221003,221005,221006,221008,221011,221011,221011,221015,221015,221017,221017,221017,221022,221023,221025,221029,221029,221029,221031,221035,221038,221039,221042,221046,221048,221048,221048,221052,221052,221052,221056,221057,221057,221057,221059,221059,221061,221061,221061,221062,221064,221065,221066,221066,221069,221070,221072,221073,221073,221076,221076,221079,221082,221082,221083,221083,221084,221084,221084,221084,221084,221084,221084,221084,221084,221084,221085,221085,221085,221086,221090,221091,221091,221091,221091,221091,221091,221091,221091,221091,221091,221091,221091,221091,221091,221091,221094,221094,221094,221094,221094,221099,221100,221100,221102,221102,221106,221106,221113,221114,221116,221116,221116,221117,221117,221117,221117,221117,221120,221120,221120,221121,221122,221122,221122,221124,221124,221124,221130,221130,221135,221135,221143,221144,221148,221148,221148,221148,221158,221161,221161,221161,221163,221163,221164,221164,221166,221166,221166,221166,221166,221166,221166,221166,221166,221166,221167,221168,221170,221170,221170,221175,221183,221186,221186,221186,221186,221187,221187,221187,221196,221199,221199,221199,221203,221211,221211,221211,221214,221221,221221,221222,221225,221226,221229,221229,221229,221230,221232,221233,221236,221239,221239,221239,221242,221244,221248,221251,221251,221251,221252,221252,221256,221257,221261,221264,221264,221264,221264,221264,221264,221265,221266,221268,221268,221268,221270,221271,221271,221272,221272,221273,221279,221280,221284,221284,221284,221284,221287,221290,221291,221291,221291,221291,221293,221294,221294,221294,221295,221295,221297,221298,221299,221300,221300,221300,221300,221300,221300,221300,221301,221301,221301,221301,221301,221301,221301,221301,221303,221305,221306,221306,221306,221307,221307,221307,221307,221311,221313,221319,221322,221325,221326,221326,221328,221331,221332,221334,221336,221340,221343,221347,221350,221351,221351,221352,221352,221352,221352,221357,221358,221359,221359,221359,221359,221359,221359,221359,221359,221359,221360,221360,221360,221360,221360,221361,221361,221361,221362,221362,221363,221363,221363,221363,221364,221365,221365,221365,221367,221367,221371,221371,221372,221373,221373,221373,221373,221373,221374,221375,221377,221379,221380,221380,221380,221381,221382,221383,221383,221385,221385,221385,221386,221386,221386,221386,221386,221386,221389,221390,221391,221391,221392,221392,221393,221395,221395,221395,221395,221396,221396,221397,221397,221397,221397,221398,221398,221399,221400,221400,221400,221401,221403,221404,221407,221407,221407,221409,221410,221410,221412,221412,221412,221413,221413,221414,221415,221417,221418,221419,221420,221422,221422,221422,221425,221426,221431,221431,221436,221436,221436,221439,221439,221443,221443,221447,221447,221449,221450,221451,221451,221454,221455,221455,221455,221460,221460,221464,221465,221465,221466,221472,221480,221483,221483,221483,221483,221483,221483,221483,221483,221483,221483,221484,221484,221484,221492,221492,221492,221493,221497,221500,221502,221512,221512,221512,221521,221528,221529,221529,221529,221531,221533,221533,221533,221533,221533,221533,221534,221535,221535,221535,221535,221535,221535,221535,221537,221539,221549,221556,221556,221556,221557,221560,221560,221560,221560,221564,221565,221565,221566,221566,221566,221566,221567,221568,221568,221568,221568,221575,221575,221576,221584,221584,221585,221585,221587,221588,221589,221597,221597,221597,221597,221597,221597,221602,221603,221604,221604,221606,221606,221606,221606,221606,221606,221608,221608,221609,221609,221609,221609,221611,221611,221612,221612,221612,221613,221613,221613,221615,221615,221615,221615,221616,221621,221621,221625,221625,221625,221629,221630,221630,221630,221631,221631,221631,221631,221631,221633,221633,221633,221633,221633,221633,221633,221633,221638,221639,221641,221641,221642,221642,221645,221645,221645,221645,221646,221646,221647,221649,221649,221649,221649,221649,221649,221649,221649,221649,221650,221652,221652,221657,221657,221657,221659,221669,221670,221671,221672,221672,221672,221677,221677,221677,221677,221680,221680,221680,221682,221683,221683,221685,221685,221686,221686,221694,221694,221698,221698,221698,221698,221698,221700,221701,221705,221706,221708,221708,221709,221709,221709,221709,221709,221710,221712,221713,221713,221713,221714,221715,221715,221715,221715,221715,221715,221715,221716,221716,221716,221716,221718,221718,221719,221720,221720,221720,221720,221721,221722,221722,221722,221724,221724,221727,221730,221731,221733,221734,221743,221744,221744,221746,221746,221746,221746,221747,221747,221747,221748,221749,221750,221751,221751,221751,221751,221754,221754,221755,221755,221757,221758,221759,221761,221761,221764,221764,221764,221764,221768,221768,221769,221769,221769,221771,221773,221782,221782,221782,221784,221787,221790,221790,221790,221794,221797,221801,221803,221805,221806,221809,221815,221820,221830,221830,221830,221837,221837,221837,221838,221838,221839,221846,221850,221853,221854,221855,221855,221856,221857,221859,221859,221859,221863,221864,221864,221867,221867,221867,221877,221879,221880,221887,221895,221901,221907,221910,221924,221924,221925,221927,221927,221927,221927,221927,221927,221927,221927,221927,221927,221929,221929,221931,221936,221936,221936,221937,221951,221951,221951,221951,221951,221951,221951,221952,221952,221955,221957,221957,221958,221958,221958,221958,221958,221958,221958,221958,221958,221958,221959,221960,221961,221961,221964,221966,221966,221966,221967,221967,221967,221967,221967,221969,221969,221970,221973,221974,221977,221978,221978,221986,221993,221993,221994,221994,221996,222008,222011,222011,222012,222012,222018,222018,222019,222019,222023,222023,222023,222026,222032,222032,222034,222035,222035,222035,222037,222038,222043,222044,222045,222047,222052,222055,222055,222055,222056,222061,222061,222061,222061,222061,222061,222066,222068,222070,222075,222075,222076,222076,222076,222076,222078,222082,222082,222084,222085,222085,222088,222089,222091,222091,222091,222091,222093,222095,222104,222106,222112,222113,222113,222117,222121,222122,222123,222123,222129,222129,222129,222129,222130,222136,222138,222142,222142,222147,222152,222154,222158,222158,222160,222161,222161,222163,222164,222165,222169,222169,222177,222177,222179,222180,222181,222183,222190,222196,222198,222198,222198,222198,222198,222198,222198,222198,222198,222201,222201,222201,222201,222202,222204,222205,222206,222206,222206,222209,222210,222210,222210,222211,222211,222212,222212,222212,222212,222213,222215,222215,222215,222215,222217,222219,222221,222223,222225,222225,222226,222235,222235,222235,222235,222235,222235,222236,222240,222240,222241,222246,222246,222247,222248,222251,222253,222254,222257,222263,222264,222277,222281,222281,222288,222289,222291,222291,222297,222298,222313,222317,222317,222317,222317,222317,222317,222317,222318,222320,222325,222325,222325,222328,222328,222328,222329,222334,222334,222337,222340,222342,222358,222360,222362,222368,222369,222380,222381,222396,222396,222396,222396,222402,222402,222402,222402,222402,222402,222402,222402,222402,222403,222404,222407,222407,222408,222408,222409,222409,222417,222421,222422,222425,222429,222432,222433,222433,222433,222433,222441,222443,222452,222460,222462,222462,222462,222462,222463,222464,222465,222465,222465,222465,222469,222469,222469,222471,222472,222474,222477,222477,222482,222482,222493,222493,222493,222499,222505,222508,222510,222515,222517,222519,222521,222526,222528,222530,222531,222533,222533,222533,222535,222539,222545,222565,222565,222565,222567,222569,222569,222569,222571,222572,222579,222581,222581,222582,222582,222582,222582,222582,222582,222582,222582,222582,222586,222586,222592,222607,222607,222612,222612,222614,222618,222619,222619,222619,222619,222619,222619,222626,222630,222637,222638,222640,222640,222641,222641,222641,222642,222642,222642,222642,222646,222649,222651,222653,222653,222654,222654,222660,222663,222666,222667,222675,222680,222682,222682,222684,222684,222686,222687,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222690,222692,222692,222693,222693,222693,222693,222693,222693,222697,222697,222700,222700,222700,222700,222701,222701,222701,222701,222701,222701,222701,222701,222701,222702,222702,222702,222706,222706,222706,222708,222709,222709,222711,222714,222715,222715,222715,222715,222715,222715,222715,222715,222722,222722,222722,222722,222723,222728,222729,222730,222730,222731,222731,222731,222731,222731,222732,222732,222732,222732,222732,222732,222733,222734,222734,222734,222734,222734,222734,222734,222734,222737,222737,222737,222737,222742,222752,222753,222755,222755,222755,222755,222755,222759,222759,222759,222759,222759,222762,222768,222779,222781,222781,222782,222782,222783,222783,222783,222788,222788,222789,222789,222792,222793,222793,222794,222794,222794,222794,222796,222796,222798,222798,222801,222802,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222810,222811,222812,222813,222814,222814,222814,222816,222819,222819,222819,222819,222820,222820,222820,222829,222832,222832,222835,222839,222845,222846,222846,222852,222852,222855,222855,222858,222858,222862,222862,222862,222873,222874,222885,222889,222890,222896,222896,222900,222905,222908,222914,222914,222914,222915,222919,222927,222927,222927,222929,222939,222940,222940,222941,222943,222947,222947,222949,222950,222953,222957,222957,222961,222961,222964,222964,222967,222973,222973,222974,222975,222975,222990,222992,222996,222996,222998,223001,223002,223002,223009,223011,223012,223013,223013,223013,223013,223014,223021,223022,223025,223026,223026,223026,223029,223029,223029,223029,223033,223039,223042,223044,223044,223045,223046,223046,223047,223048,223048,223049,223049,223049,223049,223050,223053,223057,223069,223071,223073,223074,223080,223081,223082,223082,223082,223085,223085,223091,223097,223097,223097,223100,223100,223100,223100,223100,223100,223102,223102,223105,223112,223121,223121,223121,223121,223123,223125,223126,223127,223127,223127,223127,223127,223127,223130,223130,223137,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223138,223143,223143,223146,223147,223150,223153,223157,223157,223158,223158,223159,223165,223166,223167,223168,223169,223169,223169,223171,223171,223171,223171,223171,223173,223173,223173,223173,223175,223175,223176,223178,223178,223179,223179,223179,223179,223181,223182,223184,223187,223191,223200,223200,223203,223204,223204,223204,223207,223209,223210,223210,223210,223210,223210,223211,223211,223211,223211,223211,223214,223214,223214,223214,223214,223214,223214,223215,223215,223215,223215,223217,223217,223217,223217,223217,223217,223220,223222,223222,223224,223224,223224,223225,223225,223225,223228,223228,223228,223228,223228,223228,223228,223230,223231,223231,223233,223234,223235,223235,223235,223235,223235,223239,223239,223239,223240,223240,223240,223240,223241,223241,223241,223241,223241,223241,223242,223242,223242,223243,223243,223243,223243,223243,223243,223252,223254,223255,223256,223260,223269,223272,223272,223272,223272,223273,223273,223275,223277,223277,223278,223278,223278,223279,223280,223281,223283,223283,223284,223285,223285,223285,223285,223285,223285,223285,223285,223285,223285,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223286,223288,223288,223289,223289,223289,223290,223290,223290,223290,223292,223295,223297,223297,223298,223298,223298,223299,223300,223301,223302,223302,223302,223302,223302,223303,223303,223303,223303,223303,223304,223304,223304,223304,223304,223310,223311,223311,223311,223312,223313,223313,223314,223314,223314,223316,223316,223319,223319,223319,223319,223320,223322,223322,223322,223323,223323,223323,223323,223323,223324,223325,223325,223325,223328,223328,223329,223329,223329,223330,223330,223330,223331,223334,223337,223343,223347,223353,223357,223360,223361,223362,223366,223369,223371,223374,223374,223381,223384,223385,223393,223404,223406,223414,223414,223414,223414,223414,223414,223414,223414,223414,223414,223414,223414,223414,223415,223419,223421,223422,223422,223422,223423,223430,223431,223431,223432,223432,223436,223440,223440,223440,223442,223442,223443,223443,223443,223444,223444,223447,223447,223447,223447,223447,223447,223447,223447,223447,223447,223447,223448,223449,223449,223450,223462,223462,223462,223462,223462,223462,223462,223462,223465,223467,223468,223471,223471,223473,223474,223474,223474,223474,223475,223476,223480,223483,223493,223497,223497,223499,223499,223505,223505,223506,223506,223506,223507,223510,223514,223518,223520,223520,223520,223528,223531,223532,223535,223536,223541,223544,223545,223555,223555,223555,223555,223555,223555,223555,223556,223558,223559,223559,223559,223559,223559,223560,223560,223560,223560,223560,223561,223566,223568,223568,223568,223568,223568,223572,223573,223579,223580,223581,223581,223581,223581,223581,223581,223581,223581,223581,223581,223582,223584,223586,223587,223587,223590,223590,223590,223593,223593,223593,223593,223593,223593,223593,223597,223597,223600,223602,223603,223603,223604,223607,223608,223615,223620,223620,223622,223622,223625,223627,223630,223632,223632,223632,223636,223638,223642,223642,223643,223643,223644,223644,223644,223645,223646,223647,223647,223647,223648,223649,223653,223657,223659,223660,223661,223661,223661,223664,223670,223670,223671,223671,223672,223673,223676,223679,223682,223682,223682,223682,223682,223683,223684,223684,223687,223691,223692,223694,223708,223712,223721,223722,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223723,223732,223734,223737,223739,223739,223739,223743,223743,223745,223745,223746,223747,223751,223751,223752,223752,223753,223753,223753,223754,223754,223754,223754,223755,223755,223755,223755,223755,223755,223755,223756,223757,223757,223757,223757,223757,223757,223758,223758,223758,223759,223759,223759,223759,223759,223759,223759,223760,223760,223760,223760,223760,223760,223760,223760,223761,223761,223761,223761,223761,223761,223762,223762,223762,223762,223762,223762,223762,223762,223762,223762,223765,223766,223769,223771,223773,223773,223774,223775,223775,223777,223777,223778,223778,223780,223780,223781,223781,223782,223785,223786,223789,223789,223789,223793,223793,223794,223795,223799,223799,223799,223802,223803,223803,223803,223803,223804,223805,223805,223807,223807,223807,223807,223807,223807,223813,223813,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223814,223815,223816,223816,223817,223818,223818,223822,223827,223827,223833,223833,223838,223838,223838,223841,223842,223842,223843,223846,223846,223846,223850,223850,223850,223852,223857,223858,223858,223858,223859,223869,223874,223874,223874,223875,223875,223878,223886,223887,223887,223887,223889,223891,223891,223896,223904,223905,223905,223907,223907,223910,223913,223913,223914,223915,223915,223925,223927,223930,223933,223933,223934,223934,223934,223936,223937,223940,223941,223942,223948,223952,223955,223961,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223962,223966,223968,223969,223973,223973,223973,223973,223975,223975,223975,223976,223977,223977,223977,223977,223978,223979,223984,223984,223988,223988,223989,223990,223990,223990,223996,223997,224003,224003,224003,224006,224009,224009,224009,224010,224015,224015,224015,224015,224015,224015,224016,224016,224017,224020,224023,224026,224033,224033,224033,224033,224033,224033,224035,224050,224054,224055,224056,224058,224060,224062,224064,224064,224068,224073,224078,224078,224078,224081,224081,224081,224081,224082,224084,224085,224085,224085,224085,224085,224086,224087,224088,224088,224090,224092,224092,224092,224095,224097,224097,224097,224098,224100,224102,224102,224103,224104,224108,224110,224110,224110,224111,224111,224111,224111,224112,224113,224113,224113,224115,224120,224124,224128,224141,224142,224153,224155,224159,224165,224168,224172,224174,224175,224183,224183,224183,224186,224189,224190,224190,224191,224198,224199,224199,224199,224199,224199,224202,224202,224203,224207,224212,224214,224218,224218,224218,224220,224221,224221,224224,224225,224233,224233,224233,224236,224237,224237,224237,224241,224244,224247,224247,224247,224250,224250,224250,224250,224250,224250,224250,224250,224257,224258,224260,224261,224262,224262,224263,224265,224265,224267,224267,224268,224270,224271,224272,224273,224275,224275,224279,224282,224282,224283,224286,224286,224286,224286,224294,224298,224298,224302,224302,224302,224302,224303,224304,224304,224308,224315,224320,224328,224332,224333,224335,224337,224342,224348,224349,224350,224350,224350,224350,224355,224355,224356,224358,224358,224362,224362,224365,224365,224365,224367,224368,224368,224368,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224369,224370,224373,224374,224377,224393,224393,224393,224396,224396,224396,224402,224402,224402,224415,224415,224415,224415,224415,224415,224422,224422,224427,224427,224431,224431,224434,224434,224434,224434,224435,224436,224437,224437,224438,224438,224438,224438,224438,224438,224438,224441,224441,224446,224446,224447,224448,224450,224454,224458,224458,224458,224458,224459,224459,224460,224460,224460,224460,224460,224462,224462,224466,224467,224475,224475,224476,224478,224482,224487,224491,224492,224494,224499,224507,224508,224508,224511,224511,224522,224534,224534,224534,224540,224551,224551,224551,224558,224562,224563,224563,224566,224566,224569,224569,224570,224570,224570,224575,224579,224581,224581,224581,224581,224589,224589,224601,224602,224602,224606,224606,224606,224612,224612,224615,224615,224615,224615,224615,224621,224634,224650,224653,224654,224655,224661,224662,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224665,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224666,224671,224672,224672,224675,224675,224675,224677,224677,224677,224677,224680,224683,224683,224692,224692,224695,224695,224695,224700,224700,224700,224700,224705,224706,224717,224717,224717,224717,224717,224730,224734,224736,224745,224746,224746,224753,224753,224753,224755,224755,224755,224755,224756,224757,224759,224768,224779,224779,224779,224779,224784,224785,224786,224786,224786,224786,224786,224786,224786,224786,224786,224786,224786,224787,224788,224789,224789,224789,224789,224790,224791,224793,224793,224797,224808,224809,224809,224811,224811,224814,224826,224826,224826,224827,224827,224827,224829,224830,224830,224831,224831,224831,224832,224848,224855,224859,224861,224861,224867,224871,224878,224883,224883,224903,224908,224908,224916,224919,224921,224930,224938,224943,224947,224959,224959,224961,224972,224980,224980,224980,224980,224981,224981,224991,224991,225000,225000,225002,225005,225006,225007,225008,225023,225025,225025,225025,225046,225049,225059,225061,225062,225062,225063,225063,225066,225067,225069,225069,225074,225075,225075,225075,225084,225084,225086,225090,225090,225098,225098,225099,225099,225099,225102,225104,225105,225106,225108,225108,225109,225110,225110,225110,225112,225112,225112,225113,225113,225113,225114,225118,225118,225118,225118,225118,225118,225118,225118,225118,225121,225128,225131,225131,225132,225132,225132,225132,225136,225139,225142,225146,225146,225147,225148,225153,225157,225157,225161,225162,225162,225162,225179,225206,225214,225214,225214,225221,225224,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225225,225230,225238,225238,225238,225240,225240,225245,225247,225247,225248,225248,225248,225249,225250,225251,225256,225256,225256,225256,225258,225258,225258,225258,225261,225261,225267,225269,225271,225271,225275,225276,225276,225276,225276,225277,225281,225281,225281,225284,225284,225284,225285,225285,225290,225290,225293,225293,225293,225293,225293,225294,225294,225296,225297,225299,225304,225304,225305,225306,225308,225310,225310,225310,225312,225312,225312,225313,225313,225316,225316,225321,225331,225331,225331,225331,225331,225331,225331,225331,225331,225334,225338,225338,225338,225342,225345,225345,225346,225366,225367,225379,225384,225392,225400,225400,225400,225406,225408,225413,225413,225413,225414,225415,225415,225418,225425,225425,225425,225425,225425,225427,225427,225443,225458,225462,225462,225468,225469,225477,225488,225489,225489,225494,225496,225500,225504,225506,225512,225515,225520,225520,225523,225532,225533,225538,225540,225543,225547,225548,225550,225551,225551,225553,225554,225554,225554,225554,225554,225555,225557,225557,225559,225559,225560,225560,225560,225560,225560,225560,225562,225562,225562,225564,225566,225566,225566,225566,225566,225566,225567,225567,225573,225575,225575,225575,225575,225575,225575,225585,225590,225590,225590,225590,225590,225590,225590,225595,225598,225598,225598,225598,225604,225604,225604,225606,225606,225606,225606,225611,225611,225611,225611,225616,225616,225617,225636,225638,225638,225651,225655,225655,225659,225659,225662,225662,225662,225662,225662,225662,225663,225663,225668,225673,225677,225679,225680,225692,225701,225711,225713,225718,225718,225723,225729,225748,225753,225761,225763,225765,225765,225765,225765,225767,225767,225767,225768,225768,225768,225770,225771,225772,225772,225774,225774,225774,225776,225776,225781,225781,225781,225782,225784,225784,225784,225784,225784,225784,225784,225784,225784,225785,225786,225787,225787,225787,225788,225788,225795,225795,225797,225798,225798,225798,225801,225803,225803,225808,225812,225815,225820,225820,225823,225830,225830,225830,225830,225835,225848,225848,225850,225855,225862,225863,225863,225865,225866,225866,225866,225866,225866,225866,225866,225866,225866,225866,225866,225866,225867,225867,225869,225869,225869,225869,225870,225870,225871,225877,225883,225884,225885,225888,225891,225892,225892,225895,225903,225907,225909,225910,225913,225915,225915,225916,225916,225916,225916,225916,225916,225919,225926,225927,225936,225946,225949,225949,225952,225955,225963,225975,225975,225975,225975,225975,225975,225975,225975,225975,225975,225975,225975,225975,225975,225975,225976,225976,225976,225979,225980,225980,225981,225989,225989,225989,225989,225991,225992,225997,225997,225998,226001,226020,226020,226025,226026,226026,226031,226033,226033,226034,226040,226046,226048,226054,226060,226060,226060,226061,226064,226064,226064,226064,226064,226064,226064,226064,226064,226064,226066,226067,226067,226067,226067,226067,226067,226069,226069,226069,226070,226070,226070,226072,226073,226078,226078,226080,226080,226083,226084,226084,226086,226089,226089,226095,226100,226111,226112,226112,226112,226123,226141,226144,226144,226144,226146,226146,226154,226154,226155,226170,226174,226175,226175,226175,226175,226175,226179,226183,226187,226187,226190,226190,226191,226191,226192,226195,226197,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226199,226206,226206,226206,226222,226222,226222,226225,226225,226225,226232,226238,226238,226238,226238,226238,226243,226244,226248,226252,226254,226257,226257,226257,226257,226258,226260,226260,226260,226260,226260,226262,226264,226264,226267,226267,226273,226276,226276,226277,226277,226278,226278,226278,226279,226279,226279,226279,226279,226281,226281,226282,226282,226282,226282,226282,226282,226283,226283,226284,226284,226284,226284,226287,226287,226292,226293,226294,226294,226295,226305,226308,226312,226312,226312,226312,226312,226312,226312,226312,226312,226312,226313,226314,226314,226314,226319,226320,226324,226324,226324,226324,226324,226324,226329,226332,226332,226334,226336,226337,226338,226339,226341,226341,226344,226344,226344,226344,226345,226346,226348,226352,226352,226352,226352,226352,226353,226353,226353,226356,226363,226365,226366,226368,226368,226369,226369,226378,226378,226391,226401,226403,226409,226412,226417,226418,226420,226421,226421,226423,226429,226433,226435,226439,226439,226439,226445,226445,226446,226446,226453,226456,226458,226458,226463,226464,226466,226466,226466,226467,226467,226468,226491,226495,226495,226495,226496,226497,226502,226506,226517,226517,226517,226519,226523,226524,226524,226524,226524,226524,226524,226526,226528,226536,226536,226536,226536,226536,226539,226539,226539,226541,226548,226550,226565,226565,226565,226573,226574,226574,226580,226595,226595,226597,226597,226602,226609,226614,226630,226630,226632,226637,226638,226645,226647,226648,226652,226653,226653,226656,226662,226681,226681,226681,226681,226681,226681,226681,226681,226698,226701,226704,226705,226705,226705,226705,226709,226709,226709,226709,226709,226709,226709,226709,226715,226720,226728,226737,226741,226742,226747,226753,226762,226763,226763,226764,226766,226766,226768,226768,226768,226768,226772,226775,226778,226782,226794,226794,226799,226801,226805,226806,226806,226813,226817,226822,226829,226831,226832,226836,226840,226841,226843,226848,226852,226854,226862,226862,226862,226862,226866,226867,226873,226876,226881,226881,226883,226885,226892,226893,226893,226918,226918,226918,226918,226931,226945,226949,226949,226958,226959,226964,226969,226969,226975,226979,226981,226997,227001,227002,227003,227015,227015,227027,227027,227034,227034,227036,227036,227039,227041,227044,227045,227052,227052,227052,227052,227052,227052,227052,227052,227055,227056,227057,227058,227058,227058,227074,227075,227075,227075,227075,227075,227075,227075,227075,227079,227084,227084,227092,227092,227095,227100,227100,227100,227104,227107,227110,227110,227112,227113,227113,227115,227115,227116,227117,227120,227122,227122,227124,227124,227124,227124,227124,227124,227125,227130,227135,227137,227139,227145,227153,227163,227163,227167,227167,227167,227167,227167,227167,227167,227167,227167,227167,227167,227168,227168,227168,227168,227168,227168,227168,227168,227168,227168,227170,227170,227170,227170,227171,227171,227171,227172,227172,227172,227172,227173,227173,227174,227174,227175,227177,227178,227181,227182,227182,227182,227182,227182,227182,227183,227183,227183,227183,227183,227183,227183,227184,227185,227186,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227187,227189,227190,227190,227190,227190,227190,227190,227190,227190,227190,227190,227191,227191,227191,227193,227201,227201,227201,227201,227203,227203,227203,227203,227207,227214,227214,227214,227215,227226,227229,227231,227234,227241,227241,227241,227246,227249,227253,227253,227254,227257,227258,227267,227269,227272,227275,227275,227275,227279,227279,227279,227279,227282,227284,227287,227288,227292,227294,227295,227295,227304,227308,227308,227308,227308,227313,227313,227313,227313,227313,227317,227318,227319,227321,227322,227323,227326,227329,227330,227340,227343,227346,227347,227347,227348,227359,227359,227359,227364,227364,227365,227379,227384,227393,227395,227395,227399,227402,227408,227408,227408,227428,227432,227434,227437,227445,227445,227446,227447,227450,227456,227459,227464,227464,227465,227468,227469,227472,227473,227473,227473,227473,227473,227478,227478,227478,227481,227494,227498,227506,227510,227510,227512,227512,227512,227512,227512,227512,227513,227515,227515,227516,227536,227541,227548,227549,227549,227550,227557,227557,227560,227565,227568,227573,227577,227584,227586,227587,227587,227587,227588,227588,227588,227588,227588,227599,227599,227607,227612,227613,227616,227622,227625,227635,227640,227649,227652,227652,227652,227652,227652,227652,227655,227659,227659,227659,227659,227662,227663,227665,227668,227675,227675,227675,227675,227675,227677,227680,227680,227680,227680,227682,227684,227692,227692,227698,227701,227701,227701,227701,227704,227705,227705,227706,227707,227711,227716,227727,227734,227741,227741,227751,227755,227756,227756,227756,227764,227767,227767,227767,227772,227775,227782,227794,227798,227806,227807,227817,227818,227820,227832,227841,227845,227851,227870,227877,227878,227891,227892,227892,227892,227895,227897,227897,227897,227924,227925,227930,227932,227932,227939,227946,227946,227951,227965,227965,227974,227974,227974,227981,227981,227981,227994,227994,228027,228033,228033,228039,228039,228049,228049,228049,228049,228060,228061,228061,228064,228064,228064,228064,228070,228070,228070,228074,228075,228075,228076,228078,228078,228082,228082,228088,228092,228094,228094,228101,228109,228111,228111,228111,228112,228120,228124,228130,228146,228149,228158,228167,228170,228170,228170,228177,228178,228180,228180,228182,228182,228185,228194,228202,228210,228210,228220,228220,228222,228234,228235,228248,228251,228259,228270,228274,228279,228283,228285,228289,228295,228295,228295,228298,228305,228305,228309,228309,228310,228312,228312,228314,228316,228319,228319,228320,228320,228320,228320,228322,228323,228325,228326,228326,228330,228331,228333,228343,228343,228343,228343,228343,228343,228343,228343,228351,228353,228353,228353,228355,228356,228361,228363,228363,228363,228363,228384,228385,228385,228385,228386,228394,228396,228396,228399,228399,228401,228405,228408,228409,228419,228422,228432,228445,228447,228448,228461,228461,228461,228464,228465,228467,228467,228467,228467,228472,228478,228482,228482,228485,228485,228485,228485,228486,228487,228487,228487,228487,228487,228487,228490,228490,228491,228491,228495,228503,228506,228506,228509,228514,228514,228519,228526,228530,228532,228540,228544,228553,228558,228561,228563,228565,228568,228579,228585,228591,228594,228594,228611,228624,228626,228626,228626,228626,228626,228626,228626,228626,228640,228652,228655,228657,228661,228666,228672,228679,228682,228683,228689,228698,228699,228701,228704,228705,228705,228707,228715,228719,228722,228731,228732,228732,228733,228734,228734,228734,228738,228749,228757,228775,228776,228776,228779,228780,228780,228780,228780,228781,228781,228796,228799,228804,228807,228807,228807,228809,228818,228819,228819,228820,228822,228826,228826,228828,228829,228831,228832,228833,228834,228836,228836,228840,228840,228841,228845,228845,228849,228851,228851,228852,228853,228860,228865,228874,228883,228884,228899,228909,228909,228925,228928,228933,228934,228937,228948,228950,228959,228967,228973,228973,228975,228975,228978,228978,228978,228987,228987,228995,228997,229001,229005,229005,229005,229005,229005,229005,229005,229005,229005,229008,229009,229009,229009,229009,229009,229009,229009,229009,229014,229015,229016,229017,229017,229027,229027,229027,229027,229029,229031,229039,229039,229040,229056,229058,229065,229071,229083,229083,229089,229097,229104,229105,229107,229108,229108,229108,229108,229109,229109,229110,229110,229110,229111,229111,229113,229113,229113,229114,229116,229119,229128,229140,229140,229143,229143,229143,229146,229150,229151,229152,229153,229153,229160,229165,229168,229168,229168,229168,229169,229177,229179,229180,229180,229180,229182,229184,229186,229187,229195,229201,229201,229201,229214,229216,229223,229225,229225,229225,229225,229226,229228,229228,229232,229233,229233,229235,229236,229238,229241,229243,229250,229255,229255,229255,229256,229257,229261,229261,229263,229275,229280,229282,229282,229286,229290,229316,229321,229333,229333,229344,229344,229344,229344,229354,229359,229362,229365,229375,229375,229380,229380,229380,229380,229382,229393,229397,229397,229397,229399,229402,229402,229405,229408,229413,229415,229416,229420,229420,229426,229427,229428,229430,229433,229436,229441,229446,229446,229447,229449,229452,229458,229462,229462,229465,229465,229466,229466,229466,229466,229475,229477,229484,229486,229487,229493,229509,229511,229513,229515,229523,229530,229536,229536,229536,229537,229538,229541,229543,229543,229543,229543,229544,229544,229544,229544,229544,229544,229545,229546,229546,229546,229546,229549,229550,229554,229556,229558,229570,229573,229576,229576,229576,229579,229581,229594,229594,229594,229598,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229609,229612,229614,229614,229614,229614,229615,229615,229615,229615,229615,229615,229615,229616,229616,229616,229616,229616,229616,229617,229617,229617,229617,229618,229618,229618,229618,229620,229620,229623,229623,229623,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229625,229628,229629,229629,229629,229629,229631,229631,229631,229631,229631,229631,229633,229635,229637,229637,229637,229638,229639,229645,229647,229647,229649,229650,229651,229651,229651,229651,229651,229651,229651,229651,229651,229651,229652,229652,229654,229654,229655,229656,229656,229656,229657,229657,229657,229657,229657,229657,229659,229660,229660,229660,229660,229660,229660,229660,229661,229661,229662,229663,229663,229664,229666,229666,229667,229668,229669,229669,229670,229672,229674,229675,229675,229677,229678,229684,229684,229684,229684,229685,229690,229690,229693,229698,229698,229701,229703,229704,229704,229704,229704,229704,229704,229705,229705,229705,229705,229705,229709,229710,229711,229711,229712,229712,229712,229712,229712,229712,229713,229715,229715,229715,229715,229715,229715,229715,229716,229717,229718,229718,229720,229721,229721,229725,229725,229725,229725,229725,229725,229726,229726,229727,229727,229731,229735,229736,229742,229743,229748,229748,229751,229752,229752,229753,229756,229756,229756,229757,229757,229757,229759,229762,229765,229765,229765,229769,229770,229770,229770,229770,229770,229770,229771,229773,229773,229773,229774,229775,229776,229777,229780,229780,229782,229782,229782,229786,229786,229788,229796,229796,229797,229803,229811,229814,229815,229816,229816,229820,229820,229820,229830,229832,229836,229842,229844,229845,229854,229854,229857,229863,229868,229873,229873,229873,229873,229873,229877,229877,229877,229877,229877,229884,229885,229885,229887,229887,229887,229887,229892,229893,229895,229896,229899,229899,229900,229901,229908,229909,229909,229913,229925,229925,229925,229925,229928,229931,229937,229954,229955,229956,229959,229962,229968,229972,229977,229984,229985,229985,229985,229985,229985,229985,229985,229985,229985,229985,229985,229991,229996,229996,229996,229996,229996,229998,230000,230003,230003,230003,230003,230003,230003,230004,230005,230006,230007,230010,230010,230010,230010,230010,230011,230011,230011,230021,230021,230021,230021,230022,230022,230022,230022,230022,230022,230024,230032,230032,230032,230032,230035,230046,230049,230056,230058,230062,230063,230067,230068,230085,230093,230095,230096,230101,230104,230110,230127,230127,230127,230127,230128,230128,230128,230146,230154,230158,230158,230158,230166,230172,230174,230180,230183,230190,230190,230191,230194,230194,230194,230194,230197,230198,230209,230210,230211,230214,230215,230215,230217,230226,230226,230229,230233,230256,230258,230260,230260,230267,230267,230267,230270,230275,230277,230287,230287,230292,230296,230296,230296,230297,230298,230299,230310,230314,230321,230334,230345,230351,230351,230351,230362,230364,230365,230365,230365,230370,230370,230378,230380,230385,230387,230390,230395,230395,230395,230395,230395,230396,230396,230396,230396,230397,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230401,230407,230408,230408,230408,230408,230411,230414,230414,230414,230415,230415,230416,230417,230418,230418,230420,230420,230423,230424,230425,230435,230444,230448,230448,230464,230471,230472,230487,230488,230496,230500,230504,230506,230507,230507,230507,230507,230512,230513,230515,230520,230520,230520,230520,230521,230535,230535,230536,230536,230544,230550,230550,230560,230560,230564,230564,230564,230567,230567,230569,230569,230569,230569,230569,230572,230573,230573,230573,230583,230587,230591,230605,230612,230615,230616,230616,230619,230621,230622,230626,230626,230626,230632,230633,230633,230636,230637,230637,230644,230647,230655,230655,230655,230655,230655,230655,230655,230658,230667,230679,230703,230703,230703,230708,230709,230711,230712,230727,230734,230736,230736,230736,230736,230736,230737,230740,230745,230746,230746,230747,230750,230750,230756,230756,230756,230756,230757,230757,230757,230757,230757,230759,230760,230760,230760,230760,230761,230761,230762,230764,230764,230764,230764,230764,230764,230765,230766,230767,230767,230773,230773,230775,230776,230778,230778,230781,230782,230784,230787,230795,230801,230806,230808,230811,230824,230824,230824,230828,230828,230831,230833,230841,230849,230851,230853,230859,230861,230861,230861,230861,230863,230867,230867,230869,230871,230875,230875,230876,230876,230878,230878,230878,230880,230880,230880,230880,230880,230885,230885,230885,230885,230885,230885,230885,230885,230886,230890,230890,230895,230895,230896,230899,230904,230910,230916,230916,230916,230916,230916,230916,230920,230921,230924,230932,230939,230944,230944,230944,230944,230944,230945,230945,230945,230945,230945,230946,230951,230952,230956,230958,230959,230959,230959,230959,230959,230959,230959,230959,230960,230960,230960,230960,230963,230982,230982,230982,230984,230984,230991,230992,230992,230994,230995,230998,231003,231004,231004,231004,231004,231004,231004,231004,231004,231005,231012,231013,231016,231016,231034,231039,231041,231047,231052,231056,231056,231056,231060,231061,231063,231067,231069,231073,231075,231077,231080,231086,231087,231090,231090,231092,231093,231095,231095,231098,231105,231105,231111,231118,231123,231123,231125,231125,231133,231143,231145,231146,231146,231149,231155,231155,231155,231155,231155,231155,231156,231157,231161,231163,231164,231173,231178,231205,231209,231211,231216,231217,231219,231219,231219,231219,231219,231219,231219,231219,231219,231219,231219,231219,231227,231227,231228,231232,231239,231243,231243,231243,231254,231254,231254,231254,231255,231255,231255,231255,231255,231257,231260,231262,231262,231262,231262,231262,231268,231268,231269,231269,231269,231269,231269,231269,231269,231273,231275,231279,231286,231287,231296,231296,231301,231306,231309,231310,231311,231313,231319,231319,231319,231322,231322,231322,231325,231325,231325,231325,231325,231325,231325,231325,231325,231325,231325,231326,231328,231334,231334,231334,231343,231343,231343,231343,231343,231344,231344,231344,231344,231344,231346,231346,231346,231346,231346,231348,231353,231353,231353,231353,231355,231355,231355,231355,231355,231355,231356,231356,231356,231356,231356,231358,231358,231359,231359,231359,231359,231361,231363,231364,231369,231370,231371,231371,231373,231373,231376,231379,231380,231382,231382,231382,231382,231382,231383,231395,231401,231401,231404,231404,231405,231405,231405,231405,231406,231407,231407,231408,231408,231408,231408,231408,231408,231408,231408,231409,231409,231410,231412,231413,231413,231415,231415,231415,231415,231416,231416,231417,231417,231420,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231422,231433,231433,231433,231433,231434,231436,231443,231451,231452,231458,231458,231459,231463,231465,231465,231474,231477,231480,231482,231484,231486,231490,231495,231495,231495,231495,231495,231495,231496,231496,231496,231498,231505,231509,231514,231516,231533,231537,231540,231547,231547,231554,231560,231561,231563,231565,231571,231574,231576,231579,231580,231580,231580,231595,231595,231595,231597,231597,231597,231597,231597,231597,231605,231606,231608,231608,231610,231610,231610,231610,231610,231610,231610,231610,231610,231610,231610,231610,231611,231612,231612,231612,231612,231612,231612,231612,231612,231612,231612,231612,231612,231612,231612,231612,231614,231618,231619,231621,231621,231624,231625,231626,231626,231626,231626,231626,231629,231630,231633,231633,231633,231633,231635,231636,231636,231638,231643,231645,231646,231648,231648,231651,231652,231652,231652,231657,231665,231676,231678,231678,231679,231679,231686,231686,231686,231689,231692,231693,231695,231696,231699,231699,231703,231706,231710,231710,231710,231710,231713,231714,231717,231719,231720,231720,231724,231725,231727,231727,231727,231727,231728,231729,231730,231730,231730,231730,231730,231730,231732,231732,231732,231732,231733,231733,231733,231733,231733,231733,231733,231736,231736,231738,231738,231738,231738,231738,231738,231738,231740,231740,231740,231740,231742,231742,231742,231742,231743,231743,231743,231745,231747,231747,231747,231747,231749,231750,231750,231750,231750,231751,231754,231757,231761,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231762,231763,231764,231765,231765,231769,231769,231775,231776,231778,231781,231783,231787,231789,231789,231789,231790,231790,231790,231790,231790,231790,231790,231790,231791,231791,231791,231791,231792,231795,231795,231796,231798,231800,231803,231804,231805,231806,231807,231809,231809,231809,231809,231809,231809,231812,231812,231813,231817,231822,231824,231826,231826,231826,231826,231826,231826,231826,231826,231826,231826,231826,231826,231827,231828,231830,231831,231835,231839,231842,231842,231845,231849,231849,231856,231856,231857,231857,231857,231857,231857,231857,231857,231857,231857,231858,231860,231860,231862,231862,231862,231863,231866,231867,231867,231870,231871,231871,231871,231872,231873,231873,231873,231873,231873,231873,231873,231876,231877,231877,231878,231878,231878,231879,231881,231883,231886,231886,231890,231890,231890,231891,231891,231892,231895,231895,231895,231898,231901,231903,231903,231904,231905,231905,231906,231906,231907,231908,231908,231912,231912,231914,231914,231914,231914,231914,231914,231914,231915,231915,231915,231916,231916,231916,231916,231917,231919,231919,231919,231924,231925,231925,231926,231926,231926,231927,231929,231931,231931,231931,231931,231935,231936,231940,231941,231944,231946,231946,231947,231948,231949,231955,231955,231958,231959,231961,231962,231962,231965,231965,231966,231966,231969,231969,231969,231969,231969,231973,231974,231974,231974,231974,231974,231975,231975,231976,231976,231976,231976,231977,231977,231977,231977,231977,231980,231980,231980,231981,231981,231981,231981,231981,231981,231981,231983,231984,231990,231993,231993,231996,231996,231997,231997,231997,231997,231997,231998,231998,231998,231999,232001,232001,232001,232001,232002,232002,232004,232004,232004,232004,232004,232012,232012,232013,232019,232022,232022,232024,232025,232032,232033,232035,232035,232037,232039,232042,232042,232043,232044,232046,232046,232047,232047,232047,232048,232052,232055,232059,232059,232062,232064,232064,232065,232066,232066,232066,232066,232068,232068,232068,232069,232069,232069,232072,232072,232072,232074,232075,232075,232076,232076,232076,232079,232079,232079,232079,232079,232081,232081,232081,232087,232091,232091,232093,232093,232093,232093,232094,232094,232094,232095,232097,232101,232104,232106,232106,232107,232107,232107,232107,232107,232107,232107,232107,232109,232114,232114,232116,232116,232117,232117,232118,232118,232119,232121,232121,232126,232126,232126,232126,232126,232126,232126,232126,232126,232128,232128,232130,232139,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232145,232147,232147,232154,232157,232160,232160,232160,232160,232164,232165,232170,232171,232173,232174,232175,232175,232176,232180,232180,232180,232181,232184,232186,232187,232187,232187,232188,232188,232188,232188,232188,232188,232188,232189,232191,232191,232191,232191,232191,232191,232191,232191,232193,232195,232195,232198,232202,232202,232202,232202,232204,232204,232205,232205,232205,232206,232206,232206,232207,232207,232207,232207,232208,232209,232209,232209,232209,232209,232209,232213,232214,232214,232214,232215,232215,232217,232217,232217,232217,232217,232228,232228,232228,232228,232228,232228,232228,232228,232228,232228,232229,232230,232232,232233,232233,232234,232236,232237,232238,232238,232238,232238,232239,232239,232239,232239,232241,232241,232241,232243,232243,232243,232245,232245,232245,232247,232248,232249,232250,232257,232259,232259,232259,232259,232259,232260,232260,232260,232260,232260,232260,232260,232260,232260,232262,232262,232264,232264,232266,232266,232268,232270,232270,232271,232271,232271,232271,232271,232272,232273,232274,232274,232276,232277,232278,232278,232278,232285,232285,232287,232288,232293,232294,232295,232295,232296,232296,232299,232299,232299,232303,232304,232304,232304,232306,232308,232308,232313,232315,232317,232317,232317,232318,232318,232318,232320,232321,232325,232327,232328,232330,232331,232333,232333,232335,232335,232335,232336,232336,232337,232337,232338,232340,232340,232341,232341,232342,232342,232342,232342,232342,232342,232343,232343,232345,232345,232345,232347,232347,232347,232347,232350,232350,232350,232354,232354,232355,232355,232357,232357,232358,232358,232358,232358,232360,232362,232362,232366,232366,232368,232368,232371,232371,232372,232373,232373,232373,232373,232375,232375,232377,232378,232378,232380,232380,232380,232380,232380,232380,232382,232382,232382,232382,232382,232382,232385,232389,232389,232391,232393,232393,232395,232395,232395,232399,232399,232399,232400,232400,232400,232400,232414,232425,232425,232425,232425,232425,232425,232425,232426,232428,232430,232431,232431,232431,232432,232432,232432,232433,232436,232436,232436,232441,232447,232447,232450,232452,232452,232452,232452,232454,232457,232459,232459,232461,232464,232464,232467,232469,232470,232470,232471,232471,232471,232474,232475,232476,232478,232480,232482,232482,232486,232492,232492,232492,232494,232497,232499,232504,232504,232507,232513,232513,232517,232518,232519,232521,232521,232526,232536,232541,232561,232573,232574,232574,232577,232580,232580,232584,232605,232605,232605,232606,232620,232625,232625,232635,232637,232637,232643,232646,232646,232651,232666,232666,232666,232689,232692,232692,232692,232692,232692,232692,232692,232692,232692,232694,232696,232697,232701,232709,232727,232727,232728,232730,232730,232730,232730,232732,232732,232732,232733,232733,232733,232733,232735,232735,232735,232741,232745,232745,232745,232745,232747,232751,232754,232754,232754,232754,232757,232764,232766,232766,232766,232767,232772,232774,232775,232783,232786,232786,232789,232790,232793,232797,232798,232798,232798,232802,232803,232803,232803,232804,232804,232804,232814,232816,232818,232820,232821,232823,232826,232826,232827,232829,232829,232829,232829,232834,232836,232837,232837,232838,232839,232840,232841,232844,232844,232844,232844,232847,232850,232852,232856,232857,232857,232857,232858,232858,232860,232861,232861,232861,232862,232864,232864,232864,232864,232864,232865,232865,232865,232865,232865,232865,232865,232865,232866,232866,232866,232867,232867,232867,232867,232867,232868,232868,232868,232868,232868,232870,232872,232874,232875,232875,232878,232879,232879,232879,232880,232889,232889,232889,232889,232890,232890,232892,232895,232900,232900,232900,232903,232904,232905,232905,232908,232908,232909,232915,232915,232918,232921,232930,232931,232931,232931,232933,232933,232933,232937,232937,232937,232938,232945,232945,232945,232945,232945,232950,232952,232960,232966,232966,232966,232966,232966,232966,232966,232967,232975,232981,232981,232985,232991,232993,232993,232994,232995,232995,232999,233013,233013,233016,233016,233023,233026,233026,233045,233048,233054,233055,233062,233072,233073,233074,233075,233075,233076,233080,233082,233083,233083,233083,233083,233095,233099,233099,233105,233111,233111,233113,233113,233113,233114,233116,233116,233119,233120,233124,233126,233127,233138,233139,233140,233140,233140,233151,233161,233161,233164,233177,233180,233180,233180,233180,233180,233180,233180,233183,233194,233195,233197,233199,233199,233199,233199,233199,233199,233200,233200,233200,233202,233202,233205,233205,233205,233206,233213,233224,233225,233225,233235,233235,233235,233237,233239,233239,233242,233245,233245,233247,233248,233248,233250,233250,233250,233250,233251,233256,233263,233266,233267,233268,233268,233270,233270,233270,233272,233274,233274,233276,233276,233277,233277,233277,233277,233281,233283,233283,233286,233286,233288,233290,233293,233294,233294,233294,233294,233295,233297,233297,233301,233301,233302,233303,233303,233318,233326,233329,233337,233343,233352,233352,233358,233363,233363,233363,233365,233371,233377,233379,233382,233382,233382,233382,233382,233382,233382,233382,233382,233388,233402,233403,233403,233406,233412,233414,233414,233415,233415,233416,233417,233418,233441,233458,233472,233472,233472,233473,233473,233474,233474,233474,233479,233484,233489,233494,233497,233499,233505,233505,233514,233515,233522,233522,233522,233533,233534,233539,233546,233548,233548,233549,233550,233550,233550,233550,233550,233550,233551,233551,233552,233554,233554,233556,233559,233564,233567,233567,233567,233569,233577,233577,233578,233585,233587,233588,233590,233590,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233593,233599,233601,233605,233605,233606,233606,233606,233606,233606,233616,233616,233616,233616,233616,233616,233616,233616,233616,233618,233618,233625,233625,233630,233631,233631,233632,233636,233638,233641,233643,233645,233651,233658,233658,233658,233658,233661,233661,233663,233663,233663,233666,233668,233668,233669,233677,233679,233679,233679,233679,233680,233681,233681,233681,233682,233689,233689,233691,233691,233691,233694,233694,233698,233699,233703,233703,233705,233712,233712,233712,233713,233714,233714,233714,233714,233714,233721,233722,233722,233722,233723,233723,233723,233723,233724,233724,233724,233724,233724,233724,233724,233724,233724,233724,233724,233725,233725,233726,233726,233726,233726,233726,233726,233726,233726,233726,233726,233728,233729,233729,233729,233731,233731,233731,233732,233734,233734,233734,233735,233740,233747,233747,233749,233755,233763,233766,233769,233769,233772,233772,233772,233772,233772,233773,233774,233778,233779,233779,233790,233793,233798,233799,233803,233804,233804,233807,233812,233812,233812,233815,233815,233825,233828,233828,233828,233829,233831,233831,233832,233835,233837,233838,233838,233846,233847,233848,233848,233848,233856,233863,233865,233872,233872,233873,233873,233873,233873,233878,233879,233881,233881,233881,233882,233893,233893,233893,233893,233893,233893,233897,233897,233897,233897,233897,233897,233898,233898,233898,233898,233898,233898,233905,233905,233905,233906,233907,233911,233912,233915,233918,233919,233922,233922,233922,233926,233934,233935,233940,233947,233947,233948,233948,233955,233958,233958,233959,233963,233965,233966,233969,233973,233982,233984,233988,233988,233988,233991,233991,233994,233998,233998,233998,233998,234002,234004,234004,234010,234010,234010,234014,234019,234020,234030,234034,234039,234051,234051,234051,234051,234051,234069,234072,234075,234075,234079,234081,234083,234083,234090,234093,234095,234098,234102,234105,234105,234105,234109,234109,234109,234111,234114,234122,234122,234134,234137,234138,234140,234147,234147,234147,234155,234157,234157,234159,234166,234166,234167,234167,234168,234168,234168,234172,234177,234178,234183,234185,234185,234185,234185,234185,234191,234191,234194,234195,234195,234197,234200,234216,234220,234225,234225,234225,234225,234236,234244,234250,234250,234256,234258,234258,234258,234260,234260,234260,234260,234261,234263,234266,234270,234283,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234297,234304,234307,234310,234310,234310,234311,234311,234312,234314,234320,234322,234323,234325,234332,234337,234346,234346,234346,234351,234357,234357,234357,234357,234361,234361,234361,234362,234379,234382,234385,234388,234388,234388,234388,234388,234388,234389,234391,234391,234391,234391,234391,234391,234391,234391,234394,234394,234405,234405,234408,234412,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234425,234433,234444,234445,234446,234446,234460,234460,234460,234464,234466,234466,234466,234466,234467,234467,234469,234469,234476,234478,234483,234483,234483,234483,234490,234492,234492,234493,234494,234494,234494,234494,234494,234499,234508,234511,234511,234516,234518,234519,234521,234526,234526,234526,234526,234526,234526,234526,234526,234526,234526,234526,234530,234531,234533,234538,234543,234549,234551,234556,234562,234566,234566,234567,234575,234580,234585,234592,234593,234595,234600,234604,234604,234604,234605,234611,234615,234615,234627,234636,234637,234637,234642,234646,234647,234651,234653,234653,234655,234655,234660,234660,234660,234662,234663,234665,234667,234668,234677,234679,234683,234686,234686,234691,234691,234693,234693,234696,234697,234703,234711,234711,234711,234712,234712,234716,234726,234734,234734,234734,234734,234734,234737,234745,234753,234753,234753,234758,234761,234761,234766,234769,234771,234771,234774,234774,234774,234786,234809,234816,234827,234831,234832,234841,234841,234841,234843,234851,234858,234862,234862,234865,234866,234866,234869,234880,234880,234880,234883,234883,234883,234886,234887,234892,234903,234906,234914,234920,234922,234923,234923,234924,234924,234927,234927,234928,234931,234931,234932,234938,234940,234940,234941,234942,234942,234943,234944,234944,234944,234945,234945,234945,234945,234946,234946,234946,234946,234947,234948,234948,234948,234952,234953,234954,234958,234958,234958,234959,234963,234969,234975,234980,234980,234983,234983,234985,234991,234991,235004,235007,235009,235012,235019,235023,235027,235037,235040,235044,235044,235044,235047,235052,235052,235062,235062,235064,235064,235067,235067,235070,235072,235076,235076,235077,235078,235078,235078,235078,235078,235078,235078,235078,235081,235081,235082,235082,235083,235083,235092,235093,235093,235104,235108,235112,235115,235121,235122,235123,235126,235128,235129,235129,235129,235129,235129,235130,235130,235132,235132,235135,235149,235156,235157,235157,235160,235160,235161,235167,235167,235169,235175,235178,235188,235188,235189,235189,235189,235190,235190,235190,235190,235190,235190,235190,235191,235192,235205,235216,235220,235226,235233,235234,235236,235242,235245,235255,235256,235258,235259,235261,235261,235261,235261,235261,235261,235261,235261,235266,235276,235276,235276,235286,235288,235288,235290,235292,235292,235294,235297,235316,235316,235360,235362,235363,235365,235365,235365,235365,235369,235373,235373,235376,235385,235402,235404,235404,235404,235419,235419,235426,235432,235432,235440,235448,235449,235449,235449,235449,235449,235449,235449,235449,235450,235451,235452,235452,235452,235452,235452,235452,235452,235454,235454,235455,235459,235460,235461,235461,235465,235465,235465,235465,235467,235467,235468,235468,235468,235468,235468,235475,235477,235477,235477,235477,235479,235480,235489,235489,235489,235489,235491,235492,235492,235492,235495,235495,235495,235495,235500,235500,235500,235500,235500,235500,235500,235500,235500,235503,235503,235505,235505,235506,235509,235511,235512,235512,235512,235513,235513,235513,235514,235514,235515,235516,235517,235524,235525,235526,235527,235527,235533,235539,235541,235541,235545,235551,235551,235554,235554,235557,235557,235558,235559,235559,235560,235562,235565,235579,235579,235579,235582,235582,235582,235583,235583,235585,235591,235594,235596,235596,235596,235603,235612,235612,235613,235623,235626,235629,235634,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235636,235639,235639,235639,235639,235639,235640,235649,235650,235651,235654,235657,235661,235680,235680,235680,235680,235686,235688,235690,235690,235695,235717,235728,235748,235748,235769,235781,235793,235793,235795,235795,235795,235795,235817,235817,235817,235817,235817,235817,235817,235817,235824,235824,235824,235826,235828,235835,235835,235842,235843,235844,235848,235849,235849,235849,235849,235861,235864,235864,235864,235864,235865,235867,235870,235871,235872,235874,235874,235874,235874,235874,235875,235876,235876,235876,235876,235876,235876,235876,235876,235878,235878,235878,235878,235879,235879,235880,235882,235882,235882,235884,235884,235884,235893,235894,235894,235894,235894,235896,235896,235896,235896,235896,235897,235897,235897,235897,235898,235898,235899,235906,235906,235906,235906,235908,235908,235910,235912,235927,235929,235930,235930,235930,235934,235934,235934,235934,235934,235938,235938,235938,235938,235938,235939,235940,235942,235948,235948,235948,235948,235948,235948,235948,235949,235950,235950,235950,235950,235950,235951,235954,235954,235954,235954,235956,235956,235961,235961,235961,235961,235961,235962,235963,235963,235963,235963,235963,235963,235963,235963,235963,235963,235964,235964,235964,235964,235967,235967,235968,235969,235972,235972,235972,235972,235972,235974,235974,235980,235981,235982,235982,235984,235985,235985,235993,235993,235993,235993,235993,235993,235993,235993,235993,235996,236005,236008,236011,236013,236015,236017,236018,236029,236029,236030,236034,236034,236036,236037,236044,236045,236046,236046,236046,236048,236050,236050,236051,236055,236057,236061,236070,236070,236071,236078,236078,236085,236087,236087,236087,236087,236090,236101,236102,236107,236109,236109,236109,236113,236113,236114,236114,236114,236116,236120,236151,236152,236166,236167,236170,236175,236175,236178,236192,236200,236200,236200,236203,236207,236208,236221,236227,236233,236235,236235,236235,236238,236240,236242,236248,236248,236248,236248,236248,236253,236255,236265,236266,236284,236285,236285,236285,236285,236285,236292,236292,236292,236294,236296,236296,236297,236297,236299,236300,236301,236305,236305,236305,236305,236305,236310,236311,236311,236313,236313,236313,236323,236327,236330,236332,236332,236332,236339,236339,236339,236339,236339,236339,236339,236339,236339,236339,236339,236339,236339,236339,236340,236340,236348,236357,236358,236362,236362,236369,236375,236376,236377,236377,236379,236386,236389,236393,236393,236394,236394,236394,236396,236402,236402,236402,236403,236404,236413,236413,236415,236415,236415,236416,236417,236423,236423,236425,236425,236425,236425,236426,236443,236445,236462,236466,236466,236466,236466,236468,236470,236470,236472,236472,236473,236473,236480,236488,236488,236488,236495,236500,236500,236501,236501,236506,236512,236517,236517,236517,236517,236517,236521,236521,236521,236521,236525,236527,236531,236533,236536,236536,236536,236536,236536,236536,236537,236546,236549,236549,236551,236552,236557,236557,236563,236566,236572,236574,236574,236575,236575,236575,236578,236578,236578,236579,236583,236593,236599,236599,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236603,236604,236604,236605,236605,236605,236605,236605,236605,236605,236605,236605,236605,236608,236610,236610,236614,236617,236617,236617,236617,236617,236617,236617,236620,236620,236623,236624,236624,236624,236626,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236627,236628,236630,236630,236630,236630,236631,236632,236632,236632,236635,236636,236636,236637,236637,236638,236638,236638,236641,236641,236641,236641,236641,236641,236642,236642,236644,236644,236644,236644,236644,236650,236650,236650,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236651,236653,236657,236658,236659,236660,236665,236665,236665,236666,236668,236670,236670,236674,236676,236676,236676,236676,236676,236677,236679,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236680,236681,236681,236682,236682,236682,236683,236683,236683,236683,236683,236683,236684,236684,236684,236684,236685,236685,236686,236686,236686,236686,236686,236687,236687,236688,236688,236688,236690,236690,236690,236690,236690,236691,236691,236691,236692,236692,236692,236694,236694,236694,236694,236695,236695,236695,236696,236696,236696,236696,236696,236697,236698,236699,236699,236699,236699,236699,236699,236699,236699,236699,236699,236701,236701,236703,236703,236703,236703,236703,236703,236703,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236707,236708,236708,236709,236709,236709,236709,236709,236709,236709,236710,236710,236710,236710,236710,236710,236710,236710,236710,236712,236712,236713,236713,236713,236714,236714,236714,236714,236715,236716,236716,236717,236717,236718,236718,236718,236718,236719,236721,236722,236722,236722,236722,236722,236722,236722,236723,236723,236723,236723,236727,236729,236730,236730,236730,236733,236733,236734,236736,236736,236736,236736,236736,236736,236737,236737,236738,236739,236740,236740,236741,236742,236743,236743,236749,236750,236751,236753,236754,236754,236754,236756,236757,236757,236757,236757,236757,236758,236758,236759,236760,236760,236765,236766,236766,236769,236769,236776,236785,236785,236785,236785,236787,236788,236788,236789,236789,236791,236791,236795,236796,236797,236797,236797,236797,236799,236799,236799,236799,236799,236799,236801,236803,236803,236804,236807,236807,236808,236811,236811,236811,236811,236811,236812,236822,236827,236828,236828,236828,236828,236828,236828,236828,236828,236834,236836,236840,236842,236847,236852,236853,236859,236860,236861,236861,236863,236864,236864,236864,236864,236864,236865,236868,236869,236869,236870,236870,236871,236872,236875,236876,236878,236881,236882,236882,236884,236885,236885,236886,236898,236899,236899,236899,236902,236903,236904,236904,236906,236906,236906,236907,236907,236907,236907,236908,236908,236909,236912,236915,236919,236919,236925,236927,236929,236929,236929,236929,236931,236937,236937,236944,236944,236946,236947,236947,236951,236951,236951,236951,236951,236953,236954,236954,236955,236965,236969,236969,236969,236970,236970,236971,236972,236972,236973,236974,236974,236977,236977,236980,236980,236981,236992,236998,237003,237003,237004,237004,237006,237006,237006,237006,237006,237006,237006,237006,237006,237006,237006,237006,237007,237014,237023,237023,237023,237023,237023,237026,237028,237034,237034,237034,237034,237034,237034,237037,237037,237039,237045,237046,237048,237049,237058,237058,237058,237058,237058,237058,237058,237058,237058,237058,237058,237058,237061,237065,237066,237069,237069,237071,237073,237073,237085,237089,237089,237090,237093,237095,237098,237104,237118,237118,237118,237118,237118,237118,237118,237120,237126,237129,237129,237129,237129,237129,237129,237129,237132,237132,237135,237135,237149,237149,237154,237165,237165,237166,237169,237170,237171,237171,237172,237172,237173,237173,237177,237180,237183,237194,237194,237195,237200,237201,237201,237203,237203,237204,237222,237225,237227,237228,237229,237233,237233,237233,237233,237241,237241,237242,237242,237243,237249,237252,237252,237252,237252,237256,237260,237260,237260,237260,237260,237260,237260,237260,237260,237261,237261,237261,237261,237261,237261,237261,237261,237261,237262,237262,237262,237262,237262,237262,237263,237263,237263,237263,237263,237263,237263,237264,237264,237264,237264,237264,237264,237264,237264,237264,237265,237265,237265,237266,237267,237267,237267,237267,237267,237268,237268,237268,237269,237269,237269,237269,237269,237270,237270,237271,237274,237275,237276,237276,237276,237277,237277,237280,237283,237284,237284,237285,237286,237286,237286,237286,237290,237291,237295,237295,237295,237295,237295,237295,237295,237295,237295,237295,237295,237295,237302,237302,237302,237302,237302,237308,237310,237310,237310,237311,237312,237313,237314,237317,237318,237319,237325,237340,237340,237340,237340,237340,237341,237346,237347,237348,237348,237348,237353,237362,237365,237376,237388,237390,237392,237392,237392,237392,237392,237392,237392,237393,237393,237393,237402,237411,237411,237411,237417,237417,237424,237429,237432,237433,237437,237437,237437,237439,237445,237453,237453,237455,237456,237459,237459,237461,237465,237466,237466,237466,237470,237476,237488,237491,237498,237503,237503,237513,237518,237519,237519,237520,237527,237527,237527,237528,237529,237532,237539,237539,237541,237546,237547,237549,237551,237551,237551,237551,237554,237558,237560,237560,237564,237579,237579,237583,237586,237599,237600,237602,237602,237603,237611,237611,237611,237613,237613,237613,237624,237624,237624,237624,237624,237630,237630,237630,237630,237630,237631,237639,237639,237639,237639,237639,237639,237643,237644,237644,237645,237646,237650,237650,237651,237654,237655,237659,237659,237661,237661,237662,237663,237663,237663,237663,237663,237663,237663,237667,237667,237667,237667,237667,237668,237670,237670,237675,237675,237679,237679,237680,237682,237682,237682,237682,237689,237691,237691,237691,237691,237693,237693,237698,237705,237705,237705,237705,237708,237708,237709,237709,237709,237709,237720,237720,237720,237720,237720,237720,237720,237722,237724,237724,237724,237728,237731,237736,237742,237742,237742,237742,237742,237742,237742,237751,237751,237751,237751,237751,237751,237760,237760,237765,237765,237768,237769,237775,237775,237779,237782,237783,237784,237784,237785,237793,237794,237797,237799,237799,237802,237809,237811,237812,237812,237817,237818,237820,237827,237846,237849,237849,237849,237854,237858,237865,237874,237888,237890,237891,237891,237891,237893,237893,237913,237921,237921,237926,237934,237937,237952,237956,237958,237958,237959,237959,237959,237959,237959,237966,237973,237973,237974,237980,237987,237987,237992,238002,238002,238003,238006,238008,238010,238011,238011,238011,238011,238013,238015,238029,238029,238047,238052,238054,238057,238057,238057,238057,238062,238062,238071,238071,238073,238074,238074,238074,238074,238075,238075,238092,238093,238093,238094,238094,238099,238100,238100,238101,238101,238103,238103,238104,238105,238107,238113,238113,238117,238118,238125,238132,238133,238147,238152,238152,238155,238155,238159,238161,238161,238164,238166,238167,238175,238178,238178,238178,238182,238183,238196,238199,238210,238210,238213,238213,238213,238213,238213,238214,238218,238218,238219,238228,238228,238230,238230,238237,238237,238239,238242,238247,238248,238249,238249,238250,238250,238253,238253,238253,238254,238256,238266,238280,238281,238302,238302,238304,238308,238308,238321,238324,238324,238324,238324,238327,238330,238331,238341,238344,238345,238347,238350,238350,238355,238355,238355,238355,238356,238358,238366,238366,238366,238368,238372,238372,238379,238379,238385,238385,238385,238393,238393,238398,238401,238417,238426,238427,238428,238429,238429,238429,238429,238430,238433,238433,238435,238435,238437,238439,238439,238454,238454,238458,238470,238470,238470,238470,238477,238492,238494,238503,238508,238508,238512,238515,238516,238518,238525,238525,238525,238531,238531,238533,238533,238537,238537,238537,238542,238548,238549,238556,238560,238565,238565,238589,238595,238595,238595,238595,238599,238600,238600,238603,238607,238608,238608,238620,238632,238632,238636,238637,238638,238645,238647,238647,238654,238658,238662,238666,238669,238672,238674,238682,238692,238695,238704,238706,238717,238720,238723,238723,238723,238724,238724,238724,238724,238724,238725,238725,238725,238727,238728,238728,238730,238730,238732,238732,238737,238738,238738,238738,238738,238738,238740,238740,238740,238740,238740,238740,238740,238740,238740,238740,238740,238745,238748,238749,238755,238757,238758,238758,238770,238775,238781,238786,238791,238793,238793,238795,238796,238796,238796,238797,238797,238800,238801,238804,238805,238806,238811,238811,238811,238824,238827,238832,238837,238845,238845,238845,238846,238846,238852,238854,238867,238867,238876,238877,238877,238877,238877,238877,238877,238877,238877,238877,238877,238886,238896,238896,238899,238906,238910,238910,238910,238911,238916,238921,238925,238935,238935,238938,238938,238938,238950,238958,238958,238963,238965,238965,238966,238966,238966,238967,238967,238970,238970,238971,238972,238973,238973,238973,238975,238976,238977,238978,238979,238983,238983,238983,238983,238983,238986,238988,238988,238989,238993,238997,239005,239005,239005,239005,239008,239008,239010,239030,239030,239033,239040,239043,239043,239043,239047,239054,239057,239059,239059,239061,239068,239068,239074,239085,239088,239088,239092,239095,239095,239095,239103,239104,239109,239111,239118,239121,239123,239125,239127,239128,239130,239131,239131,239131,239134,239138,239141,239143,239144,239145,239145,239147,239148,239148,239149,239150,239150,239151,239153,239153,239163,239165,239165,239165,239165,239168,239168,239170,239172,239177,239179,239188,239192,239192,239201,239202,239204,239211,239212,239213,239213,239213,239213,239213,239213,239213,239213,239213,239213,239213,239213,239214,239214,239214,239221,239224,239224,239226,239226,239229,239232,239232,239232,239232,239238,239242,239243,239244,239245,239246,239246,239246,239254,239268,239273,239280,239282,239284,239286,239290,239291,239296,239300,239309,239316,239324,239325,239334,239334,239343,239343,239343,239346,239350,239351,239351,239355,239357,239357,239357,239361,239363,239366,239374,239374,239375,239379,239382,239385,239387,239387,239401,239402,239402,239402,239402,239405,239412,239416,239417,239419,239424,239430,239433,239435,239436,239442,239451,239454,239456,239459,239463,239467,239468,239469,239469,239473,239473,239473,239478,239483,239484,239497,239498,239498,239509,239513,239517,239517,239517,239524,239525,239527,239527,239528,239528,239529,239531,239534,239536,239546,239547,239555,239558,239562,239571,239572,239574,239577,239580,239583,239589,239598,239599,239602,239602,239604,239605,239616,239628,239633,239633,239634,239637,239637,239637,239638,239640,239647,239647,239650,239651,239653,239654,239659,239665,239674,239677,239677,239678,239686,239687,239695,239695,239701,239713,239714,239717,239718,239720,239720,239732,239732,239734,239734,239734,239734,239734,239734,239739,239743,239745,239750,239755,239757,239757,239757,239757,239757,239757,239757,239757,239757,239757,239757,239757,239757,239758,239760,239760,239765,239771,239776,239780,239781,239781,239781,239781,239792,239792,239793,239794,239797,239797,239797,239799,239803,239804,239809,239809,239809,239812,239813,239817,239826,239834,239835,239840,239842,239851,239854,239860,239860,239862,239863,239869,239869,239871,239872,239874,239874,239878,239878,239878,239878,239878,239878,239880,239885,239885,239885,239887,239888,239889,239889,239889,239891,239898,239901,239906,239907,239907,239907,239907,239912,239912,239920,239931,239938,239944,239944,239950,239951,239951,239951,239958,239958,239958,239958,239960,239961,239963,239963,239963,239963,239963,239963,239965,239965,239966,239967,239968,239969,239969,239969,239984,239985,239985,239986,239988,239988,239992,239992,239992,239994,239996,239996,239997,240000,240000,240004,240005,240005,240005,240005,240005,240005,240006,240006,240006,240008,240008,240009,240009,240010,240010,240010,240011,240011,240012,240019,240029,240045,240045,240046,240050,240050,240050,240050,240053,240053,240054,240054,240054,240054,240054,240054,240055,240055,240057,240059,240062,240064,240065,240065,240068,240068,240068,240072,240076,240076,240079,240079,240082,240085,240085,240085,240085,240085,240085,240085,240085,240085,240087,240089,240089,240090,240092,240092,240092,240095,240096,240097,240097,240097,240097,240101,240101,240116,240132,240135,240135,240135,240135,240148,240151,240151,240155,240158,240161,240164,240165,240172,240172,240172,240172,240172,240172,240172,240177,240177,240177,240177,240186,240187,240189,240194,240195,240195,240195,240211,240212,240213,240214,240219,240219,240219,240219,240220,240223,240223,240234,240234,240234,240239,240245,240246,240258,240258,240258,240258,240258,240258,240258,240258,240258,240258,240258,240267,240278,240281,240285,240286,240287,240287,240287,240293,240294,240295,240305,240309,240313,240314,240316,240321,240324,240324,240324,240324,240325,240325,240325,240325,240326,240326,240326,240326,240329,240330,240330,240330,240330,240330,240330,240330,240330,240330,240330,240330,240330,240332,240333,240335,240335,240336,240338,240338,240347,240347,240348,240348,240348,240348,240350,240350,240352,240352,240358,240359,240359,240362,240367,240372,240375,240375,240376,240376,240381,240384,240389,240393,240395,240397,240397,240404,240406,240412,240417,240420,240420,240427,240429,240436,240442,240446,240448,240454,240454,240457,240459,240459,240460,240462,240462,240463,240464,240465,240470,240474,240474,240474,240474,240474,240474,240477,240484,240486,240487,240489,240496,240497,240499,240500,240500,240500,240500,240504,240514,240515,240517,240521,240538,240538,240538,240538,240542,240549,240558,240558,240573,240575,240575,240578,240580,240595,240615,240628,240631,240639,240663,240663,240663,240663,240663,240673,240673,240677,240686,240688,240697,240697,240699,240707,240707,240707,240709,240709,240716,240723,240724,240737,240737,240737,240740,240740,240740,240740,240744,240749,240749,240749,240749,240753,240753,240753,240760,240761,240765,240765,240781,240784,240785,240795,240795,240796,240798,240806,240810,240816,240821,240826,240834,240834,240838,240838,240839,240841,240841,240841,240847,240847,240847,240849,240849,240851,240851,240851,240853,240859,240859,240859,240859,240859,240863,240863,240863,240863,240880,240888,240892,240893,240895,240908,240927,240938,240946,240949,240959,240962,240970,240971,240971,240971,240989,240989,240989,240989,240991,240991,240999,241000,241000,241000,241000,241000,241000,241000,241000,241003,241005,241005,241005,241005,241005,241006,241009,241009,241012,241016,241019,241022,241022,241024,241029,241033,241046,241047,241047,241056,241066,241069,241071,241074,241077,241078,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241088,241089,241092,241092,241092,241092,241093,241093,241094,241096,241096,241096,241101,241101,241101,241101,241102,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241103,241104,241104,241104,241104,241104,241105,241105,241105,241105,241105,241106,241106,241106,241110,241110,241110,241110,241110,241110,241110,241112,241114,241114,241114,241115,241115,241116,241116,241118,241120,241120,241120,241124,241124,241124,241124,241124,241125,241125,241125,241125,241125,241126,241126,241126,241126,241128,241129,241129,241129,241130,241133,241133,241133,241139,241139,241140,241141,241146,241146,241147,241148,241148,241149,241149,241149,241149,241153,241154,241156,241156,241159,241159,241160,241161,241163,241168,241168,241168,241168,241168,241168,241168,241168,241168,241168,241168,241168,241170,241173,241174,241175,241181,241205,241210,241217,241220,241220,241224,241231,241231,241237,241237,241243,241246,241248,241249,241249,241252,241260,241260,241266,241268,241268,241268,241268,241269,241269,241270,241275,241277,241277,241278,241279,241280,241280,241280,241281,241281,241281,241281,241282,241282,241282,241282,241282,241283,241288,241291,241295,241299,241304,241304,241305,241306,241309,241314,241317,241317,241320,241328,241337,241338,241338,241348,241353,241354,241356,241359,241367,241367,241367,241369,241372,241373,241373,241377,241380,241381,241382,241385,241387,241387,241389,241394,241395,241403,241404,241405,241405,241410,241413,241413,241413,241415,241415,241415,241415,241415,241415,241415,241415,241415,241415,241426,241426,241426,241426,241426,241426,241426,241426,241426,241426,241426,241433,241441,241442,241443,241446,241446,241447,241447,241447,241447,241447,241447,241447,241449,241455,241462,241464,241464,241466,241471,241471,241474,241476,241480,241483,241484,241488,241493,241495,241499,241500,241508,241508,241513,241513,241527,241527,241532,241533,241534,241536,241538,241540,241545,241550,241550,241550,241558,241558,241558,241558,241565,241565,241568,241580,241584,241584,241584,241584,241596,241596,241596,241596,241602,241610,241613,241613,241614,241614,241625,241625,241625,241625,241627,241627,241627,241632,241634,241637,241639,241640,241645,241645,241646,241647,241648,241665,241668,241672,241674,241682,241686,241686,241690,241690,241693,241693,241694,241694,241694,241694,241694,241694,241694,241694,241696,241696,241697,241697,241701,241701,241704,241720,241721,241727,241744,241752,241754,241766,241769,241772,241772,241774,241774,241788,241788,241789,241790,241790,241795,241795,241797,241803,241803,241803,241808,241810,241810,241810,241810,241810,241816,241817,241821,241823,241823,241823,241823,241829,241829,241830,241830,241839,241847,241857,241857,241857,241857,241860,241860,241860,241862,241862,241868,241874,241875,241882,241883,241905,241909,241915,241915,241915,241923,241923,241923,241924,241928,241928,241935,241935,241937,241938,241939,241939,241943,241943,241950,241955,241955,241956,241961,241966,241971,241971,241974,241974,241974,241974,241974,241977,241982,241986,241986,241986,241987,241999,242004,242004,242004,242010,242011,242011,242025,242025,242026,242028,242043,242054,242056,242061,242061,242070,242073,242074,242078,242100,242100,242100,242100,242100,242101,242104,242108,242108,242108,242108,242113,242117,242123,242123,242125,242125,242125,242129,242129,242129,242130,242130,242132,242132,242137,242137,242137,242143,242149,242157,242173,242186,242186,242188,242189,242189,242196,242196,242196,242201,242201,242225,242231,242240,242241,242241,242241,242241,242241,242241,242244,242244,242246,242246,242246,242252,242255,242255,242255,242255,242255,242255,242255,242259,242261,242261,242264,242271,242277,242281,242281,242281,242282,242282,242282,242294,242299,242299,242311,242315,242317,242320,242325,242325,242329,242330,242330,242330,242330,242330,242330,242330,242332,242332,242332,242336,242340,242341,242345,242346,242353,242353,242353,242354,242355,242359,242367,242370,242374,242377,242378,242386,242389,242389,242389,242389,242390,242390,242390,242394,242394,242394,242394,242394,242394,242394,242395,242398,242398,242398,242400,242400,242400,242400,242403,242403,242404,242415,242415,242418,242418,242418,242418,242422,242424,242428,242437,242440,242440,242440,242441,242441,242445,242456,242468,242468,242468,242480,242481,242484,242485,242490,242496,242502,242502,242502,242504,242511,242514,242517,242517,242522,242525,242529,242533,242544,242549,242549,242552,242568,242571,242572,242572,242581,242581,242581,242586,242588,242589,242596,242596,242596,242598,242598,242603,242603,242603,242604,242611,242613,242619,242625,242645,242645,242645,242645,242654,242657,242672,242680,242680,242681,242682,242685,242685,242693,242694,242694,242695,242696,242708,242708,242708,242719,242719,242719,242721,242721,242731,242755,242757,242757,242757,242763,242763,242764,242764,242764,242764,242764,242779,242780,242780,242782,242782,242785,242785,242785,242785,242796,242798,242801,242803,242808,242815,242827,242828,242845,242845,242851,242851,242861,242865,242880,242883,242884,242884,242884,242893,242893,242903,242913,242928,242930,242936,242936,242945,242945,242949,242952,242954,242958,242959,242959,242979,243011,243011,243011,243011,243011,243011,243012,243012,243013,243013,243013,243013,243013,243013,243013,243014,243014,243014,243014,243014,243014,243014,243016,243016,243017,243024,243024,243024,243036,243037,243037,243047,243052,243058,243068,243068,243069,243069,243069,243069,243069,243069,243069,243071,243078,243079,243079,243095,243101,243102,243102,243102,243102,243102,243102,243115,243126,243127,243136,243140,243143,243143,243143,243143,243144,243151,243152,243152,243153,243154,243155,243165,243166,243168,243169,243180,243180,243183,243185,243185,243185,243185,243185,243190,243196,243201,243201,243213,243231,243233,243234,243235,243236,243241,243245,243245,243254,243254,243258,243260,243260,243268,243268,243273,243280,243295,243307,243309,243310,243312,243314,243315,243319,243327,243328,243344,243346,243359,243373,243373,243383,243401,243401,243402,243402,243403,243403,243403,243403,243404,243404,243404,243404,243404,243404,243405,243405,243405,243405,243406,243406,243406,243406,243407,243407,243407,243407,243408,243408,243409,243409,243410,243410,243411,243411,243416,243431,243433,243437,243437,243450,243453,243456,243456,243456,243460,243460,243465,243465,243465,243472,243481,243481,243491,243492,243497,243499,243504,243526,243533,243533,243533,243541,243541,243541,243541,243541,243544,243546,243546,243547,243553,243554,243554,243556,243558,243562,243566,243566,243566,243566,243566,243566,243578,243583,243602,243610,243613,243615,243625,243625,243625,243625,243625,243627,243630,243630,243631,243635,243638,243645,243648,243649,243650,243656,243658,243658,243662,243665,243665,243666,243672,243680,243682,243682,243682,243685,243689,243689,243693,243693,243697,243699,243707,243707,243707,243707,243707,243707,243709,243709,243710,243710,243710,243710,243710,243710,243711,243711,243711,243712,243712,243712,243712,243713,243714,243714,243717,243717,243717,243717,243717,243717,243723,243723,243724,243724,243724,243724,243727,243727,243733,243743,243746,243746,243749,243752,243754,243754,243754,243755,243755,243755,243758,243760,243760,243764,243765,243771,243771,243771,243776,243776,243776,243777,243777,243777,243777,243778,243780,243781,243786,243789,243789,243793,243794,243795,243795,243795,243798,243802,243802,243803,243803,243809,243810,243810,243810,243810,243810,243817,243817,243817,243817,243817,243822,243823,243827,243827,243831,243837,243853,243856,243866,243866,243868,243868,243871,243874,243874,243899,243906,243906,243906,243906,243906,243906,243906,243906,243906,243906,243906,243906,243908,243909,243916,243916,243917,243917,243917,243917,243923,243926,243926,243937,243950,243959,243962,243964,243971,243972,243972,243972,243975,243975,243977,243983,243997,243999,244002,244014,244014,244014,244019,244019,244020,244023,244023,244032,244032,244044,244046,244048,244048,244048,244048,244048,244052,244052,244052,244053,244053,244055,244061,244065,244071,244074,244080,244085,244090,244093,244098,244100,244102,244102,244107,244122,244122,244125,244131,244134,244134,244134,244134,244135,244135,244135,244136,244139,244143,244147,244147,244160,244160,244162,244163,244166,244168,244168,244169,244170,244178,244179,244179,244181,244182,244187,244187,244187,244193,244199,244202,244204,244204,244210,244219,244222,244234,244241,244243,244243,244243,244243,244244,244244,244249,244249,244249,244261,244263,244265,244275,244278,244282,244286,244287,244293,244293,244295,244301,244305,244307,244307,244307,244319,244319,244332,244336,244340,244350,244353,244357,244357,244376,244379,244379,244379,244379,244379,244379,244379,244381,244401,244405,244419,244419,244419,244419,244423,244427,244427,244427,244428,244429,244430,244430,244430,244433,244435,244438,244440,244447,244447,244451,244453,244454,244454,244454,244456,244456,244456,244457,244457,244465,244465,244465,244465,244465,244466,244470,244472,244473,244473,244473,244473,244478,244479,244481,244481,244484,244485,244486,244486,244486,244489,244495,244498,244508,244510,244510,244512,244515,244516,244542,244549,244549,244550,244550,244554,244557,244557,244559,244560,244574,244579,244580,244582,244582,244582,244586,244596,244600,244600,244600,244602,244607,244609,244612,244616,244619,244619,244623,244623,244623,244624,244636,244649,244650,244661,244661,244661,244669,244676,244676,244676,244676,244677,244677,244685,244690,244690,244692,244694,244695,244697,244697,244698,244698,244701,244701,244706,244712,244718,244724,244724,244726,244726,244726,244726,244731,244731,244737,244738,244748,244751,244754,244756,244763,244763,244769,244786,244791,244791,244791,244792,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244804,244811,244811,244824,244825,244829,244831,244839,244844,244848,244849,244850,244851,244851,244851,244852,244852,244853,244860,244861,244861,244861,244863,244864,244864,244868,244869,244870,244871,244874,244874,244875,244881,244897,244898,244903,244903,244904,244906,244913,244925,244926,244928,244939,244940,244940,244940,244944,244947,244951,244951,244951,244951,244951,244951,244959,244962,244962,244962,244962,244964,244969,244969,244969,244969,244972,244986,244992,244995,244997,244999,245000,245007,245007,245020,245022,245028,245028,245049,245049,245049,245049,245049,245057,245063,245063,245067,245071,245071,245071,245072,245072,245072,245073,245076,245077,245081,245085,245090,245091,245092,245095,245096,245097,245101,245101,245101,245107,245111,245112,245117,245125,245125,245140,245140,245140,245140,245142,245145,245167,245191,245192,245194,245197,245204,245207,245217,245220,245223,245227,245235,245236,245237,245238,245242,245242,245242,245248,245248,245257,245265,245292,245297,245298,245301,245305,245307,245314,245321,245326,245333,245333,245333,245339,245345,245347,245349,245353,245353,245353,245354,245368,245368,245368,245393,245393,245395,245395,245402,245405,245411,245413,245414,245424,245424,245446,245446,245446,245446,245447,245451,245451,245451,245456,245456,245459,245472,245476,245476,245479,245482,245483,245483,245483,245483,245483,245485,245487,245493,245494,245494,245494,245494,245502,245509,245512,245515,245522,245547,245557,245562,245564,245564,245564,245564,245564,245564,245564,245581,245585,245589,245589,245589,245589,245589,245589,245589,245590,245591,245591,245591,245591,245595,245595,245595,245602,245604,245608,245608,245609,245623,245636,245641,245662,245664,245665,245670,245676,245681,245681,245681,245682,245686,245692,245692,245694,245696,245697,245700,245702,245704,245704,245708,245708,245708,245708,245708,245717,245722,245728,245734,245734,245738,245738,245738,245741,245742,245752,245752,245768,245779,245780,245781,245784,245788,245790,245792,245795,245797,245799,245801,245803,245807,245823,245824,245824,245824,245824,245832,245836,245852,245857,245857,245857,245857,245858,245864,245864,245869,245877,245878,245881,245881,245881,245885,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245886,245889,245889,245889,245889,245889,245889,245889,245890,245891,245896,245897,245901,245903,245904,245910,245910,245914,245914,245917,245918,245918,245919,245925,245925,245929,245929,245931,245934,245934,245936,245939,245939,245939,245944,245955,245955,245962,245963,245968,245976,245977,245978,245978,245984,245986,246006,246007,246009,246009,246009,246016,246016,246020,246021,246021,246021,246030,246030,246030,246030,246042,246042,246044,246059,246067,246067,246067,246077,246078,246087,246087,246087,246087,246087,246087,246087,246093,246095,246095,246095,246095,246098,246098,246103,246108,246109,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246123,246125,246125,246134,246135,246135,246137,246137,246140,246141,246143,246143,246143,246143,246143,246143,246143,246143,246143,246143,246143,246143,246143,246144,246144,246144,246144,246144,246144,246144,246144,246144,246144,246144,246144,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246146,246150,246151,246151,246151,246151,246151,246151,246151,246152,246153,246158,246158,246159,246161,246162,246162,246163,246163,246163,246163,246163,246164,246164,246164,246164,246164,246164,246164,246164,246164,246165,246166,246166,246166,246166,246166,246167,246167,246167,246168,246168,246168,246168,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246169,246171,246171,246173,246173,246174,246175,246175,246175,246175,246175,246175,246175,246175,246175,246176,246176,246178,246178,246181,246181,246181,246181,246181,246181,246182,246183,246183,246183,246183,246183,246184,246184,246184,246186,246187,246188,246190,246191,246191,246191,246191,246191,246192,246194,246194,246195,246195,246196,246196,246196,246197,246197,246197,246198,246201,246201,246202,246203,246203,246205,246205,246205,246206,246213,246215,246215,246217,246221,246222,246222,246222,246222,246222,246222,246228,246230,246230,246230,246232,246232,246232,246233,246234,246238,246240,246240,246240,246240,246242,246244,246247,246247,246249,246249,246254,246255,246255,246255,246255,246255,246255,246255,246258,246259,246259,246261,246263,246263,246263,246263,246266,246266,246266,246266,246266,246269,246269,246275,246275,246275,246277,246278,246278,246287,246295,246298,246301,246306,246315,246323,246328,246329,246331,246331,246331,246337,246337,246337,246337,246341,246341,246341,246341,246341,246341,246341,246343,246343,246343,246343,246345,246346,246349,246357,246362,246362,246367,246370,246370,246382,246385,246386,246386,246388,246388,246393,246397,246397,246404,246404,246404,246411,246415,246420,246420,246420,246420,246421,246421,246421,246421,246421,246421,246429,246434,246439,246447,246447,246447,246451,246459,246459,246460,246460,246460,246463,246464,246464,246464,246465,246469,246469,246469,246470,246473,246476,246477,246478,246478,246478,246482,246485,246492,246505,246513,246514,246515,246515,246519,246519,246524,246526,246530,246531,246533,246533,246534,246538,246545,246547,246552,246552,246552,246555,246557,246557,246557,246558,246558,246558,246564,246567,246567,246568,246568,246568,246568,246568,246571,246571,246571,246571,246571,246571,246571,246572,246573,246573,246573,246573,246573,246573,246574,246576,246577,246580,246580,246583,246589,246589,246591,246591,246597,246599,246599,246601,246602,246603,246604,246607,246611,246613,246618,246618,246621,246627,246633,246636,246638,246643,246643,246644,246651,246656,246663,246670,246675,246675,246680,246681,246686,246695,246695,246699,246703,246710,246724,246724,246729,246749,246749,246769,246774,246774,246774,246774,246774,246774,246774,246774,246774,246774,246774,246779,246786,246792,246794,246795,246795,246795,246803,246803,246807,246822,246822,246822,246822,246823,246824,246826,246827,246834,246834,246834,246834,246834,246839,246852,246853,246867,246868,246868,246868,246890,246896,246905,246912,246919,246919,246923,246928,246928,246928,246934,246949,246954,246957,246963,246963,246964,246964,246964,246969,246972,246982,246983,246987,246994,246995,246996,247004,247005,247005,247006,247006,247006,247006,247006,247006,247006,247006,247006,247007,247009,247010,247011,247011,247012,247016,247021,247021,247021,247021,247021,247021,247021,247033,247033,247034,247035,247041,247041,247041,247041,247048,247048,247049,247060,247060,247060,247060,247063,247064,247076,247079,247088,247092,247092,247093,247095,247102,247105,247108,247113,247113,247114,247114,247114,247115,247127,247129,247129,247131,247131,247132,247138,247141,247143,247143,247147,247149,247152,247152,247153,247159,247160,247171,247179,247180,247180,247180,247184,247195,247195,247197,247202,247203,247212,247221,247230,247230,247246,247248,247250,247250,247268,247284,247304,247322,247328,247332,247332,247332,247333,247345,247345,247345,247348,247370,247370,247372,247372,247373,247376,247376,247380,247384,247396,247409,247412,247413,247413,247418,247420,247421,247421,247429,247434,247438,247438,247442,247442,247442,247442,247449,247479,247483,247485,247487,247490,247491,247491,247491,247496,247502,247508,247508,247512,247517,247517,247518,247519,247521,247521,247524,247524,247524,247524,247524,247524,247525,247525,247525,247525,247529,247531,247533,247554,247566,247567,247580,247581,247583,247586,247589,247593,247600,247601,247601,247601,247612,247617,247621,247622,247626,247628,247639,247640,247687,247687,247695,247695,247697,247698,247705,247710,247715,247715,247715,247723,247726,247732,247738,247738,247741,247747,247749,247755,247756,247762,247762,247762,247765,247770,247777,247777,247777,247780,247780,247780,247780,247780,247780,247780,247780,247780,247789,247792,247792,247799,247801,247803,247806,247807,247816,247829,247830,247830,247830,247830,247838,247838,247848,247849,247851,247851,247858,247863,247869,247871,247875,247876,247876,247876,247876,247876,247876,247876,247876,247876,247876,247876,247881,247882,247882,247882,247885,247886,247895,247899,247900,247901,247901,247903,247904,247904,247904,247904,247911,247916,247916,247917,247919,247924,247924,247944,247945,247946,247946,247950,247950,247950,247950,247950,247950,247950,247950,247951,247951,247953,247953,247953,247953,247953,247953,247953,247955,247968,247969,247971,247971,247971,247971,247971,247972,247973,247977,247977,247977,247978,247980,247981,247984,247985,247988,247988,247998,247998,247999,247999,247999,248004,248007,248024,248026,248029,248029,248031,248033,248033,248048,248053,248057,248073,248073,248073,248073,248073,248073,248073,248073,248077,248080,248080,248081,248083,248083,248084,248084,248084,248084,248084,248085,248089,248091,248091,248091,248095,248096,248102,248106,248106,248107,248117,248119,248127,248133,248134,248134,248134,248138,248148,248166,248169,248171,248171,248178,248178,248179,248180,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248181,248184,248187,248187,248187,248188,248192,248192,248197,248199,248203,248204,248209,248222,248232,248232,248235,248238,248240,248242,248244,248245,248245,248245,248245,248248,248249,248249,248253,248253,248258,248261,248261,248264,248269,248273,248276,248276,248276,248276,248290,248290,248294,248296,248306,248306,248307,248307,248307,248307,248307,248307,248310,248310,248310,248310,248310,248310,248310,248311,248311,248311,248311,248311,248313,248313,248313,248313,248317,248317,248325,248325,248325,248325,248330,248330,248340,248344,248348,248350,248352,248352,248352,248353,248353,248353,248353,248357,248362,248362,248362,248362,248362,248363,248366,248368,248368,248374,248374,248377,248381,248381,248381,248386,248387,248391,248393,248393,248394,248394,248394,248397,248400,248400,248400,248403,248404,248409,248409,248409,248412,248416,248424,248424,248424,248424,248425,248425,248426,248428,248428,248429,248429,248430,248439,248440,248450,248453,248453,248453,248453,248455,248455,248464,248467,248471,248472,248473,248473,248475,248475,248475,248478,248480,248489,248493,248493,248494,248503,248512,248514,248516,248516,248520,248520,248520,248520,248520,248520,248520,248523,248523,248523,248523,248523,248523,248523,248523,248523,248524,248524,248524,248524,248524,248525,248526,248526,248526,248529,248529,248529,248529,248529,248529,248529,248531,248531,248532,248532,248534,248535,248538,248543,248543,248544,248544,248545,248546,248548,248548,248548,248548,248553,248554,248554,248557,248559,248565,248565,248565,248567,248567,248573,248580,248580,248588,248591,248591,248591,248591,248598,248599,248600,248600,248603,248605,248606,248606,248606,248606,248614,248621,248623,248627,248629,248636,248636,248636,248641,248642,248642,248649,248660,248660,248660,248665,248667,248669,248672,248673,248673,248673,248673,248673,248675,248685,248685,248689,248689,248689,248691,248693,248693,248693,248693,248695,248695,248696,248704,248713,248720,248735,248735,248735,248736,248737,248739,248741,248746,248747,248752,248752,248761,248762,248763,248764,248766,248767,248767,248767,248768,248771,248776,248784,248785,248802,248815,248815,248821,248821,248826,248830,248834,248838,248838,248853,248857,248860,248862,248867,248870,248878,248878,248882,248900,248902,248903,248903,248913,248918,248924,248937,248949,248956,248959,248964,248964,248967,248967,248967,248967,248967,248967,248970,248970,248971,248973,248973,248977,248978,248983,248986,248986,248986,248999,249001,249002,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249005,249010,249011,249020,249023,249030,249036,249040,249047,249060,249063,249077,249077,249077,249077,249077,249077,249080,249080,249080,249080,249080,249082,249083,249083,249090,249090,249092,249092,249093,249093,249093,249094,249094,249094,249094,249094,249094,249094,249097,249101,249101,249101,249101,249101,249101,249101,249101,249108,249112,249112,249112,249114,249116,249124,249129,249129,249129,249129,249129,249131,249133,249134,249135,249137,249139,249139,249140,249142,249144,249146,249147,249148,249148,249148,249151,249151,249151,249153,249156,249157,249157,249158,249168,249168,249168,249168,249168,249168,249168,249169,249193,249194,249194,249204,249206,249209,249209,249211,249216,249216,249216,249216,249222,249235,249235,249247,249247,249247,249247,249248,249248,249248,249248,249248,249248,249248,249248,249248,249248,249248,249248,249248,249252,249253,249253,249259,249268,249268,249268,249268,249268,249285,249287,249287,249291,249292,249293,249297,249311,249311,249321,249321,249321,249321,249321,249321,249321,249321,249326,249328,249331,249333,249333,249333,249333,249337,249337,249337,249337,249337,249351,249362,249367,249369,249371,249372,249372,249372,249373,249373,249373,249373,249374,249376,249377,249377,249380,249384,249386,249390,249394,249394,249404,249406,249407,249414,249414,249416,249416,249420,249422,249426,249426,249429,249430,249432,249432,249444,249447,249447,249450,249451,249454,249458,249462,249463,249474,249474,249474,249475,249475,249475,249475,249475,249476,249476,249476,249476,249477,249478,249492,249497,249499,249499,249500,249513,249513,249513,249517,249519,249522,249528,249536,249536,249541,249541,249546,249548,249548,249550,249555,249569,249569,249569,249569,249574,249574,249574,249574,249578,249579,249586,249586,249593,249595,249601,249601,249601,249601,249604,249604,249604,249608,249608,249620,249623,249636,249636,249636,249638,249638,249645,249655,249657,249657,249657,249658,249658,249658,249658,249658,249658,249658,249662,249662,249663,249669,249669,249685,249685,249697,249699,249699,249702,249707,249707,249724,249724,249728,249729,249732,249732,249733,249734,249736,249736,249742,249749,249749,249767,249768,249770,249770,249770,249776,249777,249777,249782,249787,249788,249788,249788,249793,249794,249809,249814,249818,249827,249830,249833,249833,249839,249853,249864,249864,249866,249866,249877,249882,249893,249904,249904,249918,249918,249918,249923,249949,249958,249960,249961,249965,249965,249965,249970,249970,249974,249975,249977,249977,249980,249985,249985,249987,249991,250002,250005,250008,250020,250025,250030,250030,250030,250031,250031,250031,250035,250035,250036,250038,250043,250043,250045,250049,250049,250049,250052,250055,250055,250070,250076,250077,250079,250082,250083,250085,250085,250087,250088,250093,250093,250093,250093,250095,250116,250123,250130,250131,250132,250135,250136,250136,250137,250146,250146,250146,250147,250147,250147,250154,250158,250158,250158,250159,250160,250160,250160,250160,250161,250161,250161,250164,250165,250177,250177,250178,250189,250194,250198,250202,250204,250220,250223,250230,250241,250251,250256,250257,250258,250259,250259,250265,250268,250268,250271,250276,250279,250280,250284,250284,250287,250288,250288,250296,250299,250299,250300,250301,250302,250302,250309,250315,250325,250331,250332,250332,250332,250334,250337,250338,250351,250353,250359,250359,250359,250359,250362,250362,250369,250372,250372,250372,250376,250377,250379,250386,250386,250386,250399,250399,250406,250428,250447,250452,250452,250452,250455,250455,250472,250472,250472,250472,250472,250473,250475,250476,250476,250483,250484,250486,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250488,250496,250497,250497,250497,250503,250503,250508,250512,250512,250513,250513,250524,250524,250524,250524,250524,250524,250529,250534,250539,250540,250547,250549,250550,250552,250552,250561,250568,250571,250573,250573,250574,250576,250576,250585,250595,250605,250606,250613,250613,250613,250613,250613,250615,250617,250617,250617,250619,250628,250628,250633,250644,250644,250654,250654,250654,250671,250679,250680,250680,250706,250708,250711,250712,250715,250715,250724,250743,250747,250749,250768,250783,250784,250786,250786,250786,250796,250796,250802,250804,250804,250813,250813,250821,250821,250834,250837,250837,250837,250837,250837,250838,250838,250841,250859,250863,250866,250872,250874,250877,250889,250893,250893,250894,250898,250904,250904,250906,250907,250908,250915,250915,250916,250920,250920,250920,250922,250922,250922,250922,250923,250924,250924,250932,250935,250935,250935,250935,250935,250935,250935,250938,250938,250938,250940,250940,250942,250944,250944,250945,250946,250948,250962,250962,250971,250975,250975,250975,250975,250975,250977,250977,250980,250991,250992,250997,250999,250999,251018,251021,251025,251025,251040,251049,251049,251056,251062,251065,251067,251067,251069,251070,251074,251078,251082,251082,251082,251086,251089,251089,251091,251092,251092,251093,251093,251093,251094,251098,251099,251104,251105,251108,251116,251116,251116,251116,251117,251118,251120,251120,251120,251120,251120,251122,251128,251134,251137,251142,251142,251142,251142,251142,251142,251142,251144,251147,251149,251151,251154,251154,251161,251162,251167,251169,251186,251187,251189,251190,251191,251191,251191,251191,251203,251212,251212,251218,251220,251225,251225,251225,251231,251241,251242,251244,251246,251248,251254,251267,251273,251273,251279,251279,251279,251282,251282,251283,251285,251285,251295,251297,251297,251297,251297,251297,251300,251300,251300,251301,251301,251301,251304,251317,251318,251318,251318,251322,251329,251332,251334,251340,251346,251351,251353,251353,251354,251355,251363,251364,251370,251371,251374,251377,251381,251381,251391,251392,251394,251406,251412,251417,251418,251418,251418,251428,251432,251435,251440,251441,251444,251452,251456,251458,251459,251459,251463,251469,251475,251475,251485,251485,251485,251490,251494,251497,251497,251497,251498,251499,251527,251528,251530,251531,251542,251542,251543,251550,251550,251550,251550,251556,251570,251570,251571,251574,251574,251575,251577,251578,251580,251584,251584,251591,251591,251591,251603,251604,251621,251626,251626,251626,251626,251629,251629,251633,251635,251645,251646,251648,251655,251657,251659,251662,251665,251665,251669,251675,251676,251677,251677,251677,251681,251681,251681,251681,251683,251693,251693,251693,251693,251693,251694,251694,251694,251695,251695,251697,251697,251697,251705,251705,251706,251706,251708,251708,251708,251710,251713,251714,251718,251721,251723,251723,251729,251748,251748,251748,251750,251750,251750,251750,251752,251752,251753,251758,251763,251771,251776,251779,251784,251790,251793,251793,251801,251802,251803,251804,251804,251806,251806,251814,251819,251832,251832,251832,251834,251837,251838,251844,251852,251852,251852,251852,251852,251852,251852,251852,251852,251852,251852,251852,251852,251852,251859,251859,251861,251866,251866,251866,251866,251866,251866,251866,251866,251866,251866,251866,251866,251866,251866,251868,251873,251876,251883,251901,251905,251906,251908,251915,251915,251922,251923,251924,251924,251924,251924,251924,251924,251924,251924,251924,251924,251924,251924,251927,251927,251939,251939,251939,251939,251940,251945,251950,251952,251953,251957,251957,251957,251961,251961,251961,251961,251962,251967,251967,251967,251967,251967,251967,251967,251967,251967,251969,251977,251982,251982,251986,251988,251988,251988,251988,251988,251988,251988,251988,251992,251993,251996,251996,251997,251997,251997,251997,251999,251999,252000,252000,252002,252003,252004,252004,252007,252007,252010,252011,252012,252014,252014,252014,252014,252014,252014,252019,252019,252023,252028,252032,252039,252039,252039,252039,252042,252046,252046,252046,252048,252052,252057,252058,252062,252068,252076,252077,252077,252077,252077,252080,252080,252081,252081,252081,252081,252081,252082,252086,252086,252090,252090,252099,252105,252106,252117,252118,252135,252135,252136,252136,252138,252141,252141,252145,252145,252149,252151,252153,252153,252161,252161,252163,252164,252169,252169,252170,252170,252171,252172,252175,252175,252178,252179,252180,252180,252181,252188,252191,252194,252204,252205,252207,252223,252223,252232,252235,252236,252245,252245,252245,252255,252261,252270,252270,252280,252292,252294,252301,252308,252330,252331,252333,252333,252333,252333,252343,252367,252368,252369,252371,252372,252372,252387,252395,252397,252397,252400,252400,252400,252400,252400,252400,252400,252400,252400,252400,252401,252401,252401,252411,252413,252414,252414,252418,252420,252422,252422,252422,252422,252422,252422,252422,252422,252422,252433,252433,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252434,252438,252439,252439,252439,252439,252439,252439,252439,252439,252439,252439,252442,252443,252443,252444,252444,252444,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252445,252446,252447,252447,252448,252449,252450,252471,252473,252473,252473,252473,252473,252473,252473,252473,252473,252474,252475,252481,252482,252485,252485,252485,252493,252508,252509,252510,252511,252513,252515,252515,252516,252516,252516,252517,252519,252519,252519,252519,252519,252519,252520,252520,252521,252521,252521,252521,252521,252521,252521,252521,252522,252522,252523,252523,252523,252523,252523,252523,252523,252523,252524,252524,252524,252525,252525,252527,252527,252528,252529,252529,252530,252532,252532,252534,252536,252537,252538,252539,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252540,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252541,252542,252543,252545,252545,252545,252545,252545,252545,252545,252547,252548,252550,252550,252557,252564,252564,252564,252564,252564,252564,252564,252564,252564,252564,252564,252579,252582,252589,252593,252603,252605,252614,252616,252625,252626,252628,252628,252628,252628,252628,252630,252635,252637,252637,252641,252643,252643,252644,252648,252651,252659,252663,252665,252671,252672,252673,252682,252684,252684,252684,252687,252687,252687,252687,252696,252698,252712,252716,252719,252719,252719,252719,252721,252721,252731,252738,252741,252744,252748,252750,252753,252754,252754,252760,252775,252775,252791,252794,252794,252794,252794,252796,252797,252802,252803,252811,252811,252811,252811,252811,252811,252811,252811,252811,252811,252811,252811,252821,252825,252827,252830,252833,252835,252835,252837,252842,252843,252843,252843,252844,252848,252848,252848,252851,252853,252860,252860,252861,252863,252873,252874,252874,252874,252874,252874,252882,252882,252885,252900,252900,252918,252918,252928,252930,252937,252939,252939,252945,252947,252948,252948,252948,252956,252956,252962,252962,252966,252966,252981,252993,253005,253024,253032,253032,253040,253040,253044,253048,253052,253053,253054,253054,253057,253068,253068,253068,253068,253068,253068,253068,253068,253069,253073,253074,253075,253075,253078,253085,253087,253090,253105,253108,253119,253120,253124,253131,253131,253132,253132,253132,253132,253132,253132,253132,253133,253135,253139,253143,253143,253152,253158,253165,253169,253175,253175,253178,253181,253181,253182,253182,253182,253182,253187,253189,253189,253191,253192,253194,253198,253200,253209,253222,253222,253223,253226,253226,253234,253234,253238,253238,253242,253242,253243,253243,253243,253243,253250,253250,253251,253251,253252,253256,253259,253260,253270,253271,253272,253273,253273,253281,253281,253281,253286,253292,253295,253297,253297,253297,253297,253299,253299,253306,253308,253309,253311,253312,253312,253312,253312,253312,253312,253312,253314,253314,253314,253314,253314,253314,253319,253319,253319,253319,253319,253320,253320,253320,253320,253320,253320,253320,253320,253321,253321,253321,253321,253321,253323,253323,253323,253324,253325,253325,253326,253326,253339,253341,253343,253349,253349,253351,253352,253369,253371,253389,253393,253401,253416,253418,253421,253421,253423,253431,253435,253435,253435,253436,253436,253436,253438,253438,253438,253438,253439,253439,253439,253439,253439,253439,253439,253442,253446,253451,253453,253453,253453,253453,253454,253454,253455,253455,253455,253455,253455,253459,253459,253459,253464,253465,253465,253476,253479,253480,253486,253488,253488,253489,253489,253492,253492,253494,253494,253494,253495,253496,253507,253511,253514,253515,253515,253517,253517,253518,253518,253519,253520,253522,253526,253530,253534,253534,253534,253536,253536,253542,253546,253548,253548,253548,253553,253558,253562,253564,253564,253564,253564,253564,253564,253565,253566,253566,253567,253567,253567,253567,253568,253569,253570,253570,253570,253570,253585,253588,253588,253591,253591,253593,253595,253595,253595,253597,253597,253597,253599,253599,253599,253599,253599,253601,253608,253609,253610,253614,253618,253623,253623,253627,253627,253630,253630,253632,253633,253633,253634,253634,253634,253634,253634,253635,253635,253636,253638,253640,253646,253646,253655,253657,253657,253658,253659,253659,253663,253671,253677,253679,253679,253681,253692,253699,253699,253699,253699,253699,253700,253700,253700,253700,253702,253702,253702,253705,253710,253714,253717,253718,253722,253725,253731,253732,253754,253767,253767,253767,253772,253776,253777,253777,253777,253777,253787,253799,253805,253805,253805,253818,253818,253835,253840,253846,253846,253852,253858,253858,253868,253869,253874,253874,253874,253874,253874,253874,253874,253874,253874,253876,253878,253880,253884,253886,253889,253889,253896,253896,253896,253896,253896,253896,253896,253896,253910,253911,253913,253916,253917,253917,253922,253925,253927,253928,253936,253936,253936,253936,253939,253940,253940,253942,253947,253950,253951,253952,253952,253956,253956,253961,253966,253967,253976,253976,253977,253978,253987,253988,253988,253988,253995,254001,254005,254005,254005,254005,254005,254007,254015,254015,254015,254015,254015,254015,254015,254017,254025,254028,254030,254033,254036,254038,254038,254039,254041,254041,254043,254048,254049,254052,254054,254061,254066,254067,254069,254070,254075,254080,254080,254081,254081,254083,254083,254083,254083,254083,254084,254086,254088,254090,254091,254092,254096,254100,254106,254107,254109,254110,254113,254113,254117,254123,254124,254126,254131,254131,254131,254131,254133,254134,254134,254136,254139,254140,254140,254140,254141,254141,254141,254142,254143,254143,254144,254144,254144,254144,254144,254144,254144,254144,254144,254144,254145,254145,254147,254148,254148,254148,254148,254150,254150,254150,254150,254151,254151,254156,254156,254158,254162,254162,254162,254162,254162,254162,254163,254163,254170,254172,254174,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254175,254177,254184,254186,254186,254193,254194,254196,254199,254204,254206,254209,254214,254219,254220,254221,254222,254224,254224,254225,254226,254235,254238,254239,254241,254242,254243,254244,254244,254244,254244,254244,254244,254244,254244,254244,254244,254244,254244,254244,254245,254251,254252,254255,254268,254270,254270,254270,254270,254270,254270,254270,254270,254270,254270,254270,254272,254273,254275,254275,254276,254278,254278,254278,254278,254278,254278,254278,254278,254278,254278,254278,254288,254290,254293,254298,254298,254298,254298,254298,254298,254298,254302,254302,254302,254303,254303,254311,254312,254312,254313,254314,254315,254323,254329,254329,254332,254332,254334,254338,254340,254340,254344,254347,254349,254351,254352,254352,254353,254364,254364,254365,254367,254367,254373,254373,254376,254384,254390,254390,254390,254391,254393,254393,254395,254398,254398,254398,254408,254414,254414,254415,254418,254418,254421,254421,254421,254422,254423,254424,254427,254431,254431,254433,254435,254435,254443,254443,254444,254449,254450,254452,254453,254455,254455,254457,254458,254461,254462,254462,254463,254468,254468,254468,254471,254474,254476,254478,254479,254480,254482,254486,254490,254493,254493,254494,254495,254495,254496,254497,254497,254497,254497,254503,254506,254508,254508,254508,254509,254509,254513,254519,254520,254521,254521,254522,254522,254523,254528,254528,254528,254531,254534,254534,254534,254536,254541,254547,254551,254555,254556,254559,254566,254566,254569,254570,254579,254580,254580,254580,254580,254583,254593,254598,254599,254603,254607,254608,254616,254620,254622,254628,254632,254632,254635,254642,254652,254655,254656,254657,254657,254657,254659,254664,254666,254666,254670,254676,254676,254676,254676,254676,254676,254676,254676,254676,254676,254678,254679,254682,254690,254697,254705,254715,254721,254722,254723,254727,254731,254733,254738,254741,254747,254758,254758,254758,254758,254760,254762,254762,254773,254773,254773,254778,254792,254793,254794,254794,254794,254794,254795,254796,254798,254799,254804,254805,254805,254806,254806,254806,254806,254806,254806,254806,254810,254826,254830,254831,254836,254836,254836,254840,254840,254840,254840,254841,254854,254860,254862,254862,254862,254865,254867,254870,254877,254882,254884,254888,254889,254891,254891,254891,254894,254905,254905,254905,254905,254905,254905,254905,254905,254907,254910,254914,254914,254915,254916,254916,254930,254944,254944,254950,254959,254969,254975,254976,254983,254989,254992,254994,254995,255005,255005,255005,255005,255005,255005,255005,255005,255013,255015,255020,255022,255022,255022,255022,255022,255022,255022,255030,255033,255033,255034,255035,255036,255037,255054,255060,255063,255063,255063,255063,255063,255065,255067,255070,255079,255080,255088,255089,255094,255095,255099,255103,255103,255103,255103,255108,255108,255108,255112,255113,255118,255126,255138,255138,255141,255145,255151,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255159,255160,255171,255195,255197,255199,255202,255205,255205,255208,255209,255209,255209,255209,255209,255209,255209,255209,255218,255218,255219,255223,255223,255226,255227,255229,255230,255230,255230,255230,255230,255230,255230,255231,255232,255232,255232,255238,255242,255243,255245,255263,255265,255274,255275,255275,255278,255283,255283,255283,255295,255295,255298,255300,255306,255309,255310,255321,255322,255322,255322,255329,255330,255330,255330,255337,255338,255342,255342,255342,255342,255355,255355,255356,255361,255361,255365,255368,255368,255370,255372,255378,255378,255382,255386,255386,255386,255393,255396,255396,255397,255397,255401,255408,255408,255411,255421,255423,255434,255434,255448,255458,255460,255471,255471,255471,255472,255481,255483,255488,255493,255494,255494,255494,255496,255497,255500,255501,255504,255505,255510,255511,255535,255539,255545,255548,255556,255558,255558,255563,255567,255574,255580,255583,255585,255588,255588,255589,255589,255589,255589,255589,255589,255590,255595,255603,255606,255610,255610,255613,255613,255615,255615,255615,255615,255615,255615,255615,255615,255615,255629,255634,255634,255643,255644,255656,255660,255661,255661,255663,255679,255682,255683,255691,255691,255691,255691,255697,255703,255703,255703,255704,255704,255704,255711,255712,255720,255725,255726,255726,255726,255728,255735,255736,255743,255749,255753,255758,255767,255768,255768,255777,255812,255818,255818,255818,255819,255819,255819,255819,255819,255820,255826,255826,255826,255826,255826,255827,255827,255827,255835,255843,255846,255848,255848,255848,255848,255848,255848,255848,255854,255854,255854,255858,255871,255877,255884,255899,255915,255915,255923,255938,255942,255954,255955,255955,255955,255957,255962,255962,255968,255968,255969,255969,255971,255971,255971,255972,255977,255985,255985,255985,255987,255992,255998,256006,256009,256011,256016,256016,256019,256034,256037,256037,256049,256050,256053,256060,256061,256064,256064,256065,256071,256082,256089,256094,256102,256107,256110,256110,256110,256110,256110,256111,256114,256114,256116,256120,256120,256133,256134,256139,256141,256141,256146,256149,256149,256154,256159,256166,256168,256179,256182,256183,256186,256190,256197,256197,256197,256204,256204,256212,256212,256212,256213,256213,256228,256229,256233,256236,256237,256237,256240,256251,256255,256262,256270,256278,256288,256290,256296,256296,256297,256316,256316,256321,256321,256324,256324,256324,256327,256327,256327,256328,256328,256328,256328,256328,256333,256352,256352,256352,256366,256366,256366,256370,256373,256373,256374,256374,256374,256374,256375,256375,256375,256377,256379,256379,256380,256380,256381,256386,256387,256392,256392,256417,256418,256424,256429,256433,256435,256440,256443,256449,256450,256450,256450,256450,256454,256455,256458,256462,256463,256466,256470,256473,256475,256488,256500,256514,256514,256514,256517,256522,256522,256530,256530,256533,256539,256550,256551,256551,256551,256553,256556,256556,256556,256559,256560,256560,256560,256564,256574,256574,256574,256577,256582,256583,256595,256608,256613,256617,256630,256643,256645,256649,256653,256662,256668,256670,256674,256674,256679,256683,256683,256683,256683,256683,256683,256683,256683,256683,256683,256683,256683,256683,256683,256684,256684,256685,256685,256687,256687,256688,256690,256690,256690,256691,256691,256701,256701,256702,256703,256705,256705,256705,256706,256710,256710,256713,256717,256718,256718,256718,256718,256727,256735,256735,256743,256743,256743,256744,256747,256759,256769,256784,256784,256784,256784,256785,256791,256793,256793,256812,256812,256812,256813,256813,256813,256813,256813,256813,256813,256813,256813,256813,256815,256815,256817,256820,256831,256834,256834,256834,256837,256839,256839,256840,256841,256844,256844,256844,256844,256846,256847,256847,256848,256856,256857,256861,256863,256863,256863,256864,256865,256870,256875,256875,256875,256876,256882,256887,256887,256887,256888,256893,256893,256894,256901,256906,256912,256921,256922,256922,256926,256926,256929,256937,256938,256943,256943,256943,256943,256944,256945,256955,256965,256965,256965,256965,256965,256968,256972,256979,256982,256986,256986,256986,257001,257008,257015,257017,257018,257026,257026,257026,257030,257032,257037,257038,257038,257038,257038,257038,257040,257046,257050,257063,257073,257077,257079,257084,257087,257093,257096,257118,257118,257118,257123,257127,257127,257133,257140,257143,257144,257144,257152,257152,257154,257158,257158,257158,257160,257160,257161,257161,257166,257170,257173,257175,257175,257175,257176,257182,257184,257187,257189,257195,257195,257204,257204,257205,257223,257223,257229,257239,257242,257244,257247,257253,257263,257268,257268,257268,257269,257269,257281,257283,257284,257284,257284,257284,257284,257284,257284,257284,257284,257284,257289,257295,257295,257300,257300,257307,257308,257315,257315,257318,257318,257318,257318,257318,257318,257319,257325,257328,257328,257332,257341,257343,257344,257350,257350,257351,257351,257351,257358,257360,257361,257361,257361,257361,257362,257363,257363,257365,257365,257370,257372,257372,257374,257381,257381,257381,257386,257399,257399,257399,257409,257410,257410,257418,257422,257424,257424,257424,257438,257441,257441,257447,257453,257453,257453,257453,257453,257454,257456,257456,257456,257457,257457,257457,257457,257457,257457,257459,257459,257459,257459,257459,257459,257459,257459,257459,257461,257461,257466,257468,257470,257473,257473,257473,257473,257473,257474,257479,257479,257479,257479,257479,257486,257490,257490,257490,257490,257495,257500,257508,257510,257523,257529,257529,257529,257535,257535,257542,257543,257544,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257555,257568,257569,257572,257572,257577,257577,257577,257577,257580,257580,257580,257585,257587,257590,257608,257614,257632,257632,257635,257641,257643,257644,257644,257644,257646,257651,257653,257658,257660,257670,257671,257671,257676,257678,257678,257678,257680,257680,257690,257690,257690,257698,257698,257703,257706,257706,257708,257708,257708,257708,257714,257715,257715,257715,257715,257715,257715,257717,257717,257717,257718,257727,257729,257730,257738,257740,257740,257740,257740,257744,257744,257744,257748,257749,257749,257749,257749,257749,257750,257752,257755,257756,257759,257760,257761,257763,257765,257772,257773,257773,257773,257774,257779,257782,257799,257799,257801,257802,257815,257843,257843,257843,257843,257843,257848,257848,257848,257848,257860,257860,257867,257869,257869,257872,257872,257877,257879,257880,257884,257913,257918,257926,257927,257929,257931,257931,257938,257939,257949,257950,257952,257952,257952,257952,257952,257952,257952,257952,257952,257952,257952,257953,257957,257957,257957,257964,257969,257969,257969,257969,257976,257977,257981,257982,257982,257982,257985,257994,257999,258000,258006,258020,258020,258023,258030,258034,258037,258037,258042,258053,258056,258056,258056,258057,258066,258068,258068,258076,258080,258081,258084,258091,258114,258115,258115,258116,258121,258121,258137,258142,258144,258148,258150,258150,258159,258162,258165,258165,258165,258187,258189,258190,258190,258192,258192,258192,258197,258197,258197,258202,258207,258210,258216,258216,258218,258219,258224,258224,258224,258236,258242,258247,258248,258254,258254,258254,258255,258257,258259,258259,258259,258259,258267,258267,258267,258267,258267,258267,258267,258267,258267,258269,258269,258269,258280,258283,258283,258283,258286,258297,258312,258312,258321,258329,258332,258342,258343,258343,258352,258352,258354,258357,258369,258385,258385,258390,258390,258396,258396,258396,258396,258408,258408,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258409,258410,258410,258410,258410,258410,258410,258410,258410,258410,258410,258410,258411,258411,258411,258411,258411,258411,258411,258411,258412,258412,258412,258412,258412,258413,258413,258413,258413,258413,258415,258416,258418,258421,258421,258421,258421,258421,258422,258422,258427,258428,258429,258429,258430,258434,258434,258435,258435,258435,258436,258436,258436,258437,258437,258439,258440,258440,258440,258440,258440,258440,258441,258441,258441,258441,258441,258441,258441,258441,258442,258442,258442,258442,258442,258443,258443,258443,258444,258444,258444,258444,258444,258444,258445,258445,258445,258445,258445,258445,258445,258445,258445,258445,258446,258446,258446,258446,258446,258446,258446,258446,258446,258446,258446,258446,258451,258452,258452,258452,258453,258454,258458,258459,258459,258460,258461,258463,258463,258463,258466,258467,258468,258469,258474,258474,258478,258479,258481,258481,258481,258481,258486,258486,258486,258486,258486,258491,258492,258497,258499,258507,258507,258507,258509,258509,258512,258512,258512,258512,258512,258513,258515,258519,258519,258520,258520,258524,258525,258529,258529,258530,258534,258536,258537,258537,258537,258537,258554,258554,258554,258556,258557,258557,258562,258569,258576,258578,258578,258582,258591,258598,258598,258603,258603,258604,258606,258611,258614,258614,258617,258617,258617,258618,258619,258632,258633,258634,258637,258638,258638,258643,258643,258643,258647,258648,258653,258656,258658,258659,258659,258661,258661,258675,258679,258679,258680,258701,258713,258715,258715,258715,258715,258715,258716,258723,258724,258726,258741,258742,258745,258746,258749,258754,258756,258757,258757,258757,258760,258765,258766,258766,258769,258772,258772,258785,258787,258788,258788,258788,258797,258798,258798,258798,258806,258806,258806,258810,258811,258826,258829,258831,258836,258843,258843,258844,258848,258851,258851,258851,258851,258851,258861,258864,258865,258865,258873,258876,258876,258881,258896,258896,258902,258910,258910,258920,258920,258920,258920,258925,258927,258931,258932,258932,258934,258941,258941,258943,258954,258954,258962,258964,258965,258965,258966,258982,258982,258990,258993,258993,258996,259001,259009,259009,259016,259019,259019,259021,259022,259027,259032,259035,259037,259037,259037,259042,259047,259051,259051,259051,259051,259052,259054,259054,259057,259057,259057,259060,259067,259075,259077,259077,259077,259077,259077,259077,259077,259090,259090,259093,259095,259106,259109,259113,259114,259114,259120,259120,259120,259120,259123,259123,259125,259127,259127,259127,259129,259129,259129,259129,259129,259136,259138,259139,259139,259139,259139,259139,259149,259152,259153,259153,259155,259159,259160,259160,259169,259169,259177,259178,259179,259182,259196,259208,259209,259210,259210,259210,259214,259216,259225,259234,259234,259245,259250,259254,259254,259259,259259,259262,259269,259273,259274,259277,259278,259278,259278,259280,259280,259283,259283,259284,259287,259287,259287,259288,259297,259297,259297,259297,259299,259299,259299,259299,259299,259301,259302,259323,259324,259327,259327,259329,259333,259333,259333,259339,259341,259341,259341,259344,259345,259352,259353,259355,259357,259358,259359,259367,259367,259374,259374,259379,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259380,259388,259389,259394,259395,259403,259413,259413,259414,259417,259417,259418,259419,259436,259436,259438,259440,259446,259446,259448,259448,259448,259449,259449,259450,259451,259451,259451,259455,259457,259459,259463,259466,259466,259466,259466,259467,259467,259476,259483,259495,259498,259499,259523,259539,259540,259544,259545,259545,259551,259552,259564,259574,259574,259596,259600,259600,259600,259602,259602,259602,259603,259608,259608,259608,259608,259611,259611,259616,259617,259620,259620,259620,259621,259626,259631,259631,259631,259637,259639,259642,259642,259644,259646,259651,259652,259658,259667,259668,259668,259668,259670,259673,259674,259689,259696,259696,259696,259702,259704,259714,259722,259723,259726,259738,259738,259749,259753,259754,259762,259768,259768,259772,259772,259779,259786,259796,259804,259814,259819,259820,259822,259822,259827,259830,259830,259831,259835,259837,259837,259841,259847,259847,259847,259853,259853,259854,259866,259868,259869,259883,259883,259885,259886,259887,259889,259889,259895,259895,259895,259895,259895,259895,259895,259895,259895,259895,259901,259901,259902,259903,259903,259906,259907,259909,259909,259914,259914,259914,259918,259918,259919,259931,259934,259945,259946,259946,259953,259958,259965,259966,259967,259970,259970,259970,259970,259974,259974,259978,259978,259978,259979,259987,259990,259992,259992,259992,259992,259992,259992,259992,259992,259992,259992,259992,259992,259995,259997,259997,259999,260002,260002,260002,260007,260009,260009,260013,260029,260037,260037,260037,260047,260048,260051,260051,260055,260055,260055,260068,260068,260070,260074,260077,260077,260077,260078,260079,260083,260084,260090,260092,260105,260107,260114,260114,260117,260121,260121,260121,260123,260127,260127,260130,260134,260134,260138,260138,260140,260140,260140,260143,260143,260146,260146,260152,260156,260161,260164,260168,260169,260169,260177,260185,260189,260192,260192,260192,260192,260192,260192,260192,260196,260197,260197,260198,260198,260198,260198,260198,260198,260198,260198,260200,260205,260207,260210,260210,260210,260210,260218,260218,260218,260218,260219,260222,260223,260223,260223,260226,260229,260230,260230,260230,260230,260230,260230,260231,260232,260235,260235,260242,260247,260247,260247,260247,260248,260250,260250,260253,260253,260268,260268,260272,260275,260276,260278,260279,260279,260280,260280,260280,260286,260287,260287,260290,260292,260292,260296,260296,260299,260301,260312,260313,260315,260319,260319,260326,260330,260330,260331,260331,260332,260334,260334,260340,260340,260340,260340,260340,260341,260341,260342,260346,260346,260346,260353,260357,260365,260367,260367,260367,260367,260369,260370,260371,260372,260373,260377,260377,260379,260381,260381,260381,260383,260397,260403,260404,260404,260408,260408,260409,260411,260411,260413,260413,260416,260416,260417,260417,260417,260417,260419,260424,260430,260430,260435,260437,260455,260456,260457,260468,260470,260475,260475,260475,260475,260478,260478,260478,260478,260484,260486,260487,260488,260498,260502,260504,260505,260505,260508,260508,260508,260508,260508,260508,260508,260510,260510,260524,260526,260536,260536,260536,260541,260556,260560,260561,260561,260564,260569,260569,260569,260576,260581,260586,260596,260603,260603,260603,260603,260603,260603,260610,260613,260613,260620,260620,260620,260620,260620,260621,260621,260621,260621,260631,260632,260652,260654,260656,260660,260660,260660,260672,260678,260682,260683,260683,260688,260688,260696,260698,260703,260712,260715,260717,260723,260725,260725,260726,260729,260734,260734,260754,260760,260778,260779,260781,260782,260787,260800,260810,260812,260812,260816,260816,260816,260816,260816,260822,260824,260824,260824,260824,260824,260824,260824,260824,260824,260825,260832,260840,260845,260846,260846,260849,260860,260866,260873,260876,260878,260887,260891,260897,260901,260901,260901,260901,260901,260914,260917,260920,260928,260936,260936,260941,260953,260957,260969,260970,260986,260989,260996,260996,260997,261000,261012,261023,261023,261023,261027,261030,261036,261036,261036,261037,261048,261048,261054,261056,261060,261060,261060,261063,261064,261065,261073,261075,261078,261078,261090,261092,261093,261112,261120,261120,261120,261120,261120,261120,261120,261120,261129,261130,261130,261131,261132,261138,261139,261150,261152,261154,261169,261169,261170,261174,261174,261184,261189,261190,261191,261193,261193,261194,261199,261199,261200,261204,261207,261207,261207,261208,261209,261211,261216,261217,261221,261221,261224,261231,261248,261255,261255,261255,261255,261255,261255,261258,261258,261261,261261,261261,261261,261262,261264,261272,261272,261272,261272,261277,261278,261278,261280,261282,261289,261290,261290,261290,261290,261291,261298,261303,261303,261312,261315,261315,261315,261315,261315,261315,261316,261319,261322,261323,261325,261327,261327,261328,261328,261328,261328,261338,261346,261379,261386,261386,261388,261389,261393,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261396,261397,261398,261399,261402,261402,261405,261405,261405,261405,261405,261405,261405,261406,261407,261409,261409,261409,261412,261413,261414,261414,261414,261417,261417,261417,261418,261418,261418,261420,261420,261420,261420,261420,261421,261421,261422,261422,261423,261423,261423,261425,261425,261431,261442,261442,261443,261443,261443,261444,261447,261449,261449,261450,261452,261452,261452,261452,261452,261452,261452,261452,261452,261453,261453,261453,261453,261453,261454,261457,261462,261463,261463,261464,261467,261474,261474,261474,261477,261477,261477,261486,261490,261501,261501,261501,261513,261515,261516,261516,261517,261519,261520,261521,261523,261524,261524,261528,261528,261528,261531,261531,261532,261539,261547,261565,261565,261565,261565,261565,261565,261576,261576,261576,261576,261576,261576,261578,261578,261579,261587,261588,261589,261589,261589,261589,261589,261589,261596,261597,261597,261599,261607,261607,261607,261608,261608,261609,261609,261611,261619,261621,261621,261621,261627,261630,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261631,261633,261656,261663,261663,261667,261672,261673,261673,261673,261673,261673,261673,261673,261673,261676,261677,261677,261679,261679,261679,261686,261687,261690,261700,261701,261701,261706,261714,261721,261734,261739,261755,261766,261769,261771,261774,261783,261783,261783,261783,261783,261783,261783,261783,261791,261795,261798,261807,261812,261819,261819,261819,261819,261819,261831,261843,261848,261850,261850,261850,261866,261871,261883,261888,261888,261888,261888,261889,261892,261899,261899,261900,261901,261901,261901,261901,261901,261903,261904,261904,261907,261907,261907,261907,261913,261920,261920,261920,261923,261924,261927,261931,261936,261941,261942,261947,261953,261958,261960,261966,261966,261966,261966,261966,261970,261970,261971,261971,261971,261974,261977,261979,261980,261982,261982,261982,261982,261982,261984,261984,261984,261984,261984,261984,261984,261984,261987,261991,261991,261991,261991,261992,261992,261992,261996,261996,261996,262002,262007,262008,262013,262013,262019,262019,262028,262047,262053,262053,262055,262055,262055,262057,262062,262069,262072,262073,262075,262076,262076,262079,262082,262086,262091,262099,262100,262100,262107,262107,262119,262119,262119,262119,262119,262124,262124,262124,262124,262124,262124,262124,262125,262138,262143,262143,262143,262148,262148,262156,262156,262159,262160,262167,262180,262186,262187,262191,262191,262191,262209,262209,262209,262210,262218,262219,262220,262220,262220,262220,262221,262221,262222,262229,262233,262243,262249,262250,262252,262253,262253,262253,262255,262255,262259,262272,262272,262274,262277,262277,262282,262282,262286,262288,262294,262294,262294,262294,262294,262294,262296,262301,262306,262307,262307,262316,262316,262316,262316,262318,262318,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262322,262323,262323,262323,262325,262327,262327,262327,262328,262331,262341,262341,262341,262365,262366,262366,262369,262371,262374,262378,262381,262383,262395,262395,262395,262395,262397,262397,262397,262397,262402,262403,262411,262412,262427,262431,262436,262438,262461,262468,262468,262469,262470,262482,262484,262485,262485,262485,262494,262494,262494,262501,262515,262515,262516,262520,262527,262533,262534,262537,262540,262541,262559,262560,262560,262560,262566,262567,262568,262573,262573,262581,262582,262582,262594,262594,262595,262595,262595,262595,262607,262612,262613,262620,262621,262623,262625,262629,262634,262646,262648,262648,262648,262649,262653,262654,262656,262659,262660,262661,262664,262664,262669,262672,262678,262678,262704,262706,262706,262718,262718,262724,262725,262727,262727,262727,262727,262727,262727,262727,262727,262742,262742,262742,262744,262744,262745,262747,262750,262752,262758,262763,262764,262766,262770,262770,262773,262775,262780,262781,262787,262787,262808,262808,262811,262811,262811,262811,262811,262811,262811,262811,262811,262811,262811,262817,262817,262817,262818,262819,262823,262824,262824,262832,262832,262832,262832,262834,262837,262837,262838,262838,262838,262838,262838,262838,262844,262846,262846,262849,262849,262849,262850,262851,262851,262851,262856,262856,262856,262856,262858,262858,262858,262860,262860,262861,262863,262865,262865,262865,262868,262873,262873,262884,262888,262888,262891,262892,262893,262896,262900,262914,262920,262922,262924,262924,262924,262937,262945,262945,262972,262978,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262982,262984,262989,262991,262991,262991,262991,262991,262994,262994,262997,263003,263007,263012,263012,263012,263014,263015,263016,263026,263042,263049,263051,263051,263056,263060,263060,263061,263064,263076,263081,263082,263086,263086,263091,263091,263093,263093,263094,263094,263102,263109,263113,263113,263113,263125,263125,263130,263132,263140,263142,263143,263145,263148,263152,263154,263167,263167,263172,263172,263175,263179,263179,263179,263179,263181,263194,263203,263203,263210,263215,263223,263223,263232,263240,263240,263240,263240,263240,263245,263247,263249,263249,263249,263250,263251,263251,263251,263251,263251,263251,263251,263251,263251,263251,263251,263251,263251,263252,263271,263273,263273,263273,263273,263274,263274,263278,263281,263281,263286,263296,263296,263296,263296,263303,263306,263318,263318,263318,263321,263332,263335,263339,263339,263339,263339,263342,263342,263343,263351,263351,263355,263355,263355,263358,263372,263372,263372,263376,263376,263376,263378,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263383,263384,263388,263400,263400,263402,263402,263402,263406,263406,263406,263409,263419,263432,263432,263432,263437,263438,263440,263452,263452,263452,263454,263460,263460,263460,263460,263462,263464,263468,263471,263472,263474,263484,263484,263484,263484,263484,263485,263485,263490,263490,263494,263495,263495,263502,263503 \ No newline at end of file From 4ecd5a51c1a6e6dfed34d6d02f7c59b5397813b1 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:07:44 -0500 Subject: [PATCH 041/167] [Gradle Release Plugin] - pre tag commit: '1.0.2'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d98cf5da8..ccfe5d974 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.2-SNAPSHOT +version = 1.0.2 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 1489cce5cfe3cd211b62d68af4be88b7b81d4de0 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:07:46 -0500 Subject: [PATCH 042/167] [Gradle Release Plugin] - new version commit: '1.0.3-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ccfe5d974..54f794f6e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.2 +version = 1.0.3-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 49322dc442f77289106abdf78b19bae336f59cb5 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:12:12 -0500 Subject: [PATCH 043/167] [Gradle Release Plugin] - pre tag commit: '1.0.3'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 54f794f6e..a1f5eb003 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.3-SNAPSHOT +version = 1.0.3 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 22496b5d4ab3e689dc6d43ffb62c981812ea4245 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:12:14 -0500 Subject: [PATCH 044/167] [Gradle Release Plugin] - new version commit: '1.0.4-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a1f5eb003..5c80cbcc6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.3 +version = 1.0.4-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From c4ac8876dd576ce3c5abdd956a118d24ecef6822 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:25:06 -0500 Subject: [PATCH 045/167] [Gradle Release Plugin] - pre tag commit: '1.0.4'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5c80cbcc6..5f949dc44 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.4-SNAPSHOT +version = 1.0.4 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From a738df1b414550f8ad8b83329cdd2148f7fcf1a3 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:25:13 -0500 Subject: [PATCH 046/167] [Gradle Release Plugin] - new version commit: '1.0.5-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5f949dc44..154c058b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.4 +version = 1.0.5-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 92f79b602c8adce9d94bb0c0f7e8214bc5814c44 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:37:04 -0500 Subject: [PATCH 047/167] [Gradle Release Plugin] - pre tag commit: '1.0.5'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 154c058b9..877118e36 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.5-SNAPSHOT +version = 1.0.5 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 78da63af7eedb1ae118340d06974cfdc63cb94f6 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 7 Mar 2024 23:37:12 -0500 Subject: [PATCH 048/167] [Gradle Release Plugin] - new version commit: '1.0.6-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 877118e36..cc77b90a0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.5 +version = 1.0.6-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From dda04be1c1ff514b94875499476825daba4ed3dc Mon Sep 17 00:00:00 2001 From: "Shane Michael Mathews (Brandwatch Account)" <21181346+smmathews-bw-boston@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:48:47 -0400 Subject: [PATCH 049/167] Implement BatchIterator's promise to fill the input buffer, when possible (#712) * org.roaringbitmap.BatchIterator.nextBatch promises, in a comment, that its implementations "Aims to fill the buffer", but the two implementations of this will stop at the first consumption, even if there are many more ordinals to consume in later containers. This is muddying the idea of a container (which is essentially a roaring bitmap batch) and the user's batch (which may be smaller or larger than the roaring bitmap container cardinality). This commit attempts to make the implementation match the promise. Considering how long this implementation has been out of step with the comment, this may not be the best solution to merge upstream, but it's the solution my team would prefer. Implementation only, tests to follow. * fixup compilation, existing tests, and checkstyle. Still WIP, as we're missing tests for our specific functionality. * add test for batches that are across multiple containers will fill the buffer * now that we have our own tests for filling the buffer, leave the original testIndependenceOfClones2 tests closer to their original implementation --- .../org/roaringbitmap/ArrayBatchIterator.java | 6 +++--- .../roaringbitmap/BitmapBatchIterator.java | 6 +++--- .../roaringbitmap/ContainerBatchIterator.java | 14 +++++++++++++- .../roaringbitmap/RoaringBatchIterator.java | 6 +++--- .../org/roaringbitmap/RunBatchIterator.java | 9 +++++---- .../buffer/ArrayBatchIterator.java | 6 +++--- .../buffer/BitmapBatchIterator.java | 6 +++--- .../buffer/RoaringBatchIterator.java | 6 +++--- .../buffer/RunBatchIterator.java | 9 +++++---- .../roaringbitmap/CloneBatchIteratorTest.java | 2 +- .../RoaringBitmapBatchIteratorTest.java | 18 ++++++++++++++++++ .../buffer/CloneBatchIteratorTest.java | 2 +- ...mutableRoaringBitmapBatchIteratorTest.java | 19 +++++++++++++++++++ 13 files changed, 80 insertions(+), 29 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java index c6d248b4d..195022cf8 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java @@ -13,11 +13,11 @@ public ArrayBatchIterator(ArrayContainer array) { } @Override - public int next(int key, int[] buffer) { + public int next(int key, int[] buffer, int offset) { int consumed = 0; char[] data = array.content; - while (consumed < buffer.length && index < array.getCardinality()) { - buffer[consumed++] = key + (data[index++]); + while ((offset + consumed) < buffer.length && index < array.getCardinality()) { + buffer[offset + consumed++] = key + (data[index++]); } return consumed; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java index 4774c639f..be6e64145 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java @@ -13,9 +13,9 @@ public BitmapBatchIterator(BitmapContainer bitmap) { } @Override - public int next(int key, int[] buffer) { + public int next(int key, int[] buffer, int offset) { int consumed = 0; - while (consumed < buffer.length) { + while ((consumed + offset) < buffer.length) { while (word == 0) { ++wordIndex; if (wordIndex == 1024) { @@ -23,7 +23,7 @@ public int next(int key, int[] buffer) { } word = bitmap.bitmap[wordIndex]; } - buffer[consumed++] = key + (64 * wordIndex) + numberOfTrailingZeros(word); + buffer[offset + consumed++] = key + (64 * wordIndex) + numberOfTrailingZeros(word); word &= (word - 1); } return consumed; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java index aa185f5f6..69ac0d7ce 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java @@ -7,9 +7,21 @@ public interface ContainerBatchIterator extends Cloneable { * and returns how much of the buffer was used. * @param key the prefix of the values * @param buffer the buffer to write values onto + * @param offset the offset into the buffer to write values onto * @return how many values were written. */ - int next(int key, int[] buffer); + int next(int key, int[] buffer, int offset); + + /** + * Fills the buffer with values prefixed by the key, + * and returns how much of the buffer was used. + * @param key the prefix of the values + * @param buffer the buffer to write values onto + * @return how many values were written. + */ + default int next(int key, int[] buffer) { + return next(key, buffer, 0); + } /** * Whether the underlying container is exhausted or not diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java index f68a3841a..602e460b4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java @@ -18,9 +18,9 @@ public RoaringBatchIterator(RoaringArray highLowContainer) { @Override public int nextBatch(int[] buffer) { int consumed = 0; - while (iterator != null && consumed == 0) { - consumed = iterator.next(key, buffer); - if (consumed == 0 || !iterator.hasNext()) { + while (iterator != null && consumed < buffer.length) { + consumed += iterator.next(key, buffer, consumed); + if (consumed < buffer.length || !iterator.hasNext()) { nextContainer(); } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java index 159e3e2d9..47509fd48 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java @@ -13,16 +13,17 @@ public RunBatchIterator(RunContainer runs) { } @Override - public int next(int key, int[] buffer) { + public int next(int key, int[] buffer, int offset) { int consumed = 0; do { int runStart = (runs.getValue(run)); int runLength = (runs.getLength(run)); int chunkStart = runStart + cursor; - int chunkEnd = chunkStart + Math.min(runLength - cursor, buffer.length - consumed - 1); + int usableBufferLength = buffer.length - offset - consumed; + int chunkEnd = chunkStart + Math.min(runLength - cursor, usableBufferLength - 1); int chunk = chunkEnd - chunkStart + 1; for (int i = 0; i < chunk; ++i) { - buffer[consumed + i] = key + chunkStart + i; + buffer[offset + consumed + i] = key + chunkStart + i; } consumed += chunk; if (runStart + runLength == chunkEnd) { @@ -31,7 +32,7 @@ public int next(int key, int[] buffer) { } else { cursor += chunk; } - } while (consumed < buffer.length && run != runs.numberOfRuns()); + } while ((offset + consumed) < buffer.length && run != runs.numberOfRuns()); return consumed; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java index 44cd4a42a..f0664e95b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java @@ -17,11 +17,11 @@ public ArrayBatchIterator(MappeableArrayContainer array) { } @Override - public int next(int key, int[] buffer) { + public int next(int key, int[] buffer, int offset) { int consumed = 0; CharBuffer data = array.content; - while (consumed < buffer.length && index < array.getCardinality()) { - buffer[consumed++] = key + (data.get(index++)); + while ((offset + consumed) < buffer.length && index < array.getCardinality()) { + buffer[offset + consumed++] = key + (data.get(index++)); } return consumed; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java index 4411d6d65..e432158ae 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java @@ -15,9 +15,9 @@ public BitmapBatchIterator(MappeableBitmapContainer bitmap) { } @Override - public int next(int key, int[] buffer) { + public int next(int key, int[] buffer, int offset) { int consumed = 0; - while (consumed < buffer.length) { + while ((offset + consumed) < buffer.length) { while (word == 0) { ++wordIndex; if (wordIndex == 1024) { @@ -25,7 +25,7 @@ public int next(int key, int[] buffer) { } word = bitmap.bitmap.get(wordIndex); } - buffer[consumed++] = key + (64 * wordIndex) + numberOfTrailingZeros(word); + buffer[offset + consumed++] = key + (64 * wordIndex) + numberOfTrailingZeros(word); word &= (word - 1); } return consumed; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java index bb03181ec..98cf8402b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java @@ -20,9 +20,9 @@ public RoaringBatchIterator(MappeableContainerPointer containerPointer) { @Override public int nextBatch(int[] buffer) { int consumed = 0; - while (iterator != null && consumed == 0) { - consumed = iterator.next(key, buffer); - if (consumed == 0 || !iterator.hasNext()) { + while (iterator != null && consumed < buffer.length) { + consumed += iterator.next(key, buffer, consumed); + if (consumed < buffer.length || !iterator.hasNext()) { nextContainer(); } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java index 4b4c2fea3..66a2f7ee0 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java @@ -15,16 +15,17 @@ public RunBatchIterator(MappeableRunContainer runs) { } @Override - public int next(int key, int[] buffer) { + public int next(int key, int[] buffer, int offset) { int consumed = 0; do { int runStart = (runs.getValue(run)); int runLength = (runs.getLength(run)); int chunkStart = runStart + cursor; - int chunkEnd = chunkStart + Math.min(runLength - cursor, buffer.length - consumed - 1); + int usableBufferLength = buffer.length - offset - consumed; + int chunkEnd = chunkStart + Math.min(runLength - cursor, usableBufferLength - 1); int chunk = chunkEnd - chunkStart + 1; for (int i = 0; i < chunk; ++i) { - buffer[consumed + i] = key + chunkStart + i; + buffer[offset + consumed + i] = key + chunkStart + i; } consumed += chunk; if (runStart + runLength == chunkEnd) { @@ -33,7 +34,7 @@ public int next(int key, int[] buffer) { } else { cursor += chunk; } - } while (consumed < buffer.length && run != runs.numberOfRuns()); + } while ((offset + consumed) < buffer.length && run != runs.numberOfRuns()); return consumed; } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java index 137bc2d08..2f9e9d509 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java @@ -41,7 +41,7 @@ public void testIndependenceOfClones2() { BatchIterator it1 = bitmap.getBatchIterator(); BatchIterator it2 = it1.clone(); - int[] buffer = new int[8]; + int[] buffer = new int[3]; assertEquals(3, it2.nextBatch(buffer)); assertArrayEquals(c1, Arrays.copyOfRange(buffer, 0, 3)); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java index 6367b8b15..64de803be 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java @@ -227,4 +227,22 @@ public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { assertEquals(batch[i], number); } + @Test + public void testBatchIteratorFillsBufferAcrossContainers() { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(3 << 4, 3 << 8, 3 << 12, 3 << 16, 3 << 20, 3 << 24, 3 << 28); + assertEquals(5, bitmap.highLowContainer.size()); + BatchIterator it = bitmap.getBatchIterator(); + int[] batch = new int[3]; + int n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[]{3 << 4, 3 << 8, 3 << 12}, batch); + n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[]{3 << 16, 3 << 20, 3 << 24}, batch); + n = it.nextBatch(batch); + assertEquals(1, n); + assertArrayEquals(new int[]{3 << 28}, Arrays.copyOfRange(batch, 0, 1)); + n = it.nextBatch(batch); + assertEquals(0, n); + } } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java index d0e987075..eaad7b71b 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java @@ -42,7 +42,7 @@ public void testIndependenceOfClones2() { BatchIterator it1 = bitmap.getBatchIterator(); BatchIterator it2 = it1.clone(); - int[] buffer = new int[8]; + int[] buffer = new int[3]; assertEquals(3, it2.nextBatch(buffer)); assertArrayEquals(c1, Arrays.copyOfRange(buffer, 0, 3)); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java index 9f874d89e..467702664 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java @@ -209,4 +209,23 @@ public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { assertTrue(i >= 0, "key " + number + " not found"); assertEquals(batch[i], number); } + + @Test + public void testBatchIteratorFillsBufferAcrossContainers() { + MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(3 << 4, 3 << 8, 3 << 12, 3 << 16, 3 << 20, 3 << 24, 3 << 28); + assertEquals(5, bitmap.highLowContainer.size()); + BatchIterator it = bitmap.getBatchIterator(); + int[] batch = new int[3]; + int n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[]{3 << 4, 3 << 8, 3 << 12}, batch); + n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[]{3 << 16, 3 << 20, 3 << 24}, batch); + n = it.nextBatch(batch); + assertEquals(1, n); + assertArrayEquals(new int[]{3 << 28}, Arrays.copyOfRange(batch, 0, 1)); + n = it.nextBatch(batch); + assertEquals(0, n); + } } From 01fad43ae9a3f52bf285f6fba36febef4967392e Mon Sep 17 00:00:00 2001 From: Danny Thomas Date: Fri, 29 Mar 2024 23:22:52 +1100 Subject: [PATCH 050/167] RoaringBitmap to BitSet/long[]/byte[] (#713) * RoaringBitmap to BitSet/long[]/byte[]. Fixes #556 * Prevent bitmaps with negative bits from being converted. Add variant that avoids an intermediate array * Fix javadoc typos --- .../java/org/roaringbitmap/BitSetUtil.java | 83 ++++++++++++++++++- .../org/roaringbitmap/BitmapContainer.java | 3 + .../org/roaringbitmap/TestBitSetUtil.java | 17 +++- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java index 4d59b2bb4..a56489a33 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java @@ -14,7 +14,6 @@ * */ public class BitSetUtil { - // todo: add a method to convert a RoaringBitmap to a BitSet using BitSet.valueOf // a block consists has a maximum of 1024 words, each representing 64 bits, // thus representing at maximum 65536 bits @@ -22,6 +21,88 @@ public class BitSetUtil { // 64-bit // word + /** + * Convert a {@link RoaringBitmap} to a {@link BitSet}. + *

+ * Equivalent to calling {@code BitSet.valueOf(BitSetUtil.toLongArray(bitmap))}. + */ + public static BitSet bitsetOf(RoaringBitmap bitmap) { + return BitSet.valueOf(toLongArray(bitmap)); + } + + /** + * Convert a {@link RoaringBitmap} to a {@link BitSet} without copying to an intermediate array. + */ + public static BitSet bitsetOfWithoutCopy(RoaringBitmap bitmap) { + if (bitmap.isEmpty()) { + return new BitSet(0); + } + int last = bitmap.last(); + if (last < 0) { + throw new IllegalArgumentException("bitmap has negative bits set"); + } + BitSet bitSet = new BitSet(last); + bitmap.forEach((IntConsumer) bitSet::set); + return bitSet; + } + + /** + * Returns an array of little-endian ordered bytes, given a {@link RoaringBitmap}. + *

+ * See {@link BitSet#toByteArray()}. + */ + public static byte[] toByteArray(RoaringBitmap bitmap) { + long[] words = toLongArray(bitmap); + ByteBuffer buffer = ByteBuffer.allocate(words.length * Long.SIZE) + .order(ByteOrder.LITTLE_ENDIAN); + buffer.asLongBuffer().put(words); + return buffer.array(); + } + + /** + * Returns an array of long, given a {@link RoaringBitmap}. + *

+ * See {@link BitSet#toLongArray()}. + */ + public static long[] toLongArray(RoaringBitmap bitmap) { + if (bitmap.isEmpty()) { + return new long[0]; + } + + int last = bitmap.last(); + if (last < 0) { + throw new IllegalArgumentException("bitmap has negative bits set"); + } + int lastBit = Math.max(last, Long.SIZE); + int remainder = lastBit % Long.SIZE; + int numBits = remainder > 0 ? lastBit - remainder : lastBit; + int wordsInUse = numBits / Long.SIZE + 1; + long[] words = new long[wordsInUse]; + + ContainerPointer pointer = bitmap.getContainerPointer(); + int numContainers = Math.max(words.length / BLOCK_LENGTH, 1); + int position = 0; + for (int i = 0; i <= numContainers; i++) { + char key = Util.lowbits(i); + if (key == pointer.key()) { + BitmapContainer container = pointer.getContainer().toBitmapContainer(); + int remaining = wordsInUse - position; + int length = Math.min(BLOCK_LENGTH, remaining); + container.copyBitmapTo(words, position, length); + position += length; + pointer.advance(); + if (pointer.getContainer() == null) { + break; + } + } else { + position += BLOCK_LENGTH; + } + } + assert pointer.getContainer() == null; + assert position == wordsInUse; + return words; + } + /** * Creates array container's content char buffer. * diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index 7c2b25977..c28c55eec 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -1707,6 +1707,9 @@ public int last() { return (i + 1) * 64 - Long.numberOfLeadingZeros(bitmap[i]) - 1; } + public void copyBitmapTo(long[] words, int position, int length) { + System.arraycopy(bitmap, 0, words, position, length); + } } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java index 1f945b586..532d14599 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java @@ -7,7 +7,7 @@ import java.util.BitSet; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class TestBitSetUtil { @@ -27,7 +27,10 @@ private static BitSet randomBitset(final Random random, final int offset, final private void assertEqualBitsets(final BitSet bitset, final RoaringBitmap bitmap) { - assertTrue(BitSetUtil.equals(bitset, bitmap)); + assertTrue(BitSetUtil.equals(bitset, bitmap), "bitset and bitmap do not match"); + assertEquals(bitset, BitSetUtil.bitsetOf(bitmap), "bitsetOf doesn't match"); + assertEquals(bitset, BitSetUtil.bitsetOfWithoutCopy(bitmap), "bitsetOfWithoutCopy doesn't match"); + assertEquals(bitset, BitSet.valueOf(BitSetUtil.toByteArray(bitmap)), "toByteArray doesn't match"); } @Test @@ -236,6 +239,16 @@ public void testByteArrayWithFastRank() { Assertions.assertTrue(bitmap instanceof FastRankRoaringBitmap); } + @Test + public void testBitmapOfNegative() { + final RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(-1); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + BitSetUtil.bitsetOf(bitmap); + }); + assertEquals("bitmap has negative bits set", exception.getMessage()); + } + private static ByteBuffer toByteBuffer(BitSet bitset) { return ByteBuffer.wrap(bitset.toByteArray()); } From 9079e41f913842d4ce53eec4f36c0c14e41dd587 Mon Sep 17 00:00:00 2001 From: Danny Thomas Date: Thu, 18 Apr 2024 01:03:51 +1000 Subject: [PATCH 051/167] Avoid getCardinality in RunContainer.toBitmapContainer (#715) --- .../main/java/org/roaringbitmap/RunContainer.java | 4 +++- .../java/org/roaringbitmap/TestRunContainer.java | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index eb7aa9b97..44dda700d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -2646,13 +2646,15 @@ public void forAllInRange(char startValue, char endValue, final RelativeRangeCon @Override public BitmapContainer toBitmapContainer() { - int card = this.getCardinality(); + int card = 0; BitmapContainer answer = new BitmapContainer(); for (int rlepos = 0; rlepos < this.nbrruns; ++rlepos) { int start = (this.getValue(rlepos)); int end = start + (this.getLength(rlepos)) + 1; + card += end - start; Util.setBitmapRange(answer.bitmap, start, end); } + assert card == this.getCardinality(); answer.cardinality = card; return answer; } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java index b31b14c08..2bbfa3fe2 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java @@ -3955,6 +3955,18 @@ public void iorWithFullContainer() { assertEquals(RunContainer.full(), container); } + @Test + public void toBitmapContainer() { + Container rc = new RunContainer().add((char)1).add(5, 7).add(10, 21); + BitmapContainer bitmapContainer = rc.toBitmapContainer(); + + assertTrue(bitmapContainer.contains((char) 1)); + assertTrue(bitmapContainer.contains(5, 7)); + assertTrue(bitmapContainer.contains(10, 21)); + + assertEquals(rc.getCardinality(), bitmapContainer.getCardinality()); + } + private static int lower16Bits(int x) { return ((char)x) & 0xFFFF; } From 91ff377e89672170a5cda4b2ed0ec5c4ce1f21bd Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 17 Apr 2024 22:28:36 -0400 Subject: [PATCH 052/167] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e86816eee..69ccf9d4c 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ This library is used by The YouTube SQL Engine, [Google Procella](https://research.google/pubs/pub48388/), uses Roaring bitmaps for indexing. [Apache Lucene](http://lucene.apache.org/) uses Roaring bitmaps, though they have their own [independent implementation](https://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/RoaringDocIdSet.java?view=markup&pathrev=1629606). Derivatives of Lucene such as Solr and Elastic also use Roaring bitmaps. -Other platforms such as [Whoosh](https://pypi.python.org/pypi/Whoosh/), [Microsoft Visual Studio Team Services (VSTS)](https://www.visualstudio.com/team-services/) and [Pilosa](https://github.com/pilosa/pilosa) also use Roaring bitmaps with their own implementations. You find Roaring bitmaps in [InfluxDB](https://www.influxdata.com), [Bleve](http://www.blevesearch.com), [Cloud Torrent](https://github.com/jpillora/cloud-torrent), and so forth. +Other platforms such as [Whoosh](https://pypi.python.org/pypi/Whoosh/), [Microsoft Visual Studio Team Services (VSTS)](https://www.visualstudio.com/team-services/) and [Pilosa](https://github.com/pilosa/pilosa) also use Roaring bitmaps with their own implementations. You find Roaring bitmaps in [InfluxDB](https://www.influxdata.com), [Bleve](http://www.blevesearch.com), [Cloud Torrent](https://github.com/jpillora/cloud-torrent), [Redpanda](https://github.com/redpanda-data/redpanda), and so forth. [There is a serialized format specification for interoperability between implementations](https://github.com/RoaringBitmap/RoaringFormatSpec/). From 0905e734a4fb3d5abf0b1d9fb3859a08c4af7c41 Mon Sep 17 00:00:00 2001 From: "Shane Michael Mathews (Brandwatch Account)" <21181346+smmathews-bw-boston@users.noreply.github.com> Date: Fri, 19 Apr 2024 11:52:45 -0400 Subject: [PATCH 053/167] add Java 21 to CI, as one of four LTS versions still being supported by Eclipse Temurin (see https://adoptium.net/support/) (#719) --- .github/workflows/java-all-versions.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/java-all-versions.yml b/.github/workflows/java-all-versions.yml index 35474f684..3ab0a102e 100644 --- a/.github/workflows/java-all-versions.yml +++ b/.github/workflows/java-all-versions.yml @@ -1,4 +1,4 @@ -name: Java 8, 11, 17 CI +name: Java 8, 11, 17, 21 CI on: [push,pull_request] @@ -8,14 +8,15 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDKs 8, 11, 17 - uses: actions/setup-java@v3 + - name: Set up JDKs 8, 11, 17, 21 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: | 8 11 17 + 21 - name: Build with Gradle run: ./gradlew assemble - name: Style check @@ -26,3 +27,5 @@ jobs: run: ./gradlew test -PtestOnJava=11 --stacktrace - name: Test with Java 17 run: ./gradlew test -PtestOnJava=17 --stacktrace + - name: Test with Java 21 + run: ./gradlew test -PtestOnJava=21 --stacktrace From bea55d46dfe97c3e76d67f26a335c31014f04d77 Mon Sep 17 00:00:00 2001 From: Danny Thomas Date: Sat, 20 Apr 2024 09:44:19 +1000 Subject: [PATCH 054/167] Avoid intermediate arrays for other container types (#716) --- .../main/java/org/roaringbitmap/ArrayContainer.java | 8 ++++++++ .../src/main/java/org/roaringbitmap/BitSetUtil.java | 8 ++++++-- .../java/org/roaringbitmap/BitmapContainer.java | 13 +++++++++---- .../src/main/java/org/roaringbitmap/Container.java | 11 +++++++++++ .../main/java/org/roaringbitmap/RunContainer.java | 10 ++++++++++ .../test/java/org/roaringbitmap/TestBitSetUtil.java | 4 ++++ 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index 0fe53625e..095fb159c 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -1129,6 +1129,14 @@ public BitmapContainer toBitmapContainer() { return bc; } + @Override + public void copyBitmapTo(long[] dest, int position) { + for (int k = 0; k < cardinality; ++k) { + final char x = content[k]; + dest[position + x/64] |= 1L << x; + } + } + @Override public int nextValue(char fromValue) { int index = Util.advanceUntil(content, -1, cardinality, fromValue); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java index a56489a33..58e613834 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java @@ -85,10 +85,14 @@ public static long[] toLongArray(RoaringBitmap bitmap) { for (int i = 0; i <= numContainers; i++) { char key = Util.lowbits(i); if (key == pointer.key()) { - BitmapContainer container = pointer.getContainer().toBitmapContainer(); + Container container = pointer.getContainer(); int remaining = wordsInUse - position; int length = Math.min(BLOCK_LENGTH, remaining); - container.copyBitmapTo(words, position, length); + if (container instanceof BitmapContainer) { + ((BitmapContainer)container).copyBitmapTo(words, position, length); + } else { + container.copyBitmapTo(words, position); + } position += length; pointer.advance(); if (pointer.getContainer() == null) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index c28c55eec..85e9621ff 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -1665,6 +1665,15 @@ public BitmapContainer toBitmapContainer() { return this; } + @Override + public void copyBitmapTo(long[] words, int position) { + System.arraycopy(bitmap, 0, words, position, bitmap.length); + } + + public void copyBitmapTo(long[] words, int position, int length) { + System.arraycopy(bitmap, 0, words, position, length); + } + @Override public int nextValue(char fromValue) { return nextSetBit((fromValue)); @@ -1706,10 +1715,6 @@ public int last() { // sizeof(long) * #words from start - number of bits after the last bit set return (i + 1) * 64 - Long.numberOfLeadingZeros(bitmap[i]) - 1; } - - public void copyBitmapTo(long[] words, int position, int length) { - System.arraycopy(bitmap, 0, words, position, length); - } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Container.java b/RoaringBitmap/src/main/java/org/roaringbitmap/Container.java index cdb7a3f9f..648d3c552 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/Container.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/Container.java @@ -986,6 +986,17 @@ public Container xor(Container x) { */ public abstract BitmapContainer toBitmapContainer(); + /** + * Copy the current container to a destination {@code long[]}. Equivalent to calling + * {@link #toBitmapContainer()} and copying the result to the given position. The destination + * array should be sized to accomodate the maximum number of words required to represent + * the container bitmap. + * + * @param dest the destination array + * @param position the position to copy to + */ + public abstract void copyBitmapTo(long[] dest, int position); + /** * Gets the first value greater than or equal to the lower bound, or -1 if no such value exists. * @param fromValue the lower bound (inclusive) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index 44dda700d..268094ae2 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -2659,6 +2659,16 @@ public BitmapContainer toBitmapContainer() { return answer; } + @Override + public void copyBitmapTo(long[] dest, int position) { + int offset = position * Long.SIZE; + for (int rlepos = 0; rlepos < this.nbrruns; ++rlepos) { + int start = offset + this.getValue(rlepos); + int end = start + this.getLength(rlepos) + 1; + Util.setBitmapRange(dest, start, end); + } + } + @Override public int nextValue(char fromValue) { int index = unsignedInterleavedBinarySearch(valueslength, 0, nbrruns, fromValue); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java index 532d14599..c5bc18e23 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java @@ -31,6 +31,10 @@ private void assertEqualBitsets(final BitSet bitset, final RoaringBitmap bitmap) assertEquals(bitset, BitSetUtil.bitsetOf(bitmap), "bitsetOf doesn't match"); assertEquals(bitset, BitSetUtil.bitsetOfWithoutCopy(bitmap), "bitsetOfWithoutCopy doesn't match"); assertEquals(bitset, BitSet.valueOf(BitSetUtil.toByteArray(bitmap)), "toByteArray doesn't match"); + + RoaringBitmap runBitmap = bitmap.clone(); + runBitmap.runOptimize(); + assertEquals(bitset, BitSetUtil.bitsetOf(runBitmap), "bitsetOf doesn't match for run optimized bitmap"); } @Test From 0735196d60eec42324f1c356da56f001bad67c39 Mon Sep 17 00:00:00 2001 From: Lars Kroll Date: Sat, 20 Apr 2024 01:48:43 +0200 Subject: [PATCH 055/167] Fix for or:ing two RunContainers that produce an undersized BitmapContainer (#718) * Add test and fix for or:ing two RunContainers that produce an undersized BitmapContainer combined * Also fix MappeableRunContainer and remove unused methods --- .../java/org/roaringbitmap/RunContainer.java | 14 ++------------ .../buffer/MappeableRunContainer.java | 15 ++------------- .../java/org/roaringbitmap/TestContainer.java | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index 268094ae2..6fdddcd2d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -1550,7 +1550,7 @@ public Container ior(RunContainer x) { this.smartAppend(x.getValue(xrlepos), x.getLength(xrlepos)); ++xrlepos; } - return this.toBitmapIfNeeded(); + return this.toEfficientContainer(); } @Override @@ -1986,7 +1986,7 @@ public Container or(RunContainer x) { if (answer.isFull()) { return full(); } - return answer.toBitmapIfNeeded(); + return answer.toEfficientContainer(); } // Prepend a value length with all values starting from a given value @@ -2295,16 +2295,6 @@ private void smartAppendExclusive(char start, char length) { } } - // convert to bitmap *if needed* (useful if you know it can't be an array) - private Container toBitmapIfNeeded() { - int sizeAsRunContainer = RunContainer.serializedSizeInBytes(this.nbrruns); - int sizeAsBitmapContainer = BitmapContainer.serializedSizeInBytes(0); - if (sizeAsBitmapContainer > sizeAsRunContainer) { - return this; - } - return toBitmapContainer(); - } - /** * Convert the container to either a Bitmap or an Array Container, depending on the cardinality. * diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index 0be2d0069..2e07eaef1 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -1456,7 +1456,7 @@ public MappeableContainer ior(MappeableRunContainer x) { this.smartAppend(vl, x.getValue(xrlepos), x.getLength(xrlepos)); ++xrlepos; } - return this.toBitmapIfNeeded(); + return this.toEfficientContainer(); } @Override @@ -1940,7 +1940,7 @@ public MappeableContainer or(MappeableRunContainer x) { if (answer.isFull()) { return full(); } - return answer.toBitmapIfNeeded(); + return answer.toEfficientContainer(); } // Prepend a value length with all values starting from a given value @@ -2230,17 +2230,6 @@ private void smartAppendExclusive(char[] vl, char start, char length) { } } - - // convert to bitmap *if needed* (useful if you know it can't be an array) - private MappeableContainer toBitmapIfNeeded() { - int sizeAsRunContainer = MappeableRunContainer.serializedSizeInBytes(this.nbrruns); - int sizeAsBitmapContainer = MappeableBitmapContainer.serializedSizeInBytes(0); - if (sizeAsBitmapContainer > sizeAsRunContainer) { - return this; - } - return toBitmapContainer(); - } - /** * Convert the container to either a Bitmap or an Array Container, depending on the cardinality. * diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java index 5558267e2..6ddbcc4e8 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java @@ -801,6 +801,25 @@ public void or5() { assertTrue(checkContent(result, new char[] {1, 3, 4, 5, (char) 50000, (char) 50001})); } + @Test + public void or6() { + System.out.println("or6"); + RunContainer rc1 = new RunContainer(); + for (int i = 0; i < 6144; i += 6) { + rc1.iadd(i, i+1); + } + + RunContainer rc2 = new RunContainer(); + + for (int i = 3; i < 6144; i += 6) { + rc2.iadd(i, i+1); + } + + Container result = rc1.or(rc2); + assertTrue(result.getCardinality() < ArrayContainer.DEFAULT_MAX_SIZE); + assertTrue(result instanceof ArrayContainer); + } + @Test public void testXorContainer() throws Exception { Container rc1 = new RunContainer(new char[] {10, 12, 90, 10}, 2); From 5235aa62c32fa3bf7fae40a562e3edc75f61be4e Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 19 Apr 2024 19:51:30 -0400 Subject: [PATCH 056/167] [Gradle Release Plugin] - pre tag commit: '1.0.6'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index cc77b90a0..2e828a005 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.6-SNAPSHOT +version = 1.0.6 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 939748f6864deaace54e724f28b6b484dd56f03b Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 19 Apr 2024 19:51:32 -0400 Subject: [PATCH 057/167] [Gradle Release Plugin] - new version commit: '1.0.7-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2e828a005..9adf9c858 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.6 +version = 1.0.7-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From c112860f2f2e09bbbc28eb4fa2cac198714c7088 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 7 Jun 2024 14:59:00 -0400 Subject: [PATCH 058/167] fix: formalize edge behaviour for nextAbsentValue and previousAbsentValue (#720) * fix: formalize edge behaviour for nextAbsentValue and previousAbsentValue * simplifying --- .../ImmutableBitmapDataProvider.java | 4 +-- .../java/org/roaringbitmap/RoaringBitmap.java | 6 ++-- .../buffer/ImmutableRoaringBitmap.java | 6 ++-- .../org/roaringbitmap/TestRoaringBitmap.java | 28 +++++++++++++++++++ .../buffer/TestRoaringBitmap.java | 28 +++++++++++++++++++ 5 files changed, 64 insertions(+), 8 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java index 2a7502138..a4b1488a4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java @@ -235,7 +235,7 @@ public default IntStream reverseStream() { * * @param fromValue the lower bound (inclusive) * @return the smallest absent value larger than or equal to the specified - * value. + * value or {@code -1} if there is no such value. */ long nextAbsentValue(int fromValue); @@ -246,7 +246,7 @@ public default IntStream reverseStream() { * * @param fromValue the lower bound (inclusive) * @return the smallest absent value larger than or equal to the specified - * value. + * value or {@code -1} if there is no such value. */ long previousAbsentValue(int fromValue); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 71c5b4cb8..1162212dc 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -2845,9 +2845,9 @@ public long previousValue(int fromValue) { @Override public long nextAbsentValue(int fromValue) { long nextAbsentBit = computeNextAbsentValue(fromValue); - assert nextAbsentBit <= 0xFFFFFFFFL; - assert nextAbsentBit >= Util.toUnsignedLong(fromValue); - assert !contains((int) nextAbsentBit); + if(nextAbsentBit == 0x100000000L) { + return -1L; + } return nextAbsentBit; } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java index 146e92b9e..64120a54d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java @@ -1729,9 +1729,9 @@ public long previousValue(int fromValue) { @Override public long nextAbsentValue(int fromValue) { long nextAbsentBit = computeNextAbsentValue(fromValue); - assert nextAbsentBit <= 0xFFFFFFFFL; - assert nextAbsentBit >= Util.toUnsignedLong(fromValue); - assert !contains((int) nextAbsentBit); + if(nextAbsentBit == 0x100000000L) { + return -1L; + } return nextAbsentBit; } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java index cb601cf8f..f6d8966d1 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java @@ -5300,6 +5300,34 @@ public void testNextValue() { } } + @Test + public void testPreviousValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(1); + assertEquals(-1l, bitmap.previousValue(0)); + } + + @Test + public void testPreviousAbsentValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(0); + assertEquals(-1L, bitmap.previousAbsentValue(0)); + } + + @Test + public void testNextValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(0xffffffff-1); + assertEquals(-1L, bitmap.nextValue(0xffffffff)); + } + + @Test + public void testNextAbsentValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(-1); + assertEquals(-1L, bitmap.nextAbsentValue(-1)); + } + @Test public void testPreviousValue() { RoaringBitmap bitmap = SeededTestData.TestDataSet.testCase() diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java index 27ef64ac2..b04136424 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java @@ -3980,4 +3980,32 @@ public void test2345() { r.flip(1); assertEquals(r, MutableRoaringBitmap.bitmapOf(2, 3, 4, 5)); } + + @Test + public void testPreviousValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(1); + assertEquals(-1l, bitmap.previousValue(0)); + } + + @Test + public void testPreviousAbsentValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(0); + assertEquals(-1L, bitmap.previousAbsentValue(0)); + } + + @Test + public void testNextValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(0xffffffff-1); + assertEquals(-1L, bitmap.nextValue(0xffffffff)); + } + + @Test + public void testNextAbsentValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(-1); + assertEquals(-1L, bitmap.nextAbsentValue(-1)); + } } From 117695304617c277d44b4bf22c49da94ee7245fe Mon Sep 17 00:00:00 2001 From: lee worrall Date: Mon, 17 Jun 2024 20:29:04 +0800 Subject: [PATCH 059/167] Fix RunContainer#contains(BitmapContainer) (#721) (#722) should not advance to the next bit when advancing to the next run --- .../java/org/roaringbitmap/RunContainer.java | 1 - .../buffer/MappeableRunContainer.java | 1 - .../org/roaringbitmap/TestRunContainer.java | 22 ++++++++++++++++++- .../buffer/TestRunContainer.java | 21 ++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index 6fdddcd2d..9805c1b42 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -830,7 +830,6 @@ protected boolean contains(BitmapContainer bitmapContainer) { if (ir == runCount) { break; } - w &= w - 1; start = getValue(ir); stop = start + getLength(ir); } else if (ib * 64 + 64 < stop) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index 2e07eaef1..295e4ee5b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -2739,7 +2739,6 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) { if (ir == runCount) { break; } - w &= w - 1; start = getValue(ir); stop = start + getLength(ir); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java index 2bbfa3fe2..cee73476c 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java @@ -1,6 +1,5 @@ package org.roaringbitmap; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -3336,6 +3335,13 @@ public void testContainsBitmapContainer_IncludeProperSubsetDifferentStart() { assertTrue(rc.contains(subset)); } + @Test + public void testContainsBitmapContainer_IncludeProperSubsetMultiWordRun() { + Container rc = new RunContainer().add(0,80); + Container subset = new BitmapContainer().add(0,79); + assertTrue(rc.contains(subset)); + } + @Test public void testContainsBitmapContainer_ExcludeShiftedSet() { Container rc = new RunContainer().add(0,10); @@ -3365,6 +3371,20 @@ public void testContainsBitmapContainer_ExcludeDisJointSet() { assertFalse(disjoint.contains(rc)); } + @Test + public void testContainsBitmapContainer_Issue721Case1() { + Container rc = new RunContainer().add(0,60).add(63,64).add(66,67); + Container subset = new BitmapContainer().add(63,64); + assertTrue(rc.contains(subset)); + } + + @Test + public void testContainsBitmapContainer_Issue721Case2() { + Container rc = new RunContainer().add(0,10).add(12,13); + Container disjoint = new BitmapContainer().add(11,12); + assertFalse(rc.contains(disjoint)); + } + @Test public void testContainsRunContainer_EmptyContainsEmpty() { Container rc = new RunContainer(); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java index ad8c29bad..6a378df6a 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java @@ -2236,6 +2236,13 @@ public void testContainsMappeableBitmapContainer_IncludeProperSubsetDifferentSta assertTrue(rc.contains(subset)); } + @Test + public void testContainsBitmapContainer_IncludeProperSubsetMultiWordRun() { + MappeableContainer rc = new MappeableRunContainer().add(0,80); + MappeableContainer subset = new MappeableBitmapContainer().add(0,79); + assertTrue(rc.contains(subset)); + } + @Test public void testContainsMappeableBitmapContainer_ExcludeShiftedSet() { MappeableContainer rc = new MappeableRunContainer().add(0,10); @@ -2265,6 +2272,20 @@ public void testContainsMappeableBitmapContainer_ExcludeDisJointSet() { assertFalse(disjoint.contains(rc)); } + @Test + public void testContainsMappeableBitmapContainer_Issue721Case1() { + MappeableContainer rc = new MappeableRunContainer().add(0,60).add(63,64).add(66,67); + MappeableContainer subset = new MappeableBitmapContainer().add(63,64); + assertTrue(rc.contains(subset)); + } + + @Test + public void testContainsMappeableBitmapContainer_Issue721Case2() { + MappeableContainer rc = new MappeableRunContainer().add(0,10).add(12,13); + MappeableContainer disjoint = new MappeableBitmapContainer().add(11,12); + assertFalse(rc.contains(disjoint)); + } + @Test public void testContainsMappeableRunContainer_EmptyContainsEmpty() { MappeableContainer rc = new MappeableRunContainer(); From 70866e270627d29de873d4ab0d9a7bd93c16062e Mon Sep 17 00:00:00 2001 From: lee worrall Date: Mon, 17 Jun 2024 20:44:09 +0800 Subject: [PATCH 060/167] Fix ArrayContainer#contains(RunContainer) (#723) (#724) off-by-one error --- .../java/org/roaringbitmap/ArrayContainer.java | 2 +- .../buffer/MappeableArrayContainer.java | 2 +- .../java/org/roaringbitmap/TestArrayContainer.java | 14 ++++++++++++++ .../buffer/TestMappeableArrayContainer.java | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java index 095fb159c..1c3b355ba 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java @@ -317,7 +317,7 @@ protected boolean contains(RunContainer runContainer) { for (int i = 0; i < runContainer.numberOfRuns(); ++i) { int start = (runContainer.getValue(i)); int length = (runContainer.getLength(i)); - if (!contains(start, start + length)) { + if (!contains(start, start + length + 1)) { return false; } } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index 4a606cdc2..9069d216f 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -1651,7 +1651,7 @@ protected boolean contains(MappeableRunContainer runContainer) { for (int i = 0; i < runContainer.numberOfRuns(); ++i) { int start = (runContainer.getValue(i)); int length = (runContainer.getLength(i)); - if (!contains(start, start + length)) { + if (!contains(start, start + length + 1)) { return false; } } diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java index f7602e731..30b1583bd 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java @@ -321,6 +321,20 @@ public void testContainsRunContainer_ExcludeDisJointSet() { assertFalse(disjoint.contains(ac)); } + @Test + public void testContainsRunContainer_Issue723Case1() { + Container ac = new ArrayContainer().add(0,10); + Container subset = new RunContainer().add(5,6); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_Issue723Case2() { + Container ac = new ArrayContainer().add(0,10); + Container rc = new RunContainer().add(5,11); + assertFalse(ac.contains(rc)); + } + @Test public void testContainsArrayContainer_EmptyContainsEmpty() { Container ac = new ArrayContainer(); diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java index 8019f7bf2..722e2808f 100644 --- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java @@ -318,6 +318,20 @@ public void testToString() { ac1.add((char) -17); assertEquals("{5,6,7,8,9,10,11,12,13,14,65519,65533}", ac1.toString()); } + + @Test + public void testContainsRunContainer_Issue723Case1() { + MappeableContainer ac = new MappeableArrayContainer().add(0,10); + MappeableContainer subset = new MappeableRunContainer().add(5,6); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_Issue723Case2() { + MappeableContainer ac = new MappeableArrayContainer().add(0,10); + MappeableContainer rc = new MappeableRunContainer().add(5,11); + assertFalse(ac.contains(rc)); + } @Test public void iorNotIncreaseCapacity() { From e1f128fd7c6fa91bca55573a74c6944c8eebc12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=93=E5=90=9B?= Date: Tue, 18 Jun 2024 21:08:05 +0800 Subject: [PATCH 061/167] [feature] Add a BitSet implementation based on RoaringBitmap (#725) * Add RoaringBitSet * Add RoaringBitSet * Address review comments * Address review comments --- .../java/org/roaringbitmap/RoaringBitSet.java | 226 +++++ .../org/roaringbitmap/RoaringBitSetTest.java | 908 ++++++++++++++++++ 2 files changed, 1134 insertions(+) create mode 100644 RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java create mode 100644 RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java new file mode 100644 index 000000000..ef4a9b82a --- /dev/null +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java @@ -0,0 +1,226 @@ +package org.roaringbitmap; + +import java.util.BitSet; +import java.util.stream.IntStream; + +/** + * A {@link BitSet} implementation based on {@link RoaringBitmap}. + */ +public class RoaringBitSet extends BitSet { + private static final long serialVersionUID = 1L; + + private final RoaringBitmap roaringBitmap; + + public RoaringBitSet() { + super(0); + roaringBitmap = new RoaringBitmap(); + } + + private RoaringBitSet(RoaringBitmap roaringBitmap) { + super(0); + this.roaringBitmap = roaringBitmap; + } + + @Override + public void set(int bitIndex) { + roaringBitmap.add(bitIndex); + } + + @Override + public void set(int bitIndex, boolean value) { + if (value) { + roaringBitmap.add(bitIndex); + } else { + roaringBitmap.remove(bitIndex); + } + } + + @Override + public void set(int fromIndex, int toIndex) { + roaringBitmap.add((long) fromIndex, (long) toIndex); + } + + @Override + public void set(int fromIndex, int toIndex, boolean value) { + if (value) { + roaringBitmap.add((long) fromIndex, (long) toIndex); + } else { + roaringBitmap.remove((long) fromIndex, (long) toIndex); + } + } + + @Override + public void clear(int bitIndex) { + roaringBitmap.remove(bitIndex); + } + + @Override + public void clear(int fromIndex, int toIndex) { + roaringBitmap.remove((long) fromIndex, (long) toIndex); + } + + @Override + public void clear() { + roaringBitmap.clear(); + } + + @Override + public boolean get(int bitIndex) { + return roaringBitmap.contains(bitIndex); + } + + @Override + public BitSet get(int fromIndex, int toIndex) { + BitSet bitSet = BitSetUtil.bitsetOf(roaringBitmap); + bitSet = bitSet.get(fromIndex, toIndex); + return new RoaringBitSet(fromBitSet(bitSet)); + } + + @Override + public int nextSetBit(int fromIndex) { + return (int) roaringBitmap.nextValue(fromIndex); + } + + @Override + public int nextClearBit(int fromIndex) { + return (int) roaringBitmap.nextAbsentValue(fromIndex); + } + + @Override + public int previousSetBit(int fromIndex) { + return (int) roaringBitmap.previousValue(fromIndex); + } + + @Override + public int previousClearBit(int fromIndex) { + return (int) roaringBitmap.previousAbsentValue(fromIndex); + } + + @Override + public int length() { + if (roaringBitmap.isEmpty()) { + return 0; + } + return roaringBitmap.last() + 1; + } + + @Override + public boolean isEmpty() { + return roaringBitmap.isEmpty(); + } + + @Override + public boolean intersects(BitSet set) { + if (set instanceof RoaringBitSet) { + return RoaringBitmap.intersects(roaringBitmap, ((RoaringBitSet) set).roaringBitmap); + } + return RoaringBitmap.intersects(roaringBitmap, fromBitSet(set)); + } + + @Override + public int cardinality() { + return roaringBitmap.getCardinality(); + } + + @Override + public void and(BitSet set) { + if (set instanceof RoaringBitSet) { + roaringBitmap.and(((RoaringBitSet) set).roaringBitmap); + } else { + roaringBitmap.and(fromBitSet(set)); + } + } + + @Override + public void or(BitSet set) { + if (set instanceof RoaringBitSet) { + roaringBitmap.or(((RoaringBitSet) set).roaringBitmap); + } else { + roaringBitmap.or(fromBitSet(set)); + } + } + + @Override + public void xor(BitSet set) { + if (set instanceof RoaringBitSet) { + roaringBitmap.xor(((RoaringBitSet) set).roaringBitmap); + } else { + roaringBitmap.xor(fromBitSet(set)); + } + } + + @Override + public void andNot(BitSet set) { + if (set instanceof RoaringBitSet) { + roaringBitmap.andNot(((RoaringBitSet) set).roaringBitmap); + } else { + roaringBitmap.andNot(fromBitSet(set)); + } + } + + @Override + public int hashCode() { + return roaringBitmap.hashCode(); + } + + @Override + public int size() { + if (roaringBitmap.isEmpty()) { + return 0; + } + int lastBit = Math.max(length(), 64); + int remainder = lastBit % 64; + return remainder == 0 ? lastBit : lastBit + 64 - remainder; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof RoaringBitSet) { + return roaringBitmap.equals(((RoaringBitSet) obj).roaringBitmap); + } + return false; + } + + @Override + public Object clone() { + return new RoaringBitSet(roaringBitmap.clone()); + } + + + @Override + public IntStream stream() { + return roaringBitmap.stream(); + } + + @Override + public String toString() { + return roaringBitmap.toString(); + } + + @Override + public void flip(int bitIndex) { + roaringBitmap.flip((long) bitIndex, (long) bitIndex + 1); + } + + @Override + public void flip(int fromIndex, int toIndex) { + roaringBitmap.flip((long) fromIndex, (long) toIndex); + } + + @Override + public long[] toLongArray() { + return BitSetUtil.toLongArray(roaringBitmap); + } + + @Override + public byte[] toByteArray() { + return BitSetUtil.toByteArray(roaringBitmap); + } + + private static RoaringBitmap fromBitSet(BitSet bitSet) { + return BitSetUtil.bitmapOf(bitSet); + } +} diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java new file mode 100644 index 000000000..438889e6d --- /dev/null +++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java @@ -0,0 +1,908 @@ +package org.roaringbitmap; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Random; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +// From https://github.com/openjdk/jdk/blob/master/test/jdk/java/util/BitSet/BSMethods.java +@SuppressWarnings("all") +public class RoaringBitSetTest { + private static Random generator = new Random(); + + @Test + public void testSetGetClearFlip() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet testSet = new RoaringBitSet(); + HashSet history = new HashSet<>(); + + // Set a random number of bits in random places + // up to a random maximum + int nextBitToSet = 0; + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + for (int x = 0; x < numberOfSetBits; x++) { + nextBitToSet = generator.nextInt(highestPossibleSetBit); + history.add(Integer.valueOf(nextBitToSet)); + testSet.set(nextBitToSet); + } + + // Make sure each bit is set appropriately + for (int x = 0; x < highestPossibleSetBit; x++) { + if (testSet.get(x) != history.contains(Integer.valueOf(x))) + failCount++; + } + + // Clear the bits + Iterator setBitIterator = history.iterator(); + while (setBitIterator.hasNext()) { + Integer setBit = setBitIterator.next(); + testSet.clear(setBit.intValue()); + } + + // Verify they were cleared + for (int x = 0; x < highestPossibleSetBit; x++) + if (testSet.get(x)) + failCount++; + if (testSet.length() != 0) + failCount++; + + // Set them with set(int, boolean) + setBitIterator = history.iterator(); + while (setBitIterator.hasNext()) { + Integer setBit = setBitIterator.next(); + testSet.set(setBit.intValue(), true); + } + + // Make sure each bit is set appropriately + for (int x = 0; x < highestPossibleSetBit; x++) { + if (testSet.get(x) != history.contains(Integer.valueOf(x))) + failCount++; + } + + // Clear them with set(int, boolean) + setBitIterator = history.iterator(); + while (setBitIterator.hasNext()) { + Integer setBit = setBitIterator.next(); + testSet.set(setBit.intValue(), false); + } + + // Verify they were cleared + for (int x = 0; x < highestPossibleSetBit; x++) + if (testSet.get(x)) + failCount++; + if (testSet.length() != 0) + failCount++; + + // Flip them on + setBitIterator = history.iterator(); + while (setBitIterator.hasNext()) { + Integer setBit = setBitIterator.next(); + testSet.flip(setBit.intValue()); + } + + // Verify they were flipped + for (int x = 0; x < highestPossibleSetBit; x++) { + if (testSet.get(x) != history.contains(Integer.valueOf(x))) + failCount++; + } + + // Flip them off + setBitIterator = history.iterator(); + while (setBitIterator.hasNext()) { + Integer setBit = setBitIterator.next(); + testSet.flip(setBit.intValue()); + } + + // Verify they were flipped + for (int x = 0; x < highestPossibleSetBit; x++) + if (testSet.get(x)) + failCount++; + if (testSet.length() != 0) + failCount++; + + checkSanity(testSet); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testClear() { + int failCount = 0; + + for (int i = 0; i < 1000; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + + // Make a fairly random bitset + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) + b1.set(generator.nextInt(highestPossibleSetBit)); + + RoaringBitSet b2 = (RoaringBitSet) b1.clone(); + + // Clear out a random range + int rangeStart = generator.nextInt(100); + int rangeEnd = rangeStart + generator.nextInt(100); + + // Use the clear(int, int) call on b1 + b1.clear(rangeStart, rangeEnd); + + // Use a loop on b2 + for (int x = rangeStart; x < rangeEnd; x++) + b2.clear(x); + + // Verify their equality + if (!b1.equals(b2)) { + failCount++; + } + checkEquality(b1, b2); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testFlip() { + int failCount = 0; + + for (int i = 0; i < 1000; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + + // Make a fairly random bitset + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) + b1.set(generator.nextInt(highestPossibleSetBit)); + + RoaringBitSet b2 = (RoaringBitSet) b1.clone(); + + // Flip a random range + int rangeStart = generator.nextInt(100); + int rangeEnd = rangeStart + generator.nextInt(100); + + // Use the flip(int, int) call on b1 + b1.flip(rangeStart, rangeEnd); + + // Use a loop on b2 + for (int x = rangeStart; x < rangeEnd; x++) + b2.flip(x); + + // Verify their equality + if (!b1.equals(b2)) + failCount++; + checkEquality(b1, b2); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testSet() { + int failCount = 0; + + // Test set(int, int) + for (int i = 0; i < 1000; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + + // Make a fairly random bitset + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) + b1.set(generator.nextInt(highestPossibleSetBit)); + + RoaringBitSet b2 = (RoaringBitSet) b1.clone(); + + // Set a random range + int rangeStart = generator.nextInt(100); + int rangeEnd = rangeStart + generator.nextInt(100); + + // Use the set(int, int) call on b1 + b1.set(rangeStart, rangeEnd); + + // Use a loop on b2 + for (int x = rangeStart; x < rangeEnd; x++) + b2.set(x); + + // Verify their equality + if (!b1.equals(b2)) { + failCount++; + } + checkEquality(b1, b2); + } + + // Test set(int, int, boolean) + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + + // Make a fairly random bitset + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) + b1.set(generator.nextInt(highestPossibleSetBit)); + + RoaringBitSet b2 = (RoaringBitSet) b1.clone(); + boolean setOrClear = generator.nextBoolean(); + + // Set a random range + int rangeStart = generator.nextInt(100); + int rangeEnd = rangeStart + generator.nextInt(100); + + // Use the set(int, int, boolean) call on b1 + b1.set(rangeStart, rangeEnd, setOrClear); + + // Use a loop on b2 + for (int x = rangeStart; x < rangeEnd; x++) + b2.set(x, setOrClear); + + // Verify their equality + if (!b1.equals(b2)) { + failCount++; + } + checkEquality(b1, b2); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testGet() { + int failCount = 0; + + for (int i = 0; i < 1000; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + + // Make a fairly random bitset + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) + b1.set(generator.nextInt(highestPossibleSetBit)); + + // Get a new set from a random range + int rangeStart = generator.nextInt(100); + int rangeEnd = rangeStart + generator.nextInt(100); + + RoaringBitSet b2 = (RoaringBitSet) b1.get(rangeStart, rangeEnd); + + RoaringBitSet b3 = new RoaringBitSet(); + for (int x = rangeStart; x < rangeEnd; x++) + b3.set(x - rangeStart, b1.get(x)); + + // Verify their equality + if (!b2.equals(b3)) { + failCount++; + } + checkEquality(b2, b3); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testAndNot() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + // Set some random bits in first set and remember them + for (int x = 0; x < 10; x++) + b1.set(generator.nextInt(255)); + + // Set some random bits in second set and remember them + for (int x = 10; x < 20; x++) + b2.set(generator.nextInt(255)); + + // andNot the sets together + RoaringBitSet b3 = (RoaringBitSet) b1.clone(); + b3.andNot(b2); + + // Examine each bit of b3 for errors + for (int x = 0; x < 256; x++) { + boolean bit1 = b1.get(x); + boolean bit2 = b2.get(x); + boolean bit3 = b3.get(x); + if (!(bit3 == (bit1 & (!bit2)))) + failCount++; + } + checkSanity(b1, b2, b3); + } + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testAnd() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + // Set some random bits in first set and remember them + for (int x = 0; x < 10; x++) + b1.set(generator.nextInt(255)); + + // Set more random bits in second set and remember them + for (int x = 10; x < 20; x++) + b2.set(generator.nextInt(255)); + + // And the sets together + RoaringBitSet b3 = (RoaringBitSet) b1.clone(); + b3.and(b2); + + // Examine each bit of b3 for errors + for (int x = 0; x < 256; x++) { + boolean bit1 = b1.get(x); + boolean bit2 = b2.get(x); + boolean bit3 = b3.get(x); + if (!(bit3 == (bit1 & bit2))) + failCount++; + } + checkSanity(b1, b2, b3); + } + + // `and' that happens to clear the last word + RoaringBitSet b4 = makeSet(2, 127); + b4.and(makeSet(2, 64)); + checkSanity(b4); + if (!(b4.equals(makeSet(2)))) + failCount++; + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testOr() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + int[] history = new int[20]; + + // Set some random bits in first set and remember them + int nextBitToSet = 0; + for (int x = 0; x < 10; x++) { + nextBitToSet = generator.nextInt(255); + history[x] = nextBitToSet; + b1.set(nextBitToSet); + } + + // Set more random bits in second set and remember them + for (int x = 10; x < 20; x++) { + nextBitToSet = generator.nextInt(255); + history[x] = nextBitToSet; + b2.set(nextBitToSet); + } + + // Or the sets together + RoaringBitSet b3 = (RoaringBitSet) b1.clone(); + b3.or(b2); + + // Verify the set bits of b3 from the history + for (int x = 0; x < 20; x++) { + if (!b3.get(history[x])) + failCount++; + } + + // Examine each bit of b3 for errors + for (int x = 0; x < 256; x++) { + boolean bit1 = b1.get(x); + boolean bit2 = b2.get(x); + boolean bit3 = b3.get(x); + if (!(bit3 == (bit1 | bit2))) + failCount++; + } + checkSanity(b1, b2, b3); + } + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testXor() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + // Set some random bits in first set and remember them + for (int x = 0; x < 10; x++) + b1.set(generator.nextInt(255)); + + // Set more random bits in second set and remember them + for (int x = 10; x < 20; x++) + b2.set(generator.nextInt(255)); + + // Xor the sets together + RoaringBitSet b3 = (RoaringBitSet) b1.clone(); + b3.xor(b2); + + // Examine each bit of b3 for errors + for (int x = 0; x < 256; x++) { + boolean bit1 = b1.get(x); + boolean bit2 = b2.get(x); + boolean bit3 = b3.get(x); + if (!(bit3 == (bit1 ^ bit2))) + failCount++; + } + checkSanity(b1, b2, b3); + b3.xor(b3); + checkEmpty(b3); + } + + // xor that happens to clear the last word + RoaringBitSet b4 = makeSet(2, 64, 127); + b4.xor(makeSet(64, 127)); + checkSanity(b4); + if (!(b4.equals(makeSet(2)))) + failCount++; + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testLength() { + int failCount = 0; + + // Test length after set + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + int highestSetBit = 0; + + for (int x = 0; x < 100; x++) { + int nextBitToSet = generator.nextInt(255); + if (nextBitToSet > highestSetBit) + highestSetBit = nextBitToSet; + b1.set(nextBitToSet); + if (b1.length() != highestSetBit + 1) + failCount++; + } + checkSanity(b1); + } + + // Test length after flip + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + for (int x = 0; x < 100; x++) { + // Flip a random range twice + int rangeStart = generator.nextInt(100); + int rangeEnd = rangeStart + generator.nextInt(100); + b1.flip(rangeStart); + b1.flip(rangeStart); + if (b1.length() != 0) + failCount++; + b1.flip(rangeStart, rangeEnd); + b1.flip(rangeStart, rangeEnd); + if (b1.length() != 0) + failCount++; + } + checkSanity(b1); + } + + // Test length after or + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + int bit1 = generator.nextInt(100); + int bit2 = generator.nextInt(100); + int highestSetBit = (bit1 > bit2) ? bit1 : bit2; + b1.set(bit1); + b2.set(bit2); + b1.or(b2); + if (b1.length() != highestSetBit + 1) + failCount++; + checkSanity(b1, b2); + } + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testEquals() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + // Create BitSets of different sizes + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + // Set some random bits + int nextBitToSet = 0; + for (int x = 0; x < 10; x++) { + nextBitToSet += generator.nextInt(50) + 1; + b1.set(nextBitToSet); + b2.set(nextBitToSet); + } + + // Verify their equality despite different storage sizes + if (!b1.equals(b2)) + failCount++; + checkEquality(b1, b2); + } + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testNextSetBit() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + int numberOfSetBits = generator.nextInt(100) + 1; + RoaringBitSet testSet = new RoaringBitSet(); + int[] history = new int[numberOfSetBits]; + + // Set some random bits and remember them + int nextBitToSet = 0; + for (int x = 0; x < numberOfSetBits; x++) { + nextBitToSet += generator.nextInt(30) + 1; + history[x] = nextBitToSet; + testSet.set(nextBitToSet); + } + + // Verify their retrieval using nextSetBit() + int historyIndex = 0; + for (int x = testSet.nextSetBit(0); x >= 0; x = testSet.nextSetBit(x + 1)) { + if (x != history[historyIndex++]) + failCount++; + } + + checkSanity(testSet); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testNextClearBit() { + int failCount = 0; + + for (int i = 0; i < 1000; i++) { + RoaringBitSet b = new RoaringBitSet(); + int[] history = new int[10]; + + // Set all the bits + for (int x = 0; x < 256; x++) + b.set(x); + + // Clear some random bits and remember them + int nextBitToClear = 0; + for (int x = 0; x < 10; x++) { + nextBitToClear += generator.nextInt(24) + 1; + history[x] = nextBitToClear; + b.clear(nextBitToClear); + } + + // Verify their retrieval using nextClearBit() + int historyIndex = 0; + for (int x = b.nextClearBit(0); x < 256; x = b.nextClearBit(x + 1)) { + if (x != history[historyIndex++]) + failCount++; + } + + checkSanity(b); + } + + // regression test for 4350178 + RoaringBitSet bs = new RoaringBitSet(); + if (bs.nextClearBit(0) != 0) + failCount++; + for (int i = 0; i < 64; i++) { + bs.set(i); + if (bs.nextClearBit(0) != i + 1) + failCount++; + } + + checkSanity(bs); + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testIntersects() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + // Set some random bits in first set + int nextBitToSet = 0; + for (int x = 0; x < 30; x++) { + nextBitToSet = generator.nextInt(255); + b1.set(nextBitToSet); + } + + // Set more random bits in second set + for (int x = 0; x < 30; x++) { + nextBitToSet = generator.nextInt(255); + b2.set(nextBitToSet); + } + + // Make sure they intersect + nextBitToSet = generator.nextInt(255); + b1.set(nextBitToSet); + b2.set(nextBitToSet); + + if (!b1.intersects(b2)) + failCount++; + + // Remove the common set bits + b1.andNot(b2); + + // Make sure they don't intersect + if (b1.intersects(b2)) + failCount++; + + checkSanity(b1, b2); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testCardinality() { + int failCount = 0; + + for (int i = 0; i < 100; i++) { + RoaringBitSet b1 = new RoaringBitSet(); + + // Set a random number of increasing bits + int nextBitToSet = 0; + int iterations = generator.nextInt(20) + 1; + for (int x = 0; x < iterations; x++) { + nextBitToSet += generator.nextInt(20) + 1; + b1.set(nextBitToSet); + } + + if (b1.cardinality() != iterations) { + failCount++; + } + + checkSanity(b1); + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testEmpty() { + int failCount = 0; + + RoaringBitSet b1 = new RoaringBitSet(); + if (!b1.isEmpty()) + failCount++; + + int nextBitToSet = 0; + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + for (int x = 0; x < numberOfSetBits; x++) { + nextBitToSet = generator.nextInt(highestPossibleSetBit); + b1.set(nextBitToSet); + if (b1.isEmpty()) + failCount++; + b1.clear(nextBitToSet); + if (!b1.isEmpty()) + failCount++; + } + + Assertions.assertEquals(failCount, 0); + } + + @Test + public void testEmpty2() { + { + RoaringBitSet t = new RoaringBitSet(); + t.set(100); + t.clear(3, 600); + checkEmpty(t); + } + checkEmpty(new RoaringBitSet()); + + RoaringBitSet s = new RoaringBitSet(); + checkEmpty(s); + s.clear(92); + checkEmpty(s); + s.clear(127, 127); + checkEmpty(s); + s.set(127, 127); + checkEmpty(s); + s.set(128, 128); + checkEmpty(s); + RoaringBitSet empty = new RoaringBitSet(); + { + RoaringBitSet t = new RoaringBitSet(); + t.and(empty); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.or(empty); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.xor(empty); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.andNot(empty); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.and(t); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.or(t); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.xor(t); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.andNot(t); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.and(makeSet(1)); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.and(makeSet(127)); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.and(makeSet(128)); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + t.flip(7); + t.flip(7); + checkEmpty(t); + } + { + RoaringBitSet t = new RoaringBitSet(); + checkEmpty((RoaringBitSet) t.get(200, 300)); + } + { + RoaringBitSet t = makeSet(2, 5); + Assertions.assertEquals(makeSet(0, 3), t.get(2, 6)); + } + } + + @Test + public void testLogicalIdentities() { + int failCount = 0; + + // Verify that (!b1)|(!b2) == !(b1&b2) + for (int i = 0; i < 50; i++) { + // Construct two fairly random bitsets + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) { + b1.set(generator.nextInt(highestPossibleSetBit)); + b2.set(generator.nextInt(highestPossibleSetBit)); + } + + RoaringBitSet b3 = (RoaringBitSet) b1.clone(); + RoaringBitSet b4 = (RoaringBitSet) b2.clone(); + + for (int x = 0; x < highestPossibleSetBit; x++) { + b1.flip(x); + b2.flip(x); + } + b1.or(b2); + b3.and(b4); + for (int x = 0; x < highestPossibleSetBit; x++) + b3.flip(x); + if (!b1.equals(b3)) + failCount++; + checkSanity(b1, b2, b3, b4); + } + + // Verify that (b1&(!b2)|(b2&(!b1) == b1^b2 + for (int i = 0; i < 50; i++) { + // Construct two fairly random bitsets + RoaringBitSet b1 = new RoaringBitSet(); + RoaringBitSet b2 = new RoaringBitSet(); + + int numberOfSetBits = generator.nextInt(100) + 1; + int highestPossibleSetBit = generator.nextInt(1000) + 1; + + for (int x = 0; x < numberOfSetBits; x++) { + b1.set(generator.nextInt(highestPossibleSetBit)); + b2.set(generator.nextInt(highestPossibleSetBit)); + } + + RoaringBitSet b3 = (RoaringBitSet) b1.clone(); + RoaringBitSet b4 = (RoaringBitSet) b2.clone(); + RoaringBitSet b5 = (RoaringBitSet) b1.clone(); + RoaringBitSet b6 = (RoaringBitSet) b2.clone(); + + for (int x = 0; x < highestPossibleSetBit; x++) + b2.flip(x); + b1.and(b2); + for (int x = 0; x < highestPossibleSetBit; x++) + b3.flip(x); + b3.and(b4); + b1.or(b3); + b5.xor(b6); + if (!b1.equals(b5)) + failCount++; + checkSanity(b1, b2, b3, b4, b5, b6); + } + Assertions.assertEquals(failCount, 0); + } + + private static void checkSanity(RoaringBitSet... sets) { + for (RoaringBitSet s : sets) { + int len = s.length(); + int cardinality1 = s.cardinality(); + int cardinality2 = 0; + for (int i = s.nextSetBit(0); i >= 0; i = s.nextSetBit(i + 1)) { + Assertions.assertTrue(s.get(i)); + cardinality2++; + } + Assertions.assertEquals(s.nextSetBit(len), -1); + Assertions.assertEquals(len, s.nextClearBit(len)); + Assertions.assertEquals((len == 0), s.isEmpty()); + Assertions.assertEquals(cardinality2, cardinality1); + Assertions.assertTrue(len <= s.size()); + Assertions.assertTrue(len >= 0); + Assertions.assertTrue(cardinality1 >= 0); + } + } + + private static void checkEquality(RoaringBitSet s, RoaringBitSet t) { + checkSanity(s, t); + Assertions.assertEquals(t, s); + Assertions.assertEquals(t.toString(), s.toString()); + Assertions.assertEquals(s.length(), t.length()); + Assertions.assertEquals(s.cardinality(), t.cardinality()); + } + + private static RoaringBitSet makeSet(int... elts) { + RoaringBitSet s = new RoaringBitSet(); + for (int elt : elts) + s.set(elt); + return s; + } + + private static void checkEmpty(RoaringBitSet s) { + Assertions.assertTrue(s.isEmpty()); + Assertions.assertEquals(s.length(), 0); + Assertions.assertEquals(s.cardinality(), 0); + Assertions.assertEquals(s, new RoaringBitSet()); + Assertions.assertEquals(s.nextSetBit(0), -1); + Assertions.assertEquals(s.nextSetBit(127), -1); + Assertions.assertEquals(s.nextSetBit(128), -1); + Assertions.assertEquals(s.nextClearBit(0), 0); + Assertions.assertEquals(s.nextClearBit(127), 127); + Assertions.assertEquals(s.nextClearBit(128), 128); + Assertions.assertEquals(s.toString(), "{}"); + Assertions.assertFalse(s.get(0)); + } +} From 45d9c57cf148fab56bd2a0729db95df8348b9c7a Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 18 Jun 2024 09:08:19 -0400 Subject: [PATCH 062/167] Move instance field to static, everywhere (#726) * Move to static for BitmapContainer.MAXRUNS * ported static correction to mappeable container --------- Co-authored-by: Danny Thomas --- .../main/java/org/roaringbitmap/BitmapContainer.java | 11 +++++++---- .../buffer/MappeableBitmapContainer.java | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index 85e9621ff..e1653702f 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -24,8 +24,11 @@ public final class BitmapContainer extends Container implements Cloneable { public static final int MAX_CAPACITY = 1 << 16; + private static final int MAX_CAPACITY_BYTE = MAX_CAPACITY / Byte.SIZE; - private static final long serialVersionUID = 2L; + private static final int MAX_CAPACITY_LONG = MAX_CAPACITY / Long.SIZE; + + private static final long serialVersionUID = 3L; // bail out early when the number of runs is excessive, without // an exact count (just a decent lower bound) @@ -69,7 +72,7 @@ protected static int serializedSizeInBytes(int unusedCardinality) { // nruns value for which RunContainer.serializedSizeInBytes == // BitmapContainer.getArraySizeInBytes() - private final int MAXRUNS = (getArraySizeInBytes() - 2) / 4; + private static final int MAXRUNS = (MAX_CAPACITY_BYTE - 2) / 4; /** @@ -77,7 +80,7 @@ protected static int serializedSizeInBytes(int unusedCardinality) { */ public BitmapContainer() { this.cardinality = 0; - this.bitmap = new long[MAX_CAPACITY / 64]; + this.bitmap = new long[MAX_CAPACITY_LONG]; } @@ -463,7 +466,7 @@ public Container flip(char i) { @Override public int getArraySizeInBytes() { - return MAX_CAPACITY / 8; + return MAX_CAPACITY_BYTE; } @Override diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index 18a690595..e546b2277 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -24,10 +24,13 @@ * LongBuffer to store data. */ public final class MappeableBitmapContainer extends MappeableContainer implements Cloneable { - protected static final int MAX_CAPACITY = 1 << 16; + public static final int MAX_CAPACITY = 1 << 16; + private static final int MAX_CAPACITY_BYTE = MAX_CAPACITY / Byte.SIZE; + + private static final int MAX_CAPACITY_LONG = MAX_CAPACITY / Long.SIZE; - private static final long serialVersionUID = 2L; + private static final long serialVersionUID = 3L; // bail out early when the number of runs is excessive, without // an exact count (just a decent lower bound) @@ -52,7 +55,7 @@ protected static int serializedSizeInBytes(int unusedCardinality) { // nruns value for which RunContainer.serializedSizeInBytes == // BitmapContainer.getArraySizeInBytes() - private final int MAXRUNS = (getArraySizeInBytes() - 2) / 4; + private static final int MAXRUNS = (MAX_CAPACITY_BYTE - 2) / 4; /** * Create a bitmap container with all bits set to false @@ -504,7 +507,7 @@ public MappeableContainer flip(char i) { @Override protected int getArraySizeInBytes() { - return MAX_CAPACITY / 8; + return MAX_CAPACITY_BYTE; } From 4e59f0843c053a15bc7096a0378af8e52966c5bf Mon Sep 17 00:00:00 2001 From: sullis Date: Tue, 18 Jun 2024 06:09:07 -0700 Subject: [PATCH 063/167] bump GitHub Actions (#711) --- .github/workflows/checkascii.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/java-all-versions.yml | 2 +- .github/workflows/macos.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/checkascii.yml b/.github/workflows/checkascii.yml index 720bedd4b..29317dcac 100644 --- a/.github/workflows/checkascii.yml +++ b/.github/workflows/checkascii.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Check ASCII run: | find . -type f -name '*.java' | xargs file | grep -qv ASCII || exit 0 && exit 1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a6923df69..14d4bc438 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 497d1f389..375241d72 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -6,5 +6,5 @@ jobs: name: "validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: gradle/wrapper-validation-action@v1 diff --git a/.github/workflows/java-all-versions.yml b/.github/workflows/java-all-versions.yml index 3ab0a102e..9f089785f 100644 --- a/.github/workflows/java-all-versions.yml +++ b/.github/workflows/java-all-versions.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDKs 8, 11, 17, 21 uses: actions/setup-java@v4 with: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ff4acb6b0..dcfa5e89a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -7,9 +7,9 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 11 From 2622d2324290ea07cbdae579be3adb8073c41ca9 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 18 Jun 2024 09:16:12 -0400 Subject: [PATCH 064/167] chore: bump minor version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9adf9c858..e2f8ec8f9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.7-SNAPSHOT +version = 1.1.0-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 35bb10607a1e2c8c3ff65e401eea1f85e7b1c6ac Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 18 Jun 2024 09:39:18 -0400 Subject: [PATCH 065/167] [Gradle Release Plugin] - pre tag commit: '1.1.0'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e2f8ec8f9..92e4d9816 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.1.0-SNAPSHOT +version = 1.1.0 org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 48f5fa9a4d7de26c27e0ffe0f9a2248a2c957182 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 18 Jun 2024 09:39:21 -0400 Subject: [PATCH 066/167] [Gradle Release Plugin] - new version commit: '1.1.1-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 92e4d9816..086359b04 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.1.0 +version = 1.1.1-SNAPSHOT org.gradle.parallel=false org.gradle.daemon=true org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC From 75a97ad1e509e1e8765def1be2216aed99cc1009 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Thu, 20 Jun 2024 18:41:54 +0300 Subject: [PATCH 067/167] improve: Optimize RoaringBitSet.get(int fromIndex, int toIndex) (#727) * improve: Optimize RoaringBitSet.get(int fromIndex, int toIndex) * Add range check * Simplify implementation based on review feedback --- .../src/main/java/org/roaringbitmap/RoaringBitSet.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java index ef4a9b82a..fadce2b53 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java @@ -71,9 +71,11 @@ public boolean get(int bitIndex) { @Override public BitSet get(int fromIndex, int toIndex) { - BitSet bitSet = BitSetUtil.bitsetOf(roaringBitmap); - bitSet = bitSet.get(fromIndex, toIndex); - return new RoaringBitSet(fromBitSet(bitSet)); + RoaringBitmap newBitmap = RoaringBitmap.bitmapOfRange(fromIndex, toIndex); + newBitmap.and(roaringBitmap); + // shift the bits to start from index 0 + newBitmap = RoaringBitmap.addOffset(newBitmap, -fromIndex); + return new RoaringBitSet(newBitmap); } @Override From 3a841615cfffd3c0816337c293e43236e2ddfd06 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 20 Jun 2024 15:09:11 -0400 Subject: [PATCH 068/167] fix: add bitmapOfRange (non-static) (#728) * fix: add bitmapOfRange (non-static) * lint --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- LICENSE-2.0.txt | 2 +- README.md | 16 +-- .../org/roaringbitmap/BitmapContainer.java | 2 +- .../BitmapDataProviderSupplier.java | 2 +- .../java/org/roaringbitmap/CharIterator.java | 2 +- .../org/roaringbitmap/ContainerPointer.java | 16 +-- .../org/roaringbitmap/FastAggregation.java | 2 +- .../roaringbitmap/FastRankRoaringBitmap.java | 8 +- .../ImmutableBitmapDataProvider.java | 54 +++---- .../java/org/roaringbitmap/IntConsumer.java | 8 +- .../java/org/roaringbitmap/IntIterator.java | 2 +- .../roaringbitmap/IntIteratorFlyweight.java | 8 +- .../roaringbitmap/InvalidRoaringFormat.java | 2 +- .../roaringbitmap/PeekableCharIterator.java | 12 +- .../roaringbitmap/PeekableIntIterator.java | 32 ++--- .../ReverseIntIteratorFlyweight.java | 8 +- .../java/org/roaringbitmap/RoaringArray.java | 62 ++++---- .../java/org/roaringbitmap/RoaringBitSet.java | 3 +- .../java/org/roaringbitmap/RoaringBitmap.java | 132 +++++++++++++----- .../roaringbitmap/RoaringBitmapSupplier.java | 2 +- .../java/org/roaringbitmap/RunContainer.java | 4 +- .../src/main/java/org/roaringbitmap/Util.java | 4 +- .../buffer/BufferFastAggregation.java | 66 ++++----- .../buffer/BufferIntIteratorFlyweight.java | 6 +- .../BufferReverseIntIteratorFlyweight.java | 8 +- .../buffer/ImmutableRoaringArray.java | 2 +- .../buffer/ImmutableRoaringBitmap.java | 72 +++++++++- .../buffer/MappeableBitmapContainer.java | 22 +-- .../buffer/MappeableContainer.java | 94 ++++++------- .../buffer/MappeableContainerPointer.java | 20 +-- .../buffer/MutableRoaringArray.java | 4 +- .../buffer/MutableRoaringBitmap.java | 32 ++--- .../buffer/MutableRoaringBitmapSupplier.java | 2 +- .../buffer/PointableRoaringArray.java | 20 +-- .../roaringbitmap/buffer/package-info.java | 10 +- .../ImmutableLongBitmapDataProvider.java | 22 +-- .../roaringbitmap/longlong/LongConsumer.java | 8 +- .../roaringbitmap/longlong/LongIterator.java | 2 +- .../longlong/PeekableLongIterator.java | 40 +++--- .../longlong/Roaring64Bitmap.java | 10 +- .../longlong/Roaring64NavigableMap.java | 26 ++-- .../longlong/RoaringIntPacking.java | 10 +- .../roaringbitmap/longlong/package-info.java | 6 +- .../java/org/roaringbitmap/package-info.java | 6 +- .../org/roaringbitmap/RangeBitmapTest.java | 2 +- .../roaringbitmap/TestBitmapContainer.java | 22 +-- .../java/org/roaringbitmap/TestContainer.java | 2 +- .../java/org/roaringbitmap/TestForEach.java | 2 +- .../TestIntIteratorFlyweight.java | 10 +- .../java/org/roaringbitmap/TestIterators.java | 6 +- .../java/org/roaringbitmap/TestRange.java | 18 +-- .../org/roaringbitmap/TestRoaringBitmap.java | 12 ++ .../TestRoaringBitmap_FastRank.java | 6 +- .../org/roaringbitmap/TestSerialization.java | 4 +- .../org/roaringbitmap/TestSerializedSize.java | 6 +- .../roaringbitmap/TestVeryLargeBitmap.java | 2 +- .../buffer/TestFastAggregation.java | 4 +- .../org/roaringbitmap/buffer/TestForEach.java | 8 +- .../buffer/TestImmutableRoaringBitmap.java | 16 +-- .../roaringbitmap/buffer/TestIterators.java | 12 +- .../buffer/TestMappeableArrayContainer.java | 12 +- .../buffer/TestMappeableBitmapContainer.java | 40 +++--- .../buffer/TestMemoryMapping.java | 6 +- .../org/roaringbitmap/buffer/TestRange.java | 2 +- .../buffer/TestRoaringBitmap.java | 65 +++++---- .../buffer/TestRunContainer.java | 4 +- .../buffer/TestSerializedSize.java | 2 +- .../org/roaringbitmap/buffer/TestUtil.java | 2 +- .../buffer/TestVeryLargeBitmap.java | 2 +- .../longlong/TestRoaring64Bitmap.java | 30 ++-- .../longlong/TestRoaring64NavigableMap.java | 4 +- .../roaringbitmap/bsi/BitmapSliceIndex.java | 4 +- .../bsi/buffer/BitSliceIndexBase.java | 4 +- .../bsi/buffer/ImmutableBitSliceIndex.java | 2 +- .../bsi/buffer/MutableBitSliceIndex.java | 12 +- .../java/ImmutableRoaringBitmapExample.java | 2 +- .../src/main/java/MemoryMappingExample.java | 8 +- .../main/java/SerializeToStringExample.java | 16 +-- .../java/org/roaringbitmap/RandomData.java | 2 +- .../bithacking/SelectBenchmark.java | 6 +- .../roaringbitmap/range/ContainsRange.java | 14 +- .../RealDataSerializationBenchmark.java | 8 +- .../BitmapToRuncontainerConversions.java | 42 +++--- .../java/org/roaringbitmap/RealDataset.java | 2 +- .../ZipRealDataRangeRetriever.java | 2 +- 86 files changed, 722 insertions(+), 576 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd0a3c0a0..9d5d321bb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -42,7 +42,7 @@ Make sure to compare your version against the latest available version at https: **Java version:** -Please tell us which Java version you are using. +Please tell us which Java version you are using. diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt index efa0e258b..3bdd00362 100644 --- a/LICENSE-2.0.txt +++ b/LICENSE-2.0.txt @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2013-2016 the RoaringBitmap authors + Copyright 2013-2016 the RoaringBitmap authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 69ccf9d4c..e7d7b233e 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ When the bitset approach is applicable, it can be orders of magnitude faster than other possible implementation of a set (e.g., as a hash set) while using several times less memory. -However, a bitset, even a compressed one is not always applicable. For example, if +However, a bitset, even a compressed one is not always applicable. For example, if you have 1000 random-looking integers, then a simple array might be the best representation. We refer to this case as the "sparse" scenario. @@ -157,7 +157,7 @@ Software: Practice and Experience 46 (5), 2016. [arXiv:1402.6407](http://arxiv.o Code sample ------------- -```java +```java import org.roaringbitmap.RoaringBitmap; public class Basic { @@ -317,14 +317,14 @@ the most significant 32~bits of elements whereas the values of the tree are 32-bit Roaring bitmaps. The 32-bit Roaring bitmaps represent the least significant bits of a set of elements. -The newer `Roaring64Bitmap` approach relies on the ART data structure to hold the key/value pair. The key +The newer `Roaring64Bitmap` approach relies on the ART data structure to hold the key/value pair. The key is made of the most significant 48~bits of elements whereas the values are 16-bit Roaring containers. It is inspired by [The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases](https://db.in.tum.de/~leis/papers/ART.pdf) by Leis et al. (ICDE '13). ```java import org.roaringbitmap.longlong.*; - + // first Roaring64NavigableMap LongBitmapDataProvider r = Roaring64NavigableMap.bitmapOf(1,2,100,1000); r.addLong(1234); @@ -360,12 +360,12 @@ Range Bitmaps `RangeBitmap` is a succinct data structure supporting range queries. Each value added to the bitmap is associated with an incremental identifier, and queries produce a `RoaringBitmap` of the identifiers associated with values -that satisfy the query. Every value added to the bitmap is stored separately, -so that if a value is added twice, it will be stored twice, and if that value +that satisfy the query. Every value added to the bitmap is stored separately, +so that if a value is added twice, it will be stored twice, and if that value is less than some threshold, there will be at least two integers in the resultant `RoaringBitmap`. -It is more efficient - in terms of both time and space - to +It is more efficient - in terms of both time and space - to provide a maximum value. If you don't know the maximum value, provide a `Long.MAX_VALUE`. Unsigned order is used like elsewhere in the library. @@ -430,7 +430,7 @@ If your project depends on roaring, you can specify the dependency in the Mave where you should replace the version number by the version you require. -[For up-to-date releases, we recommend configuring maven and gradle to depend on the Jitpack repository](https://jitpack.io/#RoaringBitmap/RoaringBitmap). +[For up-to-date releases, we recommend configuring maven and gradle to depend on the Jitpack repository](https://jitpack.io/#RoaringBitmap/RoaringBitmap). Usage ------ diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java index e1653702f..f7d634fb5 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java @@ -1915,7 +1915,7 @@ public char next() { public int nextAsInt() { return next(); } - + @Override public void advanceIfNeeded(char maxval) { if (maxval < (position + 1) * 64) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java index f38fbfcf0..e8d64716f 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java @@ -7,7 +7,7 @@ /** * Enable customizing the {@link BitmapDataProvider} used by {@link Roaring64NavigableMap} - * + * * @author Benoit Lacelle * */ diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/CharIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/CharIterator.java index 1ea32a841..0dec02894 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/CharIterator.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/CharIterator.java @@ -10,7 +10,7 @@ public interface CharIterator extends Cloneable { /** * Creates a copy of the iterator. - * + * * @return a clone of the current iterator */ CharIterator clone(); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerPointer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerPointer.java index ebbdd44d5..7dd1198d0 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerPointer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerPointer.java @@ -5,7 +5,7 @@ package org.roaringbitmap; /** - * + * * This interface allows you to iterate over the containers in a roaring bitmap. * */ @@ -18,14 +18,14 @@ public interface ContainerPointer extends Comparable, Cloneabl /** * Create a copy - * + * * @return return a clone of this pointer */ - ContainerPointer clone(); + ContainerPointer clone(); /** * Return the cardinality of the current container - * + * * @return the cardinality */ int getCardinality(); @@ -33,21 +33,21 @@ public interface ContainerPointer extends Comparable, Cloneabl /** * This method can be used to check whether there is current a valid container as it returns null * when there is not. - * + * * @return null or the current container */ Container getContainer(); /** * Check whether the current container is a bitmap container. - * + * * @return whether it is a bitmap container */ boolean isBitmapContainer(); /** * Check whether the current container is a run container. - * + * * @return whether it is a run container */ boolean isRunContainer(); @@ -55,7 +55,7 @@ public interface ContainerPointer extends Comparable, Cloneabl /** * The key is a 16-bit integer that indicates the position of the container in the roaring bitmap. * To be interpreted as an unsigned integer. - * + * * @return the key */ char key(); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java b/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java index ef8695add..ab4681b8c 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java @@ -522,7 +522,7 @@ private static int horizontalOrCardinality(RoaringBitmap... bitmaps) { public static RoaringBitmap workAndMemoryShyAnd(long[] buffer, RoaringBitmap... bitmaps) { if(buffer.length < 1024) { throw new IllegalArgumentException("buffer should have at least 1024 elements."); - } + } long[] words = buffer; RoaringBitmap first = bitmaps[0]; for (int i = 0; i < first.highLowContainer.size; ++i) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java index b7bc154d7..2da9fd63d 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java @@ -5,16 +5,16 @@ /** * This extends {@link RoaringBitmap} to provide better performance for .rank and .select * operations, at the cost of maintain a cache of cardinalities. - * + * * On {@link RoaringBitmap#select(int)} and {@link RoaringBitmap#rank(int)} operations, * {@link RoaringBitmap} needs to iterate along all underlying buckets to cumulate their * cardinalities. This may lead to sub-optimal performance for application doing a large amount of * .rank/.select over read-only {@link RoaringBitmap}, especially if the {@link RoaringBitmap} holds * a large number of underlying buckets. - * + * * This implementation will discard the cache of cardinality on any write operations, and it will * memoize the computed cardinalities on any .rank or .select operation - * + * * @author Benoit Lacelle * */ @@ -264,7 +264,7 @@ public int select(int j) { return value; } - + @Override public long getLongSizeInBytes() { long size = 8; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java index a4b1488a4..c14591bfb 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java @@ -35,7 +35,7 @@ public interface ImmutableBitmapDataProvider { * @return the cardinality */ int getCardinality(); - + /** * Returns the number of distinct integers added to the bitmap (e.g., number of bits set). * This returns a full 64-bit result. @@ -46,8 +46,8 @@ public interface ImmutableBitmapDataProvider { /** * Visit all values in the bitmap and pass them to the consumer. - * - * * Usage: + * + * * Usage: *

    * {@code
    *  bitmap.forEach(new IntConsumer() {
@@ -55,7 +55,7 @@ public interface ImmutableBitmapDataProvider {
    *    {@literal @}Override
    *    public void accept(int value) {
    *      // do something here
-   *      
+   *
    *    }});
    *   }
    * }
@@ -79,9 +79,9 @@ public interface ImmutableBitmapDataProvider {
    * @return an Ordered, Distinct, Sorted and Sized IntStream in ascending order
    */
   public default IntStream stream() {
-    int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED 
+    int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED
         | Spliterator.SIZED;
-    Spliterator.OfInt x = Spliterators.spliterator(new RoaringOfInt(getIntIterator()), 
+    Spliterator.OfInt x = Spliterators.spliterator(new RoaringOfInt(getIntIterator()),
         getCardinality(), characteristics);
     return StreamSupport.intStream(x, false);
   }
@@ -91,11 +91,11 @@ public default IntStream stream() {
    */
   public default IntStream reverseStream() {
     int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SIZED;
-    Spliterator.OfInt x = Spliterators.spliterator(new RoaringOfInt(getReverseIntIterator()), 
+    Spliterator.OfInt x = Spliterators.spliterator(new RoaringOfInt(getReverseIntIterator()),
         getCardinality(), characteristics);
     return StreamSupport.intStream(x, false);
   }
-  
+
   /**
    * This iterator may be faster than others
    * @return iterator which works on batches of data.
@@ -104,13 +104,13 @@ public default IntStream reverseStream() {
 
   /**
    * Estimate of the memory usage of this data structure.
-   * 
+   *
    * Internally, this is computed as a 64-bit counter.
    *
    * @return estimated memory usage.
    */
   int getSizeInBytes();
-  
+
   /**
    * Estimate of the memory usage of this data structure. Provides
    * full 64-bit number.
@@ -138,26 +138,26 @@ public default IntStream reverseStream() {
    * Rank returns the number of integers that are smaller or equal to x (rank(infinity) would be
    * getCardinality()).  If you provide the smallest value as a parameter, this function will
    * return 1. If provide a value smaller than the smallest value, it will return 0.
-   * 
+   *
    * The value is internally computed as a 64-bit number.
-   * 
+   *
    * @param x upper limit
    *
    * @return the rank
-   * @see Ranking in statistics 
+   * @see Ranking in statistics
    */
   int rank(int x);
-  
+
   /**
    * Rank returns the number of integers that are smaller or equal to x (rankLong(infinity) would be
    * getLongCardinality()).  If you provide the smallest value as a parameter, this function will
    * return 1. If provide a value smaller than the smallest value, it will return 0.
    * Same as "rank" but produces a full 64-bit value.
-   * 
+   *
    * @param x upper limit
    *
    * @return the rank
-   * @see Ranking in statistics 
+   * @see Ranking in statistics
    */
   long rankLong(int x);
 
@@ -165,8 +165,8 @@ public default IntStream reverseStream() {
   * Computes the number of values in the interval [start,end) where
   * start is included and end excluded.
   * rangeCardinality(0,0x100000000) provides the total cardinality (getLongCardinality).
-  * The answer is a 64-bit value between 1 and 0x100000000. 
-  * 
+  * The answer is a 64-bit value between 1 and 0x100000000.
+  *
   * @param start lower limit (included)
   * @param end upper limit (excluded)
   * @return the number of elements in [start,end), between 0 and 0x100000000.
@@ -174,8 +174,8 @@ public default IntStream reverseStream() {
   long rangeCardinality(long start, long end);
 
   /**
-   * Return the jth value stored in this bitmap. The provided value 
-   * needs to be smaller than the cardinality otherwise an 
+   * Return the jth value stored in this bitmap. The provided value
+   * needs to be smaller than the cardinality otherwise an
    * IllegalArgumentException
    * exception is thrown. The smallest value is at index 0.
    * Note that this function differs in convention from the rank function which
@@ -184,7 +184,7 @@ public default IntStream reverseStream() {
    * @param j index of the value
    *
    * @return the value
-   * @see Selection algorithm 
+   * @see Selection algorithm
    */
   int select(int j);
 
@@ -215,7 +215,7 @@ public default IntStream reverseStream() {
    *       or {@code -1} if there is no such value
    */
   long nextValue(int fromValue);
-  
+
   /**
    * Returns the first value less than or equal to the provided value
    * (interpreted as an unsigned integer). If no such
@@ -263,11 +263,11 @@ public default IntStream reverseStream() {
   /**
    * Serialize this bitmap to a ByteBuffer.
    * This is the preferred method
-   * to serialize to a byte array (byte[]) or to a String 
+   * to serialize to a byte array (byte[]) or to a String
    * (via Base64.getEncoder().encodeToString)..
    *
-   *  
-   * Irrespective of the endianess of the provided buffer, data is 
+   *
+   * Irrespective of the endianess of the provided buffer, data is
    * written using LITTlE_ENDIAN as per the RoaringBitmap specification.
    *
    * The current bitmap is not modified.
@@ -301,8 +301,8 @@ public default IntStream reverseStream() {
   /**
    * An internal class to help provide streams.
    * Sad but true the interface of IntIterator and PrimitiveIterator.OfInt
-   * Does not match. Otherwise it would be easier to just make IntIterator 
-   * implement PrimitiveIterator.OfInt. 
+   * Does not match. Otherwise it would be easier to just make IntIterator
+   * implement PrimitiveIterator.OfInt.
    */
   static final class RoaringOfInt implements PrimitiveIterator.OfInt {
     private final IntIterator iterator;
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumer.java
index a1294165b..741fe227a 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumer.java
@@ -3,16 +3,16 @@
 /**
  * An IntConsumer receives the int values contained in a data structure.
  * Each value is visited once.
- * 
+ *
  * Usage:
- * 
+ *
  * 
  * {@code
  *  bitmap.forEach(new IntConsumer() {
  *
  *    public void accept(int value) {
  *      // do something here
- *      
+ *
  *    }});
  *   }
  * }
@@ -21,7 +21,7 @@
 public interface IntConsumer {
   /**
    * Receives the integer
-   * 
+   *
    * @param value the integer value
    */
   void accept(int value);
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/IntIterator.java
index d2f51c09e..75f6d264f 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/IntIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/IntIterator.java
@@ -13,7 +13,7 @@
 public interface IntIterator extends Cloneable {
   /**
    * Creates a copy of the iterator.
-   * 
+   *
    * @return a clone of the current iterator
    */
   IntIterator clone();
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java b/RoaringBitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java
index 660d2ab77..0819177bd 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java
@@ -7,9 +7,9 @@
 /**
  * Fast iterator minimizing the stress on the garbage collector. You can create one reusable
  * instance of this class and then {@link #wrap(RoaringBitmap)}
- * 
+ *
  * For better performance, consider the {@link RoaringBitmap#forEach} method.
- * 
+ *
  * @author Borislav Ivanov
  **/
 public class IntIteratorFlyweight implements PeekableIntIterator {
@@ -38,7 +38,7 @@ public IntIteratorFlyweight() {
 
   /**
    * Creates an instance that is ready for iteration.
-   * 
+   *
    * @param r bitmap to be iterated over
    */
   public IntIteratorFlyweight(RoaringBitmap r) {
@@ -94,7 +94,7 @@ private void nextContainer() {
 
   /**
    * Prepares a bitmap for iteration
-   * 
+   *
    * @param r bitmap to be iterated over
    */
   public void wrap(RoaringBitmap r) {
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java b/RoaringBitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java
index 5b7f670e1..9a09e032c 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java
@@ -5,7 +5,7 @@
 /**
  *
  * Exception thrown when attempting to deserialize a roaring bitmap from
- * an input stream missing a cookie or having other similar anomalies. 
+ * an input stream missing a cookie or having other similar anomalies.
  * Some code may translate it to an IOException
  * for convenience when the cause of the problem can be cleanly interpreted as
  * an IO issue. However, when memory-mapping the file from a ByteBuffer,
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java
index dc8083598..ec2b5cbae 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java
@@ -11,29 +11,29 @@
  */
 public interface PeekableCharIterator extends CharIterator {
   /**
-   * If needed, 
+   * If needed,
    * when iterating forward through the chars it will
    * advance as long as the next value is smaller than val (as an unsigned
    * short)
    * when iterating in reverse through the chars it will
    * advance as long as the next value is larger than val (as an unsigned
    * short)
-   * 
+   *
    * @param thresholdVal threshold
    */
   public void advanceIfNeeded(char thresholdVal);
 
   /**
-   * 
+   *
    * Look at the next value without advancing
-   * 
+   *
    * @return next value
    */
   public char peekNext();
-  
+
   /**
    * Creates a copy of the iterator.
-   * 
+   *
    * @return a clone of the current iterator
    */
   @Override
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java
index b1ea93050..e9143f5bf 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java
@@ -2,7 +2,7 @@
 
 
 /**
- * Simple extension to the IntIterator interface. 
+ * Simple extension to the IntIterator interface.
  * It allows you to "skip" values using the advanceIfNeeded
  * method, and to look at the value without advancing (peekNext).
  *
@@ -15,9 +15,9 @@ public interface PeekableIntIterator extends IntIterator {
    *
    *  The advanceIfNeeded method is used for performance reasons, to skip
    *  over unnecessary repeated calls to next.
-   *  
+   *
    *  Suppose for example that you wish to compute the intersection between
-   *  an ordered list of integers (e.g., int[] x = {1,4,5}) and a 
+   *  an ordered list of integers (e.g., int[] x = {1,4,5}) and a
    *  PeekableIntIterator.
    *  You might do it as follows...
    *     

@@ -33,24 +33,24 @@ public interface PeekableIntIterator extends IntIterator {
    *       j.advanceIfNeeded(val);
    *     }
    *     
- * - * The benefit of calling advanceIfNeeded is that each such call + * + * The benefit of calling advanceIfNeeded is that each such call * can be much faster than repeated calls to "next". The underlying * implementation can "skip" over some data. - * - * + * + * * @param minval threshold */ public void advanceIfNeeded(int minval); /** - * + * * Look at the next value without advancing - * + * * The peek is useful when working with several iterators at once. * Suppose that you have 100 iterators, and you want to compute * their intersections without materializing the result. - * You might do it as follows... + * You might do it as follows... *

    *    PriorityQueue pq = new PriorityQueue(100,
    *      new Comparator<PeekableIntIterator>() {
@@ -59,9 +59,9 @@ public interface PeekableIntIterator extends IntIterator {
    *                 return a.peek() - b.peek();
    *             }
    *         });
-   * 
+   *
    *    //...  populate pq
-   *    
+   *
    *    while(! pq.isEmpty() ) {
    *      // get iterator with a smallest value
    *      PeekableIntIterator pi = pq.poll();
@@ -70,17 +70,17 @@ public interface PeekableIntIterator extends IntIterator {
    *      if(pi.hasNext()) pq.add(pi)
    *    }
    *    
- * + * * Notice how the peek method allows you to compare iterators in a way * that the next method could not do. - * + * * @return next value */ public int peekNext(); - + /** * Creates a copy of the iterator. - * + * * @return a clone of the current iterator */ @Override diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java index 88212bce6..fcd83dd1c 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java @@ -7,9 +7,9 @@ /** * Fast iterator minimizing the stress on the garbage collector. You can create one reusable * instance of this class and then {@link #wrap(RoaringBitmap)} - * + * * This iterator enumerates the stored values in reverse (starting from the end). - * + * * @author Borislav Ivanov **/ public class ReverseIntIteratorFlyweight implements IntIterator { @@ -40,7 +40,7 @@ public ReverseIntIteratorFlyweight() { /** * Creates an instance that is ready for iteration. - * + * * @param r bitmap to be iterated over */ public ReverseIntIteratorFlyweight(RoaringBitmap r) { @@ -100,7 +100,7 @@ private void nextContainer() { /** * Prepares a bitmap for iteration - * + * * @param r bitmap to be iterated over */ public void wrap(RoaringBitmap r) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java index 3a5d53e4a..5bc2fce8b 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java @@ -368,7 +368,7 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { throw new IllegalArgumentException( "We need a buffer with a length multiple of 8. was length=" + buffer.length); } - + this.clear(); // little endian final int cookie = Integer.reverseBytes(in.readInt()); @@ -416,39 +416,39 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { Container val; if (isBitmap[k]) { final long[] bitmapArray = new long[BitmapContainer.MAX_CAPACITY / 64]; - + if (buffer == null) { // a buffer to load a Container in a single .readFully // We initialize it with the length of a BitmapContainer buffer = new byte[(BitmapContainer.MAX_CAPACITY / 64) * 8]; } - + if (buffer.length < (BitmapContainer.MAX_CAPACITY / 64) * 8) { // We have been provided a rather small buffer - + for (int iBlock = 0 ; iBlock <= 8 * bitmapArray.length / buffer.length ; iBlock++) { int start = buffer.length * iBlock; int end = Math.min(buffer.length * (iBlock +1 ), 8 * bitmapArray.length); - + in.readFully(buffer, 0, end - start); - + // little endian ByteBuffer asByteBuffer = ByteBuffer.wrap(buffer); asByteBuffer.order(LITTLE_ENDIAN); - + LongBuffer asLongBuffer = asByteBuffer.asLongBuffer(); asLongBuffer.rewind(); asLongBuffer.get(bitmapArray, start / 8, (end - start) / 8); } - + } else { // Read the whole bitmapContainer in a single pass in.readFully(buffer, 0, bitmapArray.length * 8); - + // little endian ByteBuffer asByteBuffer = ByteBuffer.wrap(buffer); asByteBuffer.order(LITTLE_ENDIAN); - + LongBuffer asLongBuffer = asByteBuffer.asLongBuffer(); asLongBuffer.rewind(); asLongBuffer.get(bitmapArray); @@ -459,13 +459,13 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { // cf RunContainer.writeArray() int nbrruns = (Character.reverseBytes(in.readChar())); final char[] lengthsAndValues = new char[2 * nbrruns]; - + if (buffer == null && lengthsAndValues.length > (BitmapContainer.MAX_CAPACITY / 64) * 8) { // a buffer to load a Container in a single .readFully // We initialize it with the length of a BitmapContainer buffer = new byte[(BitmapContainer.MAX_CAPACITY / 64) * 8]; } - + if (buffer == null) { // The RunContainer is small: skip the buffer allocation for (int j = 0; j < lengthsAndValues.length; ++j) { @@ -475,19 +475,19 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { for (int iBlock = 0 ; iBlock <= 2 * lengthsAndValues.length / buffer.length ; iBlock++) { int start = buffer.length * iBlock; int end = Math.min(buffer.length * (iBlock +1 ), 2 * lengthsAndValues.length); - + in.readFully(buffer, 0, end - start); // little endian ByteBuffer asByteBuffer = ByteBuffer.wrap(buffer); asByteBuffer.order(LITTLE_ENDIAN); - + CharBuffer asCharBuffer = asByteBuffer.asCharBuffer(); asCharBuffer.rewind(); asCharBuffer.get(lengthsAndValues, start / 2, (end - start) / 2); } } - + val = new RunContainer(lengthsAndValues, nbrruns); } else { final char[] charArray = new char[cardinalities[k]]; @@ -497,7 +497,7 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { // We initialize it with the length of a BitmapContainer buffer = new byte[(BitmapContainer.MAX_CAPACITY / 64) * 8]; } - + if (buffer == null) { // The ArrayContainer is small: skip the buffer allocation for (int j = 0; j < charArray.length; ++j) { @@ -507,38 +507,38 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { for (int iBlock = 0 ; iBlock <= 2 * charArray.length / buffer.length ; iBlock++) { int start = buffer.length * iBlock; int end = Math.min(buffer.length * (iBlock +1 ) , 2 * charArray.length); - + in.readFully(buffer, 0, end - start); // little endian ByteBuffer asByteBuffer = ByteBuffer.wrap(buffer); asByteBuffer.order(LITTLE_ENDIAN); - + CharBuffer asCharBuffer = asByteBuffer.asCharBuffer(); asCharBuffer.rewind(); asCharBuffer.get(charArray, start / 2, (end - start) / 2); } } - + val = new ArrayContainer(charArray); } this.keys[k] = keys[k]; this.values[k] = val; } } - + /** * Deserialize (retrieve) this bitmap. See format specification at * https://github.com/RoaringBitmap/RoaringFormatSpec * * The current bitmap is overwritten. - * + * * It is not necessary that limit() on the input ByteBuffer indicates the end of the serialized * data. - * + * * After loading this RoaringBitmap, you can advance to the rest of the data (if there * is more) by setting bbf.position(bbf.position() + bitmap.serializedSizeInBytes()); - * + * * Note that the input ByteBuffer is effectively copied (with the slice operation) so you should * expect the provided ByteBuffer position/mark/limit/order to remain unchanged. * @@ -546,7 +546,7 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { */ public void deserialize(ByteBuffer bbf) { this.clear(); - + // slice not to mutate the input ByteBuffer ByteBuffer buffer = bbf.slice(); buffer.order(LITTLE_ENDIAN); @@ -559,7 +559,7 @@ public void deserialize(ByteBuffer bbf) { // TODO For now, we consider the limit is already set by the caller // int theLimit = size > 0 ? computeSerializedSizeInBytes() : headerSize(hasRunContainers); // buffer.limit(theLimit); - + // logically we cannot have more than (1<<16) containers. if(this.size > (1<<16)) { throw new InvalidRoaringFormat("Size too large"); @@ -599,10 +599,10 @@ public void deserialize(ByteBuffer bbf) { Container val; if (isBitmap[k]) { final long[] bitmapArray = new long[BitmapContainer.MAX_CAPACITY / 64]; - + buffer.asLongBuffer().get(bitmapArray); buffer.position(buffer.position() + bitmapArray.length * 8); - + val = new BitmapContainer(bitmapArray, cardinalities[k]); } else if (bitmapOfRunContainers != null && ((bitmapOfRunContainers[k / 8] & (1 << (k % 8))) != 0)) { @@ -612,15 +612,15 @@ public void deserialize(ByteBuffer bbf) { buffer.asCharBuffer().get(lengthsAndValues); buffer.position(buffer.position() + lengthsAndValues.length * 2); - + val = new RunContainer(lengthsAndValues, nbrruns); } else { final char[] charArray = new char[cardinalities[k]]; - + buffer.asCharBuffer().get(charArray); buffer.position(buffer.position() + charArray.length * 2); - + val = new ArrayContainer(charArray); } this.keys[k] = keys[k]; @@ -628,7 +628,7 @@ public void deserialize(ByteBuffer bbf) { } } - + @Override public boolean equals(Object o) { if (o instanceof RoaringArray) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java index fadce2b53..23091f0a8 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java @@ -71,8 +71,7 @@ public boolean get(int bitIndex) { @Override public BitSet get(int fromIndex, int toIndex) { - RoaringBitmap newBitmap = RoaringBitmap.bitmapOfRange(fromIndex, toIndex); - newBitmap.and(roaringBitmap); + RoaringBitmap newBitmap = roaringBitmap.selectRange(fromIndex, toIndex); // shift the bits to start from index 0 newBitmap = RoaringBitmap.addOffset(newBitmap, -fromIndex); return new RoaringBitSet(newBitmap); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index 1162212dc..fc3a8ab58 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -190,7 +190,7 @@ private static void rangeSanityCheck(final long rangeStart, final long rangeEnd) * negative. Values that would fall outside * of the valid 32-bit range are discarded * so that the result can have lower cardinality. - * + * * This method can be relatively expensive when * offset is not divisible by 65536. Use sparingly. * @@ -362,9 +362,9 @@ public static RoaringBitmap and(final RoaringBitmap x1, final RoaringBitmap x2) } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); - } else { + } else { pos2 = x2.highLowContainer.advanceUntil(s1, pos2); } } @@ -395,9 +395,9 @@ public static int andCardinality(final RoaringBitmap x1, final RoaringBitmap x2) answer += c1.andCardinality(c2); ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); - } else { + } else { pos2 = x2.highLowContainer.advanceUntil(s1, pos2); } } @@ -429,11 +429,11 @@ public static RoaringBitmap andNot(final RoaringBitmap x1, final RoaringBitmap x } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { final int nextPos1 = x1.highLowContainer.advanceUntil(s2, pos1); answer.highLowContainer.appendCopy(x1.highLowContainer, pos1, nextPos1); pos1 = nextPos1; - } else { + } else { pos2 = x2.highLowContainer.advanceUntil(s1, pos2); } } @@ -457,10 +457,10 @@ public void add(final int... dat) { /** * Set the specified values to true, within given boundaries. This can be expected to be slightly - * faster than calling "add" repeatedly on the values dat[offset], dat[offset+1],..., - * dat[offset+n-1]. - * The provided integers values don't have to be in sorted order, but it may be preferable - * to sort them from a performance point of view. + * faster than calling "add" repeatedly on the values dat[offset], dat[offset+1],..., + * dat[offset+n-1]. + * The provided integers values don't have to be in sorted order, but it may be preferable + * to sort them from a performance point of view. * * @param dat set values * @param offset from which index the values should be set to true @@ -681,9 +681,9 @@ public static boolean intersects(final RoaringBitmap x1, final RoaringBitmap x2) } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); - } else { + } else { pos2 = x2.highLowContainer.advanceUntil(s1, pos2); } } @@ -711,14 +711,14 @@ protected static RoaringBitmap lazyor(final RoaringBitmap x1, final RoaringBitma } s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { answer.highLowContainer.appendCopy(x1.highLowContainer, pos1); pos1++; if (pos1 == length1) { break main; } s1 = x1.highLowContainer.getKeyAtIndex(pos1); - } else { + } else { answer.highLowContainer.appendCopy(x2.highLowContainer, pos2); pos2++; if (pos2 == length2) { @@ -763,7 +763,7 @@ protected static RoaringBitmap lazyorfromlazyinputs(final RoaringBitmap x1, } s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { Container c1 = x1.highLowContainer.getContainerAtIndex(pos1); answer.highLowContainer.append(s1, c1); pos1++; @@ -771,7 +771,7 @@ protected static RoaringBitmap lazyorfromlazyinputs(final RoaringBitmap x1, break main; } s1 = x1.highLowContainer.getKeyAtIndex(pos1); - } else { + } else { Container c2 = x2.highLowContainer.getContainerAtIndex(pos2); answer.highLowContainer.append(s2,c2); pos2++; @@ -847,14 +847,14 @@ public static RoaringBitmap or(final RoaringBitmap x1, final RoaringBitmap x2) { } s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { answer.highLowContainer.appendCopy(x1.highLowContainer, pos1); pos1++; if (pos1 == length1) { break main; } s1 = x1.highLowContainer.getKeyAtIndex(pos1); - } else { + } else { answer.highLowContainer.appendCopy(x2.highLowContainer, pos2); pos2++; if (pos2 == length2) { @@ -1062,14 +1062,14 @@ public static RoaringBitmap xor(final RoaringBitmap x1, final RoaringBitmap x2) } s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { answer.highLowContainer.appendCopy(x1.highLowContainer, pos1); pos1++; if (pos1 == length1) { break main; } s1 = x1.highLowContainer.getKeyAtIndex(pos1); - } else { + } else { answer.highLowContainer.appendCopy(x2.highLowContainer, pos2); pos2++; if (pos2 == length2) { @@ -1257,9 +1257,9 @@ public void and(final RoaringBitmap x2) { } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = highLowContainer.advanceUntil(s2, pos1); - } else { + } else { pos2 = x2.highLowContainer.advanceUntil(s1, pos2); } } @@ -1334,14 +1334,14 @@ public void andNot(final RoaringBitmap x2) { } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { if (pos1 != intersectionSize) { final Container c1 = highLowContainer.getContainerAtIndex(pos1); highLowContainer.replaceKeyAndContainerAtIndex(intersectionSize, s1, c1); } ++intersectionSize; ++pos1; - } else { + } else { pos2 = x2.highLowContainer.advanceUntil(s1, pos2); } } @@ -2128,7 +2128,7 @@ public IntIterator getReverseIntIterator() { return new RoaringReverseIntIterator(); } - + @Override public RoaringBatchIterator getBatchIterator() { return new RoaringBatchIterator(highLowContainer); @@ -2335,13 +2335,13 @@ protected void lazyor(final RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; } s1 = highLowContainer.getKeyAtIndex(pos1); - } else { + } else { highLowContainer.insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; @@ -2384,13 +2384,13 @@ protected void naivelazyor(RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; } s1 = highLowContainer.getKeyAtIndex(pos1); - } else { + } else { highLowContainer.insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; @@ -2459,13 +2459,13 @@ public void or(final RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; } s1 = highLowContainer.getKeyAtIndex(pos1); - } else { + } else { highLowContainer.insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; @@ -3034,6 +3034,68 @@ public void remove() { return bitmapsIterator; } + /** + * Creates a copy of the bitmap, limited to the values in the specified range, + * rangeStart (inclusive) and rangeEnd (exclusive). + * + * @param rangeStart inclusive + * @param rangeEnd exclusive + * @return new bitmap + */ + public RoaringBitmap selectRange(final long rangeStart, final long rangeEnd) { + final int hbStart = (Util.highbits(rangeStart)); + final int lbStart = (Util.lowbits(rangeStart)); + final int hbLast = (Util.highbits(rangeEnd - 1)); + final int lbLast = (Util.lowbits(rangeEnd - 1)); + RoaringBitmap answer = new RoaringBitmap(); + + assert(rangeStart >= 0 && rangeEnd >= 0); + + if (rangeEnd <= rangeStart) { + return answer; + } + + if (hbStart == hbLast) { + final int i = this.highLowContainer.getIndex((char) hbStart); + if (i >= 0) { + final Container c = this.highLowContainer.getContainerAtIndex(i).remove(0, lbStart) + .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); + if (!c.isEmpty()) { + answer.highLowContainer.append((char) hbStart, c); + } + } + return answer; + } + int ifirst = this.highLowContainer.getIndex((char) hbStart); + int ilast = this.highLowContainer.getIndex((char) hbLast); + if (ifirst >= 0) { + final Container c = this.highLowContainer.getContainerAtIndex(ifirst).remove(0, lbStart); + if (!c.isEmpty()) { + answer.highLowContainer.append((char) hbStart, c.clone()); + } + } + + // revised to loop on ints + for (int hb = hbStart + 1; hb <= hbLast - 1; ++hb) { + final int i = this.highLowContainer.getIndex((char)hb); + final int j = answer.highLowContainer.getIndex((char) hb); + assert j < 0; + + if (i >= 0) { + final Container c = this.highLowContainer.getContainerAtIndex(i); + answer.highLowContainer.insertNewKeyValueAt(-j - 1, (char)hb, c.clone()); + } + } + + if (ilast >= 0) { + final Container c = this.highLowContainer.getContainerAtIndex(ilast).remove(lbLast + 1, + Util.maxLowBitAsInteger() + 1); + if (!c.isEmpty()) { + answer.highLowContainer.append((char) hbLast, c); + } + } + return answer; + } /** * @@ -3045,8 +3107,6 @@ public void remove() { * @param rangeEnd exclusive * @return new bitmap */ - - // had formerly failed if rangeEnd==0 private static RoaringBitmap selectRangeWithoutCopy(RoaringBitmap rb, final long rangeStart, final long rangeEnd) { final int hbStart = (Util.highbits(rangeStart)); @@ -3213,13 +3273,13 @@ public void xor(final RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; } s1 = highLowContainer.getKeyAtIndex(pos1); - } else { + } else { highLowContainer.insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java index 59ae54d2f..abe48673a 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java @@ -6,7 +6,7 @@ /** * A {@link BitmapDataProviderSupplier} providing {@link RoaringBitmap} as * {@link BitmapDataProvider} - * + * * @author Benoit Lacelle * */ diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java index 9805c1b42..42c8981eb 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -2974,12 +2974,12 @@ public void advanceIfNeeded(char maxval) { le = maxlength + base - (maxval); } - + @Override public char peekNext() { return (char) (base + maxlength - le); } - + @Override public void remove() { throw new RuntimeException("Not implemented");// TODO diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java index 936b78eb7..1df7a8c22 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java @@ -185,8 +185,8 @@ public static int advanceUntil(char[] array, int pos, int length, char min) { return upper; } - - + + /** * Find the largest integer smaller than pos such that array[pos]<= max. If none can be found, * return length. Based on code by O. Kaser. diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java index fb8154fe5..1e9efac25 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java @@ -13,7 +13,7 @@ /** * Fast algorithms to aggregate many bitmaps. - * + * * @author Daniel Lemire */ public final class BufferFastAggregation { @@ -57,7 +57,7 @@ public static MutableRoaringBitmap and(long[] aggregationBuffer, /** * Compute the AND aggregate. - * + * * In practice, calls {#link workShyAnd} * * @param bitmaps input bitmaps (ImmutableRoaringBitmap or MutableRoaringBitmap) @@ -91,9 +91,9 @@ public static MutableRoaringBitmap and(long[] aggregationBuffer, /** * Compute the AND aggregate. - * + * * In practice, calls {#link naive_and} - * + * * @param bitmaps input bitmaps * @return aggregated bitmap */ @@ -141,7 +141,7 @@ public static int orCardinality(ImmutableRoaringBitmap... bitmaps) { /** * Convenience method converting one type of iterator into another, to avoid unnecessary warnings. - * + * * @param i input bitmaps * @return an iterator over the provided iterator, with a different type */ @@ -177,9 +177,9 @@ private static ImmutableRoaringBitmap[] convertToImmutable(MutableRoaringBitmap[ /** * Minimizes memory usage while computing the or aggregate on a moderate number of bitmaps. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #or(ImmutableRoaringBitmap...) @@ -237,7 +237,7 @@ public static MutableRoaringBitmap horizontal_or(ImmutableRoaringBitmap... bitma /** * Calls naive_or. - * + * * @param bitmaps input bitmaps (ImmutableRoaringBitmap or MutableRoaringBitmap) * @return aggregated bitmap */ @@ -248,9 +248,9 @@ public static MutableRoaringBitmap horizontal_or(@SuppressWarnings("rawtypes") I /** * Minimizes memory usage while computing the or aggregate on a moderate number of bitmaps. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #or(ImmutableRoaringBitmap...) @@ -262,9 +262,9 @@ public static MutableRoaringBitmap horizontal_or(MutableRoaringBitmap... bitmaps /** * Minimizes memory usage while computing the xor aggregate on a moderate number of bitmaps. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #xor(ImmutableRoaringBitmap...) @@ -320,9 +320,9 @@ public static MutableRoaringBitmap horizontal_xor(ImmutableRoaringBitmap... bitm /** * Minimizes memory usage while computing the xor aggregate on a moderate number of bitmaps. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #xor(ImmutableRoaringBitmap...) @@ -338,7 +338,7 @@ public static MutableRoaringBitmap horizontal_xor(MutableRoaringBitmap... bitmap * Performance hint: if you have very large and tiny bitmaps, * it may be beneficial performance-wise to put a tiny bitmap * in first position. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps @@ -374,7 +374,7 @@ public static MutableRoaringBitmap naive_and(ImmutableRoaringBitmap... bitmaps) * Performance hint: if you have very large and tiny bitmaps, * it may be beneficial performance-wise to put a tiny bitmap * in first position. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps (ImmutableRoaringBitmap or MutableRoaringBitmap) @@ -398,7 +398,7 @@ public static MutableRoaringBitmap naive_and(@SuppressWarnings("rawtypes") Itera * Performance hint: if you have very large and tiny bitmaps, * it may be beneficial performance-wise to put a tiny bitmap * in first position. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps @@ -688,7 +688,7 @@ private static int horizontalOrCardinality(ImmutableRoaringBitmap... bitmaps) { * Computes the intersection by first intersecting the keys, avoids * materialising containers, limits memory usage. You must provide a long[] array * of length at least 1024, initialized with zeroes. We do not check whether the array - * is initialized with zeros: it is the caller's responsability. + * is initialized with zeros: it is the caller's responsability. * You should expect this function to be slower than workShyAnd and the reduction * in memory usage might be small. * @@ -696,11 +696,11 @@ private static int horizontalOrCardinality(ImmutableRoaringBitmap... bitmaps) { * @param bitmaps the inputs * @return the intersection of the bitmaps */ - public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer, + public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer, ImmutableRoaringBitmap... bitmaps) { if(buffer.length < 1024) { throw new IllegalArgumentException("buffer should have at least 1024 elements."); - } + } long[] words = buffer; ImmutableRoaringBitmap first = bitmaps[0]; for (int i = 0; i < first.highLowContainer.size(); ++i) { @@ -765,7 +765,7 @@ public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer, /** * Compute overall OR between bitmaps two-by-two. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps @@ -782,7 +782,7 @@ public static MutableRoaringBitmap naive_or(ImmutableRoaringBitmap... bitmaps) { /** * Compute overall OR between bitmaps two-by-two. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps (ImmutableRoaringBitmap or MutableRoaringBitmap) @@ -818,7 +818,7 @@ public static MutableRoaringBitmap naive_or(MutableRoaringBitmap... bitmaps) { /** * Compute overall XOR between bitmaps two-by-two. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps @@ -834,7 +834,7 @@ public static MutableRoaringBitmap naive_xor(ImmutableRoaringBitmap... bitmaps) /** * Compute overall XOR between bitmaps two-by-two. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps (ImmutableRoaringBitmap or MutableRoaringBitmap) @@ -851,7 +851,7 @@ public static MutableRoaringBitmap naive_xor(@SuppressWarnings("rawtypes") Itera /** * Compute overall XOR between bitmaps two-by-two. - * + * * This function runs in linear time with respect to the number of bitmaps. * * @param bitmaps input bitmaps @@ -899,9 +899,9 @@ public static MutableRoaringBitmap or(MutableRoaringBitmap... bitmaps) { /** * Uses a priority queue to compute the or aggregate. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #horizontal_or(ImmutableRoaringBitmap...) @@ -958,9 +958,9 @@ public int compare(Integer a, Integer b) { /** * Uses a priority queue to compute the or aggregate. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #horizontal_or(ImmutableRoaringBitmap...) @@ -1022,9 +1022,9 @@ public int compare(Integer a, Integer b) { /** * Uses a priority queue to compute the xor aggregate. - * + * * This function runs in linearithmic (O(n log n)) time with respect to the number of bitmaps. - * + * * @param bitmaps input bitmaps * @return aggregated bitmap * @see #horizontal_xor(ImmutableRoaringBitmap...) @@ -1053,7 +1053,7 @@ public int compare(ImmutableRoaringBitmap a, ImmutableRoaringBitmap b) { /** * Compute overall XOR between bitmaps. - * + * * * @param bitmaps input bitmaps * @return aggregated bitmap @@ -1076,7 +1076,7 @@ public static MutableRoaringBitmap xor(@SuppressWarnings("rawtypes") Iterator bi /** * Compute overall XOR between bitmaps. - * + * * * @param bitmaps input bitmaps * @return aggregated bitmap diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java index 2868333d7..0f8a4b319 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java @@ -10,7 +10,7 @@ /** * Fast iterator minimizing the stress on the garbage collector. You can create one reusable * instance of this class and then {@link #wrap(ImmutableRoaringBitmap)} - * + * * For better performance, consider the {@link ImmutableRoaringBitmap#forEach} method. * * @author Borislav Ivanov @@ -43,7 +43,7 @@ public BufferIntIteratorFlyweight() { /** * Creates an instance that is ready for iteration. - * + * * @param r bitmap to be iterated over */ public BufferIntIteratorFlyweight(ImmutableRoaringBitmap r) { @@ -100,7 +100,7 @@ private void nextContainer() { /** * Prepares a bitmap for iteration - * + * * @param r bitmap to be iterated over */ public void wrap(ImmutableRoaringBitmap r) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java index 2caa7bc52..95662fdbf 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java @@ -10,9 +10,9 @@ /** * Fast iterator minimizing the stress on the garbage collector. You can create one reusable * instance of this class and then {@link #wrap(ImmutableRoaringBitmap)} - * + * * This iterator enumerates the stored values in reverse (starting from the end). - * + * * @author Borislav Ivanov **/ public class BufferReverseIntIteratorFlyweight implements IntIterator { @@ -45,7 +45,7 @@ public BufferReverseIntIteratorFlyweight() { /** * Creates an instance that is ready for iteration. - * + * * @param r bitmap to be iterated over */ public BufferReverseIntIteratorFlyweight(ImmutableRoaringBitmap r) { @@ -105,7 +105,7 @@ private void nextContainer() { /** * Prepares a bitmap for iteration - * + * * @param r bitmap to be iterated over */ public void wrap(ImmutableRoaringBitmap r) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java index 99d4d1999..2b7930fbe 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java @@ -157,7 +157,7 @@ public int getCardinality(int k) { - @Override + @Override public int getContainerIndex(char x) { return unsignedBinarySearch(x); } diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java index 64120a54d..aa66af9da 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java @@ -274,7 +274,7 @@ public static MutableRoaringBitmap and(final ImmutableRoaringBitmap x1, } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); } else { // s1 > s2 pos2 = x2.highLowContainer.advanceUntil(s1, pos2); @@ -308,7 +308,7 @@ public static int andCardinality(final ImmutableRoaringBitmap x1, answer += c1.andCardinality(c2); ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); } else { // s1 > s2 pos2 = x2.highLowContainer.advanceUntil(s1, pos2); @@ -415,7 +415,7 @@ public static MutableRoaringBitmap andNot(final ImmutableRoaringBitmap x1, } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { final int nextPos1 = x1.highLowContainer.advanceUntil(s2, pos1); answer.getMappeableRoaringArray().appendCopy(x1.highLowContainer, pos1, nextPos1); pos1 = nextPos1; @@ -649,6 +649,70 @@ public void remove() { return bitmapsIterator; } + /** + * Creates a copy of the bitmap, limited to the values in the specified range, + * rangeStart (inclusive) and rangeEnd (exclusive). + * + * @param rangeStart inclusive + * @param rangeEnd exclusive + * @return new bitmap + */ + public MutableRoaringBitmap selectRange(final long rangeStart, final long rangeEnd) { + final int hbStart = (BufferUtil.highbits(rangeStart)); + final int lbStart = (BufferUtil.lowbits(rangeStart)); + final int hbLast = (BufferUtil.highbits(rangeEnd - 1)); + final int lbLast = (BufferUtil.lowbits(rangeEnd - 1)); + MutableRoaringBitmap answer = new MutableRoaringBitmap(); + + assert(rangeStart >= 0 && rangeEnd >= 0); + + if (rangeEnd <= rangeStart) { + return answer; + } + + if (hbStart == hbLast) { + final int i = this.highLowContainer.getIndex((char) hbStart); + if (i >= 0) { + final MappeableContainer c = this.highLowContainer.getContainerAtIndex(i).remove(0, lbStart) + .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); + if (!c.isEmpty()) { + ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); + } + } + return answer; + } + int ifirst = this.highLowContainer.getIndex((char) hbStart); + int ilast = this.highLowContainer.getIndex((char) hbLast); + if (ifirst >= 0) { + MappeableContainer c = this.highLowContainer.getContainerAtIndex(ifirst).remove(0, lbStart); + if (!c.isEmpty()) { + ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c.clone()); + } + } + + // revised to loop on ints + for (int hb = hbStart + 1; hb <= hbLast - 1; ++hb) { + final int i = this.highLowContainer.getIndex((char)hb); + final int j = answer.highLowContainer.getIndex((char) hb); + assert j < 0; + + if (i >= 0) { + final MappeableContainer c = this.highLowContainer.getContainerAtIndex(i); + ((MutableRoaringArray) answer.highLowContainer).insertNewKeyValueAt(-j - 1, + (char)hb, c.clone()); + } + } + + if (ilast >= 0) { + MappeableContainer c = this.highLowContainer.getContainerAtIndex(ilast).remove(lbLast + 1, + Util.maxLowBitAsInteger() + 1); + if (!c.isEmpty()) { + ((MutableRoaringArray) answer.highLowContainer).append((char) hbLast, c); + } + } + return answer; + } + /** * * Extracts the values in the specified range, rangeStart (inclusive) and rangeEnd (exclusive) @@ -740,7 +804,7 @@ public static boolean intersects(final ImmutableRoaringBitmap x1, } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); } else { // s1 > s2 pos2 = x2.highLowContainer.advanceUntil(s1, pos2); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index e546b2277..50fca67d5 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -29,7 +29,7 @@ public final class MappeableBitmapContainer extends MappeableContainer implement private static final int MAX_CAPACITY_BYTE = MAX_CAPACITY / Byte.SIZE; private static final int MAX_CAPACITY_LONG = MAX_CAPACITY / Long.SIZE; - + private static final long serialVersionUID = 3L; // bail out early when the number of runs is excessive, without @@ -67,7 +67,7 @@ public MappeableBitmapContainer() { /** * Creates a new bitmap container from a non-mappeable one. This copies the data. - * + * * @param bc the original container */ public MappeableBitmapContainer(BitmapContainer bc) { @@ -79,7 +79,7 @@ public MappeableBitmapContainer(BitmapContainer bc) { * Create a bitmap container with a run of ones from firstOfRun to lastOfRun, inclusive caller * must ensure that the range isn't so small that an ArrayContainer should have been created * instead - * + * * @param firstOfRun first index * @param lastOfRun last index (range is exclusive) */ @@ -101,7 +101,7 @@ public MappeableBitmapContainer(final int firstOfRun, final int lastOfRun) { /** * Construct a new BitmapContainer backed by the provided LongBuffer. - * + * * @param array LongBuffer where the data is stored * @param initCardinality cardinality (number of values stored) */ @@ -406,11 +406,11 @@ public boolean contains(final char i) { long bitValue(final char i) { return (bitmap.get(i >>> 6) >>> i) & 1; } - - + + /** * Checks whether the container contains the value i. - * + * * @param buf underlying buffer * @param position position of the container in the buffer * @param i index @@ -1266,7 +1266,7 @@ void loadData(final MappeableArrayContainer arrayContainer) { /** * Find the index of the next set bit greater or equal to i, returns -1 if none found. - * + * * @param i starting index * @return index of the next set bit */ @@ -1361,7 +1361,7 @@ int numberOfRuns() { /** * Computes the number of runs - * + * * @return the number of runs */ private int numberOfRunsAdjustment() { @@ -1403,7 +1403,7 @@ private int numberOfRunsAdjustment() { /** * Counts how many runs there is in the bitmap, up to a maximum - * + * * @param mustNotExceed maximum of runs beyond which counting is pointless * @return estimated number of courses */ @@ -1764,7 +1764,7 @@ public int serializedSizeInBytes() { /** * Copies the data to an array container - * + * * @return the array container */ MappeableArrayContainer toArrayContainer() { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java index de53dea70..8b52482b4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java @@ -20,7 +20,7 @@ public abstract class MappeableContainer implements Iterable, Cloneab WordStorage { /** * Create a container initialized with a range of consecutive values - * + * * @param start first index * @param last last index (range is exclusive) * @return a new container initialized with the specified values @@ -47,7 +47,7 @@ public static MappeableContainer rangeOfOnes(final int start, final int last) { /** * Add a char to the container. May generate a new container. - * + * * @param x char to be added * @return the new container */ @@ -89,7 +89,7 @@ public static MappeableContainer rangeOfOnes(final int start, final int last) { /** * Computes the bitwise AND of this container with another (intersection). This container as well * as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -98,7 +98,7 @@ public static MappeableContainer rangeOfOnes(final int start, final int last) { /** * Computes the bitwise AND of this container with another (intersection). This container as well * as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -114,7 +114,7 @@ protected MappeableContainer and(MappeableContainer x) { } - + protected abstract int andCardinality(MappeableArrayContainer x); protected abstract int andCardinality(MappeableBitmapContainer x); @@ -153,11 +153,11 @@ public int andCardinality(MappeableContainer x) { } } - + /** * Computes the bitwise AND of this container with another (intersection). This container as well * as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -168,7 +168,7 @@ public int andCardinality(MappeableContainer x) { /** * Computes the bitwise ANDNOT of this container with another (difference). This container as well * as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -177,7 +177,7 @@ public int andCardinality(MappeableContainer x) { /** * Computes the bitwise ANDNOT of this container with another (difference). This container as well * as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -196,7 +196,7 @@ protected MappeableContainer andNot(MappeableContainer x) { /** * Computes the bitwise ANDNOT of this container with another (difference). This container as well * as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -244,7 +244,7 @@ public MappeableContainer iorNot(MappeableContainer x, int endOfRange) { /** * Checks whether the contain contains the provided value - * + * * @param x value to check * @return whether the value is in the container */ @@ -288,13 +288,13 @@ public boolean contains(MappeableContainer subset) { * @return true if the container contains the range */ public abstract boolean contains(int minimum, int supremum); - + /** * Fill the least significant 16 bits of the integer array, starting at index index, with the * char values from this container. The caller is responsible to allocate enough room. The most * significant 16 bits of each integer are given by the most significant bits of the provided * mask. - * + * * @param x provided array * @param i starting index * @param mask indicates most significant bits @@ -313,7 +313,7 @@ public boolean contains(MappeableContainer subset) { /** * Size of the underlying array - * + * * @return size in bytes */ protected abstract int getArraySizeInBytes(); @@ -322,14 +322,14 @@ public boolean contains(MappeableContainer subset) { /** * Computes the distinct number of char values in the container. Can be expected to run in * constant time. - * + * * @return the cardinality */ public abstract int getCardinality(); /** * Get the name of this container. - * + * * @return name of the container */ public String getContainerName() { @@ -366,7 +366,7 @@ public String getContainerName() { * @return iterator */ public abstract ContainerBatchIterator getBatchIterator(); - + /** * Iterate through the values of this container and pass them * along to the IntConsumer, using msb as the 16 most significant bits. @@ -378,7 +378,7 @@ public String getContainerName() { /** * Computes an estimate of the memory usage of this container. The estimate is not meant to be * exact. - * + * * @return estimated memory usage in bytes */ public abstract int getSizeInBytes(); @@ -396,7 +396,7 @@ public String getContainerName() { * Computes the in-place bitwise AND of this container with another (intersection). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate * a new container. - * + * * @param x other container * @return aggregated container */ @@ -406,7 +406,7 @@ public String getContainerName() { * Computes the in-place bitwise AND of this container with another (intersection). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate * a new container. - * + * * @param x other container * @return aggregated container */ @@ -428,7 +428,7 @@ protected MappeableContainer iand(MappeableContainer x) { * Computes the in-place bitwise AND of this container with another (intersection). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate * a new container. - * + * * @param x other container * @return aggregated container */ @@ -439,7 +439,7 @@ protected MappeableContainer iand(MappeableContainer x) { * Computes the in-place bitwise ANDNOT of this container with another (difference). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate * a new container. - * + * * @param x other container * @return aggregated container */ @@ -449,7 +449,7 @@ protected MappeableContainer iand(MappeableContainer x) { * Computes the in-place bitwise ANDNOT of this container with another (difference). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate * a new container. - * + * * @param x other container * @return aggregated container */ @@ -469,7 +469,7 @@ protected MappeableContainer iandNot(MappeableContainer x) { * Computes the in-place bitwise ANDNOT of this container with another (difference). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate * a new container. - * + * * @param x other container * @return aggregated container */ @@ -481,7 +481,7 @@ protected MappeableContainer iandNot(MappeableContainer x) { /** * Computes the in-place bitwise NOT of this container (complement). Only those bits within the * range are affected. The current container is generally modified. May generate a new container. - * + * * @param rangeStart beginning of range (inclusive); 0 is beginning of this container. * @param rangeEnd ending of range (exclusive) * @return (partially) completmented container @@ -532,7 +532,7 @@ public boolean intersects(MappeableContainer x) { * Computes the in-place bitwise OR of this container with another (union). The current container * is generally modified, whereas the provided container (x) is unaffected. May generate a new * container. - * + * * @param x other container * @return aggregated container */ @@ -542,7 +542,7 @@ public boolean intersects(MappeableContainer x) { * Computes the in-place bitwise OR of this container with another (union). The current container * is generally modified, whereas the provided container (x) is unaffected. May generate a new * container. - * + * * @param x other container * @return aggregated container */ @@ -562,7 +562,7 @@ protected MappeableContainer ior(MappeableContainer x) { * Computes the in-place bitwise OR of this container with another (union). The current container * is generally modified, whereas the provided container (x) is unaffected. May generate a new * container. - * + * * @param x other container * @return aggregated container */ @@ -585,7 +585,7 @@ protected MappeableContainer ior(MappeableContainer x) { * Computes the in-place bitwise XOR of this container with another (symmetric difference). The * current container is generally modified, whereas the provided container (x) is unaffected. May * generate a new container. - * + * * @param x other container * @return aggregated container */ @@ -595,7 +595,7 @@ protected MappeableContainer ior(MappeableContainer x) { * Computes the in-place bitwise XOR of this container with another (symmetric difference). The * current container is generally modified, whereas the provided container (x) is unaffected. May * generate a new container. - * + * * @param x other container * @return aggregated container */ @@ -617,7 +617,7 @@ protected MappeableContainer ixor(MappeableContainer x) { * Computes the in-place bitwise XOR of this container with another (symmetric difference). The * current container is generally modified, whereas the provided container (x) is unaffected. May * generate a new container. - * + * * @param x other container * @return aggregated container */ @@ -666,7 +666,7 @@ public MappeableContainer lazyIOR(MappeableContainer x) { * provided container are left unaffected. The resulting container may not track its cardinality * correctly. This can be fixed as follows: if(c.getCardinality()<0) * ((MappeableBitmapContainer)c).computeCardinality(); - * + * * @param x other container * @return aggregated container */ @@ -697,7 +697,7 @@ public MappeableContainer lazyOR(MappeableContainer x) { /** * Create a new MappeableContainer containing at most maxcardinality integers. - * + * * @param maxcardinality maximal cardinality * @return a new bitmap with cardinality no more than maxcardinality */ @@ -706,7 +706,7 @@ public MappeableContainer lazyOR(MappeableContainer x) { /** * Computes the bitwise NOT of this container (complement). Only those bits within the range are * affected. The current container is left unaffected. - * + * * @param rangeStart beginning of range (inclusive); 0 is beginning of this container. * @param rangeEnd ending of range (exclusive) * @return (partially) completmented container @@ -718,7 +718,7 @@ public MappeableContainer lazyOR(MappeableContainer x) { /** * Computes the bitwise OR of this container with another (union). This container as well as the * provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -728,7 +728,7 @@ public MappeableContainer lazyOR(MappeableContainer x) { /** * Computes the bitwise OR of this container with another (union). This container as well as the * provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -748,7 +748,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Computes the bitwise OR of this container with another (union). This container as well as the * provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -758,7 +758,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Rank returns the number of integers that are smaller or equal to x (Rank(infinity) would be * GetCardinality()). - * + * * @param lowbits upper limit * * @return the rank @@ -776,7 +776,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Remove the char from this container. May create a new container. - * + * * @param x to be removed * @return New container */ @@ -784,7 +784,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * The output of a lazyOR or lazyIOR might be an invalid container, this should be called on it. - * + * * @return a new valid container */ public abstract MappeableContainer repairAfterLazy(); @@ -792,7 +792,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Convert to MappeableRunContainers, when the result is smaller. Overridden by * MappeableRunContainer to possibly switch from MappeableRunContainer to a smaller alternative. - * + * * @return the new container */ public abstract MappeableContainer runOptimize(); @@ -800,7 +800,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Return the jth value - * + * * @param j index of the value * * @return the value @@ -819,7 +819,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Convert to a non-mappeable container. - * + * * @return the non-mappeable container */ public abstract Container toContainer(); @@ -833,7 +833,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Write just the underlying array. - * + * * @param out output stream * @throws IOException in case of failure */ @@ -849,7 +849,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Computes the bitwise XOR of this container with another (symmetric difference). This container * as well as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -858,7 +858,7 @@ protected MappeableContainer or(MappeableContainer x) { /** * Computes the bitwise XOR of this container with another (symmetric difference). This container * as well as the provided container are left unaffected. - * + * * @param x other container * @return aggregated container */ @@ -878,7 +878,7 @@ protected MappeableContainer xor(MappeableContainer x) { /** * Computes the bitwise XOR of this container with another (symmetric difference). This container * as well as the provided container are left unaffected. - * + * * @param x other parameter * @return aggregated container */ diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java index 1d472ca7a..287e4f2cf 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java @@ -5,9 +5,9 @@ package org.roaringbitmap.buffer; /** - * + * * This interface allows you to iterate over the containers in a roaring bitmap. - * + * */ public interface MappeableContainerPointer extends Comparable, Cloneable { @@ -18,7 +18,7 @@ public interface MappeableContainerPointer /** * Create a copy - * + * * @return return a clone of this pointer */ MappeableContainerPointer clone(); @@ -26,7 +26,7 @@ public interface MappeableContainerPointer /** * Returns the cardinality of the current container. Can be faster than loading the container * first. - * + * * @return cardinality of the current container */ int getCardinality(); @@ -34,34 +34,34 @@ public interface MappeableContainerPointer /** * This method can be used to check whether there is current a valid container as it returns null * when there is not. - * + * * @return null or the current container */ MappeableContainer getContainer(); /** * Get the size in bytes of the container. Used for sorting. - * + * * @return the size in bytes */ int getSizeInBytes(); /** - * + * * @return whether there is a container at the current position */ boolean hasContainer(); /** * Returns true if it is a bitmap container (MappeableBitmapContainer). - * + * * @return boolean indicated if it is a bitmap container */ boolean isBitmapContainer(); /** * Returns true if it is a run container (MappeableRunContainer). - * + * * @return boolean indicated if it is a run container */ boolean isRunContainer(); @@ -69,7 +69,7 @@ public interface MappeableContainerPointer /** * The key is a 16-bit integer that indicates the position of the container in the roaring bitmap. * To be interpreted as an unsigned integer. - * + * * @return the key */ char key(); diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java index 210f5f76a..65c6d7f81 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java @@ -440,8 +440,8 @@ public int getCardinality(int i) { @Override public int getContainerIndex(char x) { return this.binarySearch(0, size, x); - } - + } + @Override public MappeableContainer getContainerAtIndex(int i) { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java index 902ab5dd4..728945533 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java @@ -73,10 +73,10 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap * negative. Values that would fall outside * of the valid 32-bit range are discarded * so that the result can have lower cardinality. - * + * * This method can be relatively expensive when * offset is not divisible by 65536. Use sparingly. - * + * * @param x source bitmap * @param offset increment (can be negative) * @return a new bitmap @@ -84,7 +84,7 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap public static MutableRoaringBitmap addOffset(final ImmutableRoaringBitmap x, long offset) { // we need "offset" to be a long because we want to support values // between -0xFFFFFFFF up to +-0xFFFFFFFF - long container_offset_long = offset < 0 + long container_offset_long = offset < 0 ? (offset - (1<<16) + 1) / (1<<16) : offset / (1 << 16); if((container_offset_long < -(1<<16) ) || (container_offset_long >= (1<<16) )) { return new MutableRoaringBitmap(); // it is necessarily going to be empty @@ -251,7 +251,7 @@ public static MutableRoaringBitmap and(final MutableRoaringBitmap x1, } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = x1.highLowContainer.advanceUntil(s2, pos1); } else { // s1 > s2 pos2 = x2.highLowContainer.advanceUntil(s1, pos2); @@ -286,7 +286,7 @@ public static MutableRoaringBitmap andNot(final MutableRoaringBitmap x1, } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { final int nextPos1 = x1.highLowContainer.advanceUntil(s2, pos1); answer.getMappeableRoaringArray().appendCopy(x1.highLowContainer, pos1, nextPos1); pos1 = nextPos1; @@ -314,9 +314,9 @@ public void add(final int... dat) { /** * Set the specified values to true, within given boundaries. This can be expected to be slightly - * faster than calling "add" repeatedly on the values dat[offset], dat[offset+1],..., - * dat[offset+n-1]. - * The provided integers values don't have to be in sorted order, but it may be preferable + * faster than calling "add" repeatedly on the values dat[offset], dat[offset+1],..., + * dat[offset+n-1]. + * The provided integers values don't have to be in sorted order, but it may be preferable * to sort them from a performance point of view. * * @param dat set values @@ -611,7 +611,7 @@ public static MutableRoaringBitmap or(final MutableRoaringBitmap x1, } s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { answer.getMappeableRoaringArray().appendCopy(x1.highLowContainer.getKeyAtIndex(pos1), x1.highLowContainer.getContainerAtIndex(pos1)); pos1++; @@ -747,7 +747,7 @@ public static MutableRoaringBitmap xor(final MutableRoaringBitmap x1, } s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { answer.getMappeableRoaringArray().appendCopy(x1.highLowContainer.getKeyAtIndex(pos1), x1.highLowContainer.getContainerAtIndex(pos1)); pos1++; @@ -900,7 +900,7 @@ public void and(final ImmutableRoaringBitmap array) { } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { pos1 = highLowContainer.advanceUntil(s2, pos1); } else { // s1 > s2 pos2 = array.highLowContainer.advanceUntil(s1, pos2); @@ -935,7 +935,7 @@ public void andNot(final ImmutableRoaringBitmap x2) { } ++pos1; ++pos2; - } else if (s1 < s2) { + } else if (s1 < s2) { if (pos1 != intersectionSize) { final MappeableContainer c1 = highLowContainer.getContainerAtIndex(pos1); getMappeableRoaringArray().replaceKeyAndContainerAtIndex(intersectionSize, s1, c1); @@ -1326,7 +1326,7 @@ protected void lazyor(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; @@ -1376,7 +1376,7 @@ protected void naivelazyor(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; @@ -1428,7 +1428,7 @@ public void or(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; @@ -1702,7 +1702,7 @@ public void xor(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); - } else if (s1 < s2) { + } else if (s1 < s2) { pos1++; if (pos1 == length1) { break main; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java index 4222c24ea..e499537d4 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java @@ -9,7 +9,7 @@ /** * A {@link BitmapDataProviderSupplier} providing {@link MutableRoaringBitmap} as * {@link BitmapDataProvider} - * + * * @author Benoit Lacelle * */ diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java index ce15da377..81a0b2d14 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java @@ -10,7 +10,7 @@ /** * Generic interface for the array underlying roaring bitmap classes. - * + * */ public interface PointableRoaringArray extends Cloneable { /** @@ -26,7 +26,7 @@ public interface PointableRoaringArray extends Cloneable { /** * Create an independent copy of the underlying array - * + * * @return a copy */ PointableRoaringArray clone(); @@ -35,18 +35,18 @@ public interface PointableRoaringArray extends Cloneable { * This checks whether the container at index i has the value x. * This can be faster than calling "getContainerAtIndex" and then calling * contains. - * + * * @param i container index (assumed to be non-negative) * @param x 16-bit value to check * @return whether the container contains at index i contains x */ boolean containsForContainerAtIndex(int i, char x); - + /** * Returns the cardinality of the container at the given index. This method is expected to be * fast. - * + * * @param i index * @return the cardinality */ @@ -54,13 +54,13 @@ public interface PointableRoaringArray extends Cloneable { /** * Obsolete method (retired because it forces us to create a new container). - * + * * @param x 16-bit key * @return matching container */ //MappeableContainer getContainer(short x); - + /** * Returns either the index of the container corresponding to key x, or a negative value. * @param x 16-bit key @@ -99,16 +99,16 @@ public interface PointableRoaringArray extends Cloneable { /** * Check whether this bitmap has had its runs compressed. - * + * * @return whether this bitmap has run compression */ boolean hasRunCompression(); /** * Serialize. - * + * * The current bitmap is not modified. - * + * * @param out the DataOutput stream * @throws IOException Signals that an I/O exception has occurred. */ diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/package-info.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/package-info.java index 0de419318..3ba86b65c 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/package-info.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/package-info.java @@ -6,17 +6,17 @@ /** * The org.roaringbitmap.buffer package provides - * two classes ({@link org.roaringbitmap.buffer.MutableRoaringBitmap} and + * two classes ({@link org.roaringbitmap.buffer.MutableRoaringBitmap} and * ({@link org.roaringbitmap.buffer.ImmutableRoaringBitmap}) that users * can rely upon for fast set of integers. * It differs from the org.roaringbitmap in that - * the backing stores are ByteBuffers. - * + * the backing stores are ByteBuffers. + * * Initially, one wants to construct a bitmap using * the MutableRoaringBitmap class. After serialization, * one can memory-map an ImmutableRoaringBitmap to the * serialized bytes, enabling off-heap processing. - * + * *
  * {@code
  *      import org.roaringbitmap.buffer.*;
@@ -25,7 +25,7 @@
  *
  *      MutableRoaringBitmap r1 = new MutableRoaringBitmap();
  *      for(int k = 4000; k<4255;++k) r1.add(k);
- *      
+ *
  *      MutableRoaringBitmap r2 = new MutableRoaringBitmap();
  *      for(int k = 1000; k<4255; k+=2) r2.add(k);
  *
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java
index f6329e83d..db42fc6ea 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java
@@ -37,9 +37,9 @@ public interface ImmutableLongBitmapDataProvider {
 
   /**
    * Visit all values in the bitmap and pass them to the consumer.
-   * 
+   *
    * * Usage:
-   * 
+   *
    * 
    * {@code
    *  bitmap.forEach(new LongConsumer() {
@@ -47,19 +47,19 @@ public interface ImmutableLongBitmapDataProvider {
    *    {@literal @}Override
    *    public void accept(long value) {
    *      // do something here
-   *      
+   *
    *    }});
    *   }
    * }
    * 
- * + * * @param lc the consumer */ void forEach(LongConsumer lc); /** * For better performance, consider the Use the {@link #forEach forEach} method. - * + * * @return a custom iterator over set bits, the bits are traversed in ascending sorted order */ // RoaringBitmap proposes a PeekableLongIterator @@ -75,9 +75,9 @@ public interface ImmutableLongBitmapDataProvider { * @return an Ordered, Distinct, Sorted and Sized IntStream in ascending order */ default LongStream stream() { - int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED + int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.SIZED; - Spliterator.OfLong x = Spliterators.spliterator(new RoaringOfLong(getLongIterator()), + Spliterator.OfLong x = Spliterators.spliterator(new RoaringOfLong(getLongIterator()), getLongCardinality(), characteristics); return StreamSupport.longStream(x, false); } @@ -87,13 +87,13 @@ default LongStream stream() { */ default LongStream reverseStream() { int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SIZED; - Spliterator.OfLong x = Spliterators.spliterator(new RoaringOfLong(getLongIterator()), + Spliterator.OfLong x = Spliterators.spliterator(new RoaringOfLong(getLongIterator()), getLongCardinality(), characteristics); return StreamSupport.longStream(x, false); } /** * Estimate of the memory usage of this data structure. - * + * * Internally, this is computed as a 64-bit counter. * * @return estimated memory usage. @@ -125,9 +125,9 @@ default LongStream reverseStream() { /** * Rank returns the number of integers that are smaller or equal to x (Rank(infinity) would be * GetCardinality()). - * + * * The value is a full 64-bit value. - * + * * @param x upper limit * * @return the rank diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java index 4945f348a..a1b14a160 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java @@ -6,16 +6,16 @@ /** * An LongConsumer receives the long values contained in a data structure. Each value is visited * once. - * + * * Usage: - * + * *
  * {@code
  *  bitmap.forEach(new LongConsumer() {
  *
  *    public void accept(long value) {
  *      // do something here
- *      
+ *
  *    }});
  *   }
  * }
@@ -24,7 +24,7 @@
 public interface LongConsumer {
   /**
    * Receives the long
-   * 
+   *
    * @param value the long value
    */
   void accept(long value);
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java
index 9db3ad6cb..993b54492 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java
@@ -11,7 +11,7 @@
 public interface LongIterator extends Cloneable {
   /**
    * Creates a copy of the iterator.
-   * 
+   *
    * @return a clone of the current iterator
    */
   LongIterator clone();
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java
index 076e2cefd..d2f482ae5 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java
@@ -5,7 +5,7 @@
 
 
 /**
- * Simple extension to the IntIterator interface. 
+ * Simple extension to the IntIterator interface.
  * It allows you to "skip" values using the advanceIfNeeded
  * method, and to look at the value without advancing (peekNext).
  *
@@ -14,19 +14,19 @@
  */
 public interface PeekableLongIterator extends LongIterator {
   /**
-   * If needed, 
-   * 
-   * for a forwards iterator 
+   * If needed,
+   *
+   * for a forwards iterator
    * advance as long as the next value is smaller than thresholdVal
-   * 
-   * For a reverse iterator 
+   *
+   * For a reverse iterator
    * advance as long as the next value is greater than thresholdVal
    *
    *  The advanceIfNeeded method is used for performance reasons, to skip
    *  over unnecessary repeated calls to next.
-   *  
+   *
    *  Suppose for example that you wish to compute the intersection between
-   *  an ordered list of longs (e.g., longs[] x = {1,4,5}) and a 
+   *  an ordered list of longs (e.g., longs[] x = {1,4,5}) and a
    *  PeekableIntIterator.
    *  You might do it as follows...
    *     

@@ -42,24 +42,24 @@ public interface PeekableLongIterator extends LongIterator {
    *       j.advanceIfNeeded(val);
    *     }
    *     
- * - * The benefit of calling advanceIfNeeded is that each such call + * + * The benefit of calling advanceIfNeeded is that each such call * can be much faster than repeated calls to "next". The underlying * implementation can "skip" over some data. - * - * + * + * * @param thresholdVal threshold */ public void advanceIfNeeded(long thresholdVal); /** - * + * * Look at the next value without advancing - * + * * The peek is useful when working with several iterators at once. * Suppose that you have 100 iterators, and you want to compute * their intersections without materializing the result. - * You might do it as follows... + * You might do it as follows... *

    *    PriorityQueue pq = new PriorityQueue(100,
    *      new Comparator<PeekableIntIterator>() {
@@ -68,9 +68,9 @@ public interface PeekableLongIterator extends LongIterator {
    *                 return a.peek() - b.peek();
    *             }
    *         });
-   * 
+   *
    *    //...  populate pq
-   *    
+   *
    *    while(! pq.isEmpty() ) {
    *      // get iterator with a smallest value
    *      PeekableLongIterator pi = pq.poll();
@@ -79,17 +79,17 @@ public interface PeekableLongIterator extends LongIterator {
    *      if(pi.hasNext()) pq.add(pi)
    *    }
    *    
- * + * * Notice how the peek method allows you to compare iterators in a way * that the next method could not do. - * + * * @return next value */ public long peekNext(); /** * Creates a copy of the iterator. - * + * * @return a clone of the current iterator */ @Override diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java index 34129d44f..bbc9b3383 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java @@ -933,7 +933,7 @@ private abstract class PeekableIterator implements PeekableLongIterator { PeekableIterator(final LeafNodeIterator keyIte) { this.keyIte = keyIte; } - + abstract PeekableCharIterator getIterator(Container container); abstract boolean compare(long next, long val); @@ -1043,12 +1043,12 @@ private class ForwardPeekableIterator extends PeekableIterator { public ForwardPeekableIterator(final LeafNodeIterator keyIte) { super(keyIte); } - + @Override PeekableCharIterator getIterator(Container container) { return container.getCharIterator(); } - + @Override boolean compare(long next, long val) { return Long.compareUnsigned(next, val) >= 0; @@ -1059,12 +1059,12 @@ private class ReversePeekableIterator extends PeekableIterator { public ReversePeekableIterator(final LeafNodeIterator keyIte) { super(keyIte); } - + @Override PeekableCharIterator getIterator(Container container) { return container.getReverseCharIterator(); } - + @Override boolean compare(long next, long val) { return Long.compareUnsigned(next, val) <= 0; diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java index f8109657c..201a3d304 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java @@ -91,9 +91,9 @@ public Roaring64NavigableMap() { } /** - * + * * By default, use RoaringBitmap as underlyings {@link BitmapDataProvider} - * + * * @param signedLongs true if longs has to be ordered as plain java longs. False to handle them as * unsigned 64bits long (as RoaringBitmap with unsigned integers) */ @@ -103,7 +103,7 @@ public Roaring64NavigableMap(boolean signedLongs) { /** * By default, use RoaringBitmap as underlyings {@link BitmapDataProvider} - * + * * @param signedLongs true if longs has to be ordered as plain java longs. False to handle them as * unsigned 64bits long (as RoaringBitmap with unsigned integers) * @param cacheCardinalities true if cardinalities have to be cached. It will prevent many @@ -115,7 +115,7 @@ public Roaring64NavigableMap(boolean signedLongs, boolean cacheCardinalities) { /** * By default, longs are managed as unsigned longs and cardinalities are cached. - * + * * @param supplier provide the logic to instantiate new {@link BitmapDataProvider}, typically * instantiated once per high. */ @@ -125,7 +125,7 @@ public Roaring64NavigableMap(BitmapDataProviderSupplier supplier) { /** * By default, we activating cardinalities caching. - * + * * @param signedLongs true if longs has to be ordered as plain java longs. False to handle them as * unsigned 64bits long (as RoaringBitmap with unsigned integers) * @param supplier provide the logic to instantiate new {@link BitmapDataProvider}, typically @@ -136,7 +136,7 @@ public Roaring64NavigableMap(boolean signedLongs, BitmapDataProviderSupplier sup } /** - * + * * @param signedLongs true if longs has to be ordered as plain java longs. False to handle them as * unsigned 64bits long (as RoaringBitmap with unsigned integers) * @param cacheCardinalities true if cardinalities have to be cached. It will prevent many @@ -322,9 +322,9 @@ public long getLongCardinality() { } /** - * + * * @return the cardinality as an int - * + * * @throws UnsupportedOperationException if the cardinality does not fit in an int */ public int getIntCardinality() throws UnsupportedOperationException { @@ -539,7 +539,7 @@ private long rankLongNoCache(int high, int low) { } /** - * + * * @param high for which high bucket should we compute the cardinality * @return the highest validatedIndex */ @@ -1126,10 +1126,10 @@ public int getSizeInBytes() { @Override public long getLongSizeInBytes() { long size = 8; - + // Size of containers size += highToBitmap.values().stream().mapToLong(p -> p.getLongSizeInBytes()).sum(); - + // Size of Map data-structure: we consider each TreeMap entry costs 40 bytes // http://java-performance.info/memory-consumption-of-java-data-types-2/ size += 8L + 40L * highToBitmap.size(); @@ -1140,7 +1140,7 @@ public long getLongSizeInBytes() { // The cache impacts the size in heap size += 8L * sortedCumulatedCardinality.length; size += 4L * sortedHighs.length; - + return size; } @@ -1172,7 +1172,7 @@ public void repairAfterLazy() { /** * Use a run-length encoding where it is estimated as more space efficient - * + * * @return whether a change was applied */ public boolean runOptimize() { diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java index 9828859b7..bf5697242 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java @@ -10,14 +10,14 @@ * Used to hold the logic packing 2 integers in a long, and separating a long in two integers. It is * useful in {@link Roaring64NavigableMap} as the implementation split the input long in two * integers, one used as key of a NavigableMap while the other is added in a Bitmap - * + * * @author Benoit Lacelle * */ class RoaringIntPacking { /** - * + * * @param id any long, positive or negative * @return an int holding the 32 highest order bits of information of the input long */ @@ -26,7 +26,7 @@ public static int high(long id) { } /** - * + * * @param id any long, positive or negative * @return an int holding the 32 lowest order bits of information of the input long */ @@ -35,7 +35,7 @@ public static int low(long id) { } /** - * + * * @param high an integer representing the highest order bits of the output long * @param low an integer representing the lowest order bits of the output long * @return a long packing together the integers as computed by @@ -48,7 +48,7 @@ public static long pack(int high, int low) { /** - * + * * @param signedLongs true if long put in a {@link Roaring64NavigableMap} should be considered as * signed long. * @return the int representing the highest value which can be set as high value in a diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/package-info.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/package-info.java index 3da296b9f..f76b1745f 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/package-info.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/package-info.java @@ -8,8 +8,8 @@ * The org.roaringbitmap.longlong package provides * one class ({@link org.roaringbitmap.longlong.Roaring64NavigableMap}) that users * can rely upon for fast set of 64-bit integers. - * - * + * + * *
  * {@code
  *      import org.roaringbitmap.longlong.*;
@@ -18,7 +18,7 @@
  *
  *      Roaring64NavigableMap r1 = new Roaring64NavigableMap();
  *      for(long k = 4000l; k<4255l;++k) r1.addLong(k);
- *      
+ *
  * }
  * 
* diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/package-info.java b/RoaringBitmap/src/main/java/org/roaringbitmap/package-info.java index c05ab40fc..cf53e36e6 100644 --- a/RoaringBitmap/src/main/java/org/roaringbitmap/package-info.java +++ b/RoaringBitmap/src/main/java/org/roaringbitmap/package-info.java @@ -8,8 +8,8 @@ * The org.roaringbitmap package provides * one class ({@link org.roaringbitmap.RoaringBitmap}) that users * can rely upon for fast set of integers. - * - * + * + * *
  * {@code
  *      import org.roaringbitmap.*;
@@ -18,7 +18,7 @@
  *
  *      RoaringBitmap r1 = new RoaringBitmap();
  *      for(int k = 4000; k<4255;++k) r1.add(k);
- *      
+ *
  *      RoaringBitmap r2 = new RoaringBitmap();
  *      for(int k = 1000; k<4255; k+=2) r2.add(k);
  *
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java
index 4a5e46c8d..789753f13 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java
@@ -283,7 +283,7 @@ public void testSerializeBigSlices() {
   }
 
   @ParameterizedTest
-  @ValueSource(longs = {1L, 0xFL, 0xFFL, 0xFFFL, 0xFFFFL, 
+  @ValueSource(longs = {1L, 0xFL, 0xFFL, 0xFFFL, 0xFFFFL,
       0xFFFFFL, 0xFFFFFFL, 0xFFFFFFL, 0xFFFFFFFL, 0xFFFFFFFFL,
       0xFFFFFFFFFL, 0xFFFFFFFFFFL, 0xFFFFFFFFFFFL,
       0xFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFL,  0xFFFFFFFFFFFFFFL,
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java
index f4ab4b4ef..3db95ee71 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java
@@ -47,7 +47,7 @@ public void testToString() {
     assertEquals("{5,6,7,8,9,10,11,12,13,14,65517,65533}", bc2.toString());
   }
 
-  @Test  
+  @Test
   public void testXOR() {
     BitmapContainer bc = new BitmapContainer(100,10000);
     BitmapContainer bc2 = new BitmapContainer();
@@ -63,8 +63,8 @@ public void testXOR() {
     bc = (BitmapContainer) bc.ixor(bc2);
     assertEquals(0, bc.ixor(bc3).getCardinality());
   }
-  
-  @Test  
+
+  @Test
   public void testANDNOT() {
     BitmapContainer bc = new BitmapContainer(100,10000);
     BitmapContainer bc2 = new BitmapContainer();
@@ -87,9 +87,9 @@ public void testANDNOT() {
     bc3.clear();
     assertEquals(0, bc3.getCardinality());
   }
-  
 
-  @Test  
+
+  @Test
   public void testAND() {
     BitmapContainer bc = new BitmapContainer(100,10000);
     BitmapContainer bc2 = new BitmapContainer();
@@ -107,9 +107,9 @@ public void testAND() {
     assertEquals(0, bc.iand(bc3).getCardinality());
   }
 
-  
 
-  @Test  
+
+  @Test
   public void testOR() {
     BitmapContainer bc = new BitmapContainer(100,10000);
     BitmapContainer bc2 = new BitmapContainer();
@@ -195,7 +195,7 @@ public void runConstructorForBitmap() {
         assertEquals(0,bc2.remove(start, end).getCardinality());
         assertEquals(bc2.getCardinality(), end-start);
         assertEquals(0,bc2.not(start, end).getCardinality());
-      }  
+      }
     }
   }
 
@@ -215,7 +215,7 @@ public void runConstructorForBitmap2() {
         assertEquals(0,bc2.remove(start, end).getCardinality());
         assertEquals(bc2.getCardinality(), end-start);
         assertEquals(0,bc2.not(start, end).getCardinality());
-      }  
+      }
     }
   }
 
@@ -307,10 +307,10 @@ public void numberOfRunsLowerBound1() {
       /*
        * the unrolled guys are commented out, did not help performance and slated for removal
        * soon...
-       * 
+       *
        * assertTrue(bc.numberOfRunsLowerBoundUnrolled2(1) > 1);
        * assertTrue(bc.numberOfRunsLowerBoundUnrolled2(100) <= bc.numberOfRuns());
-       * 
+       *
        * assertEquals(bc.numberOfRunsLowerBound(100000),
        * bc.numberOfRunsLowerBoundUnrolled2(100000));
        */
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java
index 6ddbcc4e8..d747f0897 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java
@@ -36,7 +36,7 @@ public void testNames() {
     assertEquals(new ArrayContainer().getContainerName(), Container.ContainerNames[1]);
     assertEquals(new RunContainer().getContainerName(), Container.ContainerNames[2]);
   }
-  
+
   public static boolean checkContent(Container c, char[] s) {
     CharIterator si = c.getCharIterator();
     int ctr = 0;
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestForEach.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestForEach.java
index 3279d4fa1..2039f05c9 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestForEach.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestForEach.java
@@ -24,7 +24,7 @@ public void accept(int value) {
     });
     assertEquals(cardinality.value, bitmap.getCardinality());
   }
-  
+
   @Test
   public void testDense() {
     RoaringBitmap bitmap = new RoaringBitmap();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java
index a64eacba7..466c9f495 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java
@@ -81,7 +81,7 @@ public void testIteration() {
 
     IntIteratorFlyweight iter = new IntIteratorFlyweight();
     iter.wrap(bitmap);
-    
+
     IntIteratorFlyweight iter2 = new IntIteratorFlyweight(bitmap);
     PeekableIntIterator j = bitmap.getIntIterator();
     for(int k = 0; k < data.length; k+=3) {
@@ -89,7 +89,7 @@ public void testIteration() {
       iter2.advanceIfNeeded(data[k]);
       j.advanceIfNeeded(data[k]);
       j.advanceIfNeeded(data[k]);
-      assertEquals(j.peekNext(),data[k]);            
+      assertEquals(j.peekNext(),data[k]);
       assertEquals(iter2.peekNext(),data[k]);
     }
     new IntIteratorFlyweight(bitmap).advanceIfNeeded(-1);
@@ -125,7 +125,7 @@ public void testIterationFromBitmap() {
     IntIteratorFlyweight iter = new IntIteratorFlyweight(bitmap);
     assertEquals(iter.peekNext(),data[0]);
     assertEquals(iter.peekNext(),data[0]);
-    
+
     IntIteratorFlyweight iter2 = new IntIteratorFlyweight(bitmap);
     PeekableIntIterator j = bitmap.getIntIterator();
     for(int k = 0; k < data.length; k+=3) {
@@ -136,7 +136,7 @@ public void testIterationFromBitmap() {
       assertEquals(j.peekNext(),data[k]);
       assertEquals(iter2.peekNext(),data[k]);
     }
-    
+
     ReverseIntIteratorFlyweight reverseIter = new ReverseIntIteratorFlyweight(bitmap);
 
     final List intIteratorCopy = asList(iter);
@@ -176,7 +176,7 @@ public void testIterationFromBitmapClone() {
 
     assertEquals(Ints.asList(data), intIteratorCopy);
     assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy);
-  }  
+  }
   @Test
   public void testIterationSmall() {
 
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
index 81b6fa611..047d8f2fa 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
@@ -110,7 +110,7 @@ public void testSmallIteration() {
     assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy);
     assertEquals(ImmutableList.of(3, 2, 1), reverseIntIteratorCopy);
   }
-  
+
   @Test
   public void testSkips() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
@@ -134,7 +134,7 @@ public void testSkips() {
     }
     bitmap.getIntIterator().advanceIfNeeded(-1);// should not crash
   }
-  
+
   @Test
   public void testSkipsDense() {
     RoaringBitmap bitmap = new RoaringBitmap();
@@ -185,7 +185,7 @@ public void testSkipsRun() {
       assertEquals(pii.next(), i);
     }
   }
-  
+
   @Test
   public void testIndexIterator4() throws Exception {
       RoaringBitmap b = new RoaringBitmap();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRange.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRange.java
index 850559ac1..cfbb6e8e6 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRange.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRange.java
@@ -755,7 +755,7 @@ public void testStaticSetRanges() {
 
     /* nb on 20 April 2016, all unit tests above [then] were switched from
      * the original int-range functions to the wrapper int-range functions
-     * without test errors.  Then all code above switched use longs for 
+     * without test errors.  Then all code above switched use longs for
      * range endpoints, again without test errors.
      *
      * Below, check the deprecated versions for undocumented behaviours that
@@ -864,13 +864,13 @@ public void testDeprecatedIteratorAnd() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full overlap is on 300000 to 399999
 
-      RoaringBitmap result = RoaringBitmap.and(list.iterator(), 350000L,  450000L); 
+      RoaringBitmap result = RoaringBitmap.and(list.iterator(), 350000L,  450000L);
       RoaringBitmap resultInt = RoaringBitmap.and(list.iterator(), 350000,  450000);
 
     assertEquals(result, resultInt);
       assertEquals(50000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = RoaringBitmap.and(list.iterator(), 300000, 200000);
       result = RoaringBitmap.and(list.iterator(), 300000L, 200000L);
@@ -893,13 +893,13 @@ public void testDeprecatedIteratorOr() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full union is 200000 to 499999
 
-      RoaringBitmap result = RoaringBitmap.or(list.iterator(), 250000L,  550000L); 
+      RoaringBitmap result = RoaringBitmap.or(list.iterator(), 250000L,  550000L);
       RoaringBitmap resultInt = RoaringBitmap.or(list.iterator(), 250000,  550000);
 
     assertEquals(result, resultInt);
       assertEquals(250000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = RoaringBitmap.or(list.iterator(), 300000, 200000);
       result = RoaringBitmap.or(list.iterator(), 300000L, 200000L);
@@ -922,13 +922,13 @@ public void testDeprecatedIteratorAndNot() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full andNOToverlap is on 200000 to 299999
 
-      RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, 250000L,  450000L); 
+      RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, 250000L,  450000L);
       RoaringBitmap resultInt = RoaringBitmap.andNot(rb1, rb2, 250000,  450000);
 
     assertEquals(result, resultInt);
       assertEquals(50000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = RoaringBitmap.andNot(rb1, rb2, 300000, 200000);
       result = RoaringBitmap.andNot(rb1, rb2, 300000L, 200000L);
@@ -951,13 +951,13 @@ public void testDeprecatedIteratorXor() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full XOR is 200000 to 299999, 400000-4999999
 
-      RoaringBitmap result = RoaringBitmap.xor(list.iterator(), 250000L,  450000L); 
+      RoaringBitmap result = RoaringBitmap.xor(list.iterator(), 250000L,  450000L);
       RoaringBitmap resultInt = RoaringBitmap.xor(list.iterator(), 250000,  450000);
 
     assertEquals(result, resultInt);
       assertEquals(100000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = RoaringBitmap.xor(list.iterator(), 300000, 200000);
       result = RoaringBitmap.xor(list.iterator(), 300000L, 200000L);
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
index f6d8966d1..71df25e64 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
@@ -5519,4 +5519,16 @@ public void test2345() {
         assertEquals(r,  RoaringBitmap.bitmapOf(2, 3, 4, 5));
     }
 
+
+    @Test
+    public void testSelectRange() {
+        RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 1000000);
+        for(int i = 1; i <= 1000000; i+= 1000) {
+            for(int j = i; j <= 1000000; j+= 1000) {
+                RoaringBitmap rr = r.selectRange(i, j);
+                assertEquals(rr, RoaringBitmap.bitmapOfRange(i, j));
+            }
+        }
+    }
+
 }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java
index 3dd0b8652..84f61c59b 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java
@@ -496,16 +496,16 @@ public void testLongSizeInBytes() {
 
     // Check when empty
     assertEquals(16, fast.getLongSizeInBytes());
-    
+
     fast.add(0);
     fast.add(1024);
     fast.add(Integer.MAX_VALUE);
 
     assertEquals(34, fast.getLongSizeInBytes());
-    
+
     // Compute a rank: the cache is allocated
     fast.rank(1024);
-    
+
     // Check the size is bigger once the cache is allocated
     assertEquals(42, fast.getLongSizeInBytes());
   }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerialization.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerialization.java
index 1cdd714b3..20f39f457 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerialization.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerialization.java
@@ -109,7 +109,7 @@ public class TestSerialization {
   static ByteBuffer outbb;
 
   static ByteBuffer presoutbb;
-  
+
   // Very small buffer to higher to chance to encounter edge-case
   byte[] buffer = new byte[16];
 
@@ -347,7 +347,7 @@ public void testMutableRunSerializationBasicDeserialization() throws java.io.IOE
       bitmap_a.add(k); // bitmap density and too many little runs
       bitmap_ar.add(k);
       bitmap_am.add(k);
-      bitmap_amr.add(k);    
+      bitmap_amr.add(k);
     }
 
     bitmap_ar.runOptimize();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java
index 0d942861d..34c4d9192 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java
@@ -5,7 +5,7 @@
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class TestSerializedSize {
-  
+
   @Test
   public void testLucaSize() {
     System.out.println("testLucaSize");
@@ -88,7 +88,7 @@ public void testManyRanges() {
       for (long step = 1; step < 500; ++step) {
         RoaringBitmap rb = new RoaringBitmap();
         int universe_size = 0;
-        
+
         for (int i = 0; i < step; ++i) {
           final int maxv = i * (1 << 16) + stepsize;
           rb.add(i * (1L << 16), i * (1L << 16) + stepsize);
@@ -124,7 +124,7 @@ private static int[] firstPrimes(int n) {
     }
     return answer;
   }
-  
+
   @Test
   public void testPrimeSerializedSize() {
     System.out.println("[testPrimeSerializedSize]");
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java
index 29a47975f..1c5a494a6 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java
@@ -13,7 +13,7 @@ public void testSelect() {
     assertEquals(-2, map.select(-2));
     assertEquals(-1, map.select(-1));
   }
-  
+
   @Test // this should run fine given enough memory
   public void stupidlyLarge() {
     try {
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java
index 3674be408..315fae9dc 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java
@@ -97,7 +97,7 @@ public void testPriorityQueueXor() {
       BufferFastAggregation.priorityqueue_xor(data1);
     });
   }
-  
+
 
   @Test
   public void testNaiveAndMapped() {
@@ -137,7 +137,7 @@ public void testPriorityQueueOrMapped() {
     data6.add(data1);
     assertEquals(data1, BufferFastAggregation.priorityqueue_or(data6.iterator()));
   }
-  
+
   public void testBigOrMapped() {
     MutableRoaringBitmap rb1 = new MutableRoaringBitmap();
     MutableRoaringBitmap rb2 = new MutableRoaringBitmap();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java
index 2c4d7f2a4..94945668f 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java
@@ -12,7 +12,7 @@ public class TestForEach {
   public void testContinuous() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
     bitmap.add(100L, 10000L);
-  
+
     final MutableInteger cardinality = new MutableInteger();
     bitmap.forEach(new IntConsumer() {
       int expected = 100;
@@ -29,7 +29,7 @@ public void testDense() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
     for(int k = 0; k < 100000; k+=3)
       bitmap.add(k);
-  
+
     final MutableInteger cardinality = new MutableInteger();
     bitmap.forEach(new IntConsumer() {
       int expected = 0;
@@ -41,14 +41,14 @@ public void accept(int value) {
       }});
     assertEquals(cardinality.value, bitmap.getCardinality());
   }
-  
+
 
   @Test
   public void testSparse() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
     for(int k = 0; k < 100000; k+=3000)
       bitmap.add(k);
-  
+
     final MutableInteger cardinality = new MutableInteger();
     bitmap.forEach(new IntConsumer() {
       int expected = 0;
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
index 6af7d67d8..dff17730a 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
@@ -1112,13 +1112,13 @@ public void testDeprecatedIteratorAnd() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full overlap is on 300000 to 399999
 
-      MutableRoaringBitmap result = ImmutableRoaringBitmap.and(list.iterator(), 350000L,  450000L); 
+      MutableRoaringBitmap result = ImmutableRoaringBitmap.and(list.iterator(), 350000L,  450000L);
       MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.and(list.iterator(), 350000,  450000);
 
     assertEquals(result, resultInt);
       assertEquals(50000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = ImmutableRoaringBitmap.and(list.iterator(), 300000, 200000);
       result = ImmutableRoaringBitmap.and(list.iterator(), 300000L, 200000L);
@@ -1141,14 +1141,14 @@ public void testDeprecatedIteratorOr() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full union is 200000 to 499999
 
-      MutableRoaringBitmap result = ImmutableRoaringBitmap.or(list.iterator(), 250000L,  550000L); 
+      MutableRoaringBitmap result = ImmutableRoaringBitmap.or(list.iterator(), 250000L,  550000L);
       MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.or(list.iterator(), 250000,  550000);
 
 
     assertEquals(result, resultInt);
       assertEquals(250000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = ImmutableRoaringBitmap.or(list.iterator(), 300000, 200000);
       result = ImmutableRoaringBitmap.or(list.iterator(), 300000L, 200000L);
@@ -1171,13 +1171,13 @@ public void testDeprecatedIteratorAndNot() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full andNOToverlap is on 200000 to 299999
 
-      MutableRoaringBitmap result = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000L,  450000L); 
+      MutableRoaringBitmap result = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000L,  450000L);
       MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000,  450000);
 
     assertEquals(result, resultInt);
       assertEquals(50000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = ImmutableRoaringBitmap.andNot(rb1, rb2, 300000, 200000);
       result = ImmutableRoaringBitmap.andNot(rb1, rb2, 300000L, 200000L);
@@ -1200,13 +1200,13 @@ public void testDeprecatedIteratorXor() {
       rb1.add(200000L, 400000L);  // two normal positive ranges
       rb2.add(300000L, 500000L);  // full XOR is 200000 to 299999, 400000-4999999
 
-      MutableRoaringBitmap result = ImmutableRoaringBitmap.xor(list.iterator(), 250000L,  450000L); 
+      MutableRoaringBitmap result = ImmutableRoaringBitmap.xor(list.iterator(), 250000L,  450000L);
       MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.xor(list.iterator(), 250000,  450000);
 
     assertEquals(result, resultInt);
       assertEquals(100000, result.getCardinality());
 
-      
+
       // empty ranges get empty result
       resultInt = ImmutableRoaringBitmap.xor(list.iterator(), 300000, 200000);
       result = ImmutableRoaringBitmap.xor(list.iterator(), 300000L, 200000L);
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
index 510e0d292..2573b96cf 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
@@ -199,8 +199,8 @@ public void testSmallIteration1() {
     assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy);
     assertEquals(ImmutableList.of(3, 2, 1), reverseIntIteratorCopy);
   }
-  
-  
+
+
   @Test
   public void testSkips() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
@@ -224,7 +224,7 @@ public void testSkips() {
     }
     bitmap.getIntIterator().advanceIfNeeded(-1);
   }
-  
+
   @Test
   public void testSkipsDense() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
@@ -266,14 +266,14 @@ public void testSkipsRun() {
       assertEquals(pii.next(), i);
     }
   }
-  
+
   @Test
   public void testEmptySkips() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
     PeekableIntIterator it = bitmap.getIntIterator();
     it.advanceIfNeeded(0);
   }
-  
+
   @Test
   public void testIteratorsOnLargeBitmap() throws IOException {
       MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
@@ -296,7 +296,7 @@ public void testIteratorsOnLargeBitmap() throws IOException {
       for (int i : bitmap) {
           j += i;
       }
-      
+
       int jj = 0;
 
       // we can iterate over the immutable bitmap
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java
index 722e2808f..02b7090ad 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java
@@ -58,7 +58,7 @@ public void iaddSanityTest() {
     ac = ac.iadd(1, 20);
     assertEquals(79, ac.getCardinality());
   }
-  
+
   @Test
   public void remove() {
     MappeableContainer ac = new MappeableArrayContainer();
@@ -332,7 +332,7 @@ public void testContainsRunContainer_Issue723Case2() {
     MappeableContainer rc = new MappeableRunContainer().add(5,11);
     assertFalse(ac.contains(rc));
   }
-  
+
   @Test
   public void iorNotIncreaseCapacity() {
     MappeableArrayContainer ac1 = new MappeableArrayContainer();
@@ -340,13 +340,13 @@ public void iorNotIncreaseCapacity() {
     ac1.add((char) 128);
     ac1.add((char) 256);
     ac2.add((char) 1024);
-    
+
     ac1.ior(ac2);
     assertTrue(ac1.contains((char) 128));
     assertTrue(ac1.contains((char) 256));
     assertTrue(ac1.contains((char) 1024));
   }
-  
+
   @Test
   public void iorIncreaseCapacity() {
     MappeableArrayContainer ac1 = new MappeableArrayContainer();
@@ -356,7 +356,7 @@ public void iorIncreaseCapacity() {
     ac1.add((char) 512);
     ac1.add((char) 513);
     ac2.add((char) 1024);
-    
+
     ac1.ior(ac2);
     assertTrue(ac1.contains((char) 128));
     assertTrue(ac1.contains((char) 256));
@@ -364,7 +364,7 @@ public void iorIncreaseCapacity() {
     assertTrue(ac1.contains((char) 513));
     assertTrue(ac1.contains((char) 1024));
   }
-  
+
   @Test
   public void iorSanityCheck() {
     MappeableContainer ac = new MappeableArrayContainer().add(0, 10);
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java
index 414c67560..c8c8f2911 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java
@@ -52,8 +52,8 @@ public void testToString() {
     String s = bc2.toString();
     assertEquals("{5,6,7,8,9,10,11,12,13,14,65517,65533}", s);
   }
-  
-  @Test  
+
+  @Test
   public void testXOR() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -69,8 +69,8 @@ public void testXOR() {
     bc = (MappeableBitmapContainer) bc.ixor(bc2);
     assertEquals(0, bc.ixor(bc3).getCardinality());
   }
-  
-  @Test  
+
+  @Test
   public void testANDNOT() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -90,14 +90,14 @@ public void testANDNOT() {
     bc3.clear();
     assertEquals(0, bc3.getCardinality());
   }
-  
 
-  @Test  
+
+  @Test
   public void testAND() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
     MappeableBitmapContainer bc3 = new MappeableBitmapContainer();
-    
+
 
     for(int i = 100; i < 10000; ++i) {
       if((i%2 ) == 0) {
@@ -114,9 +114,9 @@ public void testAND() {
     assertEquals(0, bc.iand(bc3).getCardinality());
   }
 
-  
 
-  @Test  
+
+  @Test
   public void testOR() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -145,7 +145,7 @@ private static void removeArray(MappeableBitmapContainer bc) {
     bc.bitmap = array;
   }
 
-  @Test  
+  @Test
   public void testXORNoArray() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -163,8 +163,8 @@ public void testXORNoArray() {
     bc = (MappeableBitmapContainer) bc.ixor(bc2);
     assertEquals(0, bc.ixor(bc3).getCardinality());
   }
-  
-  @Test  
+
+  @Test
   public void testANDNOTNoArray() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -182,9 +182,9 @@ public void testANDNOTNoArray() {
     bc = (MappeableBitmapContainer) bc.iandNot(bc2);
     assertEquals(bc, bc3);
   }
-  
 
-  @Test  
+
+  @Test
   public void testANDNoArray() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -206,9 +206,9 @@ public void testANDNoArray() {
     assertEquals(0, bc.iand(bc3).getCardinality());
   }
 
-  
 
-  @Test  
+
+  @Test
   public void testORNoArray() {
     MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000);
     MappeableBitmapContainer bc2 = new MappeableBitmapContainer();
@@ -228,7 +228,7 @@ public void testORNoArray() {
     bc2 = (MappeableBitmapContainer) bc2.ior(bc);
     assertEquals(bc, bc2);
   }
-  
+
   @Test
   public void runConstructorForBitmap() {
     System.out.println("runConstructorForBitmap");
@@ -248,10 +248,10 @@ public void runConstructorForBitmap() {
         assertEquals(bc2.getCardinality(), end-start);
         assertEquals(0,bc2.not(start, end).getCardinality());
 
-      }  
+      }
     }
   }
-  
+
   @Test
   public void runConstructorForBitmap2() {
     System.out.println("runConstructorForBitmap2");
@@ -270,7 +270,7 @@ public void runConstructorForBitmap2() {
         assertEquals(0,bc2.remove(start, end).getCardinality());
         assertEquals(bc2.getCardinality(), end-start);
         assertEquals(0,bc2.not(start, end).getCardinality());
-      }  
+      }
     }
   }
 
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java
index 7ded57cf3..1605cabfc 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java
@@ -414,7 +414,7 @@ public void run() {
       }
     }
   }
-  
+
 
   @Test
   public void containsTest() throws IOException  {
@@ -426,7 +426,7 @@ public void containsTest() throws IOException  {
       for(int k = 100000; k < 200000; k+=2)
         rr1.add(k + z);
       for(int k = 400000; k < 500000; k++)
-        rr1.add(k + z);    
+        rr1.add(k + z);
       rr1.runOptimize();
       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       DataOutputStream dos = new DataOutputStream(bos);
@@ -441,7 +441,7 @@ public void containsTest() throws IOException  {
       }
     }
   }
-  
+
 
   @Test
   public void oneFormat() throws IOException {
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java
index c5f8c2f9a..b606d97a0 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java
@@ -20,7 +20,7 @@ public void flip64() {
     assertEquals(1, i.next());
     assertFalse(i.hasNext());
   }
-  
+
   @Test
   @SuppressWarnings( "deprecation" )
   public void testDeprecatedMemberFlip() {
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
index b04136424..3c4c387bb 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
@@ -38,7 +38,7 @@ public void testRangeCardinality() {
 			  }
 		  }
   }
-  
+
   @Test
   public void testRangeCardinality2() {
 		MutableRoaringBitmap r = new MutableRoaringBitmap();
@@ -50,8 +50,8 @@ public void testRangeCardinality2() {
 				 assertEquals(e - s, r.rangeCardinality(s, e));
 			  }
 		  }
-  }	
-  
+  }
+
   @Test
   public void testMultipleAdd() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
@@ -61,8 +61,8 @@ public void testMultipleAdd() {
     bitmap.add(0xFFFFFFFEL,0xFFFFFFFFL);
     assertEquals("{1,2,3,4294967294,4294967295}",bitmap.toString());
   }
-    
-  @Test 
+
+  @Test
   public void binaryTest() throws IOException {
     Random rand = new Random(1234);
     rand.setSeed(11111);
@@ -100,7 +100,7 @@ public void binaryTest() throws IOException {
       assertEquals(ImmutableRoaringBitmap.or(rrback1, rrback2),
           MutableRoaringBitmap.or(rr1, rr2));
       assertEquals(ImmutableRoaringBitmap.or(rrback2, rrback1),
-          MutableRoaringBitmap.or(rr2, rr1));      
+          MutableRoaringBitmap.or(rr2, rr1));
     }
   }
 
@@ -113,7 +113,7 @@ public void testStringer() {
 	    bitmap.add(0xFFFFFFFF);
 	    assertEquals("{1,2,3,4294967295}",bitmap.toString());
 	}
-	
+
 	@Test
 	public  void report128() {
 	    MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
@@ -127,7 +127,7 @@ public  void report128() {
         assertEquals(101993170, it.next());
         assertFalse(it.hasNext());
 	}
-	
+
 	@Test
 	public  void report128_fly() {
 	    MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
@@ -164,7 +164,7 @@ class MyConsumer implements IntConsumer {
 		assertEquals(1000000,limited.toArray().length);
 
 	}
-  
+
   @Test
   public void limitTest() {
     MutableRoaringBitmap r = new MutableRoaringBitmap();
@@ -177,7 +177,7 @@ public void limitTest() {
     assertEquals(100000,r.limit(100000).getCardinality());
     assertEquals(1000000,r.limit(1000000).getCardinality());
   }
-  
+
   @Test
   public void pointerContainerTest() {
     MutableRoaringBitmap rb = new MutableRoaringBitmap();
@@ -189,7 +189,7 @@ public void pointerContainerTest() {
     }
     for (int i = 2*(1 << 16); i < 3*((1 << 16)); i++) {
       rb.add(i);
-    }    
+    }
     rb.runOptimize();
     MappeableContainerPointer cp = rb.getContainerPointer();
     MappeableContainerPointer cpo =  (MappeableContainerPointer) cp.clone();
@@ -197,7 +197,7 @@ public void pointerContainerTest() {
     assertNotEquals(cpo.getContainer(), null);
 
     assertEquals(cp.compareTo(cpo),0);
-    
+
     assertEquals(cp.getCardinality(), (1<<16)/2);
     assertTrue(cp.isBitmapContainer());
     assertFalse(cp.isRunContainer());
@@ -224,7 +224,7 @@ public void pointerContainerTest() {
     cp.advance();
 
     assertEquals(cp.getContainer(), null);
-    
+
   }
   @Test
   public void pointerImmutableContainerTest() {
@@ -237,7 +237,7 @@ public void pointerImmutableContainerTest() {
     }
     for (int i = 2*(1 << 16); i < 3*((1 << 16)); i++) {
       rb.add(i);
-    }    
+    }
     rb.runOptimize();
     ImmutableRoaringBitmap irb =toMapped(rb);
     MappeableContainerPointer cp = irb.getContainerPointer();
@@ -246,7 +246,7 @@ public void pointerImmutableContainerTest() {
     assertNotEquals(cpo.getContainer(), null);
 
     assertEquals(cp.compareTo(cpo),0);
-    
+
     assertEquals(cp.getCardinality(), (1<<16)/2);
     assertTrue(cp.isBitmapContainer());
     assertFalse(cp.isRunContainer());
@@ -273,9 +273,9 @@ public void pointerImmutableContainerTest() {
     cp.advance();
 
     assertEquals(cp.getContainer(), null);
-    
+
   }
-  
+
   private static ImmutableRoaringBitmap toMapped(MutableRoaringBitmap r) {
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     DataOutputStream dos = new DataOutputStream(bos);
@@ -308,7 +308,7 @@ public void conversionTest() {
     assertEquals(rb, rb2);
     ImmutableRoaringBitmap irb = toMapped(mrb);
     assertEquals(irb.toRoaringBitmap(), rb2);
-    
+
   }
 
    @Test
@@ -1567,7 +1567,7 @@ public void basictest() {
     rr.add(110000);
     a[pos++] = 110000;
     final int[] array = rr.toArray();
- 
+
     assertTrue(Arrays.equals(array, a));
   }
 
@@ -1995,7 +1995,7 @@ public void flipTestBigInt() {
     final MutableRoaringBitmap rb = new MutableRoaringBitmap();
     rb.add((int) (Integer.MAX_VALUE + 100000L));
     rb.add((int) (Integer.MAX_VALUE + 100002L));
-    final MutableRoaringBitmap rb2 = MutableRoaringBitmap.flip(rb, Integer.MAX_VALUE+100001L , 
+    final MutableRoaringBitmap rb2 = MutableRoaringBitmap.flip(rb, Integer.MAX_VALUE+100001L ,
                                                      Integer.MAX_VALUE+200000L);
     assertEquals(99999, rb2.getCardinality());
     assertTrue(rb2.contains((int) (Integer.MAX_VALUE + 100000L)));
@@ -2979,7 +2979,7 @@ public void testIteratorBigInts() {
 
 
 
-  
+
   @Test
   public void testIteratorMapped() {
     MutableRoaringBitmap orb = new MutableRoaringBitmap();
@@ -3013,7 +3013,7 @@ public void testIteratorMapped() {
     }
     assertTrue(copy2.equals(toMapped(orb)));
   }
- 
+
 
  @Test
   public void testIteratorMappedBigInts() {
@@ -3048,7 +3048,7 @@ public void testIteratorMappedBigInts() {
     }
     assertTrue(copy2.equals(toMapped(orb)));
   }
- 
+
 
 
  @Test
@@ -3745,7 +3745,7 @@ public void testAndCardinality() {
   }
 
   @Test
-  public void addoffset() { 
+  public void addoffset() {
     final MutableRoaringBitmap rb = new MutableRoaringBitmap();
     rb.add(10);
     rb.add(0xFFFF);
@@ -3759,7 +3759,7 @@ public void addoffset() {
       IntIterator i = rb.getIntIterator();
       IntIterator j = rboff.getIntIterator();
       while(i.hasNext() && j.hasNext()) {
-        assertTrue(i.next() + offset ==  j.next());  
+        assertTrue(i.next() + offset ==  j.next());
       }System.out.println("offset = "+offset);
       assertTrue(i.hasNext() ==  j.hasNext());
     }
@@ -3768,7 +3768,7 @@ public void addoffset() {
       IntIterator i = rb.getIntIterator();
       IntIterator j = rboff.getIntIterator();
       while(i.hasNext() && j.hasNext()) {
-      assertTrue(i.next() + offset ==  j.next());  
+      assertTrue(i.next() + offset ==  j.next());
       }
       assertTrue(i.hasNext() ==  j.hasNext());
     }
@@ -3796,7 +3796,7 @@ public void issue418() {
           assertEquals(shifted.getCardinality(), 1);
       }
   }
-  
+
   @Test
   public void addNegativeOffset() {
     final MutableRoaringBitmap rb = new MutableRoaringBitmap();
@@ -4008,4 +4008,15 @@ public void testNextAbsentValueLimit() {
         bitmap.add(-1);
         assertEquals(-1L, bitmap.nextAbsentValue(-1));
     }
+
+    @Test
+    public void testSelectRange() {
+        MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOfRange(1, 1000000);
+        for(int i = 1; i <= 1000000; i+= 1000) {
+            for(int j = i; j <= 1000000; j+= 1000) {
+                MutableRoaringBitmap rr = r.selectRange(i, j);
+                assertEquals(rr, MutableRoaringBitmap.bitmapOfRange(i, j));
+            }
+        }
+    }
 }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
index 6a378df6a..45f476dbb 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
@@ -1488,10 +1488,10 @@ public void not10() {
    * @Test public void safeSerialization() throws Exception { MappeableRunContainer container = new
    * MappeableRunContainer(); container.add((char) 0); container.add((char) 2);
    * container.add((char) 55); container.add((char) 64); container.add((char) 256);
-   * 
+   *
    * ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new
    * ObjectOutputStream(bos); out.writeObject(container);
-   * 
+   *
    * ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream in =
    * new ObjectInputStream(bis); MappeableRunContainer newContainer = (MappeableRunContainer)
    * in.readObject(); assertEquals(container, newContainer);
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java
index 3cb8b6c2c..9a3f727b0 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java
@@ -79,7 +79,7 @@ public void testManyRanges() {
       for (long step = 1; step < 500; ++step) {
         MutableRoaringBitmap rb = new MutableRoaringBitmap();
         int universe_size = 0;
-        
+
         for (int i = 0; i < step; ++i) {
           final int maxv = i * (1 << 16) + stepsize;
           rb.add(i * (1L << 16), i * (1L << 16) + stepsize);
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java
index eeceaa023..b0103b5c1 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java
@@ -21,7 +21,7 @@
 
 @Execution(ExecutionMode.CONCURRENT)
 public class TestUtil {
-  
+
     @Test
     public void testCopy() {
       CharBuffer sb = CharBuffer.allocate(64);
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java
index 334e3c397..a6430366a 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java
@@ -13,7 +13,7 @@ public void testSelect() {
     assertEquals(-2, map.select(-2));
     assertEquals(-1, map.select(-1));
   }
-  
+
   @Test // this should run fine given enough memory
   public void stupidlyLarge() {
     try {
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
index 7470d7a72..db3be66ea 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
@@ -1507,10 +1507,10 @@ public void shouldNotThrowIAE() {
     crossRB.and(referenceRB);
     assertEquals(0, crossRB.getIntCardinality());
   }
-  
-  
-  
-  
+
+
+
+
   @Test
   public void testSkips() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
@@ -1535,7 +1535,7 @@ public void testSkips() {
     bitmap.getLongIterator().advanceIfNeeded(-1); // should not crash
     bitmap.getLongIteratorFrom(-1); // should not crash
   }
-  
+
   @Test
   public void testSkipsDense() {
     Roaring64Bitmap bitmap = new Roaring64Bitmap();
@@ -1561,11 +1561,11 @@ public void testSkipsDense() {
       assertEquals(expected, pii.next());
     }
   }
-  
+
   @Test
   public void testSkipsMultipleHighPoints() {
     Roaring64Bitmap bitmap = new Roaring64Bitmap();
-    
+
     int n = 100000;
     int numHighPoints = 10;
     for(long h = 0; h < numHighPoints; ++h) {
@@ -1595,7 +1595,7 @@ public void testSkipsMultipleHighPoints() {
       }
     }
   }
-  
+
 
   @Test
   public void testSkipsRun() {
@@ -1616,7 +1616,7 @@ public void testSkipsRun() {
       assertEquals(i, pii.next());
     }
   }
-  
+
   @Test
   public void testEmptySkips() {
     Roaring64Bitmap bitmap = new Roaring64Bitmap();
@@ -1625,8 +1625,8 @@ public void testEmptySkips() {
 
     bitmap.getLongIteratorFrom(0);
   }
-  
-  
+
+
   @Test
   public void testSkipsReverse() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
@@ -1651,7 +1651,7 @@ public void testSkipsReverse() {
     bitmap.getReverseLongIterator().advanceIfNeeded(-1);// should not crash
     bitmap.getReverseLongIteratorFrom(-1);// should not crash
   }
-  
+
   @Test
   public void testSkipsDenseReverse() {
     Roaring64Bitmap bitmap = new Roaring64Bitmap();
@@ -1676,11 +1676,11 @@ public void testSkipsDenseReverse() {
       assertEquals(expected, pii.next());
     }
   }
-  
+
   @Test
   public void testSkipsMultipleHighPointsReverse() {
     Roaring64Bitmap bitmap = new Roaring64Bitmap();
-    
+
     int n = 100000;
     int numHighPoints = 10;
     for(long h = 0; h < numHighPoints; ++h) {
@@ -1732,7 +1732,7 @@ public void testSkipsRunReverse() {
       assertEquals(i, pii.next());
     }
   }
-  
+
   @Test
   public void testEmptySkipsReverse() {
     Roaring64Bitmap bitmap = new Roaring64Bitmap();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java
index 6921d1e17..2ae20577f 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java
@@ -1503,12 +1503,12 @@ public void testLongSizeInBytes() {
     map.add(0);
     map.add(2L * Integer.MAX_VALUE);
     map.addRange(8L * Integer.MAX_VALUE, 8L * Integer.MAX_VALUE + 1024);
-    
+
     assertEquals(3, map.getHighToBitmap().size());
 
     // Size with multiple entries
     assertEquals(228, map.getLongSizeInBytes());
-    
+
     // Select does allocate some cache
     map.select(16);
     assertEquals(264, map.getLongSizeInBytes());
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java
index 4b717b435..cd012fbce 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java
@@ -12,9 +12,9 @@
  *    2. high compression ratio for number
  * Given that,we have a table T(c1,c2,c3....Cn). As we know,most database has rowId for each row.
  * then table T is actually  T(rowId,c1,c2,c3,Cn).
- * 1. if column c1 is string, we can encode c1 using dictionary. By bsi, 
+ * 1. if column c1 is string, we can encode c1 using dictionary. By bsi,
  * we can only use 33 bit slice express 2^32 cardinality dim.
- * 2. if column c2 is int32(that is 4Byte), for 1_000_000 rows, the size 
+ * 2. if column c2 is int32(that is 4Byte), for 1_000_000 rows, the size
  * of c2 is more than 3.81MB. however,
  * by bsi, the size might be less than 1MB.
  *
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
index 036ad466c..6c65ce7a3 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
@@ -299,7 +299,7 @@ private ImmutableRoaringBitmap owenGreatEqual(int predicate,
   //  }                         -- we know at this point that COUNT(G) <= k
   //  F = G OR E                      -- might be too many rows in F; check below
   //  if ((n = (COUNT(F) - k) > 0)            -- if n too many rows in F
-  //   {turn off n bits from E in F};           -- throw out some ties to return exactly k rows 
+  //   {turn off n bits from E in F};           -- throw out some ties to return exactly k rows
   public MutableRoaringBitmap topK(ImmutableRoaringBitmap foundSet, int k) {
     ImmutableRoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
     if (k > fixedFoundSet.getLongCardinality() || k < 0) {
@@ -597,7 +597,7 @@ public MutableBitSliceIndex parallelTransposeWithCount(ImmutableRoaringBitmap fo
   }
 
   /**
-   * parallelIn search the given Set values, 
+   * parallelIn search the given Set values,
    * we scan the bsi,if the value in values, we add it to result Bitmap
    *
    * @param parallelism
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java
index 0c2cc1e13..9a03fff53 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java
@@ -86,7 +86,7 @@ public void setValue(int cid, int value) {
 
 
   @Override
-  public void setValues(List> values, 
+  public void setValues(List> values,
       Integer currentMaxValue, Integer currentMinValue) {
     throw new UnsupportedOperationException("ImmutableBSI don't support setValues");
   }
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java
index 7ac2bfd92..6918db24a 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java
@@ -29,7 +29,7 @@ public class MutableBitSliceIndex extends BitSliceIndexBase implements BitmapSli
    * @param bA  bit slices for this bsi.using MutableRoaringBitmap array express
    * @param ebM exits value bitmap,use MutableRoaringBitmap express
    */
-  public MutableBitSliceIndex(int maxValue, int minValue, 
+  public MutableBitSliceIndex(int maxValue, int minValue,
       MutableRoaringBitmap[] bA, MutableRoaringBitmap ebM) {
     this.maxValue = maxValue;
     this.minValue = minValue;
@@ -161,11 +161,11 @@ private void setValueInternal(int columnId, int value) {
   }
 
 
-  public void setValues(List> values, 
+  public void setValues(List> values,
       Integer currentMaxValue, Integer currentMinValue) {
-    OptionalInt maxValue = currentMaxValue != null 
+    OptionalInt maxValue = currentMaxValue != null
         ? OptionalInt.of(currentMaxValue) : values.stream().mapToInt(Pair::getRight).max();
-    OptionalInt minValue = currentMinValue != null 
+    OptionalInt minValue = currentMinValue != null
         ? OptionalInt.of(currentMinValue) : values.stream().mapToInt(Pair::getRight).min();
 
     if (!maxValue.isPresent() || !minValue.isPresent()) {
@@ -281,9 +281,9 @@ public void merge(MutableBitSliceIndex otherBsi) {
     int bitDepth = Integer.max(this.bitCount(), otherBsi.bitCount());
     MutableRoaringBitmap[] newBA = new MutableRoaringBitmap[bitDepth];
     for (int i = 0; i < bitDepth; i++) {
-      MutableRoaringBitmap current = i < this.bA.length 
+      MutableRoaringBitmap current = i < this.bA.length
           ? this.getMutableSlice(i) : new MutableRoaringBitmap();
-      MutableRoaringBitmap other = i < otherBsi.bA.length 
+      MutableRoaringBitmap other = i < otherBsi.bA.length
           ? otherBsi.getMutableSlice(i) : new MutableRoaringBitmap();
       newBA[i] = MutableRoaringBitmap.or(current, other);
       if (this.runOptimized || otherBsi.runOptimized) {
diff --git a/examples/src/main/java/ImmutableRoaringBitmapExample.java b/examples/src/main/java/ImmutableRoaringBitmapExample.java
index d4ebf0a23..85a01747a 100644
--- a/examples/src/main/java/ImmutableRoaringBitmapExample.java
+++ b/examples/src/main/java/ImmutableRoaringBitmapExample.java
@@ -10,7 +10,7 @@ public static void main(String[] args) throws IOException {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         DataOutputStream dos = new DataOutputStream(bos);
         // If there were runs of consecutive values, you could
-        // call rr1.runOptimize(); or rr2.runOptimize(); to improve compression 
+        // call rr1.runOptimize(); or rr2.runOptimize(); to improve compression
         rr1.serialize(dos);
         rr2.serialize(dos);
         dos.close();
diff --git a/examples/src/main/java/MemoryMappingExample.java b/examples/src/main/java/MemoryMappingExample.java
index 187c37e1a..b8cbff3b4 100644
--- a/examples/src/main/java/MemoryMappingExample.java
+++ b/examples/src/main/java/MemoryMappingExample.java
@@ -6,7 +6,7 @@
 
 
 public class MemoryMappingExample {
-    
+
     public static void main(String[] args) throws IOException {
         File tmpfile = File.createTempFile("roaring", "bin");
         tmpfile.deleteOnExit();
@@ -19,14 +19,14 @@ public static void main(String[] args) throws IOException {
         System.out.println("Created the bitmap "+Bitmap2);
         int pos1 = 0; // bitmap 1 is at offset 0
         // If there were runs of consecutive values, you could
-        // call Bitmap1.runOptimize(); to improve compression 
+        // call Bitmap1.runOptimize(); to improve compression
         Bitmap1.serialize(new DataOutputStream(fos));
         int pos2 = Bitmap1.serializedSizeInBytes(); // bitmap 2 will be right after it
         // If there were runs of consecutive values, you could
-        // call Bitmap2.runOptimize(); to improve compression 
+        // call Bitmap2.runOptimize(); to improve compression
         Bitmap2.serialize(new DataOutputStream(fos));
         long totalcount = fos.getChannel().position();
-        if(totalcount != Bitmap1.serializedSizeInBytes() + Bitmap2.serializedSizeInBytes()) 
+        if(totalcount != Bitmap1.serializedSizeInBytes() + Bitmap2.serializedSizeInBytes())
            throw new RuntimeException("This will not happen.");
         System.out.println("Serialized total count = "+totalcount+" bytes");
         fos.close();
diff --git a/examples/src/main/java/SerializeToStringExample.java b/examples/src/main/java/SerializeToStringExample.java
index 63320e8fe..10b8fcfaf 100644
--- a/examples/src/main/java/SerializeToStringExample.java
+++ b/examples/src/main/java/SerializeToStringExample.java
@@ -2,7 +2,7 @@
 * This example shows how to serialize a Roaring bitmap to a String (Java 8)
 *
 *
-* It is not difficult to encode a byte array to a String so that it can be later recovered. 
+* It is not difficult to encode a byte array to a String so that it can be later recovered.
 * A standard way is to use Base 64 : https://en.wikipedia.org/wiki/Base64
 *
 */
@@ -12,23 +12,23 @@
 import java.util.*;
 
 public class SerializeToStringExample {
-    
-    
-    
-    
+
+
+
+
     // This example uses the Base64 class introduced in Java 8. Any byte[] to String encoder would do
     public static void main(String[] args) throws IOException{
-        MutableRoaringBitmap mrb = MutableRoaringBitmap.bitmapOf(1,2,3,1000); 
+        MutableRoaringBitmap mrb = MutableRoaringBitmap.bitmapOf(1,2,3,1000);
         System.out.println("starting with  bitmap "+ mrb);
         ByteBuffer outbb = ByteBuffer.allocate(mrb.serializedSizeInBytes());
         // If there were runs of consecutive values, you could
-        // call mrb.runOptimize(); to improve compression 
+        // call mrb.runOptimize(); to improve compression
         mrb.serialize(outbb);
         //
         outbb.flip();
         String serializedstring = Base64.getEncoder().encodeToString(outbb.array());
         ByteBuffer newbb = ByteBuffer.wrap(Base64.getDecoder().decode(serializedstring));
         ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(newbb);
-        System.out.println("read bitmap "+ irb);        
+        System.out.println("read bitmap "+ irb);
     }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/RandomData.java b/jmh/src/jmh/java/org/roaringbitmap/RandomData.java
index 779f416c4..d44ce5dc0 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/RandomData.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/RandomData.java
@@ -5,7 +5,7 @@
 import java.util.stream.IntStream;
 
 public class RandomData {
-  
+
   private static final SplittableRandom RANDOM = new SplittableRandom(0);
 
   private static final ThreadLocal bits = ThreadLocal.withInitial(() -> new long[1 << 10]);
diff --git a/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java
index 26f656395..d48d2e900 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java
@@ -112,7 +112,7 @@ public static int selectBitPosition(long w, int j) {
 
   /**
    * Given a word w, return the position of the jth true bit.
-   * 
+   *
    * @param w word
    * @param j index
    * @return position of jth true bit in w
@@ -129,7 +129,7 @@ public static int select(long w, int j) {
 
   /**
    * Given a word w, return the position of the jth true bit.
-   * 
+   *
    * @param w word
    * @param j index
    * @return position of jth true bit in w
@@ -147,7 +147,7 @@ public static int select(int w, int j) {
 
   /**
    * Given a word w, return the position of the jth true bit.
-   * 
+   *
    * @param w word
    * @param j index
    * @return position of jth true bit in w
diff --git a/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java b/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java
index a55973fbf..936d695b0 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java
@@ -20,7 +20,7 @@
         })
 @State(Scope.Benchmark)
 public class ContainsRange {
-  
+
   @Param({"8", "32", "8192"})
   int keys;
 
@@ -29,7 +29,7 @@ public class ContainsRange {
 
   @Param({"true", "false"})
   boolean match;
-  
+
   public enum Scenario {
     START {
       @Override
@@ -56,13 +56,13 @@ long getSup(RoaringBitmap bitmap) {
     abstract long getMin(RoaringBitmap bitmap);
     abstract long getSup(RoaringBitmap bitmap);
   }
-  
+
   private RoaringBitmap bitmap;
-  
+
   private long min;
   private long sup;
 
-  
+
   @Setup(Level.Trial)
   public void init() {
     bitmap = RandomData.randomBitmap(keys, 0.3, 0.2);
@@ -90,6 +90,6 @@ public boolean containsViaRank() {
     int endRank = bitmap.rank((int)(sup - 1));
     return endRank - startRank + 1 == sup - min;
   }
-  
-  
+
+
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java
index 09b09c2da..2d63f941f 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java
@@ -40,17 +40,17 @@
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
 /**
- * 
+ *
  * @author Richard Startin
  *
  */
 public class RealDataSerializationBenchmark {
 
-	 public void 
+	 public void
 	    launchBenchmark() throws Exception {
 
 	            Options opt = new OptionsBuilder()
-	                // Specify which benchmarks to run. 
+	                // Specify which benchmarks to run.
 	                // You can be more specific if you'd like to run only one benchmark per test.
 	                .include(this.getClass().getName() + ".*")
 	                // Set the following options as needed
@@ -70,7 +70,7 @@ public class RealDataSerializationBenchmark {
 
 	            new Runner(opt).run();
 	        }
-	 
+
   @State(Scope.Benchmark)
   public static class BenchmarkState {
 
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java
index b1a2a1006..22df8bc22 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java
@@ -19,27 +19,27 @@ public class BitmapToRuncontainerConversions {
 
   /*
    * These are commented out in BitmapContainer and soon be be deleted
-   * 
+   *
    * @Benchmark public int numberOfRunsData1(BenchmarkState benchmarkState) { return
    * benchmarkState.ac1.numberOfRuns(); }
-   * 
+   *
    * @Benchmark public int numberOfRunsData2(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRuns(); }
-   * 
-   * 
+   *
+   *
    * @Benchmark public int numberOfRunsOld1(BenchmarkState benchmarkState) { return
    * benchmarkState.ac1.numberOfRuns_old(); }
-   * 
+   *
    * @Benchmark public int numberOfRunOld2(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRuns_old(); }
-   * 
+   *
    * @Benchmark public int numberOfRunsLowerBound1(BenchmarkState benchmarkState) { return
    * benchmarkState.ac1.numberOfRunsLowerBound(); }
-   * 
-   * 
+   *
+   *
    * @Benchmark public int numberOfRunsLowerBound2(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRunsLowerBound(); }
-   * 
+   *
    */
   @Benchmark
   public int numberOfRunsLowerBound1281(BenchmarkState benchmarkState) {
@@ -55,11 +55,11 @@ public int numberOfRunsLowerBound1282(BenchmarkState benchmarkState) {
 
   /*
    * soon to be deleted...
-   * 
+   *
    * @Benchmark public int numberOfRunsLowerBound5121(BenchmarkState benchmarkState) { return
    * benchmarkState.ac1.numberOfRunsLowerBound512(10); }
-   * 
-   * 
+   *
+   *
    * @Benchmark public int numberOfRunsLowerBound5122(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRunsLowerBound512(1000); }
    */
@@ -72,19 +72,19 @@ public int numberOfRunsAdjustment(BenchmarkState benchmarkState) {
 
   /*
    * soon to be deleted...
-   * 
+   *
    * @Benchmark public int numberOfRunsAdjustmentUnrolled(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRunsAdjustmentUnrolled(); }
-   * 
-   * 
+   *
+   *
    * @Benchmark public int numberOfRunsLowerBoundUnrolled(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRunsLowerBoundUnrolled(); }
-   * 
-   * 
+   *
+   *
    * @Benchmark public int numberOfRunsLowerBoundUnrolled2(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.numberOfRunsLowerBoundUnrolled2(); }
-   * 
-   * 
+   *
+   *
    * @Benchmark public int numberOfRunsLowerBoundUnrolled2threshold1000(BenchmarkState
    * benchmarkState) { return benchmarkState.ac2.numberOfRunsLowerBoundUnrolled2(1000); }
    */
@@ -104,7 +104,7 @@ public int runOptimize(BenchmarkState benchmarkState) {
   /*
    * @Benchmark public int runOptimizeOld(BenchmarkState benchmarkState) { return
    * benchmarkState.ac2.runOptimize_old() instanceof RunContainer ? 1 : 0; }
-   * 
+   *
    */
 
   @Benchmark
@@ -115,7 +115,7 @@ public int runOptimize1(BenchmarkState benchmarkState) {
   /*
    * @Benchmark public int runOptimizeOld1(BenchmarkState benchmarkState) { return
    * benchmarkState.ac1.runOptimize_old() instanceof RunContainer ? 1 : 0; }
-   * 
+   *
    */
 
 
diff --git a/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java b/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java
index eb05b6483..f380bdf7a 100644
--- a/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java
+++ b/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java
@@ -3,7 +3,7 @@
 public final class RealDataset {
 
   private RealDataset() {
-    
+
   }
 
   public static final String CENSUS_INCOME = "census-income";
diff --git a/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java b/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java
index cdffa56bf..053e0055f 100644
--- a/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java
+++ b/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java
@@ -32,7 +32,7 @@ public String getName() {
   }
 
   /**
-   * 
+   *
    * Returns next range from file
    * @return some Iterable
    * @throws IOException it can happen

From 8d4155d29426d70a77249f6dc8a319613dd1e3c7 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 20 Jun 2024 15:10:38 -0400
Subject: [PATCH 069/167] version bump

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 086359b04..00f5d622e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.1.1-SNAPSHOT
+version = 1.2.0-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From b7b1ded6af1f2c909a454f15f4a4ff9286e15407 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 20 Jun 2024 15:11:57 -0400
Subject: [PATCH 070/167] [Gradle Release Plugin] - pre tag commit:  '1.2.0'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 00f5d622e..828ec1302 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.0-SNAPSHOT
+version = 1.2.0
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 799365ff58aa02b42ba6defe9569a81d4384f9d2 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 20 Jun 2024 15:12:00 -0400
Subject: [PATCH 071/167] [Gradle Release Plugin] - new version commit: 
 '1.2.1-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 828ec1302..bd6477a68 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.0
+version = 1.2.1-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 24790bc325a5b58f3b13d4d06b3a0bd78eb3f840 Mon Sep 17 00:00:00 2001
From: "Shane Michael Mathews (Work Account)"
 <21181346+smmathews-cision-us@users.noreply.github.com>
Date: Mon, 24 Jun 2024 07:33:07 -0400
Subject: [PATCH 072/167] add getSignedIntIterator to roaring bitmaps  (#729)

* add getSignedIntIterator to roaring bitmaps and use integers above 2^31 in the test iterators.

We sometimes use roaring bitmaps for iterative filtering where the opposite side of the join is sorted using signed comparison. Create a function to peekable int iterator to more easily allow that.

* comment cleanup

* comment cleanup

* @zoltanmeze caught that I meant we skip to the negative numbers when doing a signed int sort, not positive numbers. fixup comment.
---
 .../ImmutableBitmapDataProvider.java          | 14 ++++-
 .../java/org/roaringbitmap/RoaringBitmap.java | 43 ++++++++++---
 .../buffer/ImmutableRoaringBitmap.java        | 61 ++++++++++++++++---
 .../java/org/roaringbitmap/TestIterators.java | 28 ++++++---
 .../roaringbitmap/buffer/TestIterators.java   | 58 +++++++++++-------
 5 files changed, 153 insertions(+), 51 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
index c14591bfb..550a7faa3 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
@@ -65,13 +65,21 @@ public interface ImmutableBitmapDataProvider {
   void forEach(IntConsumer ic);
 
   /**
-   * For better performance, consider the Use the {@link #forEach forEach} method.
-   * @return a custom iterator over set bits, the bits are traversed in ascending sorted order
+   * For better performance, consider using the {@link #forEach forEach} method.
+   * @return a custom iterator over set bits, the bits are traversed in unsigned integer ascending
+   *     sorted order
    */
   PeekableIntIterator getIntIterator();
 
   /**
-   * @return a custom iterator over set bits, the bits are traversed in descending sorted order
+   * @return a custom iterator over set bits, the bits are traversed in signed integer ascending
+   *     sorted order
+   */
+  PeekableIntIterator getSignedIntIterator();
+
+  /**
+   * @return a custom iterator over set bits, the bits are traversed in unsigned integer descending
+   *     sorted order
    */
   IntIterator getReverseIntIterator();
 
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
index fc3a8ab58..a92c2d92c 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
@@ -11,7 +11,6 @@
 import java.io.*;
 import java.nio.ByteBuffer;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
 
 import static org.roaringbitmap.RoaringBitmapWriter.writer;
 import static org.roaringbitmap.Util.lowbitsAsInteger;
@@ -52,6 +51,7 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable
     ImmutableBitmapDataProvider, BitmapDataProvider, AppendableStorage {
 
   private final class RoaringIntIterator implements PeekableIntIterator {
+    private char startingContainerIndex;
     private int hs = 0;
 
     private PeekableCharIterator iter;
@@ -59,6 +59,23 @@ private final class RoaringIntIterator implements PeekableIntIterator {
     private int pos = 0;
 
     private RoaringIntIterator() {
+      this(false);
+    }
+
+    private RoaringIntIterator(final boolean signedIntSort) {
+      char index = 0;
+      if (signedIntSort) {
+        // skip to starting at negative signed integers
+        final int containerSize = RoaringBitmap.this.highLowContainer.size();
+        while (index < containerSize
+            && RoaringBitmap.this.highLowContainer.getKeyAtIndex(index) < (1 << 15)) {
+          ++index;
+        }
+        if(index >= containerSize) {
+          index = 0;
+        }
+      }
+      this.startingContainerIndex = index;
       nextContainer();
     }
 
@@ -91,9 +108,11 @@ public int next() {
     }
 
     private void nextContainer() {
-      if (pos < RoaringBitmap.this.highLowContainer.size()) {
-        iter = RoaringBitmap.this.highLowContainer.getContainerAtIndex(pos).getCharIterator();
-        hs = RoaringBitmap.this.highLowContainer.getKeyAtIndex(pos) << 16;
+      final int containerSize = RoaringBitmap.this.highLowContainer.size();
+      if (pos < containerSize) {
+        final int index = (pos + startingContainerIndex) % containerSize;
+        iter = RoaringBitmap.this.highLowContainer.getContainerAtIndex(index).getCharIterator();
+        hs = RoaringBitmap.this.highLowContainer.getKeyAtIndex(index) << 16;
       }
     }
 
@@ -2111,13 +2130,23 @@ public ContainerPointer getContainerPointer() {
 
   /**
    *
-   * For better performance, consider the Use the {@link #forEach forEach} method.
+   * For better performance, consider using the {@link #forEach forEach} method.
    *
-   * @return a custom iterator over set bits, the bits are traversed in ascending sorted order
+   * @return a custom iterator over set bits, the bits are traversed in unsigned integer ascending
+   *     sorted order
    */
   @Override
   public PeekableIntIterator getIntIterator() {
-    return new RoaringIntIterator();
+    return new RoaringIntIterator(false);
+  }
+
+  /**
+   * @return a custom iterator over set bits, the bits are traversed in signed integer ascending
+   *     sorted order
+   */
+  @Override
+  public PeekableIntIterator getSignedIntIterator() {
+    return new RoaringIntIterator(true);
   }
 
   /**
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
index aa66af9da..b2a573ef0 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
@@ -74,8 +74,9 @@ public class ImmutableRoaringBitmap
     implements Iterable, Cloneable, ImmutableBitmapDataProvider {
 
   private final class ImmutableRoaringIntIterator implements PeekableIntIterator {
-    private MappeableContainerPointer cp =
-        ImmutableRoaringBitmap.this.highLowContainer.getContainerPointer();
+    private boolean wrap;
+    private MappeableContainerPointer cp;
+    private int iterations = 0;
 
     private int hs = 0;
 
@@ -84,6 +85,27 @@ private final class ImmutableRoaringIntIterator implements PeekableIntIterator {
     private boolean ok;
 
     public ImmutableRoaringIntIterator() {
+      this(false);
+    }
+
+    public ImmutableRoaringIntIterator(final boolean signedIntSort) {
+      char index = 0;
+      if (signedIntSort) {
+        wrap = true;
+        // skip to starting at negative signed integers
+        final int containerSize = ImmutableRoaringBitmap.this.highLowContainer.size();
+        while (index < containerSize
+            && ImmutableRoaringBitmap.this.highLowContainer.getKeyAtIndex(index) < (1 << 15)) {
+          ++index;
+        }
+        if(index >= containerSize) {
+          index = 0;
+          wrap = false;
+        }
+      } else {
+        wrap = false;
+      }
+      cp = ImmutableRoaringBitmap.this.highLowContainer.getContainerPointer(index);
       nextContainer();
     }
 
@@ -97,6 +119,8 @@ public PeekableIntIterator clone() {
         if(this.cp != null) {
           x.cp = this.cp.clone();
         }
+        x.wrap = this.wrap;
+        x.iterations = this.iterations;
         return x;
       } catch (CloneNotSupportedException e) {
         return null;// will not happen
@@ -120,10 +144,21 @@ public int next() {
 
 
     private void nextContainer() {
-      ok = cp.hasContainer();
-      if (ok) {
-        iter = cp.getContainer().getCharIterator();
-        hs = (cp.key()) << 16;
+      final int containerSize = ImmutableRoaringBitmap.this.highLowContainer.size();
+      if(wrap || iterations < containerSize) {
+        ok = cp.hasContainer();
+        if (!ok && wrap && iterations < containerSize) {
+          cp = ImmutableRoaringBitmap.this.highLowContainer.getContainerPointer();
+          wrap = false;
+          ok = cp.hasContainer();
+        }
+        if (ok) {
+          iter = cp.getContainer().getCharIterator();
+          hs = (cp.key()) << 16;
+          ++iterations;
+        }
+      } else {
+        ok = false;
       }
     }
 
@@ -1395,11 +1430,21 @@ public MappeableContainerPointer getContainerPointer() {
   /**
    * For better performance, consider the Use the {@link #forEach forEach} method.
    *
-   * @return a custom iterator over set bits, the bits are traversed in ascending sorted order
+   * @return a custom iterator over set bits, the bits are traversed in unsigned integer ascending
+   *     sorted order
    */
   @Override
   public PeekableIntIterator getIntIterator() {
-    return new ImmutableRoaringIntIterator();
+    return new ImmutableRoaringIntIterator(false);
+  }
+
+  /**
+   * @return a custom iterator over set bits, the bits are traversed in signed integer ascending
+   *     sorted order
+   */
+  @Override
+  public PeekableIntIterator getSignedIntIterator() {
+    return new ImmutableRoaringIntIterator(true);
   }
 
 
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
index 047d8f2fa..0552ee5a4 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
@@ -11,10 +11,12 @@
 import com.google.common.primitives.Ints;
 import org.junit.jupiter.api.Test;
 
+import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.LinkedHashSet;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Random;
+import java.util.stream.Collectors;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -53,16 +55,16 @@ public int next() {
   }
 
   private static int[] takeSortedAndDistinct(Random source, int count) {
-    LinkedHashSet ints = new LinkedHashSet(count);
+    HashSet ints = new HashSet(count);
     for (int size = 0; size < count; size++) {
       int next;
       do {
-        next = Math.abs(source.nextInt());
+        next = source.nextInt();
       } while (!ints.add(next));
     }
-    int[] unboxed = Ints.toArray(ints);
-    Arrays.sort(unboxed);
-    return unboxed;
+    ArrayList list = new ArrayList(ints);
+    list.sort(Integer::compareUnsigned);
+    return Ints.toArray(list);
   }
 
   @Test
@@ -77,6 +79,7 @@ public void testBitmapIteration() {
   public void testEmptyIteration() {
     assertFalse(RoaringBitmap.bitmapOf().iterator().hasNext());
     assertFalse(RoaringBitmap.bitmapOf().getIntIterator().hasNext());
+    assertFalse(RoaringBitmap.bitmapOf().getSignedIntIterator().hasNext());
     assertFalse(RoaringBitmap.bitmapOf().getReverseIntIterator().hasNext());
   }
 
@@ -88,27 +91,32 @@ public void testIteration() {
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
+    final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
     assertEquals(bitmap.getCardinality(), iteratorCopy.size());
     assertEquals(bitmap.getCardinality(), intIteratorCopy.size());
+    assertEquals(bitmap.getCardinality(), signedIntIteratorCopy.size());
     assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size());
     assertEquals(Ints.asList(data), iteratorCopy);
     assertEquals(Ints.asList(data), intIteratorCopy);
+    assertEquals(Ints.asList(data).stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy);
     assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy);
   }
 
   @Test
   public void testSmallIteration() {
-    RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1, 2, 3);
+    RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1, 2, 3, -1);
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
+    final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
-    assertEquals(ImmutableList.of(1, 2, 3), iteratorCopy);
-    assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy);
-    assertEquals(ImmutableList.of(3, 2, 1), reverseIntIteratorCopy);
+    assertEquals(ImmutableList.of(1, 2, 3, -1), iteratorCopy);
+    assertEquals(ImmutableList.of(1, 2, 3, -1), intIteratorCopy);
+    assertEquals(ImmutableList.of(-1, 1, 2, 3), signedIntIteratorCopy);
+    assertEquals(ImmutableList.of(-1, 3, 2, 1), reverseIntIteratorCopy);
   }
 
   @Test
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
index 2573b96cf..ec77d5e28 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
@@ -21,6 +21,7 @@
 import java.nio.ByteBuffer;
 import java.nio.LongBuffer;
 import java.util.*;
+import java.util.stream.Collectors;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -61,16 +62,16 @@ public int next() {
 
 
   private static int[] takeSortedAndDistinct(Random source, int count) {
-    LinkedHashSet ints = new LinkedHashSet(count);
+    HashSet ints = new HashSet(count);
     for (int size = 0; size < count; size++) {
       int next;
       do {
-        next = Math.abs(source.nextInt());
+        next = source.nextInt();
       } while (!ints.add(next));
     }
-    int[] unboxed = Ints.toArray(ints);
-    Arrays.sort(unboxed);
-    return unboxed;
+    ArrayList list = new ArrayList(ints);
+    list.sort(Integer::compareUnsigned);
+    return Ints.toArray(list);
   }
 
   // https://github.com/RoaringBitmap/RoaringBitmap/issues/475
@@ -109,6 +110,7 @@ public void testBitmapIteration() {
   public void testEmptyIteration() {
     assertFalse(MutableRoaringBitmap.bitmapOf().iterator().hasNext());
     assertFalse(MutableRoaringBitmap.bitmapOf().getIntIterator().hasNext());
+    assertFalse(MutableRoaringBitmap.bitmapOf().getSignedIntIterator().hasNext());
     assertFalse(MutableRoaringBitmap.bitmapOf().getReverseIntIterator().hasNext());
   }
 
@@ -121,83 +123,93 @@ public void testIteration() {
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
+    final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
     assertEquals(bitmap.getCardinality(), iteratorCopy.size());
     assertEquals(bitmap.getCardinality(), intIteratorCopy.size());
+    assertEquals(bitmap.getCardinality(), signedIntIteratorCopy.size());
     assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size());
     assertEquals(Ints.asList(data), iteratorCopy);
     assertEquals(Ints.asList(data), intIteratorCopy);
+    assertEquals(Ints.asList(data).stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy);
     assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy);
   }
 
 
-
   @Test
   public void testIteration1() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
     final int[] data1 = takeSortedAndDistinct(source, 450000);
-    final int[] data = Arrays.copyOf(data1, data1.length + 50000);
 
-    HashSet data1Members = new HashSet();
+    HashSet data1Members = new HashSet(data1.length);
     for (int i : data1) {
       data1Members.add(i);
     }
+    final List data = new ArrayList<>(data1.length + 50000);
+    data.addAll(data1Members);
 
     int counter = 77777;
-    for (int i = data1.length; i < data.length; ++i) {
+    for (int i = data1.length; i < data.size(); ++i) {
       // ensure uniqueness
       while (data1Members.contains(counter)) {
         ++counter;
       }
-      data[i] = counter; // must be unique
+      data.set(i, counter); // must be unique
       counter++;
       if (i % 15 == 0) {
         counter += 10; // runs of length 15 or so, with gaps of 10
       }
     }
-    Arrays.sort(data);
+    data.sort(Integer::compareUnsigned);
 
-    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data);
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(Ints.toArray(data));
     bitmap.runOptimize(); // result should have some runcontainers and some non.
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
+    final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
     assertEquals(bitmap.getCardinality(), iteratorCopy.size());
     assertEquals(bitmap.getCardinality(), intIteratorCopy.size());
+    assertEquals(bitmap.getCardinality(), signedIntIteratorCopy.size());
     assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size());
-    assertEquals(Ints.asList(data), iteratorCopy);
-    assertEquals(Ints.asList(data), intIteratorCopy);
-    assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy);
+    assertEquals(data, iteratorCopy);
+    assertEquals(data, intIteratorCopy);
+    assertEquals(data.stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy);
+    assertEquals(Lists.reverse(data), reverseIntIteratorCopy);
   }
 
   @Test
   public void testSmallIteration() {
-    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3);
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3, -1);
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
+    final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
-    assertEquals(ImmutableList.of(1, 2, 3), iteratorCopy);
-    assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy);
-    assertEquals(ImmutableList.of(3, 2, 1), reverseIntIteratorCopy);
+    assertEquals(ImmutableList.of(1, 2, 3, -1), iteratorCopy);
+    assertEquals(ImmutableList.of(1, 2, 3, -1), intIteratorCopy);
+    assertEquals(ImmutableList.of(-1, 1, 2, 3), signedIntIteratorCopy);
+    assertEquals(ImmutableList.of(-1, 3, 2, 1), reverseIntIteratorCopy);
   }
 
   @Test
   public void testSmallIteration1() {
-    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3);
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3, -1);
     bitmap.runOptimize();
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
+    final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
-    assertEquals(ImmutableList.of(1, 2, 3), iteratorCopy);
-    assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy);
-    assertEquals(ImmutableList.of(3, 2, 1), reverseIntIteratorCopy);
+    assertEquals(ImmutableList.of(1, 2, 3, -1), iteratorCopy);
+    assertEquals(ImmutableList.of(1, 2, 3, -1), intIteratorCopy);
+    assertEquals(ImmutableList.of(-1, 1, 2, 3), signedIntIteratorCopy);
+    assertEquals(ImmutableList.of(-1, 3, 2, 1), reverseIntIteratorCopy);
   }
 
 

From 88292e088cac97aa283794c1a6c205210bc8a2a8 Mon Sep 17 00:00:00 2001
From: Shikhar Singh <10097451+shikharid@users.noreply.github.com>
Date: Mon, 1 Jul 2024 19:44:25 +0530
Subject: [PATCH 073/167] fix hasNext behaviour for BitmapBatchIterator (#732)

* adds failing test for issue 730

* fixes BitmapBatchIterator.hasNext to return accurate result for empty containers
---
 .../java/org/roaringbitmap/BitmapBatchIterator.java | 12 +++++++++++-
 .../roaringbitmap/buffer/BitmapBatchIterator.java   | 12 +++++++++++-
 .../roaringbitmap/ContainerBatchIteratorTest.java   | 13 ++++++++++---
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
index be6e64145..59f6a3433 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
@@ -31,7 +31,17 @@ public int next(int key, int[] buffer, int offset) {
 
   @Override
   public boolean hasNext() {
-    return wordIndex < 1024;
+    if (wordIndex > 1023) {
+      return false;
+    }
+    while (word == 0) {
+      ++wordIndex;
+      if (wordIndex == 1024) { // reached end without a non-empty word
+        return false;
+      }
+      word = bitmap.bitmap[wordIndex];
+    }
+    return true; // found some non-empty word, so hasNext
   }
 
   @Override
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java
index e432158ae..d8e26681f 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java
@@ -33,7 +33,17 @@ public int next(int key, int[] buffer, int offset) {
 
   @Override
   public boolean hasNext() {
-    return wordIndex < 1024;
+    if (wordIndex > 1023) {
+      return false;
+    }
+    while (word == 0) {
+      ++wordIndex;
+      if (wordIndex == 1024) { // reached end without a non-empty word
+        return false;
+      }
+      word = bitmap.bitmap.get(wordIndex);
+    }
+    return true; // found some non-empty word, so hasNext
   }
 
   @Override
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java b/RoaringBitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java
index f7a577976..80ee43810 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java
@@ -3,6 +3,7 @@
 
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.Execution;
 import org.junit.jupiter.api.parallel.ExecutionMode;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -14,8 +15,7 @@
 import java.util.stream.Stream;
 
 import static java.util.Arrays.copyOfRange;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.*;
 
 @Execution(ExecutionMode.CONCURRENT)
 public class ContainerBatchIteratorTest {
@@ -148,6 +148,13 @@ public void testAdvanceIfNeeded(int[] expectedValues, int batchSize) {
         assertEquals(expectedValues.length, cardinality);
     }
 
+    // https://github.com/RoaringBitmap/RoaringBitmap/issues/730
+    @Test
+    public void testHasNextBitmapIterator() {
+        BitmapContainer container = new BitmapContainer(); // create an empty container
+        assertFalse(container.getBatchIterator().hasNext());
+    }
+
     private Container createContainer(int[] expectedValues) {
         Container container = new ArrayContainer();
         for (int value : expectedValues) {
@@ -155,4 +162,4 @@ private Container createContainer(int[] expectedValues) {
         }
         return container.runOptimize();
     }
-}
\ No newline at end of file
+}

From 08b1e415758417d4e3dc59ee8a7da1f0c87d2f9b Mon Sep 17 00:00:00 2001
From: Zoltan Meze 
Date: Mon, 8 Jul 2024 15:37:40 +0200
Subject: [PATCH 074/167] Fix advanceIfNeeded in signed int iterators and
 simplify finding starting container index (#734)

* Use advanceUntil to find starting container index

* Allow advanceIfNeeded to wrap around in signed int iterators

* Simplify finding starting container index
---
 .../java/org/roaringbitmap/RoaringBitmap.java | 56 +++++++++-------
 .../buffer/ImmutableRoaringBitmap.java        | 65 ++++++++++---------
 .../java/org/roaringbitmap/TestIterators.java | 50 +++++++++++---
 .../roaringbitmap/buffer/TestIterators.java   | 52 +++++++++++----
 4 files changed, 147 insertions(+), 76 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
index a92c2d92c..a21cf4d9c 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
@@ -50,40 +50,28 @@
 public class RoaringBitmap implements Cloneable, Serializable, Iterable, Externalizable,
     ImmutableBitmapDataProvider, BitmapDataProvider, AppendableStorage {
 
-  private final class RoaringIntIterator implements PeekableIntIterator {
-    private char startingContainerIndex;
+  private class RoaringIntIterator implements PeekableIntIterator {
+    private final char startingContainerIndex;
     private int hs = 0;
 
     private PeekableCharIterator iter;
 
     private int pos = 0;
 
-    private RoaringIntIterator() {
-      this(false);
+    public RoaringIntIterator() {
+      this.startingContainerIndex = findStartingContainerIndex();
+      nextContainer();
     }
 
-    private RoaringIntIterator(final boolean signedIntSort) {
-      char index = 0;
-      if (signedIntSort) {
-        // skip to starting at negative signed integers
-        final int containerSize = RoaringBitmap.this.highLowContainer.size();
-        while (index < containerSize
-            && RoaringBitmap.this.highLowContainer.getKeyAtIndex(index) < (1 << 15)) {
-          ++index;
-        }
-        if(index >= containerSize) {
-          index = 0;
-        }
-      }
-      this.startingContainerIndex = index;
-      nextContainer();
+    char findStartingContainerIndex() {
+      return 0;
     }
 
     @Override
     public PeekableIntIterator clone() {
       try {
         RoaringIntIterator x = (RoaringIntIterator) super.clone();
-        if(this.iter != null) {
+        if (this.iter != null) {
           x.iter = this.iter.clone();
         }
         return x;
@@ -118,7 +106,7 @@ private void nextContainer() {
 
     @Override
     public void advanceIfNeeded(int minval) {
-      while (hasNext() && ((hs >>> 16) < (minval >>> 16))) {
+      while (hasNext() && shouldAdvanceContainer(hs, minval)) {
         ++pos;
         nextContainer();
       }
@@ -131,11 +119,33 @@ public void advanceIfNeeded(int minval) {
       }
     }
 
+    boolean shouldAdvanceContainer(final int hs, final int minval) {
+      return (hs >>> 16) < (minval >>> 16);
+    }
+
     @Override
     public int peekNext() {
       return (iter.peekNext()) | hs;
     }
 
+  }
+
+  private final class RoaringSignedIntIterator extends RoaringIntIterator {
+
+    @Override
+    char findStartingContainerIndex() {
+      // skip to starting at negative signed integers
+      char index = (char) RoaringBitmap.this.highLowContainer.advanceUntil((char) (1 << 15), -1);
+      if (index == RoaringBitmap.this.highLowContainer.size()) {
+        index = 0;
+      }
+      return index;
+    }
+
+    @Override
+    boolean shouldAdvanceContainer(final int hs, final int minval) {
+      return (hs >> 16) < (minval >> 16);
+    }
 
   }
 
@@ -2137,7 +2147,7 @@ public ContainerPointer getContainerPointer() {
    */
   @Override
   public PeekableIntIterator getIntIterator() {
-    return new RoaringIntIterator(false);
+    return new RoaringIntIterator();
   }
 
   /**
@@ -2146,7 +2156,7 @@ public PeekableIntIterator getIntIterator() {
    */
   @Override
   public PeekableIntIterator getSignedIntIterator() {
-    return new RoaringIntIterator(true);
+    return new RoaringSignedIntIterator();
   }
 
   /**
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
index b2a573ef0..d9cbeec36 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
@@ -73,7 +73,7 @@
 public class ImmutableRoaringBitmap
     implements Iterable, Cloneable, ImmutableBitmapDataProvider {
 
-  private final class ImmutableRoaringIntIterator implements PeekableIntIterator {
+  private class ImmutableRoaringIntIterator implements PeekableIntIterator {
     private boolean wrap;
     private MappeableContainerPointer cp;
     private int iterations = 0;
@@ -85,38 +85,24 @@ private final class ImmutableRoaringIntIterator implements PeekableIntIterator {
     private boolean ok;
 
     public ImmutableRoaringIntIterator() {
-      this(false);
-    }
-
-    public ImmutableRoaringIntIterator(final boolean signedIntSort) {
-      char index = 0;
-      if (signedIntSort) {
-        wrap = true;
-        // skip to starting at negative signed integers
-        final int containerSize = ImmutableRoaringBitmap.this.highLowContainer.size();
-        while (index < containerSize
-            && ImmutableRoaringBitmap.this.highLowContainer.getKeyAtIndex(index) < (1 << 15)) {
-          ++index;
-        }
-        if(index >= containerSize) {
-          index = 0;
-          wrap = false;
-        }
-      } else {
-        wrap = false;
-      }
+      char index = findStartingContainerIndex();
+      wrap = index != 0;
       cp = ImmutableRoaringBitmap.this.highLowContainer.getContainerPointer(index);
       nextContainer();
     }
 
+    char findStartingContainerIndex() {
+      return 0;
+    }
+
     @Override
     public PeekableIntIterator clone() {
       try {
         ImmutableRoaringIntIterator x = (ImmutableRoaringIntIterator) super.clone();
-        if(this.iter != null) {
+        if (this.iter != null) {
           x.iter = this.iter.clone();
         }
-        if(this.cp != null) {
+        if (this.cp != null) {
           x.cp = this.cp.clone();
         }
         x.wrap = this.wrap;
@@ -142,10 +128,9 @@ public int next() {
       return x;
     }
 
-
     private void nextContainer() {
       final int containerSize = ImmutableRoaringBitmap.this.highLowContainer.size();
-      if(wrap || iterations < containerSize) {
+      if (wrap || iterations < containerSize) {
         ok = cp.hasContainer();
         if (!ok && wrap && iterations < containerSize) {
           cp = ImmutableRoaringBitmap.this.highLowContainer.getContainerPointer();
@@ -164,7 +149,7 @@ private void nextContainer() {
 
     @Override
     public void advanceIfNeeded(int minval) {
-      while (hasNext() && ((hs >>> 16) < (minval >>> 16))) {
+      while (hasNext() && shouldAdvanceContainer(hs, minval)) {
         cp.advance();
         nextContainer();
       }
@@ -177,14 +162,35 @@ public void advanceIfNeeded(int minval) {
       }
     }
 
+    boolean shouldAdvanceContainer(final int hs, final int minval) {
+      return (hs >>> 16) < (minval >>> 16);
+    }
+
     @Override
     public int peekNext() {
       return (iter.peekNext()) | hs;
     }
 
-
   }
 
+  private class ImmutableRoaringSignedIntIterator extends ImmutableRoaringIntIterator {
+
+    @Override
+    char findStartingContainerIndex() {
+      // skip to starting at negative signed integers
+      char index = (char)
+          ImmutableRoaringBitmap.this.highLowContainer.advanceUntil((char) (1 << 15), -1);
+      if (index == ImmutableRoaringBitmap.this.highLowContainer.size()) {
+        index = 0;
+      }
+      return index;
+    }
+
+    @Override
+    boolean shouldAdvanceContainer(final int hs, final int minval) {
+      return (hs >> 16) < (minval >> 16);
+    }
+  }
 
   private final class ImmutableRoaringReverseIntIterator implements IntIterator {
     private MappeableContainerPointer cp = ImmutableRoaringBitmap.this.highLowContainer
@@ -1435,7 +1441,7 @@ public MappeableContainerPointer getContainerPointer() {
    */
   @Override
   public PeekableIntIterator getIntIterator() {
-    return new ImmutableRoaringIntIterator(false);
+    return new ImmutableRoaringIntIterator();
   }
 
   /**
@@ -1444,10 +1450,9 @@ public PeekableIntIterator getIntIterator() {
    */
   @Override
   public PeekableIntIterator getSignedIntIterator() {
-    return new ImmutableRoaringIntIterator(true);
+    return new ImmutableRoaringSignedIntIterator();
   }
 
-
   /**
    * @return a custom iterator over set bits, the bits are traversed in descending sorted order
    */
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
index 0552ee5a4..7f51d5582 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
@@ -13,6 +13,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Random;
@@ -54,7 +55,7 @@ public int next() {
     });
   }
 
-  private static int[] takeSortedAndDistinct(Random source, int count) {
+  private static int[] takeSortedAndDistinct(Random source, int count, Comparator comparator) {
     HashSet ints = new HashSet(count);
     for (int size = 0; size < count; size++) {
       int next;
@@ -63,7 +64,7 @@ private static int[] takeSortedAndDistinct(Random source, int count) {
       } while (!ints.add(next));
     }
     ArrayList list = new ArrayList(ints);
-    list.sort(Integer::compareUnsigned);
+    list.sort(comparator);
     return Ints.toArray(list);
   }
 
@@ -86,7 +87,7 @@ public void testEmptyIteration() {
   @Test
   public void testIteration() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
-    final int[] data = takeSortedAndDistinct(source, 450000);
+    final int[] data = takeSortedAndDistinct(source, 450000, Integer::compareUnsigned);
     RoaringBitmap bitmap = RoaringBitmap.bitmapOf(data);
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
@@ -121,28 +122,57 @@ public void testSmallIteration() {
 
   @Test
   public void testSkips() {
-    final Random source = new Random(0xcb000a2b9b5bdfb6l);
-    final int[] data = takeSortedAndDistinct(source, 45000);
+    final Random source = new Random(0xcb000a2b9b5bdfb6L);
+    final int[] data = takeSortedAndDistinct(source, 45000, Integer::compareUnsigned);
     RoaringBitmap bitmap = RoaringBitmap.bitmapOf(data);
     PeekableIntIterator pii = bitmap.getIntIterator();
-    for(int i = 0; i < data.length; ++i) {
+    for (int i = 0; i < data.length; ++i) {
       pii.advanceIfNeeded(data[i]);
       assertEquals(data[i], pii.peekNext());
     }
     pii = bitmap.getIntIterator();
-    for(int i = 0; i < data.length; ++i) {
+    for (int i = 0; i < data.length; ++i) {
       pii.advanceIfNeeded(data[i]);
       assertEquals(data[i], pii.next());
     }
     pii = bitmap.getIntIterator();
-    for(int i = 1; i < data.length; ++i) {
-      pii.advanceIfNeeded(data[i-1]);
+    for (int i = 1; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i - 1]);
       pii.next();
-      assertEquals(data[i],pii.peekNext() );
+      assertEquals(data[i], pii.peekNext());
     }
     bitmap.getIntIterator().advanceIfNeeded(-1);// should not crash
   }
 
+  @Test
+  public void testSkipsSignedIterator() {
+    final Random source = new Random(0xcb000a2b9b5bdfb6L);
+    int[] data = takeSortedAndDistinct(source, 45000, Integer::compare);
+    RoaringBitmap bitmap = RoaringBitmap.bitmapOf(data);
+
+    PeekableIntIterator pii = bitmap.getSignedIntIterator();
+    for (int i = 0; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i]);
+      assertEquals(data[i], pii.peekNext());
+    }
+    pii = bitmap.getSignedIntIterator();
+    for (int i = data.length - 1; i >= 0; --i) { // no backward advancing
+      pii.advanceIfNeeded(data[i]);
+      assertEquals(data[data.length - 1], pii.peekNext());
+    }
+    pii = bitmap.getSignedIntIterator();
+    for (int i = 0; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i]);
+      assertEquals(data[i], pii.next());
+    }
+    pii = bitmap.getSignedIntIterator();
+    for (int i = 1; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i - 1]);
+      pii.next();
+      assertEquals(data[i], pii.peekNext());
+    }
+  }
+
   @Test
   public void testSkipsDense() {
     RoaringBitmap bitmap = new RoaringBitmap();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
index ec77d5e28..2c4b7b4c0 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
@@ -61,7 +61,7 @@ public int next() {
   }
 
 
-  private static int[] takeSortedAndDistinct(Random source, int count) {
+  private static int[] takeSortedAndDistinct(Random source, int count, Comparator comparator) {
     HashSet ints = new HashSet(count);
     for (int size = 0; size < count; size++) {
       int next;
@@ -70,7 +70,7 @@ private static int[] takeSortedAndDistinct(Random source, int count) {
       } while (!ints.add(next));
     }
     ArrayList list = new ArrayList(ints);
-    list.sort(Integer::compareUnsigned);
+    list.sort(comparator);
     return Ints.toArray(list);
   }
 
@@ -118,7 +118,7 @@ public void testEmptyIteration() {
   @Test
   public void testIteration() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
-    final int[] data = takeSortedAndDistinct(source, 450000);
+    final int[] data = takeSortedAndDistinct(source, 450000, Integer::compareUnsigned);
     MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data);
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
@@ -140,7 +140,7 @@ public void testIteration() {
   @Test
   public void testIteration1() {
     final Random source = new Random(0xcb000a2b9b5bdfb6l);
-    final int[] data1 = takeSortedAndDistinct(source, 450000);
+    final int[] data1 = takeSortedAndDistinct(source, 450000, Integer::compareUnsigned);
 
     HashSet data1Members = new HashSet(data1.length);
     for (int i : data1) {
@@ -212,31 +212,58 @@ public void testSmallIteration1() {
     assertEquals(ImmutableList.of(-1, 3, 2, 1), reverseIntIteratorCopy);
   }
 
-
   @Test
   public void testSkips() {
-    final Random source = new Random(0xcb000a2b9b5bdfb6l);
-    final int[] data = takeSortedAndDistinct(source, 45000);
+    final Random source = new Random(0xcb000a2b9b5bdfb6L);
+    final int[] data = takeSortedAndDistinct(source, 45000, Integer::compareUnsigned);
     MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data);
     PeekableIntIterator pii = bitmap.getIntIterator();
-    for(int i = 0; i < data.length; ++i) {
+    for (int i = 0; i < data.length; ++i) {
       pii.advanceIfNeeded(data[i]);
       assertEquals(data[i], pii.peekNext());
     }
     pii = bitmap.getIntIterator();
-    for(int i = 0; i < data.length; ++i) {
+    for (int i = 0; i < data.length; ++i) {
       pii.advanceIfNeeded(data[i]);
       assertEquals(data[i], pii.next());
     }
     pii = bitmap.getIntIterator();
-    for(int i = 1; i < data.length; ++i) {
-      pii.advanceIfNeeded(data[i-1]);
+    for (int i = 1; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i - 1]);
       pii.next();
-      assertEquals(data[i],pii.peekNext() );
+      assertEquals(data[i], pii.peekNext());
     }
     bitmap.getIntIterator().advanceIfNeeded(-1);
   }
 
+  @Test
+  public void testSkipsSignedIterator() {
+    final Random source = new Random(0xcb000a2b9b5bdfb6L);
+    final int[] data = takeSortedAndDistinct(source, 45000, Integer::compare);
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data);
+    PeekableIntIterator pii = bitmap.getSignedIntIterator();
+    for (int i = 0; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i]);
+      assertEquals(data[i], pii.peekNext());
+    }
+    pii = bitmap.getSignedIntIterator();
+    for (int i = data.length - 1; i >= 0; --i) { // no backward advancing
+      pii.advanceIfNeeded(data[i]);
+      assertEquals(data[data.length - 1], pii.peekNext());
+    }
+    pii = bitmap.getSignedIntIterator();
+    for (int i = 0; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i]);
+      assertEquals(data[i], pii.next());
+    }
+    pii = bitmap.getSignedIntIterator();
+    for (int i = 1; i < data.length; ++i) {
+      pii.advanceIfNeeded(data[i - 1]);
+      pii.next();
+      assertEquals(data[i], pii.peekNext());
+    }
+  }
+
   @Test
   public void testSkipsDense() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();
@@ -265,7 +292,6 @@ public void testIndexIterator4() throws Exception {
     }
   }
 
-
   @Test
   public void testSkipsRun() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();

From 9a862d5ba3a87fb175c9d688969b8a229c5a90ef Mon Sep 17 00:00:00 2001
From: Zoltan Meze 
Date: Mon, 8 Jul 2024 15:44:19 +0200
Subject: [PATCH 075/167] Fix previousValue not returning correct results in
 some cases (#736)

* Step down container index if next present container key is larger than target container key

This means that previous value (if exist) must be always in the previous container

* Return value as unsigned long when previous value is also the last (largest) value in bitmap

* Remove unnecessary condition
---
 .../java/org/roaringbitmap/RoaringBitmap.java   |  5 +++--
 .../buffer/ImmutableRoaringBitmap.java          |  7 ++++---
 .../org/roaringbitmap/TestRoaringBitmap.java    | 17 +++++++++++++++++
 .../buffer/TestImmutableRoaringBitmap.java      | 17 +++++++++++++++++
 4 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
index a21cf4d9c..a1022fada 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
@@ -2861,10 +2861,11 @@ public long previousValue(int fromValue) {
     char key = Util.highbits(fromValue);
     int containerIndex = highLowContainer.advanceUntil(key, -1);
     if (containerIndex == highLowContainer.size()) {
-      return last();
+      return Util.toUnsignedLong(last());
     }
     if (highLowContainer.getKeyAtIndex(containerIndex) > key) {
-      return -1L;
+      // target absent, key of first container after target too high
+      --containerIndex;
     }
     long prevSetBit = -1L;
     while (containerIndex != -1 && prevSetBit == -1L) {
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
index d9cbeec36..32f09e818 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
@@ -1820,13 +1820,14 @@ public long previousValue(int fromValue) {
     char key = highbits(fromValue);
     int containerIndex = highLowContainer.advanceUntil(key, -1);
     if (containerIndex == highLowContainer.size()) {
-      return last();
+      return Util.toUnsignedLong(last());
     }
     if (highLowContainer.getKeyAtIndex(containerIndex) > key) {
-      return -1L;
+      // target absent, key of first container after target too high
+      --containerIndex;
     }
     long prevSetBit = -1L;
-    while (containerIndex != -1 && containerIndex < highLowContainer.size() && prevSetBit == -1L) {
+    while (containerIndex != -1 && prevSetBit == -1L) {
       char containerKey = highLowContainer.getKeyAtIndex(containerIndex);
       MappeableContainer container = highLowContainer.getContainerAtIndex(containerIndex);
       int bit = (containerKey < key
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
index 71df25e64..464d6b62c 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
@@ -5360,6 +5360,23 @@ public void testPreviousValueRegression() {
         assertEquals(-1, RoaringBitmap.bitmapOf().previousValue(403042));
     }
 
+    @Test
+    public void testPreviousValue_AbsentTargetContainer() {
+        RoaringBitmap bitmap = RoaringBitmap.bitmapOf(-1, 2, 3, 131072);
+        assertEquals(3, bitmap.previousValue(65536));
+        assertEquals(131072, bitmap.previousValue(Integer.MAX_VALUE));
+        assertEquals(131072, bitmap.previousValue(-131072));
+
+        bitmap = RoaringBitmap.bitmapOf(131072);
+        assertEquals(-1, bitmap.previousValue(65536));
+    }
+
+    @Test
+    public void testPreviousValue_LastReturnedAsUnsignedLong() {
+        RoaringBitmap bitmap = RoaringBitmap.bitmapOf(-650002, -650001, -650000);
+        assertEquals(Util.toUnsignedLong(-650000), bitmap.previousValue(-1));
+    }
+
     @Test
     public void testRangeCardinalityAtBoundary() {
         // See https://github.com/RoaringBitmap/RoaringBitmap/issues/285
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
index dff17730a..2945757da 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
@@ -1497,6 +1497,23 @@ public void testPreviousValue() {
     }
   }
 
+  @Test
+  public void testPreviousValue_AbsentTargetContainer() {
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(-1, 2, 3, 131072);
+    assertEquals(3, bitmap.previousValue(65536));
+    assertEquals(131072, bitmap.previousValue(Integer.MAX_VALUE));
+    assertEquals(131072, bitmap.previousValue(-131072));
+
+    bitmap = MutableRoaringBitmap.bitmapOf(131072);
+    assertEquals(-1, bitmap.previousValue(65536));
+  }
+
+  @Test
+  public void testPreviousValue_LastReturnedAsUnsignedLong() {
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(-650002, -650001, -650000);
+    assertEquals(Util.toUnsignedLong(-650000), bitmap.previousValue(-1));
+  }
+
   @Test
   public void testRangeCardinalityAtBoundary() {
     // See https://github.com/RoaringBitmap/RoaringBitmap/issues/285

From 3dbd2be25a63fb4cd3d1b27b4df464908d2ac801 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Mon, 8 Jul 2024 10:52:09 -0400
Subject: [PATCH 076/167] fix: add a few additional small tests (#737)

---
 .../src/test/java/org/roaringbitmap/TestIterators.java | 10 +++++-----
 .../java/org/roaringbitmap/buffer/TestIterators.java   | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
index 7f51d5582..9d6c6fc70 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
@@ -107,17 +107,17 @@ public void testIteration() {
 
   @Test
   public void testSmallIteration() {
-    RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1, 2, 3, -1);
+    RoaringBitmap bitmap = RoaringBitmap.bitmapOf(0, 1, 2, 3, -1, 2147483647, -2147483648);
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
     final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
-    assertEquals(ImmutableList.of(1, 2, 3, -1), iteratorCopy);
-    assertEquals(ImmutableList.of(1, 2, 3, -1), intIteratorCopy);
-    assertEquals(ImmutableList.of(-1, 1, 2, 3), signedIntIteratorCopy);
-    assertEquals(ImmutableList.of(-1, 3, 2, 1), reverseIntIteratorCopy);
+    assertEquals(ImmutableList.of(0, 1, 2, 3, 2147483647, -2147483648, -1), iteratorCopy);
+    assertEquals(ImmutableList.of(0, 1, 2, 3, 2147483647, -2147483648, -1), intIteratorCopy);
+    assertEquals(ImmutableList.of(-2147483648, -1, 0, 1, 2, 3, 2147483647), signedIntIteratorCopy);
+    assertEquals(ImmutableList.of(-1, -2147483648, 2147483647, 3, 2, 1, 0), reverseIntIteratorCopy);
   }
 
   @Test
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
index 2c4b7b4c0..457af4f93 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
@@ -183,17 +183,17 @@ public void testIteration1() {
 
   @Test
   public void testSmallIteration() {
-    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3, -1);
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3, -1, -2147483648 , 2147483647, 0);
 
     final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator());
     final List intIteratorCopy = asList(bitmap.getIntIterator());
     final List signedIntIteratorCopy = asList(bitmap.getSignedIntIterator());
     final List reverseIntIteratorCopy = asList(bitmap.getReverseIntIterator());
 
-    assertEquals(ImmutableList.of(1, 2, 3, -1), iteratorCopy);
-    assertEquals(ImmutableList.of(1, 2, 3, -1), intIteratorCopy);
-    assertEquals(ImmutableList.of(-1, 1, 2, 3), signedIntIteratorCopy);
-    assertEquals(ImmutableList.of(-1, 3, 2, 1), reverseIntIteratorCopy);
+    assertEquals(ImmutableList.of(0, 1, 2, 3, 2147483647, -2147483648, -1), iteratorCopy);
+    assertEquals(ImmutableList.of(0, 1, 2, 3, 2147483647, -2147483648, -1), intIteratorCopy);
+    assertEquals(ImmutableList.of(-2147483648, -1, 0, 1, 2, 3, 2147483647), signedIntIteratorCopy);
+    assertEquals(ImmutableList.of(-1, -2147483648, 2147483647, 3, 2, 1, 0), reverseIntIteratorCopy);
   }
 
   @Test

From 79f1debc980dcecd7b645df3d5a50b3d00a400de Mon Sep 17 00:00:00 2001
From: Zoltan Meze 
Date: Tue, 16 Jul 2024 14:02:19 +0200
Subject: [PATCH 077/167] Skip over empty words in
 RunContainer#contains(BitmapContainer) (#739)

* Skip empty words while iterating over bitmap container in RunContainer#contains(BitmapContainer)

* Format
---
 .../java/org/roaringbitmap/RunContainer.java    | 17 +++++++----------
 .../buffer/MappeableRunContainer.java           | 15 ++++++---------
 .../org/roaringbitmap/TestRunContainer.java     |  7 +++++++
 .../roaringbitmap/buffer/TestRunContainer.java  |  7 +++++++
 4 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java
index 42c8981eb..6c4eca896 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java
@@ -819,13 +819,13 @@ protected boolean contains(BitmapContainer bitmapContainer) {
     char ib = 0, ir = 0;
     int start = getValue(ir);
     int stop = start + getLength(ir);
-    while(ib < bitmapContainer.bitmap.length && ir < runCount) {
+    while (ib < bitmapContainer.bitmap.length && ir < runCount) {
       long w = bitmapContainer.bitmap[ib];
-      while (true) {
+      while (w != 0) {
         long r = ib * 64L + Long.numberOfTrailingZeros(w);
         if (r < start) {
           return false;
-        } else if(r > stop) {
+        } else if (r > stop) {
           ++ir;
           if (ir == runCount) {
             break;
@@ -837,20 +837,17 @@ protected boolean contains(BitmapContainer bitmapContainer) {
           w = bitmapContainer.bitmap[ib];
         } else {
           w &= w - 1;
-          if (w == 0) {
-            break;
-          }
         }
       }
-      if(w == 0) {
+      if (w == 0) {
         ++ib;
       } else {
         return false;
       }
     }
-    if(ib < bitmapContainer.bitmap.length) {
-      for(; ib < bitmapContainer.bitmap.length ; ib++) {
-        if(bitmapContainer.bitmap[ib] != 0) {
+    if (ib < bitmapContainer.bitmap.length) {
+      for (; ib < bitmapContainer.bitmap.length; ib++) {
+        if (bitmapContainer.bitmap[ib] != 0) {
           return false;
         }
       }
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java
index 295e4ee5b..a732ab097 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java
@@ -2728,9 +2728,9 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) {
     char ib = 0, ir = 0;
     int start = getValue(0);
     int stop = start + getLength(0);
-    while(ib < MappeableBitmapContainer.MAX_CAPACITY / 64 && ir < runCount) {
+    while (ib < MappeableBitmapContainer.MAX_CAPACITY / 64 && ir < runCount) {
       long w = bitmapContainer.bitmap.get(ib);
-      while (true) {
+      while (w != 0) {
         long r = ib * 64 + Long.numberOfTrailingZeros(w);
         if (r < start) {
           return false;
@@ -2747,20 +2747,17 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) {
           w = bitmapContainer.bitmap.get(ib);
         } else {
           w &= w - 1;
-          if (w == 0) {
-            break;
-          }
         }
       }
-      if(w == 0) {
+      if (w == 0) {
         ++ib;
       } else {
         return false;
       }
     }
-    if(ib < MappeableBitmapContainer.MAX_CAPACITY / 64) {
-      for(; ib < MappeableBitmapContainer.MAX_CAPACITY / 64 ; ib++) {
-        if(bitmapContainer.bitmap.get(ib) != 0) {
+    if (ib < MappeableBitmapContainer.MAX_CAPACITY / 64) {
+      for (; ib < MappeableBitmapContainer.MAX_CAPACITY / 64; ib++) {
+        if (bitmapContainer.bitmap.get(ib) != 0) {
           return false;
         }
       }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java
index cee73476c..c5e156f0f 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java
@@ -3385,6 +3385,13 @@ public void testContainsBitmapContainer_Issue721Case2() {
     assertFalse(rc.contains(disjoint));
   }
 
+  @Test
+  public void testContainsBitmapContainer_SkipEmptyWords() {
+    Container rc = new RunContainer().add(128, 512);
+    Container subset = new BitmapContainer().add(256, 320);
+    assertTrue(rc.contains(subset));
+  }
+
   @Test
   public void testContainsRunContainer_EmptyContainsEmpty() {
     Container rc = new RunContainer();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
index 45f476dbb..97b4fc705 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
@@ -2286,6 +2286,13 @@ public void testContainsMappeableBitmapContainer_Issue721Case2() {
     assertFalse(rc.contains(disjoint));
   }
 
+  @Test
+  public void testContainsMappeableBitmapContainer_SkipEmptyWords() {
+    MappeableContainer rc = new MappeableRunContainer().add(128, 512);
+    MappeableContainer subset = new MappeableBitmapContainer().add(256, 320);
+    assertTrue(rc.contains(subset));
+  }
+
   @Test
   public void testContainsMappeableRunContainer_EmptyContainsEmpty() {
     MappeableContainer rc = new MappeableRunContainer();

From 71ba146331b5ab4a7bd9f9943bd2f9fa742d2d3e Mon Sep 17 00:00:00 2001
From: Zoltan Meze 
Date: Tue, 16 Jul 2024 14:02:56 +0200
Subject: [PATCH 078/167] Implement signed first/last methods (#738)

* Implement first and last signed methods

Allows retrieving minimum and maximum signed integers from bitmap

* Remove unnecessary (duplicate) javadoc
---
 .../ImmutableBitmapDataProvider.java          | 24 ++++++++---
 .../java/org/roaringbitmap/RoaringArray.java  | 42 ++++++++++++++++---
 .../java/org/roaringbitmap/RoaringBitmap.java | 10 +++++
 .../buffer/ImmutableRoaringArray.java         | 26 +++++++++++-
 .../buffer/ImmutableRoaringBitmap.java        | 23 +++++-----
 .../buffer/MutableRoaringArray.java           | 26 +++++++++++-
 .../buffer/PointableRoaringArray.java         | 20 +++++++--
 .../org/roaringbitmap/TestRoaringBitmap.java  | 29 +++++++++++++
 .../buffer/TestImmutableRoaringBitmap.java    | 30 +++++++++++++
 9 files changed, 200 insertions(+), 30 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
index 550a7faa3..f740c23bf 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
@@ -197,21 +197,33 @@ public default IntStream reverseStream() {
   int select(int j);
 
   /**
-   * Get the first (smallest) integer in this RoaringBitmap,
-   * that is, return the minimum of the set.
-   * @return the first (smallest) integer
+   * Get the smallest unsigned (first) integer in this RoaringBitmap.
+   * @return the smallest unsigned (first) integer
    * @throws NoSuchElementException if empty
    */
   int first();
 
   /**
-   * Get the last (largest) integer in this RoaringBitmap,
-   * that is, return the maximum of the set.
-   * @return the last (largest) integer
+   * Get the largest unsigned (last) integer in this RoaringBitmap.
+   * @return the largest unsigned (last) integer
    * @throws NoSuchElementException if empty
    */
   int last();
 
+  /**
+   * Get the smallest signed integer in this RoaringBitmap.
+   * @return the smallest signed integer
+   * @throws NoSuchElementException if empty
+   */
+  int firstSigned();
+
+  /**
+   * Get the largest signed integer in this RoaringBitmap.
+   * @return the largest signed integer
+   * @throws NoSuchElementException if empty
+   */
+  int lastSigned();
+
   /**
    * Returns the first value equal to or larger than the provided value
    * (interpreted as an unsigned integer). If no such
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java
index 5bc2fce8b..427e2a35a 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java
@@ -966,8 +966,8 @@ public void writeExternal(ObjectOutput out) throws IOException {
   }
 
   /**
-   * Gets the first value in the array
-   * @return the first value in the array
+   * Gets the smallest unsigned (first) integer in the array.
+   * @return the smallest unsigned (first) integer in the array
    * @throws NoSuchElementException if empty
    */
   public int first() {
@@ -978,8 +978,8 @@ public int first() {
   }
 
   /**
-   * Gets the last value in the array
-   * @return the last value in the array
+   * Gets the largest unsigned (last) integer in the array.
+   * @return the largest unsigned (last) integer in the array
    * @throws NoSuchElementException if empty
    */
   public int last() {
@@ -989,8 +989,40 @@ public int last() {
     return lastKey << 16 | container.last();
   }
 
+  /**
+   * Gets the smallest signed integer in the array.
+   * @return the smallest signed integer in the array
+   * @throws NoSuchElementException if empty
+   */
+  public int firstSigned() {
+    assertNonEmpty();
+    int index = advanceUntil((char) (1 << 15), -1);
+    if (index == size) { // no negatives
+      index = 0;
+    }
+    char key = keys[index];
+    Container container = values[index];
+    return key << 16 | container.first();
+  }
+
+  /**
+   * Gets the largest signed integer in the array.
+   * @return the largest signed integer in the array
+   * @throws NoSuchElementException if empty
+   */
+  public int lastSigned() {
+    assertNonEmpty();
+    int index = advanceUntil((char) (1 << 15), -1) - 1;
+    if (index == -1) { // no positives
+      index += size;
+    }
+    char key = keys[index];
+    Container container = values[index];
+    return key << 16 | container.last();
+  }
+
   private void assertNonEmpty() {
-    if(size == 0) {
+    if (size == 0) {
       throw new NoSuchElementException("Empty RoaringArray");
     }
   }
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
index a1022fada..a1508626f 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
@@ -2978,6 +2978,16 @@ public int last() {
     return highLowContainer.last();
   }
 
+  @Override
+  public int firstSigned() {
+    return highLowContainer.firstSigned();
+  }
+
+  @Override
+  public int lastSigned() {
+    return highLowContainer.lastSigned();
+  }
+
   /**
    * Serialize this bitmap.
    *
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java
index 2b7930fbe..cbd173771 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java
@@ -493,8 +493,32 @@ public int last() {
     return lastKey << 16 | container.last();
   }
 
+  @Override
+  public int firstSigned() {
+    assertNonEmpty();
+    int index = advanceUntil((char) (1 << 15), -1);
+    if (index == size) { // no negatives
+      index = 0;
+    }
+    char key = getKeyAtIndex(index);
+    MappeableContainer container = getContainerAtIndex(index);
+    return key << 16 | container.first();
+  }
+
+  @Override
+  public int lastSigned() {
+    assertNonEmpty();
+    int index = advanceUntil((char) (1 << 15), -1) - 1;
+    if (index == -1) { // no positives
+      index += size;
+    }
+    char key = getKeyAtIndex(index);
+    MappeableContainer container = getContainerAtIndex(index);
+    return key << 16 | container.last();
+  }
+
   private void assertNonEmpty() {
-    if(size == 0) {
+    if (size == 0) {
       throw new NoSuchElementException("Empty ImmutableRoaringArray");
     }
   }
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
index 32f09e818..a28c089b8 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
@@ -1770,29 +1770,26 @@ public int select(int j) {
                + this.getCardinality() + ".");
   }
 
-
-  /**
-   * Get the first (smallest) integer in this RoaringBitmap,
-   * that is, returns the minimum of the set.
-   * @return the first (smallest) integer
-   * @throws NoSuchElementException if empty
-   */
   @Override
   public int first() {
     return highLowContainer.first();
   }
 
-  /**
-   * Get the last (largest) integer in this RoaringBitmap,
-   * that is, returns the maximum of the set.
-   * @return the last (largest) integer
-   * @throws NoSuchElementException if empty
-   */
   @Override
   public int last() {
     return highLowContainer.last();
   }
 
+  @Override
+  public int firstSigned() {
+    return highLowContainer.firstSigned();
+  }
+
+  @Override
+  public int lastSigned() {
+    return highLowContainer.lastSigned();
+  }
+
   @Override
   public long nextValue(int fromValue) {
     char key = highbits(fromValue);
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java
index 65c6d7f81..3e30b536b 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java
@@ -799,8 +799,32 @@ public int last() {
     return lastKey << 16 | container.last();
   }
 
+  @Override
+  public int firstSigned() {
+    assertNonEmpty();
+    int index = advanceUntil((char) (1 << 15), -1);
+    if (index == size) { // no negatives
+      index = 0;
+    }
+    char key = getKeyAtIndex(index);
+    MappeableContainer container = getContainerAtIndex(index);
+    return key << 16 | container.first();
+  }
+
+  @Override
+  public int lastSigned() {
+    assertNonEmpty();
+    int index = advanceUntil((char) (1 << 15), -1) - 1;
+    if (index == -1) { // no positives
+      index += size;
+    }
+    char key = getKeyAtIndex(index);
+    MappeableContainer container = getContainerAtIndex(index);
+    return key << 16 | container.last();
+  }
+
   private void assertNonEmpty() {
-    if(size == 0) {
+    if (size == 0) {
       throw new NoSuchElementException("Empty MutableRoaringArray");
     }
   }
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java
index 81a0b2d14..b5dc25791 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java
@@ -135,14 +135,26 @@ public interface PointableRoaringArray extends Cloneable {
   int size();
 
   /**
-   * Gets the first value in the array
-   * @return te first value in the array
+   * Gets the smallest unsigned (first) integer in the array.
+   * @return the smallest unsigned (first) integer in the array
    */
   int first();
 
   /**
-   * Gets the last value in the array
-   * @return te last value in the array
+   * Gets the largest unsigned (last) integer in the array.
+   * @return the largest unsigned (last) integer in the array
    */
   int last();
+
+  /**
+   * Gets the smallest signed integer in the array.
+   * @return the smallest signed integer in the array
+   */
+  int firstSigned();
+
+  /**
+   * Gets the largest signed integer in the array.
+   * @return the largest signed integer in the array
+   */
+  int lastSigned();
 }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
index 464d6b62c..c8e54e6b5 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
@@ -12,6 +12,8 @@
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.Execution;
 import org.junit.jupiter.api.parallel.ExecutionMode;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.*;
 import java.nio.ByteBuffer;
@@ -5142,6 +5144,33 @@ public void testNegative_last() {
         assertEquals(-7, bitmap.last());
     }
 
+    @Test
+    public void testFirstLastSigned() {
+        RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1_111_111, 3_333_333);
+        assertEquals(1_111_111, bitmap.firstSigned());
+        assertEquals(3_333_333, bitmap.lastSigned());
+
+        bitmap = RoaringBitmap.bitmapOf(-3_333_333, 3_333_333);
+        assertEquals(-3_333_333, bitmap.firstSigned());
+        assertEquals(3_333_333, bitmap.lastSigned());
+
+        bitmap = RoaringBitmap.bitmapOf(-3_333_333, -1_111_111);
+        assertEquals(-3_333_333, bitmap.firstSigned());
+        assertEquals(-1_111_111, bitmap.lastSigned());
+
+        bitmap = RoaringBitmap.bitmapOfRange(0, 1L << 32);
+        assertEquals(Integer.MIN_VALUE, bitmap.firstSigned());
+        assertEquals(Integer.MAX_VALUE, bitmap.lastSigned());
+    }
+
+    @ParameterizedTest
+    @ValueSource(ints = {Integer.MIN_VALUE, -65_536, 0, 65_536, Integer.MAX_VALUE})
+    public void testFirstLastSigned_SingleValueBitmap(int value) {
+        RoaringBitmap bitmap = RoaringBitmap.bitmapOf(value);
+        assertEquals(value, bitmap.firstSigned());
+        assertEquals(value, bitmap.lastSigned());
+    }
+
     @Test
     public void testContainsRange_ContiguousBitmap() {
         RoaringBitmap bitmap = new RoaringBitmap();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
index 2945757da..1929374ec 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
@@ -8,6 +8,8 @@
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.Execution;
 import org.junit.jupiter.api.parallel.ExecutionMode;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.roaringbitmap.*;
 
 import java.io.DataOutputStream;
@@ -1404,6 +1406,34 @@ public void testNegative_last() {
     assertEquals(-7, bitmap.last());
   }
 
+  @Test
+  public void testFirstLastSigned() {
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1_111_111, 3_333_333);
+
+    assertEquals(1_111_111, bitmap.firstSigned());
+    assertEquals(3_333_333, bitmap.lastSigned());
+
+    bitmap = MutableRoaringBitmap.bitmapOf(-3_333_333, 3_333_333);
+    assertEquals(-3_333_333, bitmap.firstSigned());
+    assertEquals(3_333_333, bitmap.lastSigned());
+
+    bitmap = MutableRoaringBitmap.bitmapOf(-3_333_333, -1_111_111);
+    assertEquals(-3_333_333, bitmap.firstSigned());
+    assertEquals(-1_111_111, bitmap.lastSigned());
+
+    bitmap = MutableRoaringBitmap.bitmapOfRange(0, 1L << 32);
+    assertEquals(Integer.MIN_VALUE, bitmap.firstSigned());
+    assertEquals(Integer.MAX_VALUE, bitmap.lastSigned());
+  }
+
+  @ParameterizedTest
+  @ValueSource(ints = {Integer.MIN_VALUE, -65_536, 0, 65_536, Integer.MAX_VALUE})
+  public void testFirstLastSigned_SingleValueBitmap(int value) {
+    MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(value);
+    assertEquals(value, bitmap.firstSigned());
+    assertEquals(value, bitmap.lastSigned());
+  }
+
   @Test
   public void testContainsRange_ContiguousBitmap() {
     MutableRoaringBitmap bitmap = new MutableRoaringBitmap();

From a6cc3da09a2a780b8736eacda95a48c918b1ff46 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 16 Jul 2024 08:06:13 -0400
Subject: [PATCH 079/167] [Gradle Release Plugin] - pre tag commit:  '1.2.1'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index bd6477a68..98bce0a44 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.1-SNAPSHOT
+version = 1.2.1
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From d2c6c3bcb087bc4d7785c05b37bf1240b99efd1e Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 16 Jul 2024 08:06:16 -0400
Subject: [PATCH 080/167] [Gradle Release Plugin] - new version commit: 
 '1.2.2-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 98bce0a44..ddf64fdac 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.1
+version = 1.2.2-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 81c4e34f8721e0d739b0d6a45156ab25ca3f3ca2 Mon Sep 17 00:00:00 2001
From: Peyz <30936555+iszhangpch@users.noreply.github.com>
Date: Wed, 21 Aug 2024 20:49:47 +0800
Subject: [PATCH 081/167] Add BSI based on Roaring64Bitmap (#733)

* Add BSI based on Roaring64Bitmap so as to support (cid:bigint, value:bigint)

* Change implementation of Roaring64Bitmap's or and xor (not in place) operation

* Fix variable name

* Add some analysis functions

* Fix variable type

* fix some problem

---------

Co-authored-by: zhangpeicheng 
---
 .../org/roaringbitmap/art/KeyIterator.java    |   5 +
 .../longlong/HighLowContainer.java            |  23 +
 .../longlong/Roaring64Bitmap.java             | 250 +++++++
 .../longlong/TestRoaring64Bitmap.java         | 183 ++++++
 .../longlong/Roaring64BitmapSliceIndex.java   | 616 ++++++++++++++++++
 .../org/roaringbitmap/bsi/R64BSITest.java     | 370 +++++++++++
 6 files changed, 1447 insertions(+)
 create mode 100644 bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
 create mode 100644 bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java b/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java
index 4c7c20eb4..65cb21259 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java
@@ -26,6 +26,10 @@ public byte[] next() {
     return current.getKeyBytes();
   }
 
+  public byte[] peekNext() {
+    return leafNodeIterator.peekNext().getKeyBytes();
+  }
+
   public long nextKey() {
     return current.getKey();
   }
@@ -34,6 +38,7 @@ public long currentContainerIdx() {
     return current.getContainerIdx();
   }
 
+  @Override
   public void remove() {
     leafNodeIterator.remove();
   }
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
index ad7e0ee62..5986d1a13 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
@@ -147,6 +147,29 @@ public long last() {
     return LongUtils.toLong(high, low);
   }
 
+  /**
+   * Compares two unsigned byte arrays for order.
+   * Result is a negative integer, zero, or a positive integer
+   * as the first array is less than, equal to, or greater than the second.
+   * @return result of comparing
+   */
+  public static int compareUnsigned(byte[] a, byte[] b) {
+    if (a == null) {
+      return b == null ? 0 : 1;
+    }
+    if (b == null) {
+      return -1;
+    }
+    for (int i = 0; i < Math.min(a.length, b.length); i++) {
+      int aVal = a[i] & 0xff;
+      int bVal = b[i] & 0xff;
+      if (aVal != bVal) {
+        return Integer.compare(aVal, bVal);
+      }
+    }
+    return Integer.compare(a.length, b.length);
+  }
+
   /**
    * serialize into the ByteBuffer in little endian
    * @param buffer the ByteBuffer should be large enough to hold the data
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
index bbc9b3383..db353730d 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
@@ -334,6 +334,56 @@ public void or(final Roaring64Bitmap x2) {
     }
   }
 
+  /**
+   * Bitwise OR (union) operation. The provided bitmaps are *not* modified. This operation is
+   * thread-safe as long as the provided bitmaps remain unchanged.
+   *
+   * @param x1 first bitmap
+   * @param x2 other bitmap
+   * @return result of the operation
+   */
+  public static Roaring64Bitmap or(final Roaring64Bitmap x1, final Roaring64Bitmap x2) {
+    Roaring64Bitmap result = new Roaring64Bitmap();
+    KeyIterator it1 = x1.highLowContainer.highKeyIterator();
+    KeyIterator it2 = x2.highLowContainer.highKeyIterator();
+
+    byte[] highKey1 = null, highKey2 = null;
+    if (it1.hasNext()) {
+      highKey1 = it1.next();
+    }
+    if (it2.hasNext()) {
+      highKey2 = it2.next();
+    }
+
+    while (highKey1 != null || highKey2 != null) {
+      int compare = HighLowContainer.compareUnsigned(highKey1, highKey2);
+      if (compare == 0) {
+        long containerIdx1 = it1.currentContainerIdx();
+        long containerIdx2 = it2.currentContainerIdx();
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        Container container2 = x2.highLowContainer.getContainer(containerIdx2);
+        Container orResult = container1.or(container2);
+        result.highLowContainer.put(highKey1, orResult);
+
+        highKey1 = it1.hasNext() ? it1.next() : null;
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      } else if (compare < 0) {
+        long containerIdx1 = it1.currentContainerIdx();
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        result.highLowContainer.put(highKey1, container1.clone());
+
+        highKey1 = it1.hasNext() ? it1.next() : null;
+      } else {
+        long containerIdx2 = it2.currentContainerIdx();
+        Container container2 = x2.highLowContainer.getContainer(containerIdx2);
+        result.highLowContainer.put(highKey2, container2.clone());
+
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      }
+    }
+    return result;
+  }
+
   /**
    * In-place bitwise XOR (symmetric difference) operation. The current bitmap is modified.
    *
@@ -360,6 +410,56 @@ public void xor(final Roaring64Bitmap x2) {
     }
   }
 
+  /**
+   * Bitwise XOR (symmetric difference) operation. The provided bitmaps are *not* modified. This
+   * operation is thread-safe as long as the provided bitmaps remain unchanged.
+   *
+   * @param x1 first bitmap
+   * @param x2 other bitmap
+   * @return result of the operation
+   */
+  public static Roaring64Bitmap xor(final Roaring64Bitmap x1, final Roaring64Bitmap x2) {
+    Roaring64Bitmap result = new Roaring64Bitmap();
+    KeyIterator it1 = x1.highLowContainer.highKeyIterator();
+    KeyIterator it2 = x2.highLowContainer.highKeyIterator();
+
+    byte[] highKey1 = null, highKey2 = null;
+    if (it1.hasNext()) {
+      highKey1 = it1.next();
+    }
+    if (it2.hasNext()) {
+      highKey2 = it2.next();
+    }
+
+    while (highKey1 != null || highKey2 != null) {
+      int compare = HighLowContainer.compareUnsigned(highKey1, highKey2);
+      if (compare == 0) {
+        long containerIdx1 = it1.currentContainerIdx();
+        long containerIdx2 = it2.currentContainerIdx();
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        Container container2 = x2.highLowContainer.getContainer(containerIdx2);
+        Container xorResult = container1.xor(container2);
+        result.highLowContainer.put(highKey1, xorResult);
+
+        highKey1 = it1.hasNext() ? it1.next() : null;
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      } else if (compare < 0) {
+        long containerIdx1 = it1.currentContainerIdx();
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        result.highLowContainer.put(highKey1, container1.clone());
+
+        highKey1 = it1.hasNext() ? it1.next() : null;
+      } else {
+        long containerIdx2 = it2.currentContainerIdx();
+        Container container2 = x2.highLowContainer.getContainer(containerIdx2);
+        result.highLowContainer.put(highKey2, container2.clone());
+
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      }
+    }
+    return result;
+  }
+
   /**
    * In-place bitwise AND (intersection) operation. The current bitmap is modified.
    *
@@ -386,6 +486,110 @@ public void and(final Roaring64Bitmap x2) {
     }
   }
 
+  /**
+   * Bitwise AND (intersection) operation. The provided bitmaps are *not* modified. This operation
+   * is thread-safe as long as the provided bitmaps remain unchanged.
+   *
+   * @param x1 first bitmap
+   * @param x2 other bitmap
+   * @return result of the operation
+   */
+  public static Roaring64Bitmap and(final Roaring64Bitmap x1, final Roaring64Bitmap x2) {
+    Roaring64Bitmap result = new Roaring64Bitmap();
+    KeyIterator it1 = x1.highLowContainer.highKeyIterator();
+    while (it1.hasNext()) {
+      byte[] highKey = it1.next();
+      long containerIdx1 = it1.currentContainerIdx();
+      ContainerWithIndex containerWithIdx2 = x2.highLowContainer.searchContainer(highKey);
+      if (containerWithIdx2 != null) {
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        Container container2 = containerWithIdx2.getContainer();
+        Container andResult = container1.and(container2);
+        if (!andResult.isEmpty()) {
+          result.highLowContainer.put(highKey, andResult);
+        }
+      }
+    }
+
+    return result;
+  }
+
+  /**
+   * Checks whether the two bitmaps intersect. This can be much faster than calling "and" and
+   * checking the cardinality of the result.
+   *
+   * @param x1 first bitmap
+   * @param x2 other bitmap
+   * @return true if they intersect
+   */
+  public static boolean intersects(final Roaring64Bitmap x1, final Roaring64Bitmap x2) {
+    KeyIterator it1 = x1.highLowContainer.highKeyIterator();
+    KeyIterator it2 = x2.highLowContainer.highKeyIterator();
+
+    byte[] highKey1 = it1.hasNext() ? it1.next() : null;
+    byte[] highKey2 = it2.hasNext() ? it2.next() : null;
+
+    while (highKey1 != null && highKey2 != null) {
+      int compare = HighLowContainer.compareUnsigned(highKey1, highKey2);
+      if (compare == 0) {
+        long containerIdx1 = it1.currentContainerIdx();
+        long containerIdx2 = it2.currentContainerIdx();
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        Container container2 = x2.highLowContainer.getContainer(containerIdx2);
+        if (container1.intersects(container2)) {
+          return true;
+        }
+        highKey1 = it1.hasNext() ? it1.next() : null;
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      } else if (compare < 0) {
+        highKey1 = it1.hasNext() ? it1.next() : null;
+      } else {
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Cardinality of Bitwise AND (intersection) operation. The provided bitmaps are *not* modified.
+   * This operation is thread-safe as long as the provided bitmaps remain unchanged.
+   *
+   * @param x1 first bitmap
+   * @param x2 other bitmap
+   * @return as if you did and(x1,x2).getCardinality()
+   */
+  public static long andCardinality(final Roaring64Bitmap x1, final Roaring64Bitmap x2) {
+    long cardinality = 0;
+    KeyIterator it1 = x1.highLowContainer.highKeyIterator();
+    KeyIterator it2 = x2.highLowContainer.highKeyIterator();
+
+    byte[] highKey1 = null, highKey2 = null;
+    if (it1.hasNext()) {
+      highKey1 = it1.next();
+    }
+    if (it2.hasNext()) {
+      highKey2 = it2.next();
+    }
+
+    while (highKey1 != null && highKey2 != null) {
+      int compare = HighLowContainer.compareUnsigned(highKey1, highKey2);
+      if (compare == 0) {
+        long containerIdx1 = it1.currentContainerIdx();
+        long containerIdx2 = it2.currentContainerIdx();
+        Container container1 = x1.highLowContainer.getContainer(containerIdx1);
+        Container container2 = x2.highLowContainer.getContainer(containerIdx2);
+        cardinality += container1.andCardinality(container2);
+        highKey1 = it1.hasNext() ? it1.next() : null;
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      } else if (compare < 0) {
+        highKey1 = it1.hasNext() ? it1.next() : null;
+      } else {
+        highKey2 = it2.hasNext() ? it2.next() : null;
+      }
+    }
+    return cardinality;
+  }
 
   /**
    * In-place bitwise ANDNOT (difference) operation. The current bitmap is modified.
@@ -415,6 +619,35 @@ public void andNot(final Roaring64Bitmap x2) {
     }
   }
 
+  /**
+   * Bitwise ANDNOT (difference) operation. The provided bitmaps are *not* modified. This operation
+   * is thread-safe as long as the provided bitmaps remain unchanged.
+   *
+   * @param x1 first bitmap
+   * @param x2 other bitmap
+   * @return result of the operation
+   */
+  public static Roaring64Bitmap andNot(final Roaring64Bitmap x1, final Roaring64Bitmap x2) {
+    Roaring64Bitmap result = new Roaring64Bitmap();
+    KeyIterator it1 = x1.highLowContainer.highKeyIterator();
+    while (it1.hasNext()) {
+      byte[] highKey = it1.next();
+      long containerIdx = it1.currentContainerIdx();
+      ContainerWithIndex containerWithIdx2 = x2.highLowContainer.searchContainer(highKey);
+      Container container1 = x1.highLowContainer.getContainer(containerIdx);
+      if (containerWithIdx2 != null) {
+        Container andNotResult = container1.andNot(containerWithIdx2.getContainer());
+        if (!andNotResult.isEmpty()) {
+          result.highLowContainer.put(highKey, andNotResult);
+        }
+      } else {
+        result.highLowContainer.put(highKey, container1.clone());
+      }
+    }
+
+    return result;
+  }
+
   /**
    * Complements the bits in the given range, from rangeStart (inclusive) rangeEnd (exclusive). The
    * given bitmap is unchanged.
@@ -740,6 +973,23 @@ public static Roaring64Bitmap bitmapOf(final long... dat) {
     return ans;
   }
 
+  /**
+   * If present remove the specified integer (effectively, sets its bit value to false)
+   *
+   * @param x integer value representing the index in a bitmap
+   */
+  public void remove(final long x) {
+    byte[] highKey = LongUtils.highPart(x);
+    ContainerWithIndex containerWithIdx = highLowContainer.searchContainer(highKey);
+    if (containerWithIdx != null) {
+      char low = LongUtils.lowPart(x);
+      containerWithIdx.getContainer().remove(low);
+      if (containerWithIdx.getContainer().isEmpty()) {
+        highLowContainer.remove(highKey);
+      }
+    }
+  }
+
   /**
    * Set all the specified values to true. This can be expected to be slightly faster than calling
    * "add" repeatedly. The provided integers values don't have to be in sorted order, but it may be
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
index db3be66ea..54ed486d2 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
@@ -602,12 +602,18 @@ public void testOrSameBucket() {
     left.addLong(123);
     right.addLong(234);
 
+    Roaring64Bitmap orNotInPlace = Roaring64Bitmap.or(left, right);
     left.or(right);
 
     assertEquals(2, left.getLongCardinality());
 
     assertEquals(123, left.select(0));
     assertEquals(234, left.select(1));
+
+    assertEquals(2, orNotInPlace.getLongCardinality());
+
+    assertEquals(123, orNotInPlace.select(0));
+    assertEquals(234, orNotInPlace.select(1));
   }
 
   @Test
@@ -619,6 +625,7 @@ public void testOrMultipleBuckets() {
     left.addLong(Long.MAX_VALUE);
     right.addLong(234);
 
+    Roaring64Bitmap orNotInPlace = Roaring64Bitmap.or(left, right);
     left.or(right);
 
     assertEquals(3, left.getLongCardinality());
@@ -626,6 +633,12 @@ public void testOrMultipleBuckets() {
     assertEquals(123, left.select(0));
     assertEquals(234, left.select(1));
     assertEquals(Long.MAX_VALUE, left.select(2));
+
+    assertEquals(3, orNotInPlace.getLongCardinality());
+
+    assertEquals(123, orNotInPlace.select(0));
+    assertEquals(234, orNotInPlace.select(1));
+    assertEquals(Long.MAX_VALUE, orNotInPlace.select(2));
   }
 
   @Test
@@ -636,12 +649,18 @@ public void testOrDifferentBucket() {
     left.addLong(123);
     right.addLong(Long.MAX_VALUE / 2);
 
+    Roaring64Bitmap orNotInPlace = Roaring64Bitmap.or(left, right);
     left.or(right);
 
     assertEquals(2, left.getLongCardinality());
 
     assertEquals(123, left.select(0));
     assertEquals(Long.MAX_VALUE / 2, left.select(1));
+
+    assertEquals(2, orNotInPlace.getLongCardinality());
+
+    assertEquals(123, orNotInPlace.select(0));
+    assertEquals(Long.MAX_VALUE / 2, orNotInPlace.select(1));
   }
 
 
@@ -653,12 +672,18 @@ public void testOrDifferentBucket2() {
     left.addLong(123);
     right.addLong(Long.MAX_VALUE);
 
+    Roaring64Bitmap orNotInPlace = Roaring64Bitmap.or(left, right);
     left.or(right);
 
     assertEquals(2, left.getLongCardinality());
 
     assertEquals(123, left.select(0));
     assertEquals(Long.MAX_VALUE, left.select(1));
+
+    assertEquals(2, orNotInPlace.getLongCardinality());
+
+    assertEquals(123, orNotInPlace.select(0));
+    assertEquals(Long.MAX_VALUE, orNotInPlace.select(1));
   }
 
   @Test
@@ -694,11 +719,16 @@ public void testXorBucket() {
     right.addLong(345);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap xorNotInPlace = Roaring64Bitmap.xor(left, right);
     left.xor(right);
 
     assertEquals(2, left.getLongCardinality());
     assertEquals(123, left.select(0));
     assertEquals(345, left.select(1));
+
+    assertEquals(2, xorNotInPlace.getLongCardinality());
+    assertEquals(123, xorNotInPlace.select(0));
+    assertEquals(345, xorNotInPlace.select(1));
   }
 
   @Test
@@ -711,11 +741,16 @@ public void testXor() {
     right.addLong(234);
     right.addLong(345);
 
+    Roaring64Bitmap xorNotInPlace = Roaring64Bitmap.xor(left, right);
     left.xor(right);
 
     assertEquals(2, left.getLongCardinality());
     assertEquals(123, left.select(0));
     assertEquals(345, left.select(1));
+
+    assertEquals(2, xorNotInPlace.getLongCardinality());
+    assertEquals(123, xorNotInPlace.select(0));
+    assertEquals(345, xorNotInPlace.select(1));
   }
 
   @Test
@@ -727,11 +762,16 @@ public void testXorDifferentBucket() {
     right.addLong(Long.MAX_VALUE);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap xorNotInPlace = Roaring64Bitmap.xor(left, right);
     left.xor(right);
 
     assertEquals(2, left.getLongCardinality());
     assertEquals(123, left.select(0));
     assertEquals(Long.MAX_VALUE, left.select(1));
+
+    assertEquals(2, xorNotInPlace.getLongCardinality());
+    assertEquals(123, xorNotInPlace.select(0));
+    assertEquals(Long.MAX_VALUE, xorNotInPlace.select(1));
   }
 
   @Test
@@ -744,10 +784,14 @@ public void testXor_MultipleBucket() {
     right.addLong(Long.MAX_VALUE);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap xorNotInPlace = Roaring64Bitmap.xor(left, right);
     left.xor(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(123, left.select(0));
+
+    assertEquals(1, xorNotInPlace.getLongCardinality());
+    assertEquals(123, xorNotInPlace.select(0));
   }
 
 
@@ -762,10 +806,14 @@ public void testAndSingleBucket() {
     right.addLong(345);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotInPlace = Roaring64Bitmap.and(left, right);
     left.and(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(234, left.select(0));
+
+    assertEquals(1, andNotInPlace.getLongCardinality());
+    assertEquals(234, andNotInPlace.select(0));
   }
 
   @Test
@@ -777,10 +825,14 @@ public void testAnd() {
     right.addLong(123);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotInPlace = Roaring64Bitmap.and(left, right);
     left.and(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(123, left.select(0));
+
+    assertEquals(1, andNotInPlace.getLongCardinality());
+    assertEquals(123, andNotInPlace.select(0));
   }
 
   @Test
@@ -792,17 +844,24 @@ public void testAndDisjoint() {
     Roaring64Bitmap left = Roaring64Bitmap.bitmapOf(leftData);
     Roaring64Bitmap right = Roaring64Bitmap.bitmapOf(rightData);
 
+    Roaring64Bitmap andNotInPlace = Roaring64Bitmap.and(left, right);
     left.and(right);
 
     Roaring64Bitmap swapLeft = Roaring64Bitmap.bitmapOf(rightData);
     Roaring64Bitmap swapRight = Roaring64Bitmap.bitmapOf(leftData);
 
+    Roaring64Bitmap swapAndNotInPlace = Roaring64Bitmap.and(left, right);
     swapLeft.and(swapRight);
 
     assertEquals(0, left.getLongCardinality());
     assertEquals(0, swapLeft.getLongCardinality());
     assertThrows(IllegalArgumentException.class, () -> left.select(0));
     assertThrows(IllegalArgumentException.class, () -> swapLeft.select(0));
+
+    assertEquals(0, andNotInPlace.getLongCardinality());
+    assertEquals(0, swapAndNotInPlace.getLongCardinality());
+    assertThrows(IllegalArgumentException.class, () -> andNotInPlace.select(0));
+    assertThrows(IllegalArgumentException.class, () -> swapAndNotInPlace.select(0));
   }
 
   @Test
@@ -813,9 +872,11 @@ void testToArrayAfterAndOptHasEmptyContainer() {
     Roaring64Bitmap bitmap2 = new Roaring64Bitmap();
     bitmap2.addLong(1);
     //bit and
+    Roaring64Bitmap andNotInPlace = Roaring64Bitmap.and(bitmap, bitmap2);
     bitmap.and(bitmap2);
     //to array
     Assertions.assertDoesNotThrow(bitmap::toArray);
+    Assertions.assertDoesNotThrow(andNotInPlace::toArray);
   }
 
   @Test
@@ -842,12 +903,118 @@ public void testAndMultipleBucket() {
     right.addLong(Long.MAX_VALUE);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotInPlace = Roaring64Bitmap.and(left, right);
     left.and(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(Long.MAX_VALUE, left.select(0));
+
+    assertEquals(1, andNotInPlace.getLongCardinality());
+    assertEquals(Long.MAX_VALUE, andNotInPlace.select(0));
   }
 
+  @Test
+  public void intersecttest() {
+    final Roaring64Bitmap rr1 = new Roaring64Bitmap();
+    final Roaring64Bitmap rr2 = new Roaring64Bitmap();
+    for (int k = 0; k < 40000; ++k) {
+      rr1.add(2 * k);
+      rr2.add(2 * k + 1);
+    }
+    assertFalse(Roaring64Bitmap.intersects(rr1, rr2));
+    rr1.add(2 * 500 + 1);
+    assertTrue(Roaring64Bitmap.intersects(rr1, rr2));
+    final Roaring64Bitmap rr3 = new Roaring64Bitmap();
+    rr3.add(2 * 501 + 1);
+    assertTrue(Roaring64Bitmap.intersects(rr3, rr2));
+    assertFalse(Roaring64Bitmap.intersects(rr3, rr1));
+    for (int k = 0; k < 40000; ++k) {
+      rr1.add(2 * k + 1);
+    }
+    rr1.runOptimize();
+    assertTrue(Roaring64Bitmap.intersects(rr1, rr2));
+  }
+
+  @Test
+  public void andcounttest() {
+    // This is based on andtest
+    final Roaring64Bitmap rr = new Roaring64Bitmap();
+    for (int k = 0; k < 4000; ++k) {
+      rr.add(k);
+    }
+    rr.add(100000);
+    rr.add(110000);
+    final Roaring64Bitmap rr2 = new Roaring64Bitmap();
+    rr2.add(13);
+    final Roaring64Bitmap rrand = Roaring64Bitmap.and(rr, rr2);
+    assertEquals(rrand.getLongCardinality(), Roaring64Bitmap.andCardinality(rr, rr2));
+    assertEquals(rrand.getLongCardinality(), Roaring64Bitmap.andCardinality(rr2, rr));
+    rr.and(rr2);
+    assertEquals(rrand.getLongCardinality(), Roaring64Bitmap.andCardinality(rr2, rr));
+  }
+
+  @Test
+  public void andCounttest3() {
+    // This is based on andtest3
+    final int[] arrayand = new int[11256];
+    int pos = 0;
+    final Roaring64Bitmap rr = new Roaring64Bitmap();
+    for (int k = 4000; k < 4256; ++k) {
+      rr.add(k);
+    }
+    for (int k = 65536; k < 65536 + 4000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 3 * 65536; k < 3 * 65536 + 1000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 3 * 65536 + 7000; k < 3 * 65536 + 9000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 4 * 65536; k < 4 * 65536 + 7000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 6 * 65536; k < 6 * 65536 + 10000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 8 * 65536; k < 8 * 65536 + 1000; ++k) {
+      rr.add(k);
+    }
+    for (int k = 9 * 65536; k < 9 * 65536 + 30000; ++k) {
+      rr.add(k);
+    }
+    final Roaring64Bitmap rr2 = new Roaring64Bitmap();
+    for (int k = 4000; k < 4256; ++k) {
+      rr2.add(k);
+      arrayand[pos++] = k;
+    }
+    for (int k = 65536; k < 65536 + 4000; ++k) {
+      rr2.add(k);
+      arrayand[pos++] = k;
+    }
+    for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) {
+      rr2.add(k);
+      arrayand[pos++] = k;
+    }
+    for (int k = 6 * 65536; k < 6 * 65536 + 1000; ++k) {
+      rr2.add(k);
+      arrayand[pos++] = k;
+    }
+    for (int k = 7 * 65536; k < 7 * 65536 + 1000; ++k) {
+      rr2.add(k);
+    }
+    for (int k = 10 * 65536; k < 10 * 65536 + 5000; ++k) {
+      rr2.add(k);
+    }
+
+    final Roaring64Bitmap rrand = Roaring64Bitmap.and(rr, rr2);
+    final long rrandCount = Roaring64Bitmap.andCardinality(rr, rr2);
+
+    assertEquals(rrand.getLongCardinality(), rrandCount);
+  }
 
   @Test
   public void testAndNotSingleBucket() {
@@ -860,10 +1027,14 @@ public void testAndNotSingleBucket() {
     right.addLong(345);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotNotInPlace = Roaring64Bitmap.andNot(left, right);
     left.andNot(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(123, left.select(0));
+
+    assertEquals(1, andNotNotInPlace.getLongCardinality());
+    assertEquals(123, andNotNotInPlace.select(0));
   }
 
   @Test
@@ -875,10 +1046,14 @@ public void testAndNot() {
     right.addLong(234);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotNotInPlace = Roaring64Bitmap.andNot(left, right);
     left.andNot(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(123, left.select(0));
+
+    assertEquals(1, andNotNotInPlace.getLongCardinality());
+    assertEquals(123, andNotNotInPlace.select(0));
   }
 
   @Test
@@ -890,10 +1065,14 @@ public void testAndNotDifferentBucket() {
     right.addLong(Long.MAX_VALUE);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotNotInPlace = Roaring64Bitmap.andNot(left, right);
     left.andNot(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(123, left.select(0));
+
+    assertEquals(1, andNotNotInPlace.getLongCardinality());
+    assertEquals(123, andNotNotInPlace.select(0));
   }
 
   @Test
@@ -906,10 +1085,14 @@ public void testAndNot_MultipleBucket() {
     right.addLong(Long.MAX_VALUE);
 
     // We have 1 shared value: 234
+    Roaring64Bitmap andNotNotInPlace = Roaring64Bitmap.andNot(left, right);
     left.andNot(right);
 
     assertEquals(1, left.getLongCardinality());
     assertEquals(123, left.select(0));
+
+    assertEquals(1, andNotNotInPlace.getLongCardinality());
+    assertEquals(123, andNotNotInPlace.select(0));
   }
 
   @Test
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
new file mode 100644
index 000000000..a56f32526
--- /dev/null
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
@@ -0,0 +1,616 @@
+package org.roaringbitmap.bsi.longlong;
+
+import org.roaringbitmap.bsi.BitmapSliceIndex;
+import org.roaringbitmap.bsi.Pair;
+import org.roaringbitmap.bsi.WritableUtils;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.IntStream;
+
+public class Roaring64BitmapSliceIndex {
+  /**
+   * the maxValue of this bsi
+   */
+  private long maxValue;
+
+  /**
+   * the minValue of this bsi
+   */
+  private long minValue;
+
+  /**
+   * the bit component slice Array of this bsi
+   */
+  private Roaring64Bitmap[] bA;
+
+  /**
+   * the exist bitmap of this bsi which means the columnId have value in this bsi
+   */
+  private Roaring64Bitmap ebM;
+
+
+  private Boolean runOptimized = false;
+
+  /**
+   * NewBSI constructs a new BSI.  Min/Max values are optional.  If set to 0
+   * then the underlying BSI will be automatically sized.
+   */
+  public Roaring64BitmapSliceIndex(long minValue, long maxValue) {
+    if (minValue < 0) {
+      throw new IllegalArgumentException("Values should be non-negative");
+    }
+
+    this.bA = new Roaring64Bitmap[64 - Long.numberOfLeadingZeros(maxValue)];
+    for (int i = 0; i < bA.length; i++) {
+      this.bA[i] = new Roaring64Bitmap();
+    }
+
+    this.ebM = new Roaring64Bitmap();
+  }
+
+  /**
+   * NewDefaultBSI constructs an auto-sized BSI
+   */
+  public Roaring64BitmapSliceIndex() {
+    this(0L, 0L);
+  }
+
+  public void add(Roaring64BitmapSliceIndex otherBsi) {
+    if (null == otherBsi || otherBsi.ebM.isEmpty()) {
+      return;
+    }
+
+    this.ebM.or(otherBsi.ebM);
+    if (otherBsi.bitCount() > this.bitCount()) {
+      grow(otherBsi.bitCount());
+    }
+
+    for (int i = 0; i < otherBsi.bitCount(); i++) {
+      this.addDigit(otherBsi.bA[i], i);
+    }
+
+    // update min and max after adding
+    this.minValue = minValue();
+    this.maxValue = maxValue();
+  }
+
+  private void addDigit(Roaring64Bitmap foundSet, int i) {
+    Roaring64Bitmap carry = Roaring64Bitmap.and(this.bA[i], foundSet);
+    this.bA[i].xor(foundSet);
+    if (!carry.isEmpty()) {
+      if (i + 1 >= this.bitCount()) {
+        grow(this.bitCount() + 1);
+      }
+      this.addDigit(carry, i + 1);
+    }
+
+  }
+
+  private long minValue() {
+    if (ebM.isEmpty()) {
+      return 0;
+    }
+
+    Roaring64Bitmap minValuesId = ebM;
+    for (int i = bA.length - 1; i >= 0; i -= 1) {
+      Roaring64Bitmap tmp = Roaring64Bitmap.andNot(minValuesId, bA[i]);
+      if (!tmp.isEmpty()) {
+        minValuesId = tmp;
+      }
+    }
+
+    return valueAt(minValuesId.first());
+  }
+
+  private long maxValue() {
+    if (ebM.isEmpty()) {
+      return 0;
+    }
+
+    Roaring64Bitmap maxValuesId = ebM;
+    for (int i = bA.length - 1; i >= 0; i -= 1) {
+      Roaring64Bitmap tmp = Roaring64Bitmap.and(maxValuesId, bA[i]);
+      if (!tmp.isEmpty()) {
+        maxValuesId = tmp;
+      }
+    }
+
+    return valueAt(maxValuesId.first());
+  }
+
+  private long valueAt(long columnId) {
+    int value = 0;
+    for (int i = 0; i < this.bitCount(); i += 1) {
+      if (this.bA[i].contains(columnId)) {
+        value |= (1 << i);
+      }
+    }
+
+    return value;
+  }
+
+  /**
+   * RunOptimize attempts to further compress the runs of consecutive values found in the bitmap
+   */
+  public void runOptimize() {
+    this.ebM.runOptimize();
+
+    for (Roaring64Bitmap integers : this.bA) {
+      integers.runOptimize();
+    }
+    this.runOptimized = true;
+  }
+
+  /**
+   * hasRunCompression returns true if the bitmap benefits from run compression
+   */
+
+  public boolean hasRunCompression() {
+    return this.runOptimized;
+  }
+
+  /**
+   * GetExistenceBitmap returns a pointer to the underlying existence bitmap of the BSI
+   */
+
+  public Roaring64Bitmap getExistenceBitmap() {
+    return this.ebM;
+  }
+
+  public int bitCount() {
+    return this.bA.length;
+  }
+
+  public long getLongCardinality() {
+    return this.ebM.getLongCardinality();
+  }
+
+  /**
+   * GetValue gets the value at the column ID.  Second param will be false for non-existence values.
+   */
+  public Pair getValue(long columnId) {
+    boolean exists = this.ebM.contains(columnId);
+    if (!exists) {
+      return Pair.newPair(0L, false);
+    }
+
+    return Pair.newPair(valueAt(columnId), true);
+  }
+
+
+  private void clear() {
+    this.maxValue = 0;
+    this.minValue = 0;
+    this.ebM = null;
+    this.bA = null;
+  }
+
+  public void serialize(DataOutput output) throws IOException {
+    // write meta
+    WritableUtils.writeVLong(output, minValue);
+    WritableUtils.writeVLong(output, maxValue);
+    output.writeBoolean(this.runOptimized);
+
+    // write ebm
+    this.ebM.serialize(output);
+
+    // write ba
+    WritableUtils.writeVInt(output, this.bA.length);
+    for (Roaring64Bitmap rb : this.bA) {
+      rb.serialize(output);
+    }
+  }
+
+  public void deserialize(DataInput in) throws IOException {
+    this.clear();
+
+    // read meta
+    this.minValue = WritableUtils.readVInt(in);
+    this.maxValue = WritableUtils.readVInt(in);
+    this.runOptimized = in.readBoolean();
+
+    // read ebm
+    Roaring64Bitmap ebm = new Roaring64Bitmap();
+    ebm.deserialize(in);
+    this.ebM = ebm;
+
+    // read ba
+    int bitDepth = WritableUtils.readVInt(in);
+    Roaring64Bitmap[] ba = new Roaring64Bitmap[bitDepth];
+    for (int i = 0; i < bitDepth; i++) {
+      Roaring64Bitmap rb = new Roaring64Bitmap();
+      rb.deserialize(in);
+      ba[i] = rb;
+    }
+    this.bA = ba;
+  }
+
+  public void serialize(ByteBuffer buffer) throws IOException {
+    // write meta
+    buffer.putLong(this.minValue);
+    buffer.putLong(this.maxValue);
+    buffer.put(this.runOptimized ? (byte) 1 : (byte) 0);
+    // write ebm
+    this.ebM.serialize(buffer);
+
+    // write ba
+    buffer.putInt(this.bA.length);
+    for (Roaring64Bitmap rb : this.bA) {
+      rb.serialize(buffer);
+    }
+  }
+
+  public void deserialize(ByteBuffer buffer) throws IOException {
+    this.clear();
+    // read meta
+    this.minValue = buffer.getLong();
+    this.maxValue = buffer.getLong();
+    this.runOptimized = buffer.get() == (byte) 1;
+
+    // read ebm
+    Roaring64Bitmap ebm = new Roaring64Bitmap();
+    ebm.deserialize(buffer);
+    this.ebM = ebm;
+    // read ba
+    buffer.position(buffer.position() + ebm.getSizeInBytes());
+    int bitDepth = buffer.getInt();
+    Roaring64Bitmap[] ba = new Roaring64Bitmap[bitDepth];
+    for (int i = 0; i < bitDepth; i++) {
+      Roaring64Bitmap rb = new Roaring64Bitmap();
+      rb.deserialize(buffer);
+      ba[i] = rb;
+      buffer.position(buffer.position() + rb.getSizeInBytes());
+    }
+    this.bA = ba;
+  }
+
+  public int serializedSizeInBytes() {
+    int size = 0;
+    for (Roaring64Bitmap rb : this.bA) {
+      size += rb.getSizeInBytes();
+    }
+    return 8 + 8 + 1 + 4 + this.ebM.getSizeInBytes() + size;
+  }
+
+  /**
+   * valueExists tests whether the value exists.
+   */
+  public boolean valueExist(Long columnId) {
+    return this.ebM.contains(columnId);
+  }
+
+  /**
+   * SetValue sets a value for a given columnID.
+   */
+  public void setValue(long columnId, long value) {
+    ensureCapacityInternal(value, value);
+    setValueInternal(columnId, value);
+  }
+
+  private void setValueInternal(long columnId, long value) {
+    for (int i = 0; i < this.bitCount(); i += 1) {
+      if ((value & (1L << i)) > 0) {
+        this.bA[i].add(columnId);
+      } else {
+        this.bA[i].remove(columnId);
+      }
+    }
+    this.ebM.add(columnId);
+  }
+
+  private void ensureCapacityInternal(long minValue, long maxValue) {
+    if (ebM.isEmpty()) {
+      this.minValue = minValue;
+      this.maxValue = maxValue;
+      grow(Long.toBinaryString(maxValue).length());
+    } else if (this.minValue > minValue) {
+      this.minValue = minValue;
+    } else if (this.maxValue < maxValue) {
+      this.maxValue = maxValue;
+      grow(Long.toBinaryString(maxValue).length());
+    }
+  }
+
+  private void grow(int newBitDepth) {
+    int oldBitDepth = this.bA.length;
+
+    if (oldBitDepth >= newBitDepth) {
+      return;
+    }
+
+    Roaring64Bitmap[] newBA = new Roaring64Bitmap[newBitDepth];
+    if (oldBitDepth != 0) {
+      System.arraycopy(this.bA, 0, newBA, 0, oldBitDepth);
+    }
+
+    for (int i = newBitDepth - 1; i >= oldBitDepth; i--) {
+      newBA[i] = new Roaring64Bitmap();
+      if (this.runOptimized) {
+        newBA[i].runOptimize();
+      }
+    }
+    this.bA = newBA;
+  }
+
+  public void setValues(List> values) {
+    long maxValue = values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).max().getAsLong();
+    long minValue = values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).min().getAsLong();
+    ensureCapacityInternal(minValue, maxValue);
+    for (Pair pair : values) {
+      setValueInternal(pair.getKey(), pair.getValue());
+    }
+  }
+
+  /**
+   * merge will merge 2 bsi into current
+   * merge API was designed for distributed computing
+   * note: current and other bsi has no intersection
+   *
+   * @param otherBsi other bsi we need merge
+   */
+  public void merge(Roaring64BitmapSliceIndex otherBsi) {
+
+    if (null == otherBsi || otherBsi.ebM.isEmpty()) {
+      return;
+    }
+
+    // todo whether we need this
+    if (Roaring64Bitmap.intersects(this.ebM, otherBsi.ebM)) {
+      throw new IllegalArgumentException("merge can be used only in bsiA  bsiB  is null");
+    }
+
+    int bitDepth = Integer.max(this.bitCount(), otherBsi.bitCount());
+    Roaring64Bitmap[] newBA = new Roaring64Bitmap[bitDepth];
+    for (int i = 0; i < bitDepth; i++) {
+      Roaring64Bitmap current = i < this.bA.length ? this.bA[i] : new Roaring64Bitmap();
+      Roaring64Bitmap other = i < otherBsi.bA.length ? otherBsi.bA[i] : new Roaring64Bitmap();
+      newBA[i] = Roaring64Bitmap.or(current, other);
+      if (this.runOptimized || otherBsi.runOptimized) {
+        newBA[i].runOptimize();
+      }
+    }
+    this.bA = newBA;
+    this.ebM.or(otherBsi.ebM);
+    this.runOptimized = this.runOptimized || otherBsi.runOptimized;
+    this.maxValue = Long.max(this.maxValue, otherBsi.maxValue);
+    this.minValue = Long.min(this.minValue, otherBsi.minValue);
+  }
+
+  @Override
+  public Roaring64BitmapSliceIndex clone() {
+    Roaring64BitmapSliceIndex bitSliceIndex = new Roaring64BitmapSliceIndex();
+    bitSliceIndex.minValue = this.minValue;
+    bitSliceIndex.maxValue = this.maxValue;
+    bitSliceIndex.ebM = this.ebM.clone();
+    Roaring64Bitmap[] cloneBA = new Roaring64Bitmap[this.bitCount()];
+    for (int i = 0; i < cloneBA.length; i++) {
+      cloneBA[i] = this.bA[i].clone();
+    }
+    bitSliceIndex.bA = cloneBA;
+    bitSliceIndex.runOptimized = this.runOptimized;
+
+    return bitSliceIndex;
+  }
+
+  /**
+   * O'Neil range using a bit-sliced index
+   *
+   * @param operation compare operation
+   * @param predicate the value we found filter
+   * @param foundSet  columnId set we want compare,using RoaringBitmap to express
+   * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
+   * see https://github.com/lemire/BitSliceIndex/blob/master/src/main/java/org/roaringbitmap/circuits/comparator/BasicComparator.java
+   */
+  private Roaring64Bitmap oNeilCompare(BitmapSliceIndex.Operation operation, long predicate, Roaring64Bitmap foundSet) {
+    Roaring64Bitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
+
+    Roaring64Bitmap GT = new Roaring64Bitmap();
+    Roaring64Bitmap LT = new Roaring64Bitmap();
+    Roaring64Bitmap EQ = this.ebM;
+
+
+    for (int i = this.bitCount() - 1; i >= 0; i--) {
+      int bit = (int) ((predicate >> i) & 1);
+      if (bit == 1) {
+        LT = Roaring64Bitmap.or(LT, Roaring64Bitmap.andNot(EQ, this.bA[i]));
+        EQ = Roaring64Bitmap.and(EQ, this.bA[i]);
+      } else {
+        GT = Roaring64Bitmap.or(GT, Roaring64Bitmap.and(EQ, this.bA[i]));
+        EQ = Roaring64Bitmap.andNot(EQ, this.bA[i]);
+      }
+
+    }
+    EQ = Roaring64Bitmap.and(fixedFoundSet, EQ);
+    switch (operation) {
+      case EQ:
+        return EQ;
+      case NEQ:
+        return Roaring64Bitmap.andNot(fixedFoundSet, EQ);
+      case GT:
+        return Roaring64Bitmap.and(GT, fixedFoundSet);
+      case LT:
+        return Roaring64Bitmap.and(LT, fixedFoundSet);
+      case LE:
+        return Roaring64Bitmap.and(Roaring64Bitmap.or(LT, EQ), fixedFoundSet);
+      case GE:
+        return Roaring64Bitmap.and(Roaring64Bitmap.or(GT, EQ), fixedFoundSet);
+      default:
+        throw new IllegalArgumentException("");
+    }
+  }
+
+  /**
+   * BSI Compare using single thread
+   * this Function compose algorithm from O'Neil and Owen Kaser
+   * the GE algorithm is from Owen since the performance is better.  others are from O'Neil
+   *
+   * @param operation
+   * @param startOrValue the start or value of comparison, when the comparison operation is range, it's start,
+   *                     when others,it's value.
+   * @param end          the end value of comparison. when the comparison operation is not range,the end = 0
+   * @param foundSet     columnId set we want compare,using RoaringBitmap to express
+   * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
+   */
+  public Roaring64Bitmap compare(BitmapSliceIndex.Operation operation, long startOrValue, long end, Roaring64Bitmap foundSet) {
+    Roaring64Bitmap result = compareUsingMinMax(operation, startOrValue, end, foundSet);
+    if (result != null) {
+      return result;
+    }
+
+    switch (operation) {
+      case EQ:
+        return oNeilCompare(BitmapSliceIndex.Operation.EQ, startOrValue, foundSet);
+      case NEQ:
+        return oNeilCompare(BitmapSliceIndex.Operation.NEQ, startOrValue, foundSet);
+      case GE:
+        return oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet);
+      case GT: {
+        return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
+      }
+      case LT:
+        return oNeilCompare(BitmapSliceIndex.Operation.LT, startOrValue, foundSet);
+
+      case LE:
+        return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
+
+      case RANGE: {
+        Roaring64Bitmap left = oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet);
+        Roaring64Bitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
+
+        return Roaring64Bitmap.and(left, right);
+      }
+      default:
+        throw new IllegalArgumentException("not support operation!");
+    }
+  }
+
+  private Roaring64Bitmap compareUsingMinMax(BitmapSliceIndex.Operation operation, long startOrValue, long end, Roaring64Bitmap foundSet) {
+    Roaring64Bitmap all = foundSet == null ? ebM.clone() : Roaring64Bitmap.and(ebM, foundSet);
+    Roaring64Bitmap empty = new Roaring64Bitmap();
+
+    switch (operation) {
+      case LT:
+        if (startOrValue > maxValue) {
+          return all;
+        } else if (startOrValue <= minValue) {
+          return empty;
+        }
+
+        break;
+      case LE:
+        if (startOrValue >= maxValue) {
+          return all;
+        } else if (startOrValue < minValue) {
+          return empty;
+        }
+
+        break;
+      case GT:
+        if (startOrValue < minValue) {
+          return all;
+        } else if (startOrValue >= maxValue) {
+          return empty;
+        }
+
+        break;
+      case GE:
+        if (startOrValue <= minValue) {
+          return all;
+        } else if (startOrValue > maxValue) {
+          return empty;
+        }
+
+        break;
+      case EQ:
+        if (minValue == maxValue && minValue == startOrValue) {
+          return all;
+        } else if (startOrValue < minValue || startOrValue > maxValue) {
+          return empty;
+        }
+
+        break;
+      case NEQ:
+        if (minValue == maxValue) {
+          return minValue == startOrValue ? empty : all;
+        }
+
+        break;
+      case RANGE:
+        if (startOrValue <= minValue && end >= maxValue) {
+          return all;
+        } else if (startOrValue > maxValue || end < minValue) {
+          return empty;
+        }
+
+        break;
+      default:
+        return null;
+    }
+
+    return null;
+  }
+
+  public Pair sum(Roaring64Bitmap foundSet) {
+    if (null == foundSet || foundSet.isEmpty()) {
+      return Pair.newPair(0L, 0L);
+    }
+    long count = foundSet.getLongCardinality();
+
+    Long sum = IntStream.range(0, this.bitCount())
+        .mapToLong(x -> (1L << x) * Roaring64Bitmap.andCardinality(this.bA[x], foundSet))
+        .sum();
+
+    return Pair.newPair(sum, count);
+  }
+
+  public Roaring64Bitmap topK(Roaring64Bitmap foundSet, long k) {
+    if (null == foundSet || foundSet.isEmpty()) {
+      return new Roaring64Bitmap();
+    }
+    if (k >= foundSet.getLongCardinality()) {
+      return foundSet;
+    }
+    Roaring64Bitmap re = new Roaring64Bitmap();
+    Roaring64Bitmap candidates = foundSet.clone();
+
+    for (int x = this.bitCount() - 1; x >= 0 && !candidates.isEmpty() && k > 0; x--) {
+      long cardinality = Roaring64Bitmap.and(candidates, this.bA[x]).getLongCardinality();
+
+      if (cardinality > k) {
+        candidates.and(this.bA[x]);
+      } else {
+        re.or(Roaring64Bitmap.and(candidates, this.bA[x]));
+        candidates.andNot(this.bA[x]);
+        k -= cardinality;
+      }
+    }
+    return re;
+  }
+
+  public Roaring64Bitmap transpose(Roaring64Bitmap foundSet) {
+    Roaring64Bitmap re = new Roaring64Bitmap();
+    Roaring64Bitmap fixedFoundSet = foundSet == null ? this.ebM : Roaring64Bitmap.and(foundSet, this.ebM);
+    fixedFoundSet.forEach((long x) -> re.add(this.getValue(x).getKey()));
+    return re;
+  }
+
+  public Roaring64BitmapSliceIndex transposeWithCount(Roaring64Bitmap foundSet) {
+    Roaring64BitmapSliceIndex re = new Roaring64BitmapSliceIndex();
+    Roaring64Bitmap fixedFoundSet = foundSet == null ? this.ebM : Roaring64Bitmap.and(foundSet, this.ebM);
+    fixedFoundSet.forEach((long x) -> {
+      long nk = this.getValue(x).getKey();
+      if (re.valueExist(nk)) {
+        re.setValue(nk, re.getValue(nk).getKey() + 1);
+      } else {
+        re.setValue(nk, 1);
+      }
+    });
+    return re;
+  }
+}
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
new file mode 100644
index 000000000..808bd92ec
--- /dev/null
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
@@ -0,0 +1,370 @@
+package org.roaringbitmap.bsi;
+
+import org.junit.jupiter.api.*;
+import org.roaringbitmap.bsi.longlong.Roaring64BitmapSliceIndex;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+
+public class R64BSITest {
+  private Map testDataSet = new HashMap<>();
+
+  private Roaring64BitmapSliceIndex bsi;
+
+  @BeforeEach
+  public void setup() {
+    LongStream.range(1, 100).forEach(x -> testDataSet.put(x, x));
+    bsi = new Roaring64BitmapSliceIndex(1, 99);
+    testDataSet.forEach((k, v) -> {
+      bsi.setValue(k, v);
+    });
+  }
+
+  @Test
+  public void testSetAndGet() {
+    LongStream.range(1, 100).forEach(x -> {
+      Pair pair = bsi.getValue(x);
+      Assertions.assertTrue(pair.getRight());
+      Assertions.assertEquals((long) pair.getKey(), x);
+    });
+
+    IntStream.range(1, 100).forEach(x -> {
+      Pair pair = bsi.getValue(x);
+      Assertions.assertTrue(pair.getRight());
+      Assertions.assertEquals((long) pair.getKey(), x);
+    });
+  }
+
+  @Test
+  public void testMerge() {
+    Roaring64BitmapSliceIndex bsiA = new Roaring64BitmapSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    Roaring64BitmapSliceIndex bsiB = new Roaring64BitmapSliceIndex();
+    IntStream.range(100, 199).forEach(x -> bsiB.setValue(x, x));
+    Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99);
+    Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99);
+    bsiA.merge(bsiB);
+    IntStream.range(1, 199).forEach(x -> {
+      Pair bsiValue = bsiA.getValue(x);
+      Assertions.assertTrue(bsiValue.getRight());
+      Assertions.assertEquals((long) bsiValue.getKey(), x);
+    });
+  }
+
+
+  @Test
+  public void testClone() {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
+    List> collect = testDataSet.entrySet()
+        .stream().map(x -> Pair.newPair(x.getKey(), x.getValue())).collect(Collectors.toList());
+
+    bsi.setValues(collect);
+
+    Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99);
+    final Roaring64BitmapSliceIndex clone = bsi.clone();
+
+    IntStream.range(1, 100).forEach(x -> {
+      Pair bsiValue = clone.getValue(x);
+      Assertions.assertTrue(bsiValue.getRight());
+      Assertions.assertEquals((long) bsiValue.getKey(), x);
+    });
+  }
+
+
+  @Test
+  public void testAdd() {
+    Roaring64BitmapSliceIndex bsiA = new Roaring64BitmapSliceIndex();
+    LongStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    Roaring64BitmapSliceIndex bsiB = new Roaring64BitmapSliceIndex();
+    LongStream.range(1, 120).forEach(x -> bsiB.setValue(x, x));
+
+    bsiA.add(bsiB);
+
+    LongStream.range(1, 120).forEach(x -> {
+      Pair bsiValue = bsiA.getValue(x);
+      Assertions.assertTrue(bsiValue.getRight());
+      if (x < 100) {
+        Assertions.assertEquals((long) bsiValue.getKey(), x * 2);
+      } else {
+        Assertions.assertEquals((long) bsiValue.getKey(), x);
+      }
+
+    });
+  }
+
+  @Test
+  public void testAddAndEvaluate() {
+    Roaring64BitmapSliceIndex bsiA = new Roaring64BitmapSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    Roaring64BitmapSliceIndex bsiB = new Roaring64BitmapSliceIndex();
+    IntStream.range(1, 120).forEach(x -> bsiB.setValue(120 - x, x));
+
+    bsiA.add(bsiB);
+
+    Roaring64Bitmap result = bsiA.compare(BitmapSliceIndex.Operation.EQ, 120, 0, null);
+    Assertions.assertEquals(99, result.getLongCardinality());
+    Assertions.assertArrayEquals(result.toArray(), LongStream.range(1, 100).toArray());
+
+    result = bsiA.compare(BitmapSliceIndex.Operation.RANGE, 1, 20, null);
+    Assertions.assertEquals(20, result.getLongCardinality());
+    Assertions.assertArrayEquals(result.toArray(), LongStream.range(100, 120).toArray());
+  }
+
+
+  @Test
+  public void TestIO4Stream() throws IOException {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
+    LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    DataOutputStream bdo = new DataOutputStream(bos);
+    bsi.serialize(bdo);
+    byte[] data = bos.toByteArray();
+
+    Roaring64BitmapSliceIndex newBsi = new Roaring64BitmapSliceIndex();
+
+    ByteArrayInputStream bis = new ByteArrayInputStream(data);
+    DataInputStream bdi = new DataInputStream(bis);
+    newBsi.deserialize(bdi);
+
+    Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+
+    LongStream.range(1, 100).forEach(x -> {
+      Pair bsiValue = newBsi.getValue(x);
+      Assertions.assertTrue(bsiValue.getRight());
+      Assertions.assertEquals((long) bsiValue.getKey(), x);
+    });
+  }
+
+  @Test
+  public void testIO4Buffer() throws IOException {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
+    LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
+    bsi.serialize(buffer);
+
+    byte[] data = buffer.array();
+    Roaring64BitmapSliceIndex newBsi = new Roaring64BitmapSliceIndex();
+    newBsi.deserialize(ByteBuffer.wrap(data));
+    Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+
+    LongStream.range(1, 100).forEach(x -> {
+      Pair bsiValue = newBsi.getValue(x);
+      Assertions.assertTrue(bsiValue.getRight());
+      Assertions.assertEquals((long) bsiValue.getKey(), x);
+    });
+  }
+
+
+  @Test
+  public void testIOFromExternal() {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
+    LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+
+    LongStream.range(1, 100).forEach(x -> {
+      Pair bsiValue = bsi.getValue(x);
+      Assertions.assertTrue(bsiValue.getRight());
+      Assertions.assertEquals((long) bsiValue.getKey(), x);
+    });
+  }
+
+
+  @Test
+  public void testEQ() {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
+    LongStream.range(1, 100).forEach(x -> {
+      if (x <= 50) {
+        bsi.setValue(x, 1);
+      } else {
+        bsi.setValue(x, x);
+      }
+
+    });
+
+    Roaring64Bitmap bitmap = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
+    Assertions.assertEquals(50L, bitmap.getLongCardinality());
+
+  }
+
+  @Test
+  public void testNotEQ() {
+    bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(1, 99);
+    bsi.setValue(2, 1);
+    bsi.setValue(3, 50);
+
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
+    Assertions.assertEquals(2, result.getLongCardinality());
+    Assertions.assertArrayEquals(new long[]{2, 3}, result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null);
+    Assertions.assertEquals(3, result.getLongCardinality());
+    Assertions.assertArrayEquals(new long[]{1, 2, 3}, result.toArray());
+
+    bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(1, 99);
+    bsi.setValue(2, 99);
+    bsi.setValue(3, 99);
+
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null);
+    Assertions.assertEquals(3, result.getLongCardinality());
+    Assertions.assertArrayEquals(new long[]{1, 2, 3}, result.toArray());
+  }
+
+
+  // parallel operation test
+
+  @Test
+  public void testGT() {
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.GT, 50, 0, null);
+    Assertions.assertEquals(49, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(51, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.GT, 0, 0, null);
+    Assertions.assertEquals(99, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.GT, 99, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+
+  @Test
+  public void testGE() {
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null);
+    Assertions.assertEquals(50, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(50, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, 1, 0, null);
+    Assertions.assertEquals(99, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testLT() {
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.LT, 50, 0, null);
+    Assertions.assertEquals(49, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 50).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.LT, Integer.MAX_VALUE, 0, null);
+    Assertions.assertEquals(99, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.LT, 1, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+
+  @Test
+  public void testLE() {
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null);
+    Assertions.assertEquals(50, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 51).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, null);
+    Assertions.assertEquals(99, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testRANGE() {
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 10, 20, null);
+    Assertions.assertEquals(11, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(10, 21).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1, 200, null);
+    Assertions.assertEquals(99, result.getLongCardinality());
+    Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1000, 2000, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testSum() {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
+    LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+
+    Roaring64Bitmap foundSet = Roaring64Bitmap.bitmapOf(LongStream.range(1, 51).toArray());
+
+    Pair sumPair = bsi.sum(foundSet);
+
+    System.out.println("sum:" + sumPair.toString());
+
+    long sum = LongStream.range(1, 51).sum();
+    long count = LongStream.range(1, 51).count();
+
+    Assertions.assertTrue(sumPair.getLeft().intValue() == sum && sumPair.getRight() == count);
+  }
+
+  @Test
+  public void testValueZero() {
+    bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(0, 0);
+    bsi.setValue(1, 0);
+    bsi.setValue(2, 1);
+
+    Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null);
+    Assertions.assertEquals(2, result.getLongCardinality());
+    Assertions.assertArrayEquals(new long[]{0, 1}, result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
+    Assertions.assertEquals(1, result.getLongCardinality());
+    Assertions.assertArrayEquals(new long[]{2}, result.toArray());
+  }
+
+  @Test
+  public void testTopK() {
+    bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(1, 3);
+    bsi.setValue(2, 6);
+    bsi.setValue(3, 4);
+    bsi.setValue(4, 10);
+    bsi.setValue(5, 7);
+    Roaring64Bitmap re = bsi.topK(bsi.getExistenceBitmap(), 2);
+    Assertions.assertEquals(re, Roaring64Bitmap.bitmapOf(4, 5));
+  }
+
+  @Test
+  public void testTranspose() {
+    bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(1, 2);
+    bsi.setValue(2, 4);
+    bsi.setValue(3, 4);
+    bsi.setValue(4, 8);
+    bsi.setValue(5, 8);
+    Roaring64Bitmap re = bsi.transpose(null);
+    Assertions.assertEquals(re, Roaring64Bitmap.bitmapOf(2, 4, 8));
+  }
+
+  @Test
+  public void testTransposeWithCount() {
+    bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(1, 2);
+    bsi.setValue(2, 4);
+    bsi.setValue(3, 4);
+    bsi.setValue(4, 8);
+    bsi.setValue(5, 8);
+    Roaring64BitmapSliceIndex re = bsi.transposeWithCount(null);
+    Assertions.assertEquals(re.getExistenceBitmap(), Roaring64Bitmap.bitmapOf(2, 4, 8));
+    Assertions.assertEquals(re.getValue(2).getKey(), 1);
+    Assertions.assertEquals(re.getValue(4).getKey(), 2);
+    Assertions.assertEquals(re.getValue(8).getKey(), 2);
+  }
+}
+

From 8241bd70158e42f9566f7c6b9153b1238447cfd9 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Mon, 9 Sep 2024 09:06:51 -0400
Subject: [PATCH 082/167] [no-ci] Update README.md

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index e7d7b233e..1042c8389 100644
--- a/README.md
+++ b/README.md
@@ -273,6 +273,10 @@ from the org.roaringbitmap.buffer package. They are incompatible. They serialize
 to the same output however. The performance of the code in org.roaringbitmap package is
 generally superior because there is no overhead due to the use of ByteBuffer instances.
 
+Thread safety
+-----
+
+In general, it is unsafe to access the same bitmaps using different threads--the bitmaps are unsynchronized for performance. Should you want to access a Bitmap from more than one thread, you should provide synchronization. However, you can access an immutable bitmap from multiple threads, as long as you abide by the `ImmutableBitmapDataProvider` interface.
 
 Kryo
 -----

From d74b6ba39129695edd08b4768b02d0ee3190b543 Mon Sep 17 00:00:00 2001
From: Anand Kr Shaw 
Date: Wed, 18 Sep 2024 00:44:23 +0530
Subject: [PATCH 083/167] Changes for adding container size (#742)

* Changes for adding container size

* Changes for adding container size

* Changes for adding container size
---
 .../org/roaringbitmap/ImmutableBitmapDataProvider.java |  8 ++++++++
 .../src/main/java/org/roaringbitmap/RoaringBitmap.java |  9 +++++++++
 .../roaringbitmap/buffer/ImmutableRoaringBitmap.java   |  9 +++++++++
 .../test/java/org/roaringbitmap/TestRoaringBitmap.java | 10 ++++++++++
 .../buffer/TestImmutableRoaringBitmap.java             | 10 ++++++++++
 5 files changed, 46 insertions(+)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
index f740c23bf..0dcc67168 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
@@ -318,6 +318,14 @@ public default IntStream reverseStream() {
    */
   int[] toArray();
 
+  /**
+   * Returns the number of containers in the bitmap.
+   *
+   * @return the number of containers
+   */
+  int getContainerCount();
+
+
   /**
    * An internal class to help provide streams.
    * Sad but true the interface of IntIterator and PrimitiveIterator.OfInt
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
index a1508626f..e312b541a 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
@@ -3381,5 +3381,14 @@ public static RoaringBitmap xor(final Iterator bitmaps,
     return xor(bitmaps, (long) rangeStart, (long) rangeEnd);
   }
 
+  /**
+   * Returns the number of containers in the bitmap.
+   *
+   * @return the number of containers
+   */
+  @Override
+  public int getContainerCount() {
+    return highLowContainer.size();
+  }
 
 }
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
index a28c089b8..763fdbbdf 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
@@ -2039,4 +2039,13 @@ public String toString() {
     return answer.toString();
   }
 
+  /**
+   * Returns the number of containers in the bitmap.
+   *
+   * @return the number of containers
+   */
+  @Override
+  public int getContainerCount() {
+    return highLowContainer.size();
+  }
 }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
index c8e54e6b5..bfff5c652 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
@@ -5577,4 +5577,14 @@ public void testSelectRange() {
         }
     }
 
+    @Test
+    public void testContainerSizeRoaringBitmapMultiple() {
+        RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 1000000);
+        assertEquals(16, r.getContainerCount());
+    }
+    @Test
+    public void testContainerSizeRoaringBitmapSingle() {
+        RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 100);
+        assertEquals(1, r.getContainerCount());
+    }
 }
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
index 1929374ec..cc8f0a2ff 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
@@ -1588,4 +1588,14 @@ public void testAbsentBits() {
   public void invalidCookie() {
     assertThrows(InvalidRoaringFormat.class, () -> new ImmutableRoaringBitmap(ByteBuffer.allocate(8)));
   }
+  @Test
+  public void testContainerSizeRoaringBitmapMultiple() {
+    ImmutableRoaringBitmap r = ImmutableRoaringBitmap.bitmapOf(1, 1000000);
+    assertEquals(2, r.getContainerCount());
+  }
+  @Test
+  public void testContainerSizeRoaringBitmapSingle() {
+    ImmutableRoaringBitmap r = ImmutableRoaringBitmap.bitmapOf(1);
+    assertEquals(1, r.getContainerCount());
+  }
 }

From e065c2095aa55a36e86c28e782b2cb9d09f70648 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:16:48 -0400
Subject: [PATCH 084/167] [Gradle Release Plugin] - pre tag commit:  '1.2.2'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index ddf64fdac..7788d6c6c 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.2-SNAPSHOT
+version = 1.2.2
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 42e8183259638a17aacb6776c2ddb17b848539ae Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:16:50 -0400
Subject: [PATCH 085/167] [Gradle Release Plugin] - new version commit: 
 '1.2.3-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 7788d6c6c..d98cd7104 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.2
+version = 1.2.3-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 31a98c507a04a51723cb64fc092e6dc17cc62f49 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:17:15 -0400
Subject: [PATCH 086/167] [Gradle Release Plugin] - pre tag commit:  '1.2.3'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index d98cd7104..fd286021d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.3-SNAPSHOT
+version = 1.2.3
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From abc1146cd93f802fb9fbf7842aae68af36ca9faf Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:17:17 -0400
Subject: [PATCH 087/167] [Gradle Release Plugin] - new version commit: 
 '1.2.4-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index fd286021d..4b08fc5b5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.3
+version = 1.2.4-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From d660709610a35c77594cef9ccce3fe09b0749601 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:18:03 -0400
Subject: [PATCH 088/167] bump

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 4b08fc5b5..65f288983 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.2.4-SNAPSHOT
+version = 1.3.0-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From bd392073de6ba9c578a3d1690b3c72002395925b Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:18:35 -0400
Subject: [PATCH 089/167] [Gradle Release Plugin] - pre tag commit:  '1.3.0'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 65f288983..e13497425 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.0-SNAPSHOT
+version = 1.3.0
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 10d0e15af5bbd7cb4f71a2feb43e2e8b8ba17c89 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 17 Sep 2024 15:18:37 -0400
Subject: [PATCH 090/167] [Gradle Release Plugin] - new version commit: 
 '1.3.1-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index e13497425..0996f0b6a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.0
+version = 1.3.1-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 637edeb5a2e69a2f45e43e80074e12f714cc7e43 Mon Sep 17 00:00:00 2001
From: xtonik 
Date: Tue, 17 Sep 2024 21:24:34 +0200
Subject: [PATCH 091/167] Merging bitmap keys deduplicated (#706)

* common routine for bitmap keys intersection

* common routine for immutable bitmap keys intersection

* common routine for conversion bitmap array to array of values

* merge new methods with existing one

* Update RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java

Co-authored-by: Daniel Lemire 

* Update RoaringBitmap/src/main/java/org/roaringbitmap/Util.java

Co-authored-by: Daniel Lemire 

---------

Co-authored-by: Daniel Lemire 
---
 .../java/org/roaringbitmap/BitSetUtil.java    |  30 +++--
 .../org/roaringbitmap/BitmapContainer.java    |   9 ++
 .../org/roaringbitmap/FastAggregation.java    |  84 ++----------
 .../src/main/java/org/roaringbitmap/Util.java |  25 ++++
 .../buffer/BufferFastAggregation.java         | 127 ++----------------
 .../org/roaringbitmap/buffer/BufferUtil.java  |  35 +++++
 .../buffer/MappeableBitmapContainer.java      |  24 ++++
 7 files changed, 140 insertions(+), 194 deletions(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
index 58e613834..1681a5ce4 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
@@ -119,20 +119,34 @@ public static long[] toLongArray(RoaringBitmap bitmap) {
    */
   public static char[] arrayContainerBufferOf(final int from, final int to, final int cardinality,
                                               final long[] words) {
-    // precondition: cardinality is max 4096
-    final char[] content = new char[cardinality];
-    int index = 0;
+    return arrayContainerBufferOf(from, to, new char[cardinality], words);
+  }
 
-    for (int i = from, socket = 0; i < to; ++i, socket += Long.SIZE) {
+  /**
+   * Creates array container's content char buffer.
+   *
+   * @param from        first value of the range
+   * @param to          last value of the range
+   * @param buffer      new buffer, expected to have size less than 4096 and more than present
+   *                    values in given bitmap
+   * @param words       bitmap
+   * @return array container's content char buffer - the same as {@code buffer}
+   */
+  public static char[] arrayContainerBufferOf(final int from, final int to, final char[] buffer,
+                                              final long[] words) {
+    // precondition: cardinality is max 4096
+    int base = 0;
+    int pos = 0;
+    for (int i = from; i < to; i++) {
       long word = words[i];
-      while (word != 0) {
-        content[index++] = (char) (socket + numberOfTrailingZeros(word));
+      while (word != 0L) {
+        buffer[pos++] = (char) (base + numberOfTrailingZeros(word));
         word &= (word - 1);
       }
+      base += 64;
     }
-    return content;
+    return buffer;
   }
-
   private static ArrayContainer arrayContainerOf(final int from, final int to,
                                                  final int cardinality, final long[] words) {
     return new ArrayContainer(arrayContainerBufferOf(from, to, cardinality, words));
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
index f7d634fb5..297504576 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
@@ -428,6 +428,15 @@ public boolean equals(Object o) {
   }
 
 
+  /**
+   * Fill the array with set bits
+   *
+   * @param array container (should be sufficiently large)
+   */
+  void fillArray(final char[] array) {
+    BitSetUtil.arrayContainerBufferOf(0, bitmap.length, array, bitmap);
+  }
+
   @Override
   public void fillLeastSignificant16bits(int[] x, int i, int mask) {
     int pos = i;
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java b/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java
index ab4681b8c..6c89b97f1 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java
@@ -355,29 +355,11 @@ public static RoaringBitmap naive_and(RoaringBitmap... bitmaps) {
    */
   public static RoaringBitmap workShyAnd(long[] buffer, RoaringBitmap... bitmaps) {
     long[] words = buffer;
-    RoaringBitmap first = bitmaps[0];
-    for (int i = 0; i < first.highLowContainer.size; ++i) {
-      char key = first.highLowContainer.keys[i];
-      words[key >>> 6] |= 1L << key;
-    }
-    int numContainers = first.highLowContainer.size;
-    for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) {
-      numContainers = Util.intersectArrayIntoBitmap(words,
-              bitmaps[i].highLowContainer.keys, bitmaps[i].highLowContainer.size);
-    }
-    if (numContainers == 0) {
+    char[] keys = Util.intersectKeys(words, bitmaps);
+    if (keys.length == 0) {
       return new RoaringBitmap();
     }
-    char[] keys = new char[numContainers];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    int numContainers = keys.length;
     Container[][] containers = new Container[numContainers][bitmaps.length];
     for (int i = 0; i < bitmaps.length; ++i) {
       RoaringBitmap bitmap = bitmaps[i];
@@ -415,29 +397,11 @@ public static RoaringBitmap workShyAnd(long[] buffer, RoaringBitmap... bitmaps)
 
   private static int workShyAndCardinality(RoaringBitmap... bitmaps) {
     long[] words = new long[1024];
-    RoaringBitmap first = bitmaps[0];
-    for (int i = 0; i < first.highLowContainer.size; ++i) {
-      char key = first.highLowContainer.keys[i];
-      words[key >>> 6] |= 1L << key;
-    }
-    int numKeys = first.highLowContainer.size;
-    for (int i = 1; i < bitmaps.length && numKeys > 0; ++i) {
-      numKeys = Util.intersectArrayIntoBitmap(words,
-          bitmaps[i].highLowContainer.keys, bitmaps[i].highLowContainer.size);
-    }
-    if (numKeys == 0) {
+    char[] keys = Util.intersectKeys(words, bitmaps);
+    if (keys.length == 0) {
       return 0;
     }
-    char[] keys = new char[numKeys];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    int numKeys = keys.length;
     int cardinality = 0;
     for (int i = 0; i < numKeys; i++) {
       Arrays.fill(words, -1L);
@@ -474,16 +438,7 @@ private static int horizontalOrCardinality(RoaringBitmap... bitmaps) {
       }
     }
     int numKeys = Util.cardinalityInBitmapRange(words, minKey, maxKey + 1);
-    char[] keys = new char[numKeys];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    char[] keys = BitSetUtil.arrayContainerBufferOf(0, words.length, numKeys, words);
 
     int cardinality = 0;
     for (char key : keys) {
@@ -524,29 +479,12 @@ public static RoaringBitmap workAndMemoryShyAnd(long[] buffer, RoaringBitmap...
       throw new IllegalArgumentException("buffer should have at least 1024 elements.");
     }
     long[] words = buffer;
-    RoaringBitmap first = bitmaps[0];
-    for (int i = 0; i < first.highLowContainer.size; ++i) {
-      char key = first.highLowContainer.keys[i];
-      words[key >>> 6] |= 1L << key;
-    }
-    int numContainers = first.highLowContainer.size;
-    for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) {
-      numContainers = Util.intersectArrayIntoBitmap(words,
-              bitmaps[i].highLowContainer.keys, bitmaps[i].highLowContainer.size);
-    }
-    if (numContainers == 0) {
+    char[] keys = Util.intersectKeys(words, bitmaps);
+    if (keys.length == 0) {
       return new RoaringBitmap();
     }
-    char[] keys = new char[numContainers];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    int numContainers = keys.length;
+
     RoaringArray array =
             new RoaringArray(keys, new Container[numContainers], 0);
     for (int i = 0; i < numContainers; ++i) {
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java
index 1df7a8c22..b2b656276 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java
@@ -1233,6 +1233,31 @@ public static void partialRadixSort(int[] data) {
       System.arraycopy(copy, 0, data, 0, data.length);
     }
   }
+
+  /**
+   * It computes the intersection of the containers' keys between given bitmaps.
+   *
+   * @param words bitmap buffer
+   * @param bitmaps bitmaps
+   * @return keys intersection
+   */
+  static char[] intersectKeys(long[] words, RoaringBitmap[] bitmaps) {
+    RoaringBitmap first = bitmaps[0];
+    for (int i = 0; i < first.highLowContainer.size; ++i) {
+      char key = first.highLowContainer.keys[i];
+      words[key >>> 6] |= 1L << key;
+    }
+    int numContainers = first.highLowContainer.size;
+    for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) {
+      numContainers = Util.intersectArrayIntoBitmap(words,
+          bitmaps[i].highLowContainer.keys, bitmaps[i].highLowContainer.size);
+    }
+    if (numContainers == 0) {
+      return new char[0];
+    }
+    return BitSetUtil.arrayContainerBufferOf(0, words.length, numContainers, words);
+  }
+
   /**
    * Private constructor to prevent instantiation of utility class
    */
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java
index 1e9efac25..cef3ec1b4 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java
@@ -4,6 +4,7 @@
 
 package org.roaringbitmap.buffer;
 
+import org.roaringbitmap.BitSetUtil;
 import org.roaringbitmap.Util;
 
 import java.nio.CharBuffer;
@@ -426,39 +427,12 @@ public static MutableRoaringBitmap naive_and(MutableRoaringBitmap... bitmaps) {
   static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer,
                                          ImmutableRoaringBitmap... bitmaps) {
     long[] words = aggregationBuffer;
-    ImmutableRoaringBitmap first = bitmaps[0];
-    for (int i = 0; i < first.highLowContainer.size(); ++i) {
-      char key = first.highLowContainer.getKeyAtIndex(i);
-      words[key >>> 6] |= 1L << key;
-    }
-    int numContainers = first.highLowContainer.size();
-    for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) {
-      final char[] keys;
-      if (bitmaps[i].highLowContainer instanceof MutableRoaringArray) {
-        keys = ((MutableRoaringArray) bitmaps[i].highLowContainer).keys;
-      } else {
-        keys = new char[bitmaps[i].highLowContainer.size()];
-        for (int j = 0; j < keys.length; ++j) {
-          keys[j] = bitmaps[i].highLowContainer.getKeyAtIndex(j);
-        }
-      }
-      numContainers = BufferUtil.intersectArrayIntoBitmap(words,
-              CharBuffer.wrap(keys),
-              bitmaps[i].highLowContainer.size());
-    }
-    if (numContainers == 0) {
+    char[] keys = BufferUtil.intersectKeys(words, bitmaps);
+    if (keys.length == 0) {
       return new MutableRoaringBitmap();
     }
-    char[] keys = new char[numContainers];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    int numContainers = keys.length;
+
     MappeableContainer[][] containers = new MappeableContainer[numContainers][bitmaps.length];
     for (int i = 0; i < bitmaps.length; ++i) {
       ImmutableRoaringBitmap bitmap = bitmaps[i];
@@ -534,16 +508,8 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer,
     if (numContainers == 0) {
       return new MutableRoaringBitmap();
     }
-    char[] keys = new char[numContainers];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    char[] keys = BitSetUtil.arrayContainerBufferOf(0, words.length, numContainers, words);
+
     MappeableContainer[][] containers = new MappeableContainer[numContainers][bitmapCount];
     for (int i = 0; i < bitmapCount; ++i) {
       ImmutableRoaringBitmap bitmap = collected.get(i);
@@ -581,39 +547,10 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer,
 
   private static int workShyAndCardinality(ImmutableRoaringBitmap... bitmaps) {
     long[] words = new long[1024];
-    ImmutableRoaringBitmap first = bitmaps[0];
-    for (int i = 0; i < first.highLowContainer.size(); ++i) {
-      char key = first.highLowContainer.getKeyAtIndex(i);
-      words[key >>> 6] |= 1L << key;
-    }
-    int numKeys = first.highLowContainer.size();
-    for (int i = 1; i < bitmaps.length && numKeys > 0; ++i) {
-      final char[] keys;
-      if (bitmaps[i].highLowContainer instanceof MutableRoaringArray) {
-        keys = ((MutableRoaringArray) bitmaps[i].highLowContainer).keys;
-      } else {
-        keys = new char[bitmaps[i].highLowContainer.size()];
-        for (int j = 0; j < keys.length; ++j) {
-          keys[j] = bitmaps[i].highLowContainer.getKeyAtIndex(j);
-        }
-      }
-      numKeys = BufferUtil.intersectArrayIntoBitmap(words,
-          CharBuffer.wrap(keys),
-          bitmaps[i].highLowContainer.size());
-    }
-    if (numKeys == 0) {
+    char[] keys = BufferUtil.intersectKeys(words, bitmaps);
+    if (keys.length == 0) {
       return 0;
     }
-    char[] keys = new char[numKeys];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
 
     LongBuffer longBuffer = LongBuffer.wrap(words);
     int cardinality = 0;
@@ -652,16 +589,7 @@ private static int horizontalOrCardinality(ImmutableRoaringBitmap... bitmaps) {
       }
     }
     int numKeys = Util.cardinalityInBitmapRange(words, minKey, maxKey + 1);
-    char[] keys = new char[numKeys];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    char[] keys = BitSetUtil.arrayContainerBufferOf(0, words.length, numKeys, words);
 
     LongBuffer longBuffer = LongBuffer.wrap(words);
     int cardinality = 0;
@@ -702,39 +630,12 @@ public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer,
       throw new IllegalArgumentException("buffer should have at least 1024 elements.");
     }
     long[] words = buffer;
-    ImmutableRoaringBitmap first = bitmaps[0];
-    for (int i = 0; i < first.highLowContainer.size(); ++i) {
-      char key = first.highLowContainer.getKeyAtIndex(i);
-      words[key >>> 6] |= 1L << key;
-    }
-    int numContainers = first.highLowContainer.size();
-    for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) {
-      final char[] keys;
-      if (bitmaps[i].highLowContainer instanceof MutableRoaringArray) {
-        keys = ((MutableRoaringArray) bitmaps[i].highLowContainer).keys;
-      } else {
-        keys = new char[bitmaps[i].highLowContainer.size()];
-        for (int j = 0; j < keys.length; ++j) {
-          keys[j] = bitmaps[i].highLowContainer.getKeyAtIndex(j);
-        }
-      }
-      numContainers = BufferUtil.intersectArrayIntoBitmap(words,
-              CharBuffer.wrap(keys),
-              bitmaps[i].highLowContainer.size());
-    }
-    if (numContainers == 0) {
+    char[] keys = BufferUtil.intersectKeys(words, bitmaps);
+    if (keys.length == 0) {
       return new MutableRoaringBitmap();
     }
-    char[] keys = new char[numContainers];
-    int base = 0;
-    int pos = 0;
-    for (long word : words) {
-      while (word != 0L) {
-        keys[pos++] = (char)(base + Long.numberOfTrailingZeros(word));
-        word &= (word - 1);
-      }
-      base += 64;
-    }
+    int numContainers = keys.length;
+
     MutableRoaringArray array =
             new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0);
     for (int i = 0; i < numContainers; ++i) {
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java
index 6421bf65a..50bbd14cf 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java
@@ -4,6 +4,7 @@
 
 package org.roaringbitmap.buffer;
 
+import org.roaringbitmap.BitSetUtil;
 import org.roaringbitmap.Util;
 
 import java.nio.Buffer;
@@ -1097,6 +1098,40 @@ protected static int unsignedUnion2by2(
     // return pos;
   }
 
+  /**
+   * It computes the intersection of the containers' keys between given bitmaps.
+   *
+   * @param words bitmap buffer
+   * @param bitmaps bitmaps
+   * @return keys intersection
+   */
+  static char[] intersectKeys(long[] words, ImmutableRoaringBitmap[] bitmaps) {
+    ImmutableRoaringBitmap first = bitmaps[0];
+    for (int i = 0; i < first.highLowContainer.size(); ++i) {
+      char key = first.highLowContainer.getKeyAtIndex(i);
+      words[key >>> 6] |= 1L << key;
+    }
+    int numContainers = first.highLowContainer.size();
+    for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) {
+      final char[] keys;
+      if (bitmaps[i].highLowContainer instanceof MutableRoaringArray) {
+        keys = ((MutableRoaringArray) bitmaps[i].highLowContainer).keys;
+      } else {
+        keys = new char[bitmaps[i].highLowContainer.size()];
+        for (int j = 0; j < keys.length; ++j) {
+          keys[j] = bitmaps[i].highLowContainer.getKeyAtIndex(j);
+        }
+      }
+      numContainers = BufferUtil.intersectArrayIntoBitmap(words,
+          CharBuffer.wrap(keys),
+          bitmaps[i].highLowContainer.size());
+    }
+    if (numContainers == 0) {
+      return new char[0];
+    }
+    return BitSetUtil.arrayContainerBufferOf(0, words.length, numContainers, words);
+  }
+
   /**
    * Private constructor to prevent instantiation of utility class
    */
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java
index 50fca67d5..104484b18 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java
@@ -453,6 +453,30 @@ public boolean equals(Object o) {
     return false;
   }
 
+  /**
+   * Fill the array with set bits
+   * 
+   * @param array container (should be sufficiently large)
+   */
+  void fillArray(final char[] array) {
+    int pos = 0;
+    if (BufferUtil.isBackedBySimpleArray(bitmap)) {
+      long[] b = bitmap.array();
+      BitSetUtil.arrayContainerBufferOf(0, b.length, array, b);
+    } else {
+      int len = this.bitmap.limit();
+      int base = 0;
+      for (int k = 0; k < len; ++k) {
+        long bitset = bitmap.get(k);
+        while (bitset != 0) {
+          array[pos++] = (char) (base + numberOfLeadingZeros(bitset));
+          bitset &= (bitset - 1);
+        }
+        base += 64;
+      }
+    }
+  }
+
   @Override
   public void fillLeastSignificant16bits(int[] x, int i, int mask) {
     int pos = i;

From 933b441a2439d3682db62325d27d81fde506859a Mon Sep 17 00:00:00 2001
From: Peyz <30936555+iszhangpch@users.noreply.github.com>
Date: Wed, 18 Sep 2024 12:37:28 +0800
Subject: [PATCH 092/167] Fix an issue that may cause RoaringBSI's fountSet to
 not work (#740)

* Fix an issue that may cause RoaringBSI's fountSet to not take effect correctly when doing LE and GE comparisons

* add UTs

---------

Co-authored-by: zhangpeicheng 
---
 .../bsi/RoaringBitmapSliceIndex.java          |  4 +--
 .../java/org/roaringbitmap/bsi/RBBsiTest.java | 26 +++++++++++++++++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
index 29ce0ce64..e6b55db2a 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
@@ -459,9 +459,9 @@ private RoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation, int pre
       case LT:
         return RoaringBitmap.and(LT, fixedFoundSet);
       case LE:
-        return RoaringBitmap.or(LT, EQ);
+        return RoaringBitmap.and(RoaringBitmap.or(LT, EQ), fixedFoundSet);
       case GE:
-        return RoaringBitmap.or(GT, EQ);
+        return RoaringBitmap.and(RoaringBitmap.or(GT, EQ), fixedFoundSet);
       default:
         throw new IllegalArgumentException("");
     }
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
index b39a76dac..1bd0c8d80 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
@@ -252,6 +252,19 @@ public void testGE() {
 
         result = bsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null);
         Assertions.assertTrue(result.isEmpty());
+
+        RoaringBitmap foundSet = RoaringBitmap.bitmapOf(51, 52, 53);
+
+        result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, foundSet);
+        Assertions.assertTrue(result.getLongCardinality() == 3);
+        Assertions.assertArrayEquals(IntStream.range(51, 54).toArray(), result.toArray());
+
+        result = bsi.compare(BitmapSliceIndex.Operation.GE, 0, 0, foundSet);
+        Assertions.assertTrue(result.getLongCardinality() == 3);
+        Assertions.assertArrayEquals(IntStream.range(51, 54).toArray(), result.toArray());
+
+        result = bsi.compare(BitmapSliceIndex.Operation.GE, Integer.MAX_VALUE, 0, foundSet);
+        Assertions.assertTrue(result.isEmpty());
     }
 
     @Test
@@ -281,6 +294,19 @@ public void testLE() {
 
         result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null);
         Assertions.assertTrue(result.isEmpty());
+
+        RoaringBitmap foundSet = RoaringBitmap.bitmapOf(1, 2, 3);
+
+        result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, foundSet);
+        Assertions.assertTrue(result.getLongCardinality() == 3);
+        Assertions.assertArrayEquals(IntStream.range(1, 4).toArray(), result.toArray());
+
+        result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, foundSet);
+        Assertions.assertTrue(result.getLongCardinality() == 3);
+        Assertions.assertArrayEquals(IntStream.range(1, 4).toArray(), result.toArray());
+
+        result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, foundSet);
+        Assertions.assertTrue(result.isEmpty());
     }
 
     @Test

From 11f3bef58232e7d614a0bffa1ff3f25ef1e0b18a Mon Sep 17 00:00:00 2001
From: Lari Hotari 
Date: Fri, 27 Sep 2024 15:32:57 +0300
Subject: [PATCH 093/167] Update README.md - add Apache Pulsar to users of the
 library (#744)

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 1042c8389..43d70f96d 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ This library is used by
 *   [SirixDB](https://sirix.io)
 *   [EvitaDB](https://evitadb.io/)
 *   [Apache Iceberg](https://iceberg.apache.org/)
+*   [Apache Pulsar](https://pulsar.apache.org/)
 
 
 The YouTube SQL Engine, [Google Procella](https://research.google/pubs/pub48388/), uses Roaring bitmaps for indexing. [Apache Lucene](http://lucene.apache.org/) uses  Roaring bitmaps, though they have their own [independent implementation](https://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/RoaringDocIdSet.java?view=markup&pathrev=1629606). Derivatives of Lucene such as Solr and Elastic also use Roaring bitmaps.

From 966c40e25c0cd2adb9bda115d6e28833f6e88633 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 10:48:54 -0400
Subject: [PATCH 094/167] fix for issue 745 (#746)

---
 .../bsi/buffer/BitSliceIndexBase.java         | 13 ++------
 .../org/roaringbitmap/bsi/BufferBSITest.java  | 30 +++++++------------
 2 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
index 6c65ce7a3..4552589ae 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
@@ -326,17 +326,8 @@ public MutableRoaringBitmap topK(ImmutableRoaringBitmap foundSet, int k) {
 
     MutableRoaringBitmap F = ImmutableRoaringBitmap.or(G, E);
     long n = F.getLongCardinality() - k;
-    if (n > 0) {
-      IntIterator i = F.getIntIterator();
-      while (i.hasNext() && n > 0) {
-        F.remove(i.next());
-        --n;
-      }
-    }
-
-    if (F.getCardinality() != k)
-      throw new RuntimeException("bugs found when compute topK");
-
+    F.remove(0L,(long)F.select((int)n));
+    assert(F.getLongCardinality() == k);
     return F;
   }
 
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java
index 0a0aead81..02e794927 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java
@@ -399,28 +399,9 @@ public void testTransposeWithCount() throws ExecutionException, InterruptedExcep
         List> pairs = result.toPairList();
         pairs.forEach(System.out::println);
 
-
         Assertions.assertEquals(30, (int) result.getValue(1).getKey());
         Assertions.assertEquals(30, (int) result.getValue(2).getKey());
         Assertions.assertEquals(39, (int) result.getValue(3).getKey());
-
-    }
-
-    @Test
-    public void removeTopValuesWhenIterating() {
-        RoaringBitmap expected = new RoaringBitmap();
-        expected.add(210, 1000);
-        RoaringBitmap bitmap = new RoaringBitmap();
-        bitmap.add(10, 1000);
-
-        IntIterator it = bitmap.getIntIterator();
-        int n = 200;
-        while (it.hasNext() && n > 0) {
-            bitmap.remove(it.next());
-            --n;
-        }
-
-        Assertions.assertEquals(expected, bitmap);
     }
 
     @Test
@@ -433,6 +414,17 @@ public void testTopK() {
         System.out.println(top.toString() + " \ntime cost:" + (end - start));
     }
 
+    @Test
+    public void testIssue745() {
+        MutableBitSliceIndex bsi = new MutableBitSliceIndex();
+        bsi.setValue(1, 1);
+        bsi.setValue(2, 1);
+        bsi.setValue(3, 1);
+        bsi.setValue(4, 1);
+        bsi.setValue(5, 1);
+        MutableRoaringBitmap top = bsi.topK(null, 1);
+        System.out.println(top);
+    }
 
 }
 

From dd94f8f55e6ea14e7a466dcd27b3a02c275e0090 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 13:53:46 -0400
Subject: [PATCH 095/167] fix issue 743 (#747)

* fix issue 743

* trimming
---
 .../longlong/HighLowContainer.java             |  2 ++
 .../longlong/Roaring64BitmapSliceIndex.java    |  2 +-
 .../java/org/roaringbitmap/bsi/R64BSITest.java | 18 ++++++++++++++++++
 .../java/org/roaringbitmap/bsi/RBBsiTest.java  | 16 ++++++++++++++++
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
index 5986d1a13..917f12414 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
@@ -180,6 +180,8 @@ public void serialize(ByteBuffer buffer) throws IOException {
         : buffer.slice().order(LITTLE_ENDIAN);
     if (art.isEmpty()) {
       byteBuffer.put(EMPTY_TAG);
+      byteBuffer.position();
+      buffer.position(buffer.position() + byteBuffer.position());
       return;
     } else {
       byteBuffer.put(NOT_EMPTY_TAG);
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
index a56f32526..658cb2f26 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
@@ -257,7 +257,7 @@ public void deserialize(ByteBuffer buffer) throws IOException {
     Roaring64Bitmap ebm = new Roaring64Bitmap();
     ebm.deserialize(buffer);
     this.ebM = ebm;
-    // read ba
+    // read back
     buffer.position(buffer.position() + ebm.getSizeInBytes());
     int bitDepth = buffer.getInt();
     Roaring64Bitmap[] ba = new Roaring64Bitmap[bitDepth];
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
index 808bd92ec..0e609411f 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
@@ -366,5 +366,23 @@ public void testTransposeWithCount() {
     Assertions.assertEquals(re.getValue(4).getKey(), 2);
     Assertions.assertEquals(re.getValue(8).getKey(), 2);
   }
+
+
+  @Test
+  public void testIssue743() throws IOException {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(100L, 3L);
+    bsi.setValue(1L, 392L);
+    System.out.println(bsi.getValue(100L));
+    System.out.println(bsi.getValue(1L));
+
+    ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
+    bsi.serialize(buffer);
+
+    Roaring64BitmapSliceIndex de_bsi = new Roaring64BitmapSliceIndex();
+    de_bsi.deserialize(ByteBuffer.wrap(buffer.array()));
+    Assertions.assertEquals(de_bsi.getValue(100L), bsi.getValue(100L));
+    Assertions.assertEquals(de_bsi.getValue(1L), bsi.getValue(1L));
+  }
 }
 
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
index 1bd0c8d80..69f751167 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
@@ -355,5 +355,21 @@ public void testValueZero() {
         Assertions.assertTrue(result.getLongCardinality() == 1);
         Assertions.assertArrayEquals(new int[]{2}, result.toArray());
     }
+  @Test
+  public void testIssue743() throws IOException {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex();
+    bsi.setValue(100, 3);
+    bsi.setValue(1, 392);
+    System.out.println(bsi.getValue(100));
+    System.out.println(bsi.getValue(1));
+
+    ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
+    bsi.serialize(buffer);
+
+    RoaringBitmapSliceIndex de_bsi = new RoaringBitmapSliceIndex();
+    de_bsi.deserialize(ByteBuffer.wrap(buffer.array()));
+    Assertions.assertEquals(de_bsi.getValue(100), bsi.getValue(100));
+    Assertions.assertEquals(de_bsi.getValue(1), bsi.getValue(1));
+  }
 }
 

From 3dd262d664c638965610e39fe2c147414a24a1ca Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 14:21:34 -0400
Subject: [PATCH 096/167] setting up automatic release in CI

---
 .github/workflows/releases.yml | 48 +++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 65939873e..46824fcae 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -1,22 +1,34 @@
-name: "tagged-release"
-
+name: Publish package to the Maven Central Repository and GitHub Packages
 on:
-  push:
-    tags:
-      - "(\\d)+\\.(\\d)+\\.(\\d)+"
-
+  release:
+    types: [created]
 jobs:
-  tagged-release:
-    name: "Tagged Release"
-    runs-on: "ubuntu-latest"
-
+  publish:
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      packages: write
     steps:
-      - name: "Creating a release"
-        run: |
-          echo "done!"
-
-      - uses: "marvinpinto/action-automatic-releases@latest"
+      - uses: actions/checkout@v4
+      - name: Set up Java for publishing to Maven Central Repository
+        uses: actions/setup-java@v4
         with:
-          repo_token: "${{ secrets.GITHUB_TOKEN }}"
-          prerelease: false
-
+          java-version: '11'
+          distribution: 'temurin'
+          server-id: ossrh
+          server-username: MAVEN_USERNAME
+          server-password: MAVEN_PASSWORD
+      - name: Publish to the Maven Central Repository
+        run: mvn --batch-mode deploy
+        env:
+          MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
+          MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
+      - name: Set up Java for publishing to GitHub Packages
+        uses: actions/setup-java@v4
+        with:
+          java-version: '11'
+          distribution: 'temurin'
+      - name: Publish to GitHub Packages
+        run: mvn --batch-mode deploy
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

From 3ec50b668e2fa8a9bee37d0631712260df711f48 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 14:41:20 -0400
Subject: [PATCH 097/167] let us drop to automatic sonatype

---
 build.gradle.kts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index 7efd6c644..cd0dd5152 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -149,10 +149,10 @@ subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach
             }
         }
 
-        // releasing should publish
-        rootProject.tasks.afterReleaseBuild {
-            dependsOn(provider { project.tasks.named("publishToSonatype") })
-        }
+        // releasing should publish (As of Oct 22 2024 this fails. We will rely on GitHub CI for releases.)
+        //rootProject.tasks.afterReleaseBuild {
+        //    dependsOn(provider { project.tasks.named("publishToSonatype") })
+        //}
     }
 }
 

From ab60b4a087a7d97be5c8a1a86c34e02285f43a04 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 14:42:59 -0400
Subject: [PATCH 098/167] [Gradle Release Plugin] - pre tag commit:  '1.3.1'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 0996f0b6a..3a5d0c27a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.1-SNAPSHOT
+version = 1.3.1
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 71662df23250426f3a9a0aa4d662ed7fd398ad4b Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 14:43:05 -0400
Subject: [PATCH 099/167] [Gradle Release Plugin] - new version commit: 
 '1.3.2-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 3a5d0c27a..588ace6f9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.1
+version = 1.3.2-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 9a1d0cd03a24318bf4f1da7092df9248f4c5d5b9 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 14:52:04 -0400
Subject: [PATCH 100/167] removing bad release script

---
 .github/workflows/releases.yml | 34 ----------------------------------
 1 file changed, 34 deletions(-)
 delete mode 100644 .github/workflows/releases.yml

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
deleted file mode 100644
index 46824fcae..000000000
--- a/.github/workflows/releases.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Publish package to the Maven Central Repository and GitHub Packages
-on:
-  release:
-    types: [created]
-jobs:
-  publish:
-    runs-on: ubuntu-latest
-    permissions:
-      contents: read
-      packages: write
-    steps:
-      - uses: actions/checkout@v4
-      - name: Set up Java for publishing to Maven Central Repository
-        uses: actions/setup-java@v4
-        with:
-          java-version: '11'
-          distribution: 'temurin'
-          server-id: ossrh
-          server-username: MAVEN_USERNAME
-          server-password: MAVEN_PASSWORD
-      - name: Publish to the Maven Central Repository
-        run: mvn --batch-mode deploy
-        env:
-          MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
-          MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
-      - name: Set up Java for publishing to GitHub Packages
-        uses: actions/setup-java@v4
-        with:
-          java-version: '11'
-          distribution: 'temurin'
-      - name: Publish to GitHub Packages
-        run: mvn --batch-mode deploy
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

From df04c3d6ff1b04ea457991cb5e5e9ecdb8922e15 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 14:53:39 -0400
Subject: [PATCH 101/167] trying to restore release

---
 build.gradle.kts | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index cd0dd5152..ef16f8526 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -149,10 +149,9 @@ subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach
             }
         }
 
-        // releasing should publish (As of Oct 22 2024 this fails. We will rely on GitHub CI for releases.)
-        //rootProject.tasks.afterReleaseBuild {
-        //    dependsOn(provider { project.tasks.named("publishToSonatype") })
-        //}
+        rootProject.tasks.afterReleaseBuild {
+            dependsOn(provider { project.tasks.named("publishToSonatype") })
+        }
     }
 }
 

From f462fec4b1c099e3a56e22017ed63cb8aa6c8247 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:11:19 -0400
Subject: [PATCH 102/167] adding github pack.

---
 build.gradle.kts | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index ef16f8526..c840e52f4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,6 +5,20 @@ plugins {
     id("net.researchgate.release") version "2.8.1"
     id("io.github.gradle-nexus.publish-plugin") version "1.0.0"
     id("com.github.ben-manes.versions") version "0.38.0"
+    id("maven-publish")
+}
+
+publishing {
+    repositories {
+        maven {
+            name = "GitHubPackages"
+            url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
+            credentials {
+                username = System.getenv("GITHUB_ACTOR")
+                password = System.getenv("GITHUB_TOKEN")
+            }
+        }
+    }
 }
 
 // some parts of the Kotlin DSL don't work inside a `subprojects` block yet, so we do them the old way
@@ -149,9 +163,9 @@ subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach
             }
         }
 
-        rootProject.tasks.afterReleaseBuild {
-            dependsOn(provider { project.tasks.named("publishToSonatype") })
-        }
+        //rootProject.tasks.afterReleaseBuild {
+        //    dependsOn(provider { project.tasks.named("publishToSonatype") })
+        //}
     }
 }
 

From ff0a9310ba14218ab8751b57a213058b93e28f42 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:12:43 -0400
Subject: [PATCH 103/167] adding release script

---
 .github/workflows/releases.yml | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 .github/workflows/releases.yml

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
new file mode 100644
index 000000000..9c1471eb4
--- /dev/null
+++ b/.github/workflows/releases.yml
@@ -0,0 +1,23 @@
+name: Publish package to GitHub Packages
+on:
+  release:
+    types: [created]
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      packages: write
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-java@v4
+        with:
+          java-version: '17'
+          distribution: 'temurin'
+      - name: Setup Gradle
+        uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
+
+      - name: Publish package
+        run: ./gradlew publish
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

From 2e63395f8282bfa496ebc2711423bd7cc2014bac Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:13:10 -0400
Subject: [PATCH 104/167] [Gradle Release Plugin] - pre tag commit:  '1.3.2'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 588ace6f9..4129f5fce 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.2-SNAPSHOT
+version = 1.3.2
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 39a0ae7157e0dcd794eb8a1625fc5914d142e018 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:13:12 -0400
Subject: [PATCH 105/167] [Gradle Release Plugin] - new version commit: 
 '1.3.3-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 4129f5fce..ede9f1842 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.2
+version = 1.3.3-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 550e4cf4194bc161d6fb67c4ca71551d320f1f5f Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:15:05 -0400
Subject: [PATCH 106/167] reverting to java 11

---
 .github/workflows/releases.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 9c1471eb4..80a017cac 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -12,7 +12,7 @@ jobs:
       - uses: actions/checkout@v4
       - uses: actions/setup-java@v4
         with:
-          java-version: '17'
+          java-version: '11'
           distribution: 'temurin'
       - name: Setup Gradle
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0

From 35f5d08241b4d6e793f6f957dd620894aa18b3e7 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:15:17 -0400
Subject: [PATCH 107/167] [Gradle Release Plugin] - pre tag commit:  '1.3.3'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index ede9f1842..f373d7d86 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.3-SNAPSHOT
+version = 1.3.3
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From d39a0226dc29593d74eaba853cce1de415efe6ff Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:15:19 -0400
Subject: [PATCH 108/167] [Gradle Release Plugin] - new version commit: 
 '1.3.4-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index f373d7d86..1cc73cba2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.3
+version = 1.3.4-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From ee35004db6d81100548b93d549c111d979b435fd Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:20:03 -0400
Subject: [PATCH 109/167] further simplification

---
 build.gradle.kts | 95 ------------------------------------------------
 1 file changed, 95 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index c840e52f4..9f90a9e94 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,7 +3,6 @@ import java.time.Duration
 
 plugins {
     id("net.researchgate.release") version "2.8.1"
-    id("io.github.gradle-nexus.publish-plugin") version "1.0.0"
     id("com.github.ben-manes.versions") version "0.38.0"
     id("maven-publish")
 }
@@ -90,84 +89,6 @@ subprojects.filter { !listOf("jmh", "fuzz-tests", "examples", "bsi", "simplebenc
     }
 }
 
-subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach { project ->
-    project.run {
-        apply(plugin = "maven-publish")
-        apply(plugin = "signing")
-
-        configure {
-            withSourcesJar()
-            withJavadocJar()
-        }
-
-        configure {
-            publications {
-                register("sonatype") {
-                    groupId = project.group.toString()
-                    artifactId = project.name
-                    version = project.version.toString()
-
-                    from(components["java"])
-
-                    // requirements for maven central
-                    // https://central.sonatype.org/pages/requirements.html
-                    pom {
-                        name.set("${project.group}:${project.name}")
-                        description.set("Roaring bitmaps are compressed bitmaps (also called bitsets) which tend to outperform conventional compressed bitmaps such as WAH or Concise.")
-                        url.set("https://github.com/RoaringBitmap/RoaringBitmap")
-                        issueManagement {
-                            system.set("GitHub Issue Tracking")
-                            url.set("https://github.com/RoaringBitmap/RoaringBitmap/issues")
-                        }
-                        licenses {
-                            license {
-                                name.set("Apache 2")
-                                url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
-                                distribution.set("repo")
-                            }
-                        }
-                        developers {
-                            developer {
-                                id.set("lemire")
-                                name.set("Daniel Lemire")
-                                email.set("lemire@gmail.com")
-                                url.set("http://lemire.me/en/")
-                                roles.addAll("architect", "developer", "maintainer")
-                                timezone.set("-5")
-                                properties.put("picUrl", "http://lemire.me/fr/images/JPG/profile2011B_152.jpg")
-                            }
-                        }
-                        scm {
-                            connection.set("scm:git:https://github.com/RoaringBitmap/RoaringBitmap.git")
-                            developerConnection.set("scm:git:https://github.com/RoaringBitmap/RoaringBitmap.git")
-                            url.set("https://github.com/RoaringBitmap/RoaringBitmap")
-                        }
-                    }
-                }
-            }
-
-             // A safe throw-away place to publish to:
-            // ./gradlew publishSonatypePublicationToLocalDebugRepository -Pversion=foo
-            repositories {
-                maven {
-                    name = "localDebug"
-                    url = project.buildDir.toPath().resolve("repos").resolve("localDebug").toUri()
-                }
-            }
-        }
-
-        // don't barf for devs without signing set up
-        if (project.hasProperty("signing.keyId")) {
-            configure {
-                sign(project.extensions.getByType().publications["sonatype"])
-            }
-        }
-
-        //rootProject.tasks.afterReleaseBuild {
-        //    dependsOn(provider { project.tasks.named("publishToSonatype") })
-        //}
-    }
-}
 
 tasks {
     register("build") {
@@ -180,19 +101,3 @@ release {
     // instead of just 0.1.0 or v0.1.0.
     tagTemplate = "\$version"
 }
-
-nexusPublishing {
-    repositories {
-        sonatype {
-            // sonatypeUsername and sonatypePassword properties are used automatically
-            // id found via clicking the desired profile in the web ui and noting the url fragment
-            stagingProfileId.set("144dd9b55bb0c2")
-            nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
-            snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
-        }
-    }
-    // these are not strictly required. The default timeouts are set to 1 minute. But Sonatype can be really slow.
-    // If you get the error "java.net.SocketTimeoutException: timeout", these lines will help.
-    connectTimeout.set(Duration.ofMinutes(3))
-    clientTimeout.set(Duration.ofMinutes(3))
-}

From 755dced477e84630714b3f00c242cca1b945714d Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:20:53 -0400
Subject: [PATCH 110/167] removing more

---
 RoaringBitmap/build.gradle.kts | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/RoaringBitmap/build.gradle.kts b/RoaringBitmap/build.gradle.kts
index b9beaf5a3..a6d01fc2a 100644
--- a/RoaringBitmap/build.gradle.kts
+++ b/RoaringBitmap/build.gradle.kts
@@ -13,13 +13,6 @@ buildscript {
 // files with Java 8 compatibility
 apply(plugin = "org.javamodularity.moduleplugin")
 
-// Work around
-// https://github.com/java9-modularity/gradle-modules-plugin/issues/220
-// by excluding module-info.class from non-executable JARs.
-tasks.named("javadocJar") {
-    exclude("module-info.class")
-}
-
 tasks.named("sourcesJar") {
     exclude("module-info.class")
 }

From d9ae2522e1ba2a96aac724e326d6e339cefbf9ea Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:21:15 -0400
Subject: [PATCH 111/167] more

---
 RoaringBitmap/build.gradle.kts | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/RoaringBitmap/build.gradle.kts b/RoaringBitmap/build.gradle.kts
index a6d01fc2a..d53dceaa4 100644
--- a/RoaringBitmap/build.gradle.kts
+++ b/RoaringBitmap/build.gradle.kts
@@ -13,9 +13,6 @@ buildscript {
 // files with Java 8 compatibility
 apply(plugin = "org.javamodularity.moduleplugin")
 
-tasks.named("sourcesJar") {
-    exclude("module-info.class")
-}
 
 // Unset Java 8 release applied from root project to allow modularity plugin to
 // control the class file versions.

From d697eceaa498fb6ef647b508570be3c4f91fdeb9 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:21:25 -0400
Subject: [PATCH 112/167] [Gradle Release Plugin] - pre tag commit:  '1.3.4'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 1cc73cba2..41f259fbf 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.4-SNAPSHOT
+version = 1.3.4
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 7db92f6e374fb97e40282505c22a9806a0c6ad06 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:21:32 -0400
Subject: [PATCH 113/167] [Gradle Release Plugin] - new version commit: 
 '1.3.5-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 41f259fbf..893e92f62 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.4
+version = 1.3.5-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From db0fe413ccfced94a23a0a91b3f511053b21c62c Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:54:05 -0400
Subject: [PATCH 114/167] trying again

---
 .github/workflows/releases.yml |  7 +++++--
 build.gradle.kts               | 29 ++++++++++++++++-------------
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 80a017cac..45895aec7 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -16,8 +16,11 @@ jobs:
           distribution: 'temurin'
       - name: Setup Gradle
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
-
+      - name: Build with Gradle
+        run: ./gradlew build
       - name: Publish package
-        run: ./gradlew publish
+        run: ./gradlew publishAllPublicationsTogithubPackagesRepository
         env:
+          GITHUB_USER: ${{ github.actor }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 9f90a9e94..11995b147 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,21 +4,10 @@ import java.time.Duration
 plugins {
     id("net.researchgate.release") version "2.8.1"
     id("com.github.ben-manes.versions") version "0.38.0"
-    id("maven-publish")
+    id("com.vanniktech.maven.publish") version "0.30.0"
 }
 
-publishing {
-    repositories {
-        maven {
-            name = "GitHubPackages"
-            url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
-            credentials {
-                username = System.getenv("GITHUB_ACTOR")
-                password = System.getenv("GITHUB_TOKEN")
-            }
-        }
-    }
-}
+
 
 // some parts of the Kotlin DSL don't work inside a `subprojects` block yet, so we do them the old way
 // (without typesafe accessors)
@@ -101,3 +90,17 @@ release {
     // instead of just 0.1.0 or v0.1.0.
     tagTemplate = "\$version"
 }
+
+publishing {
+    repositories {
+        maven {
+            name = "githubPackages"
+            url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
+            // username and password (a personal Github access token) should be specified as
+            // `githubPackagesUsername` and `githubPackagesPassword` Gradle properties or alternatively
+            // as `ORG_GRADLE_PROJECT_githubPackagesUsername` and `ORG_GRADLE_PROJECT_githubPackagesPassword`
+            // environment variables
+            credentials(PasswordCredentials::class)
+        }
+    }
+}
\ No newline at end of file

From d92e8cacf14cdb7ff4aaaee951a34bcb3009ced2 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 15:59:41 -0400
Subject: [PATCH 115/167] java is a mess

---
 build.gradle.kts | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index 11995b147..fa3bd64e6 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ import java.time.Duration
 plugins {
     id("net.researchgate.release") version "2.8.1"
     id("com.github.ben-manes.versions") version "0.38.0"
-    id("com.vanniktech.maven.publish") version "0.30.0"
+    id("maven-publish")
 }
 
 
@@ -90,17 +90,16 @@ release {
     // instead of just 0.1.0 or v0.1.0.
     tagTemplate = "\$version"
 }
-
+	
 publishing {
     repositories {
         maven {
-            name = "githubPackages"
+            name = "GitHubPackages"
             url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
-            // username and password (a personal Github access token) should be specified as
-            // `githubPackagesUsername` and `githubPackagesPassword` Gradle properties or alternatively
-            // as `ORG_GRADLE_PROJECT_githubPackagesUsername` and `ORG_GRADLE_PROJECT_githubPackagesPassword`
-            // environment variables
-            credentials(PasswordCredentials::class)
+            credentials {
+                username = System.getenv("GITHUB_ACTOR")
+                password = System.getenv("GITHUB_TOKEN")
+            }
         }
     }
 }
\ No newline at end of file

From 7f22731cec2b64e22574189af1ee700899b42eaa Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:00:01 -0400
Subject: [PATCH 116/167] [Gradle Release Plugin] - pre tag commit:  '1.3.5'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 893e92f62..4ab13c6ff 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.5-SNAPSHOT
+version = 1.3.5
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From ca2bc0a65c10c5518d367c2bb68363415629b0ca Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:00:08 -0400
Subject: [PATCH 117/167] [Gradle Release Plugin] - new version commit: 
 '1.3.6-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 4ab13c6ff..c9ef7b170 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.5
+version = 1.3.6-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From ac86c5f7a0c312cecd5332b99439215fd263d196 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:02:28 -0400
Subject: [PATCH 118/167] Update releases.yml

---
 .github/workflows/releases.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 45895aec7..6ea43fe1f 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -17,10 +17,10 @@ jobs:
       - name: Setup Gradle
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
       - name: Build with Gradle
-        run: ./gradlew build
+        run: ./gradlew build -x test
       - name: Publish package
-        run: ./gradlew publishAllPublicationsTogithubPackagesRepository
+        run: ./gradlew publish
         env:
           GITHUB_USER: ${{ github.actor }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-    
\ No newline at end of file
+    

From de3ecb85d5809309bd8083331df48907b96ec14a Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:03:32 -0400
Subject: [PATCH 119/167] Update README.md

---
 README.md | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/README.md b/README.md
index 43d70f96d..58f71558f 100644
--- a/README.md
+++ b/README.md
@@ -419,24 +419,6 @@ Download
 You can download releases from github:
 https://github.com/RoaringBitmap/RoaringBitmap/releases
 
-Maven repository
-----------------
-If your project depends on roaring, you  can  specify the dependency in the Maven "pom.xml" file:
-
-```xml
-        
-          
-            org.roaringbitmap
-            RoaringBitmap
-            0.9.9
-          
-        
-```
-
-where you should replace the version number by the version you require.
-
-[For up-to-date releases, we recommend configuring maven and gradle to depend on the Jitpack repository](https://jitpack.io/#RoaringBitmap/RoaringBitmap).
-
 Usage
 ------
 

From 7438b5d5166c1e3194ee3878d30a0ad7d3fe1088 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:18:20 -0400
Subject: [PATCH 120/167] tweak

---
 .github/workflows/releases.yml |  2 +-
 build.gradle.kts               | 26 +++++++++++++-------------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 6ea43fe1f..d48ff14af 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -17,7 +17,7 @@ jobs:
       - name: Setup Gradle
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
       - name: Build with Gradle
-        run: ./gradlew build -x test
+        run: ./gradlew assemble
       - name: Publish package
         run: ./gradlew publish
         env:
diff --git a/build.gradle.kts b/build.gradle.kts
index fa3bd64e6..399d19595 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -23,7 +23,19 @@ subprojects {
     }
 
     apply(plugin = "java-library")
-
+    apply(plugin = "maven-publish")
+    publishing {
+        repositories {
+            maven {
+                name = "GitHubPackages"
+                url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
+                credentials {
+                    username = System.getenv("GITHUB_ACTOR")
+                    password = System.getenv("GITHUB_TOKEN")
+                }
+            }
+        }
+    }
     repositories {
         mavenCentral()
     }
@@ -91,15 +103,3 @@ release {
     tagTemplate = "\$version"
 }
 	
-publishing {
-    repositories {
-        maven {
-            name = "GitHubPackages"
-            url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
-            credentials {
-                username = System.getenv("GITHUB_ACTOR")
-                password = System.getenv("GITHUB_TOKEN")
-            }
-        }
-    }
-}
\ No newline at end of file

From 6d851fbaa4e6477ee96a11a366c839dcdf9ede7a Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:25:18 -0400
Subject: [PATCH 121/167] [Gradle Release Plugin] - pre tag commit:  '1.3.6'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index c9ef7b170..275d10250 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.6-SNAPSHOT
+version = 1.3.6
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 45dd59e0e11f22beac18004db0f944994e9f6f43 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 16:25:21 -0400
Subject: [PATCH 122/167] [Gradle Release Plugin] - new version commit: 
 '1.3.7-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 275d10250..d0c173f6d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.6
+version = 1.3.7-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From a4d37c81ab58374390f91b669c9b41346002b1d6 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 17:47:25 -0400
Subject: [PATCH 123/167] Update releases.yml

---
 .github/workflows/releases.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index d48ff14af..6ea43fe1f 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -17,7 +17,7 @@ jobs:
       - name: Setup Gradle
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
       - name: Build with Gradle
-        run: ./gradlew assemble
+        run: ./gradlew build -x test
       - name: Publish package
         run: ./gradlew publish
         env:

From 8a1e6e877283f5d64e5d15ede665dcee0a38cacd Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Tue, 22 Oct 2024 17:48:33 -0400
Subject: [PATCH 124/167] Update releases.yml

---
 .github/workflows/releases.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 6ea43fe1f..10cb12dac 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -17,9 +17,9 @@ jobs:
       - name: Setup Gradle
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
       - name: Build with Gradle
-        run: ./gradlew build -x test
+        run: ./gradlew build -x test -i
       - name: Publish package
-        run: ./gradlew publish
+        run: ./gradlew publish -i 
         env:
           GITHUB_USER: ${{ github.actor }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

From 00fcd5fb36ad84f4f3b48d7d10de9613ddb51a1e Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 08:24:35 -0400
Subject: [PATCH 125/167] Update HighLowContainer.java

---
 .../main/java/org/roaringbitmap/longlong/HighLowContainer.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
index 917f12414..8b5695e27 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
@@ -180,7 +180,6 @@ public void serialize(ByteBuffer buffer) throws IOException {
         : buffer.slice().order(LITTLE_ENDIAN);
     if (art.isEmpty()) {
       byteBuffer.put(EMPTY_TAG);
-      byteBuffer.position();
       buffer.position(buffer.position() + byteBuffer.position());
       return;
     } else {

From 282265d0618e0d5d58c3f979b28ae14b2fb5f13a Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 09:50:34 -0400
Subject: [PATCH 126/167] Update README.md

---
 README.md | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 58f71558f..652f49eb0 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ This library is used by
 *   [Apache Iceberg](https://iceberg.apache.org/)
 *   [Apache Pulsar](https://pulsar.apache.org/)
 
+The library is mature and has been used in production for many years.
 
 The YouTube SQL Engine, [Google Procella](https://research.google/pubs/pub48388/), uses Roaring bitmaps for indexing. [Apache Lucene](http://lucene.apache.org/) uses  Roaring bitmaps, though they have their own [independent implementation](https://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/RoaringDocIdSet.java?view=markup&pathrev=1629606). Derivatives of Lucene such as Solr and Elastic also use Roaring bitmaps.
 Other platforms such as [Whoosh](https://pypi.python.org/pypi/Whoosh/), [Microsoft Visual Studio Team Services (VSTS)](https://www.visualstudio.com/team-services/) and [Pilosa](https://github.com/pilosa/pilosa) also use Roaring bitmaps with their own implementations. You find Roaring bitmaps in [InfluxDB](https://www.influxdata.com), [Bleve](http://www.blevesearch.com), [Cloud Torrent](https://github.com/jpillora/cloud-torrent), [Redpanda](https://github.com/redpanda-data/redpanda), and so forth.
@@ -265,7 +266,7 @@ generate a RoaringBitmap which lies in RAM. As the name suggest, the
 ImmutableRoaringBitmap itself cannot be modified.
 
 
-This design was inspired by Druid.
+This design was inspired by Apache Druid.
 
 One can find a complete working example in the test file TestMemoryMapping.java.
 
@@ -410,8 +411,6 @@ Prerequisites
  - Version 0.6.x requires JDK 7 or better
  - Version 0.5.x requires JDK 6 or better
 
-To build the project you need maven (version 3).
-
 
 Download
 ---------
@@ -435,10 +434,10 @@ Usage
 IntelliJ and Eclipse
 --------
 
-If you plan to contribute to RoaringBitmap, you can have load
+If you plan to contribute to RoaringBitmap, you can load
 it up in your favorite IDE.
 - For IntelliJ, in the IDE create a new project, possibly from existing sources, choose import, gradle.
-- For Eclipse: File, Import, Existing Gradle Projects, Select RoaringBitmap on my disk
+- For Eclipse: File, Import, Existing Gradle Projects, Select RoaringBitmap from your disk.
 
 Contributing
 ------------

From 0b1dcca8ccdc7c1b7989b1568132c667e785091d Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 18:44:36 -0400
Subject: [PATCH 127/167] some tweaks

---
 build.gradle.kts | 98 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 82 insertions(+), 16 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index 399d19595..61c0428ca 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -23,22 +23,6 @@ subprojects {
     }
 
     apply(plugin = "java-library")
-    apply(plugin = "maven-publish")
-    publishing {
-        repositories {
-            maven {
-                name = "GitHubPackages"
-                url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
-                credentials {
-                    username = System.getenv("GITHUB_ACTOR")
-                    password = System.getenv("GITHUB_TOKEN")
-                }
-            }
-        }
-    }
-    repositories {
-        mavenCentral()
-    }
 
     group = "org.roaringbitmap"
 
@@ -91,6 +75,88 @@ subprojects.filter { !listOf("jmh", "fuzz-tests", "examples", "bsi", "simplebenc
 }
 
 
+subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach { project ->
+    project.run {
+        apply(plugin = "maven-publish")
+        configure {
+            withSourcesJar()
+            withJavadocJar()
+        }
+
+        configure {
+            publications {
+                register("sonatype") {
+                    groupId = project.group.toString()
+                    artifactId = project.name
+                    version = project.version.toString()
+
+                    from(components["java"])
+
+                    // requirements for maven central
+                    // https://central.sonatype.org/pages/requirements.html
+                    pom {
+                        name.set("${project.group}:${project.name}")
+                        description.set("Roaring bitmaps are compressed bitmaps (also called bitsets) which tend to outperform conventional compressed bitmaps such as WAH or Concise.")
+                        url.set("https://github.com/RoaringBitmap/RoaringBitmap")
+                        issueManagement {
+                            system.set("GitHub Issue Tracking")
+                            url.set("https://github.com/RoaringBitmap/RoaringBitmap/issues")
+                        }
+                        licenses {
+                            license {
+                                name.set("Apache 2")
+                                url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
+                                distribution.set("repo")
+                            }
+                        }
+                        developers {
+                            developer {
+                                id.set("lemire")
+                                name.set("Daniel Lemire")
+                                email.set("lemire@gmail.com")
+                                url.set("http://lemire.me/en/")
+                                roles.addAll("architect", "developer", "maintainer")
+                                timezone.set("-5")
+                                properties.put("picUrl", "http://lemire.me/fr/images/JPG/profile2011B_152.jpg")
+                            }
+                        }
+                        scm {
+                            connection.set("scm:git:https://github.com/RoaringBitmap/RoaringBitmap.git")
+                            developerConnection.set("scm:git:https://github.com/RoaringBitmap/RoaringBitmap.git")
+                            url.set("https://github.com/RoaringBitmap/RoaringBitmap")
+                        }
+                    }
+                }
+            }
+
+             // A safe throw-away place to publish to:
+            // ./gradlew publishSonatypePublicationToLocalDebugRepository -Pversion=foo
+            repositories {
+                maven {
+                    name = "localDebug"
+                    url = project.buildDir.toPath().resolve("repos").resolve("localDebug").toUri()
+                }
+            }
+
+            // ./gradlew publishSonatypePublicationToGitHubPackagesRepository
+            repositories {
+                maven {
+                    name = "GitHubPackages"
+                    url = uri("https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap")
+                    credentials {
+                        username = System.getenv("GITHUB_ACTOR")
+                        password = System.getenv("GITHUB_TOKEN")
+                    }
+                }
+            }
+
+        }
+
+
+    }
+}
+
+
 tasks {
     register("build") {
         // dummy build task to appease release plugin

From 133f7518207b20936e22e3586753fc8d3d7f0f6f Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:03:24 -0400
Subject: [PATCH 128/167] trying again

---
 .github/workflows/releases.yml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 10cb12dac..75d5ed511 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -10,6 +10,10 @@ jobs:
       packages: write
     steps:
       - uses: actions/checkout@v4
+        with:
+          path: main
+      - name: Rename directory
+        run: mv main/RoaringBitmap roaring
       - uses: actions/setup-java@v4
         with:
           java-version: '11'
@@ -18,8 +22,10 @@ jobs:
         uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
       - name: Build with Gradle
         run: ./gradlew build -x test -i
+        working-directory: ./roaring
       - name: Publish package
-        run: ./gradlew publish -i 
+        run: ./gradlew publishSonatypePublicationToGitHubPackagesRepository -i
+        working-directory: ./roaring
         env:
           GITHUB_USER: ${{ github.actor }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

From c3b8caabe0cc05eba4350a7a6eb46ccd8ed6d7ba Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:03:36 -0400
Subject: [PATCH 129/167] [Gradle Release Plugin] - pre tag commit:  '1.3.7'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index d0c173f6d..47c066665 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.7-SNAPSHOT
+version = 1.3.7
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From ad56e5df10c089c479256b2c566e40bdd89a73c0 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:03:38 -0400
Subject: [PATCH 130/167] [Gradle Release Plugin] - new version commit: 
 '1.3.8-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 47c066665..2e8285dbf 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.7
+version = 1.3.8-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From ddc2ba99cc4d2a11761a6706d3070d9116ed239b Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:08:01 -0400
Subject: [PATCH 131/167] trying to debug

---
 .github/workflows/releases.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 75d5ed511..8ad334365 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -14,6 +14,11 @@ jobs:
           path: main
       - name: Rename directory
         run: mv main/RoaringBitmap roaring
+      - name: List content
+        run: ls -la
+      - name: List content roaring
+        run: ls -la
+        working-directory: ./roaring
       - uses: actions/setup-java@v4
         with:
           java-version: '11'

From 3a3d6fd7c1cd2be4737f8ec57094fcd400bfc8b6 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:09:42 -0400
Subject: [PATCH 132/167] [Gradle Release Plugin] - pre tag commit:  '1.3.8'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 2e8285dbf..c2e8864dd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.8-SNAPSHOT
+version = 1.3.8
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 092a6452bbdab8a0e69bfcf02f5f9f81bd666489 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:09:44 -0400
Subject: [PATCH 133/167] [Gradle Release Plugin] - new version commit: 
 '1.3.9-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index c2e8864dd..b433f19f2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.8
+version = 1.3.9-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 797481616555cc2196d11fb21bafff3d5d44dbaa Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:11:03 -0400
Subject: [PATCH 134/167] again

---
 .github/workflows/releases.yml | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 8ad334365..d2c44f100 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -11,14 +11,7 @@ jobs:
     steps:
       - uses: actions/checkout@v4
         with:
-          path: main
-      - name: Rename directory
-        run: mv main/RoaringBitmap roaring
-      - name: List content
-        run: ls -la
-      - name: List content roaring
-        run: ls -la
-        working-directory: ./roaring
+          path: roaring
       - uses: actions/setup-java@v4
         with:
           java-version: '11'

From 86ea2d99d2b60ba4560789f343e86e1d86e31d13 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:11:13 -0400
Subject: [PATCH 135/167] [Gradle Release Plugin] - pre tag commit:  '1.3.9'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index b433f19f2..f8dfdeccb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.9-SNAPSHOT
+version = 1.3.9
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From e12cd714b066c02121fd153d46a728a336f2cae1 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:11:15 -0400
Subject: [PATCH 136/167] [Gradle Release Plugin] - new version commit: 
 '1.3.10-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index f8dfdeccb..eabf7b28f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.9
+version = 1.3.10-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From c738c074577ca6935b1f79b38337e8be5069b04e Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:17:43 -0400
Subject: [PATCH 137/167] removing style...

---
 .github/PULL_REQUEST_TEMPLATE.md        |  1 -
 .github/workflows/java-all-versions.yml |  2 --
 .travis.yml                             | 41 -------------------------
 README.md                               |  6 ++--
 build.gradle.kts                        | 23 --------------
 5 files changed, 2 insertions(+), 71 deletions(-)
 delete mode 100644 .travis.yml

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 9d8aa8f83..18c2b823c 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,4 +6,3 @@
 ### Automated Checks
 
 - [ ] I have run `./gradlew test` and made sure that my PR does not break any unit test.
-- [ ] I have run `./gradlew checkstyleMain` or the equivalent and corrected the formatting warnings reported.
diff --git a/.github/workflows/java-all-versions.yml b/.github/workflows/java-all-versions.yml
index 9f089785f..ecfa7471d 100644
--- a/.github/workflows/java-all-versions.yml
+++ b/.github/workflows/java-all-versions.yml
@@ -19,8 +19,6 @@ jobs:
             21
       - name: Build with Gradle
         run: ./gradlew assemble
-      - name: Style check
-        run: ./gradlew checkstyleMain
       - name: Test with Java 8
         run: ./gradlew test -PtestOnJava=8 --stacktrace
       - name: Test with Java 11
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 2492d43e9..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-language: java
-sudo: false
-
-jdk:
-  - openjdk8
-  - openjdk11
-  - openjdk14
-  - oraclejdk11
-  
-
-############
-# We still support and test jdk8 for clients, but on travis we no longer build with jkd8, see
-# https://github.com/RoaringBitmap/RoaringBitmap/pull/290 for rationale.
-##########
-# we removed oraclejdk7 as per https://github.com/RoaringBitmap/RoaringBitmap/pull/176#issuecomment-322257170
-#########
-
-# from https://docs.travis-ci.com/user/languages/java/#caching
-before_cache:
-  - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
-  - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
-cache:
-  directories:
-    - $HOME/.gradle/caches/
-    - $HOME/.gradle/wrapper/
-
-# Install silently to ensure all pom are installed and compilation is OK: actual checks will be processed by script:
-# Including testClasses so tests will compile too.
-install: "./gradlew assemble testClasses"
-
-branches:
-  only:
-    - master
-
-script:
-  # run checkstyle, etc, without the tests to fail fast
-  - ./gradlew check -x test
-  - ./gradlew test jacocoTestReport -DBITMAP_TYPES=ROARING_ONLY
-
-after_success:
-  - ./gradlew coveralls
diff --git a/README.md b/README.md
index 652f49eb0..dc6ad20bb 100644
--- a/README.md
+++ b/README.md
@@ -428,7 +428,6 @@ Usage
 * ``./gradlew test `` will run the tests
 * ``./gradlew :roaringbitmap:test --tests TestIterators.testIndexIterator4`` runs just the test `TestIterators.testIndexIterator4`; `./gradlew -i :roaringbitmap:test --tests TestRoaringBitmap.issue623` runs just the test `issue623` in the class ` TestRoaringBitmap` while printing out to the console.
 * ``./gradlew  bsi:test --tests BufferBSITest.testEQ``  run just the test `BufferBSITest.testEQ` in the `bsi` submodule
-* ``./gradlew checkstyleMain`` will check that you abide by the code style and that the code compiles. We enforce a strict style so that there is no debate as to the proper way to format the code.
 
 
 IntelliJ and Eclipse
@@ -442,9 +441,8 @@ it up in your favorite IDE.
 Contributing
 ------------
 
-Contributions are invited. We enforce the Google Java style.
-Please run  ``./gradlew checkstyleMain`` on your code before submitting
-a patch.
+Contributions are invited. We use the Google Java style (see `roaring_google_checks.xml`).
+Please do not reformat the code needlessly.
 
 FAQ
 ----
diff --git a/build.gradle.kts b/build.gradle.kts
index 61c0428ca..e342dce6a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -52,29 +52,6 @@ subprojects {
     }
 }
 
-subprojects.filter { !listOf("jmh", "fuzz-tests", "examples", "bsi", "simplebenchmark").contains(it.name) }.forEach {
-    it.run {
-        apply(plugin = "checkstyle")
-
-        tasks {
-            withType {
-                configFile = File(rootProject.projectDir, "RoaringBitmap/style/roaring_google_checks.xml")
-                isIgnoreFailures = false
-                isShowViolations = true
-
-                // Skip checkstyle on module-info.java since it breaks.
-                exclude("module-info.java")
-            }
-
-            // don't checkstyle source
-            named("checkstyleTest") {
-                exclude("**/**")
-            }
-        }
-    }
-}
-
-
 subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach { project ->
     project.run {
         apply(plugin = "maven-publish")

From 4446cba44ab43e7c8718aaa8b90e9c180c0b7a4f Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:18:17 -0400
Subject: [PATCH 138/167] pruning

---
 RoaringBitmap/build.gradle.kts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/RoaringBitmap/build.gradle.kts b/RoaringBitmap/build.gradle.kts
index d53dceaa4..7bf9a05ef 100644
--- a/RoaringBitmap/build.gradle.kts
+++ b/RoaringBitmap/build.gradle.kts
@@ -86,7 +86,6 @@ tasks.named("jar") {
 
 tasks.test {
     systemProperty("kryo.unsafe", "false")
-    mustRunAfter(tasks.checkstyleMain)
     useJUnitPlatform()
     failFast = true
 

From 9d527a57c6f3b678c60eb26c3f668946ec062830 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:18:33 -0400
Subject: [PATCH 139/167] [Gradle Release Plugin] - pre tag commit:  '1.3.10'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index eabf7b28f..ae99748da 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.10-SNAPSHOT
+version = 1.3.10
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From e7add4f10ac420685b6f52e7be45c84a45c75f16 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:18:35 -0400
Subject: [PATCH 140/167] [Gradle Release Plugin] - new version commit: 
 '1.3.11-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index ae99748da..4218114d5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.10
+version = 1.3.11-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 2d80e394d588077994674a5445e0b549d2739718 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:38:08 -0400
Subject: [PATCH 141/167] putting back repo

---
 build.gradle.kts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/build.gradle.kts b/build.gradle.kts
index e342dce6a..0be9575c7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -24,6 +24,10 @@ subprojects {
 
     apply(plugin = "java-library")
 
+    repositories {
+        mavenCentral()
+    }
+
     group = "org.roaringbitmap"
 
     tasks {

From e7b82b6fdcffb8ef198c9f0178974f59ef7d3785 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:38:26 -0400
Subject: [PATCH 142/167] [Gradle Release Plugin] - pre tag commit:  '1.3.11'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 4218114d5..f3ef4b118 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.11-SNAPSHOT
+version = 1.3.11
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From a8bda2b00e0ff9d2cd0778d83139e24d0c07b461 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:38:28 -0400
Subject: [PATCH 143/167] [Gradle Release Plugin] - new version commit: 
 '1.3.12-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index f3ef4b118..7142bc94e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.11
+version = 1.3.12-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 85861ab76f548febddd46b70150fa8a4d42155a5 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:51:51 -0400
Subject: [PATCH 144/167] must be lower case

---
 .gitignore                                          |   1 -
 README.md                                           |   2 +-
 bsi/build.gradle.kts                                |   2 +-
 build.gradle.kts                                    |   4 ++--
 examples/build.gradle.kts                           |   2 +-
 fuzz-tests/build.gradle.kts                         |   2 +-
 jmh/build.gradle.kts                                |   6 +++---
 {RoaringBitmap => roaringbitmap}/build.gradle.kts   |   0
 .../java11/java/org/roaringbitmap/ArraysShim.java   |   0
 .../src/main/java/module-info.java                  |   0
 .../java/org/roaringbitmap/AppendableStorage.java   |   0
 .../java/org/roaringbitmap/ArrayBatchIterator.java  |   0
 .../main/java/org/roaringbitmap/ArrayContainer.java |   0
 .../src/main/java/org/roaringbitmap/ArraysShim.java |   0
 .../java/org/roaringbitmap/BatchIntIterator.java    |   0
 .../main/java/org/roaringbitmap/BatchIterator.java  |   0
 .../src/main/java/org/roaringbitmap/BitSetUtil.java |   0
 .../java/org/roaringbitmap/BitmapBatchIterator.java |   0
 .../java/org/roaringbitmap/BitmapContainer.java     |   0
 .../java/org/roaringbitmap/BitmapDataProvider.java  |   0
 .../roaringbitmap/BitmapDataProviderSupplier.java   |   0
 .../main/java/org/roaringbitmap/CharIterator.java   |   0
 .../ConstantMemoryContainerAppender.java            |   0
 .../src/main/java/org/roaringbitmap/Container.java  |   0
 .../java/org/roaringbitmap/ContainerAppender.java   |   0
 .../org/roaringbitmap/ContainerBatchIterator.java   |   0
 .../java/org/roaringbitmap/ContainerPointer.java    |   0
 .../java/org/roaringbitmap/FastAggregation.java     |   0
 .../org/roaringbitmap/FastRankRoaringBitmap.java    |   0
 .../roaringbitmap/ImmutableBitmapDataProvider.java  |   0
 .../main/java/org/roaringbitmap/IntConsumer.java    |   0
 .../IntConsumerRelativeRangeAdapter.java            |   0
 .../main/java/org/roaringbitmap/IntIterator.java    |   0
 .../org/roaringbitmap/IntIteratorFlyweight.java     |   0
 .../org/roaringbitmap/InvalidRoaringFormat.java     |   0
 .../java/org/roaringbitmap/ParallelAggregation.java |   0
 .../org/roaringbitmap/PeekableCharIterator.java     |   0
 .../org/roaringbitmap/PeekableCharRankIterator.java |   0
 .../java/org/roaringbitmap/PeekableIntIterator.java |   0
 .../org/roaringbitmap/PeekableIntRankIterator.java  |   0
 .../main/java/org/roaringbitmap/RangeBitmap.java    |   0
 .../org/roaringbitmap/RelativeRangeConsumer.java    |   0
 .../roaringbitmap/ReverseIntIteratorFlyweight.java  |   0
 .../main/java/org/roaringbitmap/RoaringArray.java   |   0
 .../org/roaringbitmap/RoaringBatchIterator.java     |   0
 .../main/java/org/roaringbitmap/RoaringBitSet.java  |   0
 .../main/java/org/roaringbitmap/RoaringBitmap.java  |   0
 .../org/roaringbitmap/RoaringBitmapPrivate.java     |   0
 .../org/roaringbitmap/RoaringBitmapSupplier.java    |   0
 .../java/org/roaringbitmap/RoaringBitmapWriter.java |   0
 .../java/org/roaringbitmap/RunBatchIterator.java    |   0
 .../main/java/org/roaringbitmap/RunContainer.java   |   0
 .../src/main/java/org/roaringbitmap/Util.java       |   0
 .../main/java/org/roaringbitmap/WordStorage.java    |   0
 .../java/org/roaringbitmap/art/AbstractShuttle.java |   0
 .../src/main/java/org/roaringbitmap/art/Art.java    |   0
 .../java/org/roaringbitmap/art/BackwardShuttle.java |   0
 .../org/roaringbitmap/art/ContainerIterator.java    |   0
 .../main/java/org/roaringbitmap/art/Containers.java |   0
 .../java/org/roaringbitmap/art/ForwardShuttle.java  |   0
 .../java/org/roaringbitmap/art/KeyIterator.java     |   0
 .../main/java/org/roaringbitmap/art/LeafNode.java   |   0
 .../org/roaringbitmap/art/LeafNodeIterator.java     |   0
 .../src/main/java/org/roaringbitmap/art/Node.java   |   0
 .../src/main/java/org/roaringbitmap/art/Node16.java |   0
 .../main/java/org/roaringbitmap/art/Node256.java    |   0
 .../src/main/java/org/roaringbitmap/art/Node4.java  |   0
 .../src/main/java/org/roaringbitmap/art/Node48.java |   0
 .../main/java/org/roaringbitmap/art/NodeType.java   |   0
 .../java/org/roaringbitmap/art/SearchResult.java    |   0
 .../main/java/org/roaringbitmap/art/Shuttle.java    |   0
 .../roaringbitmap/buffer/ArrayBatchIterator.java    |   0
 .../roaringbitmap/buffer/BitmapBatchIterator.java   |   0
 .../org/roaringbitmap/buffer/BufferBitSetUtil.java  |   0
 .../roaringbitmap/buffer/BufferFastAggregation.java |   0
 .../buffer/BufferIntIteratorFlyweight.java          |   0
 .../buffer/BufferParallelAggregation.java           |   0
 .../buffer/BufferReverseIntIteratorFlyweight.java   |   0
 .../java/org/roaringbitmap/buffer/BufferUtil.java   |   0
 .../roaringbitmap/buffer/ImmutableRoaringArray.java |   0
 .../buffer/ImmutableRoaringBitmap.java              |   0
 .../buffer/MappeableArrayContainer.java             |   0
 .../buffer/MappeableBitmapContainer.java            |   0
 .../roaringbitmap/buffer/MappeableContainer.java    |   0
 .../buffer/MappeableContainerPointer.java           |   0
 .../roaringbitmap/buffer/MappeableRunContainer.java |   0
 .../roaringbitmap/buffer/MutableRoaringArray.java   |   0
 .../roaringbitmap/buffer/MutableRoaringBitmap.java  |   0
 .../buffer/MutableRoaringBitmapPrivate.java         |   0
 .../buffer/MutableRoaringBitmapSupplier.java        |   0
 .../roaringbitmap/buffer/PointableRoaringArray.java |   0
 .../roaringbitmap/buffer/RoaringBatchIterator.java  |   0
 .../org/roaringbitmap/buffer/RunBatchIterator.java  |   0
 .../java/org/roaringbitmap/buffer/package-info.java |   0
 .../org/roaringbitmap/insights/BitmapAnalyser.java  |   0
 .../roaringbitmap/insights/BitmapStatistics.java    |   0
 .../insights/NaiveWriterRecommender.java            |   0
 .../roaringbitmap/longlong/ContainerWithIndex.java  |   0
 .../roaringbitmap/longlong/HighLowContainer.java    |   0
 .../longlong/ImmutableLongBitmapDataProvider.java   |   0
 .../org/roaringbitmap/longlong/IntegerUtil.java     |   0
 .../longlong/LongBitmapDataProvider.java            |   0
 .../org/roaringbitmap/longlong/LongConsumer.java    |   0
 .../longlong/LongConsumerRelativeRangeAdapter.java  |   0
 .../org/roaringbitmap/longlong/LongIterator.java    |   0
 .../java/org/roaringbitmap/longlong/LongUtils.java  |   0
 .../longlong/PeekableLongIterator.java              |   0
 .../org/roaringbitmap/longlong/Roaring64Bitmap.java |   0
 .../longlong/Roaring64NavigableMap.java             |   0
 .../roaringbitmap/longlong/RoaringIntPacking.java   |   0
 .../org/roaringbitmap/longlong/package-info.java    |   0
 .../main/java/org/roaringbitmap/package-info.java   |   0
 .../org/roaringbitmap/CloneBatchIteratorTest.java   |   0
 .../roaringbitmap/ContainerBatchIteratorTest.java   |   0
 .../src/test/java/org/roaringbitmap/KryoTest.java   |   0
 .../java/org/roaringbitmap/OrNotTruncationTest.java |   0
 .../org/roaringbitmap/ParallelAggregationTest.java  |   0
 .../java/org/roaringbitmap/PreviousValueTest.java   |   0
 .../java/org/roaringbitmap/RangeBitmapTest.java     |   0
 .../java/org/roaringbitmap/RoaringArrayTest.java    |   0
 .../java/org/roaringbitmap/RoaringBitSetTest.java   |   0
 .../RoaringBitmapBatchIteratorTest.java             |   0
 .../RoaringBitmapIntervalIntersectionTest.java      |   0
 .../org/roaringbitmap/RoaringBitmapSubsetTest.java  |   0
 .../RoaringBitmapWriterRandomisedTest.java          |   0
 .../test/java/org/roaringbitmap/SeededTestData.java |   0
 .../org/roaringbitmap/TestAdversarialInputs.java    |   0
 .../java/org/roaringbitmap/TestArrayContainer.java  |   0
 .../test/java/org/roaringbitmap/TestBitSetUtil.java |   0
 .../java/org/roaringbitmap/TestBitmapContainer.java |   0
 .../java/org/roaringbitmap/TestConcatenation.java   |   0
 .../test/java/org/roaringbitmap/TestContainer.java  |   0
 .../TestEmptyRoaringBatchIterator.java              |   0
 .../java/org/roaringbitmap/TestFastAggregation.java |   0
 .../java/org/roaringbitmap/TestForAllInRange.java   |   0
 .../test/java/org/roaringbitmap/TestForEach.java    |   0
 .../roaringbitmap/TestImmutableRoaringBitmap.java   |   0
 .../org/roaringbitmap/TestIntIteratorFlyweight.java |   0
 .../java/org/roaringbitmap/TestIteratorMemory.java  |   0
 .../test/java/org/roaringbitmap/TestIterators.java  |   0
 .../src/test/java/org/roaringbitmap/TestMemory.java |   0
 .../src/test/java/org/roaringbitmap/TestRange.java  |   0
 .../org/roaringbitmap/TestRangeCardinality.java     |   0
 .../java/org/roaringbitmap/TestRankIterator.java    |   0
 .../TestRankIteratorsOfContainers.java              |   0
 .../TestReverseIteratorsOfContainers.java           |   0
 .../java/org/roaringbitmap/TestRoaringBitmap.java   |   0
 .../org/roaringbitmap/TestRoaringBitmapOrNot.java   |   0
 .../org/roaringbitmap/TestRoaringBitmapWriter.java  |   0
 .../TestRoaringBitmapWriterWizard.java              |   0
 .../roaringbitmap/TestRoaringBitmap_FastRank.java   |   0
 .../java/org/roaringbitmap/TestRunContainer.java    |   0
 .../java/org/roaringbitmap/TestSerialization.java   |   0
 .../TestSerializationViaByteBuffer.java             |   0
 .../java/org/roaringbitmap/TestSerializedSize.java  |   0
 .../test/java/org/roaringbitmap/TestStreams.java    |   0
 .../src/test/java/org/roaringbitmap/TestUtil.java   |   0
 .../java/org/roaringbitmap/TestVeryLargeBitmap.java |   0
 .../UnorderedRoaringBitmapWriterRandomisedTest.java |   0
 .../org/roaringbitmap/ValidationRangeConsumer.java  |   0
 .../test/java/org/roaringbitmap/art/Node16Test.java |   0
 .../java/org/roaringbitmap/art/Node256Test.java     |   0
 .../test/java/org/roaringbitmap/art/Node48Test.java |   0
 .../test/java/org/roaringbitmap/art/Node4Test.java  |   0
 .../buffer/BufferContainerBatchIteratorTest.java    |   0
 .../buffer/CloneBatchIteratorTest.java              |   0
 .../ImmutableRoaringBitmapBatchIteratorTest.java    |   0
 .../buffer/MutableRoaringArrayTest.java             |   0
 .../buffer/MutableRoaringBitmapSubsetTest.java      |   0
 .../RoaringBitmapIntervalIntersectionTest.java      |   0
 .../org/roaringbitmap/buffer/TestBitSetUtil.java    |   0
 .../buffer/TestBufferAdversarialInputs.java         |   0
 .../buffer/TestBufferRangeCardinality.java          |   0
 .../roaringbitmap/buffer/TestCompressionRates.java  |   0
 .../org/roaringbitmap/buffer/TestContainer.java     |   0
 .../java/org/roaringbitmap/buffer/TestExamples.java |   0
 .../roaringbitmap/buffer/TestFastAggregation.java   |   0
 .../java/org/roaringbitmap/buffer/TestForEach.java  |   0
 .../buffer/TestImmutableRoaringBitmap.java          |   0
 .../buffer/TestImmutableRoaringBitmapOrNot.java     |   0
 .../buffer/TestIntIteratorFlyweight.java            |   0
 .../org/roaringbitmap/buffer/TestIterators.java     |   0
 .../buffer/TestMappeableArrayContainer.java         |   0
 .../buffer/TestMappeableBitmapContainer.java        |   0
 .../TestMappeableBitmapContainerCharIterator.java   |   0
 .../buffer/TestMappeableRunContainer.java           |   0
 .../java/org/roaringbitmap/buffer/TestMemory.java   |   0
 .../org/roaringbitmap/buffer/TestMemoryMapping.java |   0
 .../java/org/roaringbitmap/buffer/TestRange.java    |   0
 .../buffer/TestReverseMappeableRunContainer.java    |   0
 .../org/roaringbitmap/buffer/TestRoaringBitmap.java |   0
 .../org/roaringbitmap/buffer/TestRunContainer.java  |   0
 .../buffer/TestSerializationViaByteBuffer.java      |   0
 .../roaringbitmap/buffer/TestSerializedSize.java    |   0
 .../java/org/roaringbitmap/buffer/TestUtil.java     |   0
 .../roaringbitmap/buffer/TestVeryLargeBitmap.java   |   0
 .../roaringbitmap/insights/BitmapAnalyserTest.java  |   0
 .../insights/BitmapStatisticsTest.java              |   0
 .../insights/NaiveWriterRecommenderTest.java        |   0
 .../java/org/roaringbitmap/longlong/ArtTest.java    |   0
 .../java/org/roaringbitmap/longlong/BytesUtil.java  |   0
 .../org/roaringbitmap/longlong/ContainersTest.java  |   0
 .../org/roaringbitmap/longlong/IntegerUtilTest.java |   0
 .../java/org/roaringbitmap/longlong/Issue319.java   |   0
 .../roaringbitmap/longlong/JolBenchmarksTest.java   |   0
 .../roaringbitmap/longlong/TestRoaring64Bitmap.java |   0
 .../longlong/TestRoaring64NavigableMap.java         |   0
 .../src/test/resources/junit-platform.properties    |   0
 .../src/test/resources/testdata/64map32bitvals.bin  | Bin
 .../src/test/resources/testdata/64mapempty.bin      | Bin
 .../src/test/resources/testdata/64maphighvals.bin   | Bin
 .../src/test/resources/testdata/64mapspreadvals.bin | Bin
 .../test/resources/testdata/bitmapwithoutruns.bin   | Bin
 .../src/test/resources/testdata/bitmapwithruns.bin  | Bin
 .../test/resources/testdata/crashproneinput1.bin    | Bin
 .../test/resources/testdata/crashproneinput2.bin    | Bin
 .../test/resources/testdata/crashproneinput3.bin    |   0
 .../test/resources/testdata/crashproneinput4.bin    |   0
 .../test/resources/testdata/crashproneinput5.bin    |   0
 .../test/resources/testdata/crashproneinput6.bin    | Bin
 .../test/resources/testdata/crashproneinput7.bin    | Bin
 .../test/resources/testdata/crashproneinput8.bin    | Bin
 .../resources/testdata/offset_failure_case_1.txt    |   0
 .../resources/testdata/offset_failure_case_2.txt    |   0
 .../resources/testdata/offset_failure_case_3.txt    |   0
 .../test/resources/testdata/ornot-fuzz-failure.json |   0
 .../resources/testdata/prevvalue-regression.txt     |   0
 .../resources/testdata/rangebitmap_regression.txt   |   0
 .../src/test/resources/testdata/testIssue260.txt    |   0
 .../style/eclipse-java-google-style.xml             |   0
 .../style/roaring_google_checks.xml                 |   0
 settings.gradle.kts                                 |   2 +-
 simplebenchmark/build.gradle.kts                    |   2 +-
 233 files changed, 11 insertions(+), 12 deletions(-)
 rename {RoaringBitmap => roaringbitmap}/build.gradle.kts (100%)
 rename {RoaringBitmap => roaringbitmap}/src/java11/java/org/roaringbitmap/ArraysShim.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/module-info.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/AppendableStorage.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ArrayBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ArrayContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ArraysShim.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BatchIntIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BitSetUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BitmapBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BitmapContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BitmapDataProvider.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/CharIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/Container.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ContainerAppender.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ContainerBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ContainerPointer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/FastAggregation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/IntConsumer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/IntConsumerRelativeRangeAdapter.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/IntIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ParallelAggregation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/PeekableCharIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/PeekableCharRankIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/PeekableIntIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RangeBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RelativeRangeConsumer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringArray.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringBitSet.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringBitmapPrivate.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RunBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/RunContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/Util.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/WordStorage.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/AbstractShuttle.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Art.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/BackwardShuttle.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/ContainerIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Containers.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/ForwardShuttle.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/KeyIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/LeafNode.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Node.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Node16.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Node256.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Node4.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Node48.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/NodeType.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/SearchResult.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/art/Shuttle.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/BufferUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapPrivate.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/buffer/package-info.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/ContainerWithIndex.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/IntegerUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/LongConsumer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/LongConsumerRelativeRangeAdapter.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/LongIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/LongUtils.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/longlong/package-info.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/main/java/org/roaringbitmap/package-info.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/KryoTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/OrNotTruncationTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/ParallelAggregationTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/PreviousValueTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RangeBitmapTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RoaringArrayTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RoaringBitSetTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/SeededTestData.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestAdversarialInputs.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestArrayContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestBitSetUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestBitmapContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestConcatenation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestFastAggregation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestForAllInRange.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestForEach.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestIteratorMemory.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestIterators.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestMemory.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRange.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRangeCardinality.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRankIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestRunContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestSerialization.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestSerializedSize.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestStreams.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/art/Node16Test.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/art/Node256Test.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/art/Node48Test.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/art/Node4Test.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestExamples.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestForEach.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestIterators.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestMemory.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestRange.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/ArtTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/BytesUtil.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/ContainersTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/Issue319.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/junit-platform.properties (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/64map32bitvals.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/64mapempty.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/64maphighvals.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/64mapspreadvals.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/bitmapwithoutruns.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/bitmapwithruns.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput1.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput2.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput3.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput4.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput5.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput6.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput7.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/crashproneinput8.bin (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/offset_failure_case_1.txt (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/offset_failure_case_2.txt (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/offset_failure_case_3.txt (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/ornot-fuzz-failure.json (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/prevvalue-regression.txt (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/rangebitmap_regression.txt (100%)
 rename {RoaringBitmap => roaringbitmap}/src/test/resources/testdata/testIssue260.txt (100%)
 rename {RoaringBitmap => roaringbitmap}/style/eclipse-java-google-style.xml (100%)
 rename {RoaringBitmap => roaringbitmap}/style/roaring_google_checks.xml (100%)

diff --git a/.gitignore b/.gitignore
index 5ec4ec483..f8309e05d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,5 +30,4 @@ pom.xml.tag
 
 # We ignore .bin files as they may be generated by fuzz-tests
 # Beware there is real .bin files in /testdata
-# git add --force ./RoaringBitmap/src/test/resources/testdata/*.bin
 *.bin
diff --git a/README.md b/README.md
index dc6ad20bb..668f3b18b 100644
--- a/README.md
+++ b/README.md
@@ -508,7 +508,7 @@ You can also run specific benchmarks...
 Mailing list/discussion group
 -----------------------------
 
-https://groups.google.com/forum/#!forum/roaring-bitmaps
+https://groups.google.com/forum/#!forum/roaringbitmaps
 
 Funding
 ----------
diff --git a/bsi/build.gradle.kts b/bsi/build.gradle.kts
index 4eb92a893..69171d56e 100644
--- a/bsi/build.gradle.kts
+++ b/bsi/build.gradle.kts
@@ -1,7 +1,7 @@
 val deps: Map by extra
 
 dependencies {
-    implementation(project(":RoaringBitmap"))
+    implementation(project(":roaringbitmap"))
 
     testImplementation("org.junit.jupiter:junit-jupiter-api:${deps["jupiter"]}")
     testImplementation("org.junit.jupiter:junit-jupiter-params:${deps["jupiter"]}")
diff --git a/build.gradle.kts b/build.gradle.kts
index 0be9575c7..3b975a8a4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -56,7 +56,7 @@ subprojects {
     }
 }
 
-subprojects.filter { listOf("RoaringBitmap", "bsi").contains(it.name) }.forEach { project ->
+subprojects.filter { listOf("roaringbitmap", "bsi").contains(it.name) }.forEach { project ->
     project.run {
         apply(plugin = "maven-publish")
         configure {
@@ -145,7 +145,7 @@ tasks {
 }
 
 release {
-    // for some odd reason, we used to have our tags be of the form RoaringBitmap-0.1.0
+    // for some odd reason, we used to have our tags be of the form roaringbitmap-0.1.0
     // instead of just 0.1.0 or v0.1.0.
     tagTemplate = "\$version"
 }
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
index 27402af6a..d9e5f6490 100644
--- a/examples/build.gradle.kts
+++ b/examples/build.gradle.kts
@@ -1,5 +1,5 @@
 dependencies {
-    implementation(project(":RoaringBitmap"))
+    implementation(project(":roaringbitmap"))
 }
 
 tasks {
diff --git a/fuzz-tests/build.gradle.kts b/fuzz-tests/build.gradle.kts
index 1bea179be..dac73142b 100644
--- a/fuzz-tests/build.gradle.kts
+++ b/fuzz-tests/build.gradle.kts
@@ -1,7 +1,7 @@
 val deps: Map by extra
 
 dependencies {
-    implementation(project(":RoaringBitmap"))
+    implementation(project(":roaringbitmap"))
     testImplementation("org.junit.jupiter:junit-jupiter-api:${deps["jupiter"]}")
     testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${deps["jupiter"]}")
     testImplementation("com.google.guava:guava:${deps["guava"]}")
diff --git a/jmh/build.gradle.kts b/jmh/build.gradle.kts
index afaaac228..367b0e4a8 100644
--- a/jmh/build.gradle.kts
+++ b/jmh/build.gradle.kts
@@ -30,7 +30,7 @@ dependencies {
 
     // tests and benchmarks both need dependencies: javaEWAH, extendedset, etc.
     listOf(
-            project(":RoaringBitmap"),
+            project(":roaringbitmap"),
             project(":bsi"),
             "com.google.guava:guava:${deps["guava"]}",
             "com.googlecode.javaewah:JavaEWAH:1.0.8",
@@ -67,8 +67,8 @@ tasks.test {
     if (!project.hasProperty("roaringbitmap.jmh")) {
         exclude("**")
     } else {
-        // stop these tests from running before RoaringBitmap
-        shouldRunAfter(project(":RoaringBitmap").tasks.test)
+        // stop these tests from running before roaringbitmap
+        shouldRunAfter(project(":roaringbitmap").tasks.test)
         useJUnitPlatform()
         failFast = true
     }
diff --git a/RoaringBitmap/build.gradle.kts b/roaringbitmap/build.gradle.kts
similarity index 100%
rename from RoaringBitmap/build.gradle.kts
rename to roaringbitmap/build.gradle.kts
diff --git a/RoaringBitmap/src/java11/java/org/roaringbitmap/ArraysShim.java b/roaringbitmap/src/java11/java/org/roaringbitmap/ArraysShim.java
similarity index 100%
rename from RoaringBitmap/src/java11/java/org/roaringbitmap/ArraysShim.java
rename to roaringbitmap/src/java11/java/org/roaringbitmap/ArraysShim.java
diff --git a/RoaringBitmap/src/main/java/module-info.java b/roaringbitmap/src/main/java/module-info.java
similarity index 100%
rename from RoaringBitmap/src/main/java/module-info.java
rename to roaringbitmap/src/main/java/module-info.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/AppendableStorage.java b/roaringbitmap/src/main/java/org/roaringbitmap/AppendableStorage.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/AppendableStorage.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/AppendableStorage.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ArraysShim.java b/roaringbitmap/src/main/java/org/roaringbitmap/ArraysShim.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ArraysShim.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ArraysShim.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/BatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapDataProvider.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProvider.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BitmapDataProvider.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/BitmapDataProviderSupplier.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/CharIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/CharIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/CharIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/CharIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java b/roaringbitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Container.java b/roaringbitmap/src/main/java/org/roaringbitmap/Container.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/Container.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/Container.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerAppender.java b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerAppender.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ContainerAppender.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ContainerAppender.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ContainerPointer.java b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerPointer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ContainerPointer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ContainerPointer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/FastAggregation.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/FastAggregation.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/FastAggregation.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumer.java b/roaringbitmap/src/main/java/org/roaringbitmap/IntConsumer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/IntConsumer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumerRelativeRangeAdapter.java b/roaringbitmap/src/main/java/org/roaringbitmap/IntConsumerRelativeRangeAdapter.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/IntConsumerRelativeRangeAdapter.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/IntConsumerRelativeRangeAdapter.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/IntIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/IntIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/IntIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java b/roaringbitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharRankIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharRankIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/PeekableCharRankIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharRankIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/RangeBitmap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RangeBitmap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RangeBitmap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RelativeRangeConsumer.java b/roaringbitmap/src/main/java/org/roaringbitmap/RelativeRangeConsumer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RelativeRangeConsumer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RelativeRangeConsumer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringArray.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringArray.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringArray.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapPrivate.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapPrivate.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapPrivate.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapPrivate.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/Util.java b/roaringbitmap/src/main/java/org/roaringbitmap/Util.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/Util.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/Util.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/WordStorage.java b/roaringbitmap/src/main/java/org/roaringbitmap/WordStorage.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/WordStorage.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/WordStorage.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Art.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Art.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Art.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Art.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/BackwardShuttle.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Containers.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Containers.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Containers.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Containers.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/ForwardShuttle.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/KeyIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNode.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNode.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNode.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNode.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Node.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Node.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node16.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node16.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Node16.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Node16.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node256.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node256.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Node256.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Node256.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node4.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node4.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Node4.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Node4.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Node48.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node48.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Node48.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Node48.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/NodeType.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/NodeType.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/NodeType.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/NodeType.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/SearchResult.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/SearchResult.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/SearchResult.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/SearchResult.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/art/Shuttle.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Shuttle.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/art/Shuttle.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/art/Shuttle.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapPrivate.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapPrivate.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapPrivate.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapPrivate.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/package-info.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/package-info.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/buffer/package-info.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/buffer/package-info.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java b/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java b/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java b/roaringbitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ContainerWithIndex.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/ContainerWithIndex.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ContainerWithIndex.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/ContainerWithIndex.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/IntegerUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/IntegerUtil.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/IntegerUtil.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/IntegerUtil.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongConsumer.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumerRelativeRangeAdapter.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongConsumerRelativeRangeAdapter.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongConsumerRelativeRangeAdapter.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongConsumerRelativeRangeAdapter.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/package-info.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/package-info.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/longlong/package-info.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/longlong/package-info.java
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/package-info.java b/roaringbitmap/src/main/java/org/roaringbitmap/package-info.java
similarity index 100%
rename from RoaringBitmap/src/main/java/org/roaringbitmap/package-info.java
rename to roaringbitmap/src/main/java/org/roaringbitmap/package-info.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/KryoTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/KryoTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/KryoTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/KryoTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/SeededTestData.java b/roaringbitmap/src/test/java/org/roaringbitmap/SeededTestData.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/SeededTestData.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/SeededTestData.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestConcatenation.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestConcatenation.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestConcatenation.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestConcatenation.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestForEach.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestForEach.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestForEach.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestForEach.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestIterators.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestIterators.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestIterators.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestMemory.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestMemory.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestMemory.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestMemory.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRange.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRange.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRange.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRange.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRankIterator.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIterator.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRankIterator.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRankIterator.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRunContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestRunContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestRunContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerialization.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerialization.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestSerialization.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestSerialization.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestStreams.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestStreams.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestStreams.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestStreams.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestUtil.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestUtil.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestUtil.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java b/roaringbitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/art/Node16Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node16Test.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/art/Node16Test.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/art/Node16Test.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/art/Node256Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node256Test.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/art/Node256Test.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/art/Node256Test.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/art/Node48Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node48Test.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/art/Node48Test.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/art/Node48Test.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/art/Node4Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node4Test.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/art/Node4Test.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/art/Node4Test.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/BytesUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/BytesUtil.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/BytesUtil.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/BytesUtil.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java
similarity index 100%
rename from RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java
rename to roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java
diff --git a/RoaringBitmap/src/test/resources/junit-platform.properties b/roaringbitmap/src/test/resources/junit-platform.properties
similarity index 100%
rename from RoaringBitmap/src/test/resources/junit-platform.properties
rename to roaringbitmap/src/test/resources/junit-platform.properties
diff --git a/RoaringBitmap/src/test/resources/testdata/64map32bitvals.bin b/roaringbitmap/src/test/resources/testdata/64map32bitvals.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/64map32bitvals.bin
rename to roaringbitmap/src/test/resources/testdata/64map32bitvals.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/64mapempty.bin b/roaringbitmap/src/test/resources/testdata/64mapempty.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/64mapempty.bin
rename to roaringbitmap/src/test/resources/testdata/64mapempty.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/64maphighvals.bin b/roaringbitmap/src/test/resources/testdata/64maphighvals.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/64maphighvals.bin
rename to roaringbitmap/src/test/resources/testdata/64maphighvals.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/64mapspreadvals.bin b/roaringbitmap/src/test/resources/testdata/64mapspreadvals.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/64mapspreadvals.bin
rename to roaringbitmap/src/test/resources/testdata/64mapspreadvals.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/bitmapwithoutruns.bin b/roaringbitmap/src/test/resources/testdata/bitmapwithoutruns.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/bitmapwithoutruns.bin
rename to roaringbitmap/src/test/resources/testdata/bitmapwithoutruns.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/bitmapwithruns.bin b/roaringbitmap/src/test/resources/testdata/bitmapwithruns.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/bitmapwithruns.bin
rename to roaringbitmap/src/test/resources/testdata/bitmapwithruns.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput1.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput1.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput1.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput1.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput2.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput2.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput2.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput2.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput3.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput3.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput3.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput3.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput4.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput4.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput4.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput4.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput5.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput5.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput5.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput5.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput6.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput6.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput6.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput6.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput7.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput7.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput7.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput7.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/crashproneinput8.bin b/roaringbitmap/src/test/resources/testdata/crashproneinput8.bin
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/crashproneinput8.bin
rename to roaringbitmap/src/test/resources/testdata/crashproneinput8.bin
diff --git a/RoaringBitmap/src/test/resources/testdata/offset_failure_case_1.txt b/roaringbitmap/src/test/resources/testdata/offset_failure_case_1.txt
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/offset_failure_case_1.txt
rename to roaringbitmap/src/test/resources/testdata/offset_failure_case_1.txt
diff --git a/RoaringBitmap/src/test/resources/testdata/offset_failure_case_2.txt b/roaringbitmap/src/test/resources/testdata/offset_failure_case_2.txt
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/offset_failure_case_2.txt
rename to roaringbitmap/src/test/resources/testdata/offset_failure_case_2.txt
diff --git a/RoaringBitmap/src/test/resources/testdata/offset_failure_case_3.txt b/roaringbitmap/src/test/resources/testdata/offset_failure_case_3.txt
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/offset_failure_case_3.txt
rename to roaringbitmap/src/test/resources/testdata/offset_failure_case_3.txt
diff --git a/RoaringBitmap/src/test/resources/testdata/ornot-fuzz-failure.json b/roaringbitmap/src/test/resources/testdata/ornot-fuzz-failure.json
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/ornot-fuzz-failure.json
rename to roaringbitmap/src/test/resources/testdata/ornot-fuzz-failure.json
diff --git a/RoaringBitmap/src/test/resources/testdata/prevvalue-regression.txt b/roaringbitmap/src/test/resources/testdata/prevvalue-regression.txt
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/prevvalue-regression.txt
rename to roaringbitmap/src/test/resources/testdata/prevvalue-regression.txt
diff --git a/RoaringBitmap/src/test/resources/testdata/rangebitmap_regression.txt b/roaringbitmap/src/test/resources/testdata/rangebitmap_regression.txt
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/rangebitmap_regression.txt
rename to roaringbitmap/src/test/resources/testdata/rangebitmap_regression.txt
diff --git a/RoaringBitmap/src/test/resources/testdata/testIssue260.txt b/roaringbitmap/src/test/resources/testdata/testIssue260.txt
similarity index 100%
rename from RoaringBitmap/src/test/resources/testdata/testIssue260.txt
rename to roaringbitmap/src/test/resources/testdata/testIssue260.txt
diff --git a/RoaringBitmap/style/eclipse-java-google-style.xml b/roaringbitmap/style/eclipse-java-google-style.xml
similarity index 100%
rename from RoaringBitmap/style/eclipse-java-google-style.xml
rename to roaringbitmap/style/eclipse-java-google-style.xml
diff --git a/RoaringBitmap/style/roaring_google_checks.xml b/roaringbitmap/style/roaring_google_checks.xml
similarity index 100%
rename from RoaringBitmap/style/roaring_google_checks.xml
rename to roaringbitmap/style/roaring_google_checks.xml
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 915e323ce..58ae10f92 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,5 +1,5 @@
 include(
-        "RoaringBitmap",
+        "roaringbitmap",
         "bsi",
         "fuzz-tests",
         "jmh",
diff --git a/simplebenchmark/build.gradle.kts b/simplebenchmark/build.gradle.kts
index 1e9fe497a..94c880484 100644
--- a/simplebenchmark/build.gradle.kts
+++ b/simplebenchmark/build.gradle.kts
@@ -1,5 +1,5 @@
 dependencies {
-    implementation(project(":RoaringBitmap"))
+    implementation(project(":roaringbitmap"))
 }
 
 tasks {

From 1ce8ea5c9b27be2259fad31abe3c93c0c8214c49 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:52:06 -0400
Subject: [PATCH 145/167] [Gradle Release Plugin] - pre tag commit:  '1.3.12'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 7142bc94e..79ec47009 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.12-SNAPSHOT
+version = 1.3.12
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 28b863e980c961615d6450e6707563d4b2d3c088 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 19:52:08 -0400
Subject: [PATCH 146/167] [Gradle Release Plugin] - new version commit: 
 '1.3.13-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 79ec47009..516f6c87f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.12
+version = 1.3.13-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From fae8af7034ee24ea5077799bf3309f3417e5115d Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 20:33:27 -0400
Subject: [PATCH 147/167] adding maven pom instructions

---
 README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/README.md b/README.md
index 668f3b18b..9e05d199e 100644
--- a/README.md
+++ b/README.md
@@ -418,6 +418,59 @@ Download
 You can download releases from github:
 https://github.com/RoaringBitmap/RoaringBitmap/releases
 
+Using from Maven
+---------
+
+Add the following dependency to your `pom.xml` file inside the `` element...
+
+```xml
+    
+      org.roaringbitmap
+      roaringbitmap
+      1.3.12
+    
+```
+
+Add the GitHub repository inside the `` element (`pom.xml` file)...
+
+```xml
+
+    
+        github
+        Roaring Maven Packages
+        https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap
+        true
+        true
+    
+
+```
+
+See https://github.com/RoaringBitmap/MavenRoaringBitmapProject for a complete example.
+
+The registry access is is protected by an authorisation. So you have to add your GitHub credentials to your global settings.xml: `$HOME\.m2\settings.xml`.
+
+You will need a token which you can generate on GitHub.
+
+```
+GitHub > Settings > Developer Settings > Personal access tokens > Generate new token
+```
+
+The token needs the read:packages permission. The token identifier is a long string such as `ghp_ieOkN`.
+
+Put the following in your `settings.xml` file, within the `` element.
+
+```xml
+
+  github
+  lemire
+  ghp_ieOkN
+
+```
+
+Replace `lemire` by your GitHub username and `ghp_ieOkN` by the token identifier
+you just generated.
+
+
 Usage
 ------
 

From 92bd46af764807ca682623cd6b025f9652e18bc3 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 23 Oct 2024 20:58:15 -0400
Subject: [PATCH 148/167] Update README.md

---
 README.md | 241 +++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 164 insertions(+), 77 deletions(-)

diff --git a/README.md b/README.md
index 9e05d199e..677f58739 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,34 @@ RoaringBitmap
 [![docs-badge][]][docs]
 ![Java 11 CI](https://github.com/RoaringBitmap/RoaringBitmap/workflows/Java%2011%20CI/badge.svg)
 
+- [Introduction](#introduction)
+- [When should you use a bitmap?](#when-should-you-use-a-bitmap)
+- [When should you use compressed bitmaps?](#when-should-you-use-compressed-bitmaps)
+- [How does Roaring compare with the alternatives?](#how-does-roaring-compare-with-the-alternatives)
+- [Code sample](#code-sample)
+- [API docs](#api-docs)
+- [Download](#download)
+- [Usage within a Maven project](#usage-within-a-maven-project)
+- [Usage within a gradle project](#usage-within-a-gradle-project)
+- [Scientific Documentation](#scientific-documentation)
+- [Unsigned integers](#unsigned-integers)
+- [Working with memory-mapped bitmaps](#working-with-memory-mapped-bitmaps)
+- [Thread safety](#thread-safety)
+- [Kryo](#kryo)
+- [64-bit integers (long)](#64-bit-integers-long)
+- [Range Bitmaps](#range-bitmaps)
+- [Prerequisites](#prerequisites)
+- [Usage for RoaringBitmap Developers](#usage-for-roaringbitmap-developers)
+- [IntelliJ and Eclipse](#intellij-and-eclipse)
+- [Contributing](#contributing)
+- [FAQ](#faq)
+- [Benchmark](#benchmark)
+- [Mailing list/discussion group](#mailing-listdiscussion-group)
+- [Funding](#funding)
+
+Introduction
+-------------
+
 Bitsets, also called bitmaps, are commonly used as fast data structures.
 Unfortunately, they can use too much memory. To compensate, we often use
 compressed bitmaps.
@@ -56,7 +84,7 @@ This code is licensed under Apache License, Version 2.0 (AL2.0).
 
 
 When should you use a bitmap?
-===================================
+-------------------------------
 
 
 Sets are a fundamental abstraction in
@@ -89,7 +117,7 @@ you have 1000 random-looking integers, then a simple array might be the best rep
 We refer to this case as the "sparse" scenario.
 
 When should you use compressed bitmaps?
-===================================
+--------------------------
 
 An uncompressed BitSet can use a lot of memory. For example, if you take a BitSet
 and set the bit at position 1,000,000 to true and you have just over 100kB. That is over 100kB
@@ -110,8 +138,7 @@ Keep in mind that random-looking data is usually not compressible. E.g., if you
 and attempts at compression can be counterproductive.
 
 How does Roaring compare with the alternatives?
-==================================================
-
+------------------------------------------------
 
 Most alternatives to Roaring are part of a larger family of compressed bitmaps that are run-length-encoded
 bitmaps. They identify long runs of 1s or 0s and they represent them with a marker word.
@@ -141,21 +168,6 @@ formats like WAH, EWAH, Concise... Maybe surprisingly, Roaring also generally of
 
 
 
-API docs
----------
-
-http://www.javadoc.io/doc/org.roaringbitmap/RoaringBitmap/
-
-Scientific Documentation
---------------------------
-
-- Daniel Lemire, Owen Kaser, Nathan Kurz, Luca Deri, Chris O'Hara, François Saint-Jacques, Gregory Ssi-Yan-Kai, Roaring Bitmaps: Implementation of an Optimized Software Library, Software: Practice and Experience 48 (4), 2018 [arXiv:1709.07821](https://arxiv.org/abs/1709.07821)
--  Samy Chambi, Daniel Lemire, Owen Kaser, Robert Godin,
-Better bitmap performance with Roaring bitmaps,
-Software: Practice and Experience 46 (5), 2016. [arXiv:1402.6407](http://arxiv.org/abs/1402.6407) This paper used data from http://lemire.me/data/realroaring2014.html
-- Daniel Lemire, Gregory Ssi-Yan-Kai, Owen Kaser, Consistently faster and smaller compressed bitmaps with Roaring, Software: Practice and Experience 46 (11), 2016. [arXiv:1603.06549](http://arxiv.org/abs/1603.06549)
-- Samy Chambi, Daniel Lemire, Robert Godin, Kamel Boukhalfa, Charles Allen, Fangjin Yang, Optimizing Druid with Roaring bitmaps, IDEAS 2016, 2016. http://r-libre.teluq.ca/950/
-
 Code sample
 -------------
 
@@ -190,6 +202,138 @@ public class Basic {
 
 Please see the examples folder for more examples, which you can run with `./gradlew :examples:runAll`, or run a specific one with `./gradlew :examples:runExampleBitmap64`, etc.
 
+API docs
+---------
+
+http://www.javadoc.io/doc/org.roaringbitmap/RoaringBitmap/
+
+
+Download
+---------
+
+You can download releases from github:
+https://github.com/RoaringBitmap/RoaringBitmap/releases
+
+Usage within a Maven project
+---------
+
+Add the following dependency to your `pom.xml` file inside the `` element...
+
+```xml
+    
+      org.roaringbitmap
+      roaringbitmap
+      1.3.12
+    
+```
+
+Add the GitHub repository inside the `` element (`pom.xml` file)...
+
+```xml
+
+    
+        github
+        Roaring Maven Packages
+        https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap
+        true
+        true
+    
+
+```
+
+See https://github.com/RoaringBitmap/MavenRoaringBitmapProject for a complete example.
+
+The registry access is is protected by an authorisation. So you have to add your GitHub credentials to your global settings.xml: `$HOME\.m2\settings.xml`.
+
+You will need a token which you can generate on GitHub.
+
+```
+GitHub > Settings > Developer Settings > Personal access tokens > Generate new token
+```
+
+The token needs the read:packages permission. The token identifier is a long string such as `ghp_ieOkN`.
+
+Put the following in your `settings.xml` file, within the `` element.
+
+```xml
+
+  github
+  lemire
+  ghp_ieOkN
+
+```
+
+Replace `lemire` by your GitHub username and `ghp_ieOkN` by the token identifier
+you just generated.
+
+Usage within a gradle project
+------------------
+
+
+The approach with gradle is similar. You still need your GitHub credentials. Go
+to 
+
+```
+GitHub > Settings > Developer Settings > Personal access tokens > Generate new token
+```
+
+And create a token with read:packages permission.
+
+If your GitHub user name is `lemire` and your GitHub personal token `ghp_ieOkN`,
+then you can set them using system variables. Under bash, you can do it like so:
+```
+export GITHUB_USER=lemire
+export GITHUB_PASSWORD=ghp_ieOkN
+```
+
+
+If you prefer you can write your GitHub credentials in your  gradle.properties
+file
+
+```
+# gradle.properties
+githubUser=lemire
+githubPassword=ghp_ieOkN
+```
+
+Then all you need is the following `build.gradle` file:
+
+```groovy
+plugins {
+    id 'java'
+}
+
+group 'org.roaringbitmap' // name of your project
+version '1.0-SNAPSHOT' // version of your project
+
+repositories {
+    mavenCentral()
+    maven {
+        url 'https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap'
+        credentials {
+            username = System.properties['githubUser'] ?: System.env.GITHUB_USER
+            password = System.properties['githubPassword'] ?: System.env.GITHUB_PASSWORD
+        }
+    }
+}
+
+dependencies {
+    implementation 'org.roaringbitmap:roaringbitmap:1.3.12'
+    testImplementation 'junit:junit:3.8.1'
+}
+```
+
+
+Scientific Documentation
+--------------------------
+
+- Daniel Lemire, Owen Kaser, Nathan Kurz, Luca Deri, Chris O'Hara, François Saint-Jacques, Gregory Ssi-Yan-Kai, Roaring Bitmaps: Implementation of an Optimized Software Library, Software: Practice and Experience 48 (4), 2018 [arXiv:1709.07821](https://arxiv.org/abs/1709.07821)
+-  Samy Chambi, Daniel Lemire, Owen Kaser, Robert Godin,
+Better bitmap performance with Roaring bitmaps,
+Software: Practice and Experience 46 (5), 2016. [arXiv:1402.6407](http://arxiv.org/abs/1402.6407) This paper used data from http://lemire.me/data/realroaring2014.html
+- Daniel Lemire, Gregory Ssi-Yan-Kai, Owen Kaser, Consistently faster and smaller compressed bitmaps with Roaring, Software: Practice and Experience 46 (11), 2016. [arXiv:1603.06549](http://arxiv.org/abs/1603.06549)
+- Samy Chambi, Daniel Lemire, Robert Godin, Kamel Boukhalfa, Charles Allen, Fangjin Yang, Optimizing Druid with Roaring bitmaps, IDEAS 2016, 2016. http://r-libre.teluq.ca/950/
+
 
 Unsigned integers
 ------------------
@@ -412,66 +556,9 @@ Prerequisites
  - Version 0.5.x requires JDK 6 or better
 
 
-Download
----------
-
-You can download releases from github:
-https://github.com/RoaringBitmap/RoaringBitmap/releases
-
-Using from Maven
----------
-
-Add the following dependency to your `pom.xml` file inside the `` element...
-
-```xml
-    
-      org.roaringbitmap
-      roaringbitmap
-      1.3.12
-    
-```
-
-Add the GitHub repository inside the `` element (`pom.xml` file)...
-
-```xml
-
-    
-        github
-        Roaring Maven Packages
-        https://maven.pkg.github.com/RoaringBitmap/RoaringBitmap
-        true
-        true
-    
-
-```
-
-See https://github.com/RoaringBitmap/MavenRoaringBitmapProject for a complete example.
-
-The registry access is is protected by an authorisation. So you have to add your GitHub credentials to your global settings.xml: `$HOME\.m2\settings.xml`.
-
-You will need a token which you can generate on GitHub.
-
-```
-GitHub > Settings > Developer Settings > Personal access tokens > Generate new token
-```
-
-The token needs the read:packages permission. The token identifier is a long string such as `ghp_ieOkN`.
-
-Put the following in your `settings.xml` file, within the `` element.
-
-```xml
-
-  github
-  lemire
-  ghp_ieOkN
-
-```
-
-Replace `lemire` by your GitHub username and `ghp_ieOkN` by the token identifier
-you just generated.
 
 
-Usage
+Usage for RoaringBitmap Developers
 ------
 
 * Get java

From 4381a8819c1e2ae216c06a5ce1992b365fc058bb Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 12:06:11 -0400
Subject: [PATCH 149/167] adding jitpack, see
 https://jitpack.io/docs/BUILDING/#custom-commands

---
 jitpack.yml | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 jitpack.yml

diff --git a/jitpack.yml b/jitpack.yml
new file mode 100644
index 000000000..4a7f5081e
--- /dev/null
+++ b/jitpack.yml
@@ -0,0 +1,5 @@
+jdk:
+  - openjdk17
+before_install:
+   - sdk install java 17.0.1-open
+   - sdk use java 17.0.1-open

From e8e1484a08fbd73c3cbd76eb7d4d32b3a322ab7c Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 12:34:49 -0400
Subject: [PATCH 150/167] updating documentation.

---
 README.md            | 11 ++++++++---
 jmh/build.gradle.kts |  1 -
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 677f58739..c4d157a76 100644
--- a/README.md
+++ b/README.md
@@ -636,11 +636,16 @@ application, you might be better served with a conventional bitset (e.g., Java's
 Benchmark
 -----------
 
-To run JMH benchmarks, use the following command:
+To run JMH benchmarks, use the following commands:
 
-         $ ./gradlew jmhJar
+         $ ./gradlew jmh::shadowJar
+         $ java -jar jmh/build/libs/benchmarks.jar
 
-You can also run specific benchmarks...
+You can also run a specific benchmark:
+
+         $ java -jar jmh/build/libs/benchmarks.jar 'org.roaringbitmap.aggregation.and.identical.*'
+
+If you have a bash shell, you can also run our script which automatically builds and run specific tests...
 
          $ ./jmh/run.sh 'org.roaringbitmap.aggregation.and.identical.*'
 
diff --git a/jmh/build.gradle.kts b/jmh/build.gradle.kts
index 367b0e4a8..4964a0f48 100644
--- a/jmh/build.gradle.kts
+++ b/jmh/build.gradle.kts
@@ -74,7 +74,6 @@ tasks.test {
     }
 }
 
-
 // jmhJar task provided by jmh gradle plugin is currently broken
 // https://github.com/melix/jmh-gradle-plugin/issues/97
 // so instead, we configure the shadowJar task to have JMH bits in it

From a93f01f3f1dd6218eefe3fa7888a35c97dc84606 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 12:37:37 -0400
Subject: [PATCH 151/167] [Gradle Release Plugin] - pre tag commit:  '1.3.13'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 516f6c87f..28ea135be 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.13-SNAPSHOT
+version = 1.3.13
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 27a84fa60def6d3f7404eea68bd27360ab9259d9 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 12:37:39 -0400
Subject: [PATCH 152/167] [Gradle Release Plugin] - new version commit: 
 '1.3.14-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 28ea135be..ed3b8f849 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.13
+version = 1.3.14-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 91f190ac4abda780c002327f66a904f4b1ef6e24 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 13:07:59 -0400
Subject: [PATCH 153/167] downgrading jitpack

---
 jitpack.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/jitpack.yml b/jitpack.yml
index 4a7f5081e..7a64387b6 100644
--- a/jitpack.yml
+++ b/jitpack.yml
@@ -1,5 +1,5 @@
 jdk:
-  - openjdk17
+  - openjdk11
 before_install:
-   - sdk install java 17.0.1-open
-   - sdk use java 17.0.1-open
+   - sdk install java 11.0.1-open
+   - sdk use java 11.0.1-open

From fc687b2003c965315a5b0f2473f3c4962fc182a1 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 13:08:25 -0400
Subject: [PATCH 154/167] [Gradle Release Plugin] - pre tag commit:  '1.3.14'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index ed3b8f849..f219311bb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.14-SNAPSHOT
+version = 1.3.14
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From e023cfee6f6db73a8ab3f17368e9f6e538f2e2af Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 13:08:27 -0400
Subject: [PATCH 155/167] [Gradle Release Plugin] - new version commit: 
 '1.3.15-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index f219311bb..73028e410 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.14
+version = 1.3.15-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 6647a9508ad3bd819b4b1ca0595f88dc5c985b51 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 13:09:38 -0400
Subject: [PATCH 156/167] [Gradle Release Plugin] - pre tag commit:  '1.3.15'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 73028e410..5f5158f7b 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.15-SNAPSHOT
+version = 1.3.15
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From a8d5a7eda0b3ca9508a561e9b21fde06b476c458 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 13:09:40 -0400
Subject: [PATCH 157/167] [Gradle Release Plugin] - new version commit: 
 '1.3.16-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 5f5158f7b..00e2fc0fb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.15
+version = 1.3.16-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 5ae9e235f1d5340c1382ce5cd41ccc9eea0085fb Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 24 Oct 2024 13:42:00 -0400
Subject: [PATCH 158/167] Update README.md

---
 README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index c4d157a76..7465f5600 100644
--- a/README.md
+++ b/README.md
@@ -217,6 +217,36 @@ https://github.com/RoaringBitmap/RoaringBitmap/releases
 Usage within a Maven project
 ---------
 
+### 1. Using JitPack
+
+
+Add the following dependency to your pom.xml file...
+
+```xml
+	
+	    com.github.RoaringBitmap.RoaringBitmap
+	    roaringbitmap
+	    1.3.15
+	
+```
+
+You may adjust the version number.
+
+Then add the repository to your pom.xml file:
+
+```xml
+
+		
+		    jitpack.io
+		    https://jitpack.io
+		
+
+```
+See https://github.com/RoaringBitmap/JitPackRoaringBitmapProject for a complete example.
+
+
+### 2. Using GitHub Packages
+
 Add the following dependency to your `pom.xml` file inside the `` element...
 
 ```xml
@@ -269,8 +299,40 @@ you just generated.
 Usage within a gradle project
 ------------------
 
+### 1. Using JitPack
+
+Then all you need is to edit your `build.gradle` file like so:
+
+
+```groovy
+plugins {
+    id 'java'
+}
+
+group 'org.roaringbitmap' // name of your project
+version '1.0-SNAPSHOT' // version of your project
+
+repositories {
+    mavenCentral()
+    maven {
+        url 'https://jitpack.io'
+    }
+}
+
+dependencies {
+    implementation 'com.github.RoaringBitmap.RoaringBitmap:roaringbitmap:1.3.15'
+    testImplementation 'junit:junit:3.8.1'
+}
+```
+
+
+See https://github.com/RoaringBitmap/JitPackRoaringBitmapProject for a complete example.
+
 
-The approach with gradle is similar. You still need your GitHub credentials. Go
+### 2. Using GitHub Packages
+
+
+You first need your GitHub credentials. Go
 to 
 
 ```
@@ -296,7 +358,7 @@ githubUser=lemire
 githubPassword=ghp_ieOkN
 ```
 
-Then all you need is the following `build.gradle` file:
+Then all you need is to edit your `build.gradle` file like so:
 
 ```groovy
 plugins {
@@ -323,6 +385,9 @@ dependencies {
 }
 ```
 
+See https://github.com/RoaringBitmap/MavenRoaringBitmapProject for a complete example.
+
+
 
 Scientific Documentation
 --------------------------

From d684f308a8566d30fee7cbecc1a8870a9aaa83cd Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Fri, 25 Oct 2024 08:19:30 -0400
Subject: [PATCH 159/167] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 7465f5600..9eba27794 100644
--- a/README.md
+++ b/README.md
@@ -257,7 +257,7 @@ Add the following dependency to your `pom.xml` file inside the ``
     
 ```
 
-Add the GitHub repository inside the `` element (`pom.xml` file)...
+Add the GitHub repository inside the `` element (`pom.xml` file)...
 
 ```xml
 

From d5fdee3146a93e0e2d2df82cf640a5a2a8c64c47 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 30 Oct 2024 01:14:12 -0400
Subject: [PATCH 160/167] Update README.md

---
 README.md | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/README.md b/README.md
index 9eba27794..3fde08ef2 100644
--- a/README.md
+++ b/README.md
@@ -223,11 +223,11 @@ Usage within a Maven project
 Add the following dependency to your pom.xml file...
 
 ```xml
-	
-	    com.github.RoaringBitmap.RoaringBitmap
-	    roaringbitmap
-	    1.3.15
-	
+
+    com.github.RoaringBitmap.RoaringBitmap
+    roaringbitmap
+    1.3.15
+
 ```
 
 You may adjust the version number.
@@ -236,10 +236,10 @@ Then add the repository to your pom.xml file:
 
 ```xml
 
-		
-		    jitpack.io
-		    https://jitpack.io
-		
+    
+        jitpack.io
+        https://jitpack.io
+    
 
 ```
 See https://github.com/RoaringBitmap/JitPackRoaringBitmapProject for a complete example.
@@ -250,11 +250,11 @@ See https://github.com/RoaringBitmap/JitPackRoaringBitmapProject for a complete
 Add the following dependency to your `pom.xml` file inside the `` element...
 
 ```xml
-    
-      org.roaringbitmap
-      roaringbitmap
-      1.3.12
-    
+
+    org.roaringbitmap
+    roaringbitmap
+    1.3.12
+
 ```
 
 Add the GitHub repository inside the `` element (`pom.xml` file)...

From 8ba205e68a9fd5b0c081a60869b2f67858021e03 Mon Sep 17 00:00:00 2001
From: fanson 
Date: Thu, 31 Oct 2024 02:09:20 +0800
Subject: [PATCH 161/167] fix issue 755 (#756)

Co-authored-by: haiyang.zhou 
---
 .../bsi/longlong/Roaring64BitmapSliceIndex.java       |  4 ++--
 .../test/java/org/roaringbitmap/bsi/R64BSITest.java   | 11 +++++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
index 658cb2f26..48295cc79 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
@@ -125,10 +125,10 @@ private long maxValue() {
   }
 
   private long valueAt(long columnId) {
-    int value = 0;
+    long value = 0;
     for (int i = 0; i < this.bitCount(); i += 1) {
       if (this.bA[i].contains(columnId)) {
-        value |= (1 << i);
+        value |= (1L << i);
       }
     }
 
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
index 0e609411f..d777d158e 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
@@ -384,5 +384,16 @@ public void testIssue743() throws IOException {
     Assertions.assertEquals(de_bsi.getValue(100L), bsi.getValue(100L));
     Assertions.assertEquals(de_bsi.getValue(1L), bsi.getValue(1L));
   }
+
+  @Test
+  public void testIssue755() throws IOException {
+    Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex();
+    bsi.setValue(100L, 3L);
+    bsi.setValue(1L, (long)Integer.MAX_VALUE * 2 + 23456);
+    bsi.setValue(2L, (long)Integer.MAX_VALUE + 23456);
+    Assertions.assertEquals(bsi.getValue(100L).getKey(), 3L); // {{3,true}}
+    Assertions.assertEquals(bsi.getValue(1L).getKey(), (long)Integer.MAX_VALUE * 2 + 23456); // {23455,true}
+    Assertions.assertEquals(bsi.getValue(2L).getKey(), (long)Integer.MAX_VALUE + 23456); // {-2147460193,true}
+  }
 }
 

From 38ee8af17a7f954ef931c12c9fc72b4d332ba1f0 Mon Sep 17 00:00:00 2001
From: fanson 
Date: Thu, 31 Oct 2024 05:21:51 +0800
Subject: [PATCH 162/167] fix issue 753 (#754)

Co-authored-by: haiyang.zhou 
Co-authored-by: Daniel Lemire 
---
 .../bsi/RoaringBitmapSliceIndex.java          |  6 +++++
 .../bsi/buffer/BitSliceIndexBase.java         |  6 +++++
 .../longlong/Roaring64BitmapSliceIndex.java   |  6 +++++
 .../org/roaringbitmap/bsi/R64BSITest.java     | 22 +++++++++++++++++++
 .../java/org/roaringbitmap/bsi/RBBsiTest.java | 22 +++++++++++++++++++
 5 files changed, 62 insertions(+)

diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
index e6b55db2a..6be414fd4 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
@@ -502,6 +502,12 @@ public RoaringBitmap compare(BitmapSliceIndex.Operation operation, int startOrVa
         return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
 
       case RANGE: {
+        if (startOrValue < minValue) {
+          startOrValue = minValue;
+        }
+        if (end > maxValue) {
+          end = maxValue;
+        }
         RoaringBitmap left = oNeilCompare(Operation.GE, startOrValue, foundSet);
         RoaringBitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
 
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
index 4552589ae..b4d8d6593 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
@@ -433,6 +433,12 @@ public ImmutableRoaringBitmap compare(BitmapSliceIndex.Operation operation, int
         return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
 
       case RANGE: {
+        if (startOrValue < minValue) {
+          startOrValue = minValue;
+        }
+        if (end > maxValue) {
+          end = maxValue;
+        }
         ImmutableRoaringBitmap left = owenGreatEqual(startOrValue, foundSet);
         ImmutableRoaringBitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
 
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
index 48295cc79..a54db4b95 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
@@ -480,6 +480,12 @@ public Roaring64Bitmap compare(BitmapSliceIndex.Operation operation, long startO
         return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
 
       case RANGE: {
+        if (startOrValue < minValue) {
+          startOrValue = minValue;
+        }
+        if (end > maxValue) {
+          end = maxValue;
+        }
         Roaring64Bitmap left = oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet);
         Roaring64Bitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
 
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
index d777d158e..44164dce1 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
@@ -385,6 +385,28 @@ public void testIssue743() throws IOException {
     Assertions.assertEquals(de_bsi.getValue(1L), bsi.getValue(1L));
   }
 
+  @Test
+  public void testIssue753() throws IOException {
+    bsi = new Roaring64BitmapSliceIndex();
+    LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getLongCardinality(), 56);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getLongCardinality(), 99);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getLongCardinality(), 99);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getLongCardinality(), 99);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getLongCardinality(), 0);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getLongCardinality(), 0);
+
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getLongCardinality(), 53);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getLongCardinality(), 96);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getLongCardinality(), 96);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getLongCardinality(), 96);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getLongCardinality(), 0);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getLongCardinality(), 0);
+
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getLongCardinality(), 0);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getLongCardinality(), 0);
+  }
+  
   @Test
   public void testIssue755() throws IOException {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex();
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
index 69f751167..6ae606144 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
@@ -371,5 +371,27 @@ public void testIssue743() throws IOException {
     Assertions.assertEquals(de_bsi.getValue(100), bsi.getValue(100));
     Assertions.assertEquals(de_bsi.getValue(1), bsi.getValue(1));
   }
+
+@Test
+public void testIssue753() throws IOException {
+    bsi = new RoaringBitmapSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getCardinality(), 56);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getCardinality(), 99);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getCardinality(), 99);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getCardinality(), 99);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getCardinality(), 0);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getCardinality(), 0);
+
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getCardinality(), 53);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getCardinality(), 96);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getCardinality(), 96);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getCardinality(), 96);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getCardinality(), 0);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getCardinality(), 0);
+
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getCardinality(), 0);
+    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getCardinality(), 0);
+  }
 }
 

From 992f823500989787d2079f9f614f6dee670b5e1b Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 30 Oct 2024 17:22:20 -0400
Subject: [PATCH 163/167] [Gradle Release Plugin] - pre tag commit:  '1.3.16'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 00e2fc0fb..515286d28 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.16-SNAPSHOT
+version = 1.3.16
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From b68098f0608778c0ebd059dddcfed4e008635e24 Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Wed, 30 Oct 2024 17:22:26 -0400
Subject: [PATCH 164/167] [Gradle Release Plugin] - new version commit: 
 '1.3.17-SNAPSHOT'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 515286d28..db68c2f30 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version = 1.3.16
+version = 1.3.17-SNAPSHOT
 org.gradle.parallel=false
 org.gradle.daemon=true
 org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC

From 62782af4201d42358176039caad9512a7a29b42b Mon Sep 17 00:00:00 2001
From: Daniel Lemire 
Date: Thu, 31 Oct 2024 10:38:55 -0400
Subject: [PATCH 165/167] Update README.md with version .16

---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 3fde08ef2..4019bc6d6 100644
--- a/README.md
+++ b/README.md
@@ -226,7 +226,7 @@ Add the following dependency to your pom.xml file...
 
     com.github.RoaringBitmap.RoaringBitmap
     roaringbitmap
-    1.3.15
+    1.3.16
 
 ```
 
@@ -253,7 +253,7 @@ Add the following dependency to your `pom.xml` file inside the ``
 
     org.roaringbitmap
     roaringbitmap
-    1.3.12
+    1.3.16
 
 ```
 
@@ -320,7 +320,7 @@ repositories {
 }
 
 dependencies {
-    implementation 'com.github.RoaringBitmap.RoaringBitmap:roaringbitmap:1.3.15'
+    implementation 'com.github.RoaringBitmap.RoaringBitmap:roaringbitmap:1.3.16'
     testImplementation 'junit:junit:3.8.1'
 }
 ```
@@ -380,7 +380,7 @@ repositories {
 }
 
 dependencies {
-    implementation 'org.roaringbitmap:roaringbitmap:1.3.12'
+    implementation 'org.roaringbitmap:roaringbitmap:1.3.16'
     testImplementation 'junit:junit:3.8.1'
 }
 ```

From ad4143a6782ab047dcde8b5c8cf7b20e0fdd7a4c Mon Sep 17 00:00:00 2001
From: Benoit Chatain Lacelle 
Date: Fri, 8 Nov 2024 00:08:15 +0400
Subject: [PATCH 166/167] Integrate spotless (#759)

* trying spotless

* Small change

* CherryPick latest build.gradle.kts with Spotless

* Spotless with latest configuration

* Setup ratchetFrom

* Add comments

* Change Spotless version to 6.25.0, latest stabl;e

* .gitignore handles .java-version

* Apply suggested importOrder

* Clean wildcard imports, and prevent them with Spotless

---------

Co-authored-by: Daniel Lemire 
---
 .gitignore                                    |     1 +
 README.md                                     |     6 +-
 .../roaringbitmap/bsi/BitmapSliceIndex.java   |     7 +-
 .../main/java/org/roaringbitmap/bsi/Pair.java |    18 +-
 .../bsi/RoaringBitmapSliceIndex.java          |    83 +-
 .../org/roaringbitmap/bsi/WritableUtils.java  |     2 -
 .../bsi/buffer/BitSliceIndexBase.java         |   237 +-
 .../bsi/buffer/ImmutableBitSliceIndex.java    |    25 +-
 .../bsi/buffer/MutableBitSliceIndex.java      |    51 +-
 .../longlong/Roaring64BitmapSliceIndex.java   |    83 +-
 .../org/roaringbitmap/bsi/BufferBSITest.java  |   803 +-
 .../org/roaringbitmap/bsi/R64BSITest.java     |   227 +-
 .../java/org/roaringbitmap/bsi/RBBsiTest.java |   627 +-
 build.gradle.kts                              |    53 +-
 examples/src/main/java/Basic.java             |    29 +-
 examples/src/main/java/Bitmap64.java          |    16 +-
 .../src/main/java/CompressionResults.java     |    56 +-
 examples/src/main/java/ForEachExample.java    |    60 +-
 .../java/ImmutableRoaringBitmapExample.java   |    45 +-
 examples/src/main/java/IntervalCheck.java     |    21 +-
 .../src/main/java/MemoryMappingExample.java   |    85 +-
 examples/src/main/java/PagedIterator.java     |    30 +-
 .../java/SerializeToByteArrayExample.java     |    12 +-
 .../java/SerializeToByteBufferExample.java    |    36 +-
 .../src/main/java/SerializeToDiskExample.java |    84 +-
 .../main/java/SerializeToStringExample.java   |    57 +-
 examples/src/main/java/VeryLargeBitmap.java   |    13 +-
 .../java/org/roaringbitmap/BufferFuzzer.java  |   578 +-
 .../test/java/org/roaringbitmap/Fuzzer.java   |   653 +-
 .../org/roaringbitmap/RandomisedTestData.java |    54 +-
 .../test/java/org/roaringbitmap/Reporter.java |    30 +-
 jmh/build.gradle.kts                          |     2 -
 .../roaringbitmap/AbstractBenchmarkState.java |    39 +-
 .../org/roaringbitmap/AddOffsetBenchmark.java |    62 +-
 .../AdvanceIfNeededBenchmark.java             |    79 +-
 .../org/roaringbitmap/BasicBenchmark.java     |    34 +-
 .../roaringbitmap/BitSetUtilBenchmark.java    |    55 +-
 .../roaringbitmap/BitmapOfRangeBenchmark.java |    24 +-
 .../roaringbitmap/CheckedAddBenchmark.java    |    18 +-
 .../IntermediateByteArrayBenchmark.java       |    48 +-
 .../jmh/java/org/roaringbitmap/RadixSort.java |    12 +-
 .../java/org/roaringbitmap/RandomData.java    |    15 +-
 .../RangeOperationBenchmark.java              |     4 +-
 .../RoaringOnlyBenchmarkState.java            |    41 +-
 .../SelectTopValuesBenchmark.java             |    16 +-
 .../java/org/roaringbitmap/UtilBenchmark.java |    39 +-
 .../FastAggregationRLEStressTest.java         |    40 +-
 .../and/BitmapContainerAndBenchmark.java      |    10 +-
 .../bestcase/Roaring64BitmapBenchmark.java    |     7 +-
 .../and/bestcase/RoaringBitmapBenchmark.java  |     6 +-
 .../identical/Roaring64BitmapBenchmark.java   |     7 +-
 .../and/identical/RoaringBitmapBenchmark.java |     6 +-
 .../worstcase/Roaring64BitmapBenchmark.java   |     7 +-
 .../and/worstcase/RoaringBitmapBenchmark.java |     6 +-
 .../bestcase/Roaring64BitmapBenchmark.java    |     7 +-
 .../bestcase/RoaringBitmapBenchmark.java      |     6 +-
 .../identical/Roaring64BitmapBenchmark.java   |     7 +-
 .../identical/RoaringBitmapBenchmark.java     |     6 +-
 .../worstcase/Roaring64BitmapBenchmark.java   |     7 +-
 .../worstcase/RoaringBitmapBenchmark.java     |     6 +-
 .../or/BitmapContainerOrBenchmark.java        |    10 +-
 .../or/RoaringBitmapBenchmark.java            |    55 +-
 .../xor/BitmapContainerXorBenchmark.java      |     9 +-
 .../arraycontainer/AddBenchmark.java          |    43 +-
 .../bithacking/SelectBenchmark.java           |    44 +-
 .../bithacking/UnsignedVSFlip.java            |     8 +-
 .../bitmapcontainer/SelectBenchmark.java      |    12 +-
 .../buffer/BufferUtilBenchmark.java           |    41 +-
 .../MutableRoaringBitmapBenchmark.java        |     6 +-
 .../MutableRoaringBitmapBenchmark.java        |     6 +-
 .../MutableRoaringBitmapBenchmark.java        |     6 +-
 .../MutableRoaringBitmapBenchmark.java        |     6 +-
 .../MutableRoaringBitmapBenchmark.java        |     6 +-
 .../MutableRoaringBitmapBenchmark.java        |     6 +-
 .../cardinality64/Cardinality64Benchmark.java |    18 +-
 .../Roaring64BmpCardinalityBenchmark.java     |    19 +-
 .../CombinedCardinalityBenchmark.java         |   169 +-
 .../contains/ContainsBenchmark.java           |    25 +-
 ...mapContainersDeserializationBenchmark.java |    16 +-
 .../roaringbitmap/equals/EqualsBenchmark.java |    30 +-
 .../iteration/BatchIteratorBenchmark.java     |    18 +-
 .../iteration/BitmapIteratorBenchmark.java    |    15 +-
 .../iteration/BitmapNextBenchmark.java        |    28 +-
 .../iteration/Concatenation.java              |    97 +-
 .../iteration/IteratorsBenchmark32.java       |    54 +-
 .../iteration/IteratorsBenchmark64.java       |    37 +-
 .../IteratorsBenchmarkRoaring64Bmp.java       |    37 +-
 ...iftLeftFromSpecifiedPositionBenchmark.java |    12 +-
 .../org/roaringbitmap/map/MapBenchmark.java   |    45 +-
 .../roaringbitmap/needwork/RandomAccess.java  |    21 +-
 .../needwork/SlowMappedORaggregate1.java      |    39 +-
 .../needwork/SlowMappedORaggregate2.java      |    39 +-
 .../needwork/SlowORaggregate1.java            |    19 +-
 .../needwork/SlowORaggregate2.java            |    19 +-
 .../needwork/SlowORaggregate3.java            |    21 +-
 .../state/NeedWorkBenchmarkState.java         |    23 +-
 .../roaringbitmap/range/ContainsRange.java    |    43 +-
 .../rangebitmap/RangeBitmapBenchmark.java     |    42 +-
 .../realdata/ParallelAggregatorBenchmark.java |    75 +-
 .../realdata/RealDataBenchmarkAnd.java        |     6 +-
 .../realdata/RealDataBenchmarkAndNot.java     |     6 +-
 .../RealDataBenchmarkCardinality.java         |     7 +-
 .../realdata/RealDataBenchmarkContains.java   |    12 +-
 .../realdata/RealDataBenchmarkForEach.java    |    10 +-
 .../realdata/RealDataBenchmarkIOr.java        |     8 +-
 .../realdata/RealDataBenchmarkInot.java       |     6 +-
 .../realdata/RealDataBenchmarkIterate.java    |    10 +-
 .../realdata/RealDataBenchmarkOr.java         |     8 +-
 .../realdata/RealDataBenchmarkOrNot.java      |    16 +-
 .../RealDataBenchmarkReverseIterate.java      |    10 +-
 .../RealDataBenchmarkWideAndNaive.java        |     8 +-
 .../RealDataBenchmarkWideOrNaive.java         |     8 +-
 .../realdata/RealDataBenchmarkWideOrPq.java   |     8 +-
 .../realdata/RealDataBenchmarkXor.java        |     6 +-
 .../RealDataSerializationBenchmark.java       |   115 +-
 .../state/RealDataBenchmarkState.java         |    20 +-
 .../state/RealDataRoaringBitmaps.java         |    47 +-
 .../RealDataRoaringOnlyBenchmarkState.java    |    40 +-
 .../realdata/wrapper/Bitmap.java              |     5 +-
 .../realdata/wrapper/BitmapAggregator.java    |     1 -
 .../realdata/wrapper/BitmapFactory.java       |    21 +-
 .../realdata/wrapper/BitmapIterator.java      |     1 -
 .../wrapper/ConciseSetIteratorWrapper.java    |     1 -
 .../realdata/wrapper/ConciseSetWrapper.java   |    26 +-
 .../realdata/wrapper/Ewah32BitmapWrapper.java |    51 +-
 .../realdata/wrapper/EwahBitmapWrapper.java   |    48 +-
 .../realdata/wrapper/EwahIteratorWrapper.java |     1 -
 .../wrapper/ImmutableConciseSetWrapper.java   |    37 +-
 .../ImmutableRoaringBitmapWrapper.java        |    13 +-
 .../wrapper/RoaringBitmapWrapper.java         |    15 +-
 .../wrapper/RoaringIteratorWrapper.java       |     1 -
 .../AllRunHorizontalOrBenchmark.java          |    32 +-
 ...yContainerAndNotRunContainerBenchmark.java |    12 +-
 .../BasicAndContainerBenchmark.java           |    36 +-
 .../BasicAndNotContainerBenchmark.java        |    28 +-
 .../BasicHorizontalOrBenchmark.java           |    49 +-
 .../runcontainer/BasicIteratorBenchmark.java  |    29 +-
 .../BasicOrContainerBenchmark.java            |    34 +-
 .../BasicXorContainerBenchmark.java           |    35 +-
 .../BitmapToRuncontainerConversions.java      |    20 +-
 ...ardinalityMappeableContainerBenchmark.java |    28 +-
 ...ContainerRealDataBenchmarkRunOptimize.java |    39 +-
 .../runcontainer/RandomUtil.java              |    32 +-
 .../runcontainer/RunArrayAndBenchmark.java    |    26 +-
 .../runcontainer/RunArrayAndNotBenchmark.java |    26 +-
 .../runcontainer/RunArrayOrBenchmark.java     |    16 +-
 .../runcontainer/RunArrayXorBenchmark.java    |    26 +-
 ...ContainerRealDataBenchmarkRunOptimize.java |    36 +-
 .../Roaring64BmpSerializationBenchmark.java   |    27 +-
 .../serialization/SerializationBenchmark.java |    43 +-
 .../roaring/RealDataBenchmarkAnd.java         |     6 +-
 .../roaring/RealDataBenchmarkOr.java          |     8 +-
 .../roaring/RealDataBenchmarkWideOrNaive.java |     8 +-
 .../roaring/state/RealDataBenchmarkState.java |    11 +-
 .../runroaring/RealDataBenchmarkAnd.java      |     6 +-
 .../runroaring/RealDataBenchmarkOr.java       |     8 +-
 .../RealDataBenchmarkWideOrNaive.java         |     8 +-
 .../state/RealDataBenchmarkState.java         |    11 +-
 .../roaringbitmap/writer/WriteSequential.java |    18 +-
 .../roaringbitmap/writer/WriteUnordered.java  |    19 +-
 .../realdata/RealDataBenchmarkAndNotTest.java |    39 +-
 .../realdata/RealDataBenchmarkAndTest.java    |    37 +-
 .../RealDataBenchmarkForEachTest.java         |    45 +-
 .../realdata/RealDataBenchmarkIOrTest.java    |    47 +-
 .../RealDataBenchmarkIterateTest.java         |    38 +-
 .../realdata/RealDataBenchmarkOrTest.java     |    65 +-
 .../RealDataBenchmarkReverseIterateTest.java  |    41 +-
 .../realdata/RealDataBenchmarkSanityTest.java |    50 +-
 .../RealDataBenchmarkWideAndNaiveTest.java    |     1 -
 .../RealDataBenchmarkWideOrNaiveTest.java     |    38 +-
 .../RealDataBenchmarkWideOrPqTest.java        |    37 +-
 .../realdata/RealDataBenchmarkXorTest.java    |    39 +-
 .../java/org/roaringbitmap/RealDataset.java   |    15 +-
 .../ZipRealDataRangeRetriever.java            |     6 +-
 .../roaringbitmap/ZipRealDataRetriever.java   |    12 +-
 .../java/org/roaringbitmap/ArraysShim.java    |     4 +-
 .../org/roaringbitmap/AppendableStorage.java  |     1 -
 .../org/roaringbitmap/ArrayBatchIterator.java |     3 +-
 .../org/roaringbitmap/ArrayContainer.java     |   261 +-
 .../java/org/roaringbitmap/ArraysShim.java    |     4 +-
 .../org/roaringbitmap/BatchIntIterator.java   |     2 +-
 .../java/org/roaringbitmap/BatchIterator.java |     2 -
 .../java/org/roaringbitmap/BitSetUtil.java    |    49 +-
 .../roaringbitmap/BitmapBatchIterator.java    |     2 +-
 .../org/roaringbitmap/BitmapContainer.java    |   123 +-
 .../java/org/roaringbitmap/CharIterator.java  |     2 -
 .../ConstantMemoryContainerAppender.java      |    19 +-
 .../java/org/roaringbitmap/Container.java     |    54 +-
 .../org/roaringbitmap/ContainerAppender.java  |    28 +-
 .../roaringbitmap/ContainerBatchIterator.java |     1 -
 .../org/roaringbitmap/ContainerPointer.java   |     3 +-
 .../org/roaringbitmap/FastAggregation.java    |    81 +-
 .../roaringbitmap/FastRankRoaringBitmap.java  |    28 +-
 .../ImmutableBitmapDataProvider.java          |    33 +-
 .../java/org/roaringbitmap/IntIterator.java   |     1 -
 .../roaringbitmap/IntIteratorFlyweight.java   |     8 +-
 .../roaringbitmap/InvalidRoaringFormat.java   |     9 +-
 .../roaringbitmap/ParallelAggregation.java    |    46 +-
 .../roaringbitmap/PeekableCharIterator.java   |     3 -
 .../roaringbitmap/PeekableIntIterator.java    |     3 -
 .../PeekableIntRankIterator.java              |     2 -
 .../java/org/roaringbitmap/RangeBitmap.java   |   605 +-
 .../ReverseIntIteratorFlyweight.java          |    17 +-
 .../java/org/roaringbitmap/RoaringArray.java  |    87 +-
 .../roaringbitmap/RoaringBatchIterator.java   |    10 +-
 .../java/org/roaringbitmap/RoaringBitSet.java |     1 -
 .../java/org/roaringbitmap/RoaringBitmap.java |   671 +-
 .../roaringbitmap/RoaringBitmapSupplier.java  |     1 -
 .../roaringbitmap/RoaringBitmapWriter.java    |    18 +-
 .../org/roaringbitmap/RunBatchIterator.java   |     4 +-
 .../java/org/roaringbitmap/RunContainer.java  |   260 +-
 .../src/main/java/org/roaringbitmap/Util.java |   190 +-
 .../java/org/roaringbitmap/WordStorage.java   |     1 -
 .../roaringbitmap/art/AbstractShuttle.java    |    41 +-
 .../main/java/org/roaringbitmap/art/Art.java  |   133 +-
 .../roaringbitmap/art/ContainerIterator.java  |     3 +-
 .../org/roaringbitmap/art/Containers.java     |    20 +-
 .../java/org/roaringbitmap/art/LeafNode.java  |     7 +-
 .../roaringbitmap/art/LeafNodeIterator.java   |     1 -
 .../main/java/org/roaringbitmap/art/Node.java |    23 +-
 .../java/org/roaringbitmap/art/Node16.java    |    42 +-
 .../java/org/roaringbitmap/art/Node256.java   |     7 +-
 .../java/org/roaringbitmap/art/Node4.java     |    12 +-
 .../java/org/roaringbitmap/art/Node48.java    |    21 +-
 .../java/org/roaringbitmap/art/NodeType.java  |     7 +-
 .../buffer/ArrayBatchIterator.java            |     7 +-
 .../buffer/BitmapBatchIterator.java           |     7 +-
 .../buffer/BufferBitSetUtil.java              |    46 +-
 .../buffer/BufferFastAggregation.java         |   129 +-
 .../buffer/BufferIntIteratorFlyweight.java    |    11 +-
 .../buffer/BufferParallelAggregation.java     |    58 +-
 .../BufferReverseIntIteratorFlyweight.java    |    12 +-
 .../org/roaringbitmap/buffer/BufferUtil.java  |   185 +-
 .../buffer/ImmutableRoaringArray.java         |    44 +-
 .../buffer/ImmutableRoaringBitmap.java        |   431 +-
 .../buffer/MappeableArrayContainer.java       |   371 +-
 .../buffer/MappeableBitmapContainer.java      |   198 +-
 .../buffer/MappeableContainer.java            |    67 +-
 .../buffer/MappeableContainerPointer.java     |     2 -
 .../buffer/MappeableRunContainer.java         |   285 +-
 .../buffer/MutableRoaringArray.java           |    71 +-
 .../buffer/MutableRoaringBitmap.java          |   490 +-
 .../buffer/MutableRoaringBitmapSupplier.java  |     1 -
 .../buffer/PointableRoaringArray.java         |     7 +-
 .../buffer/RoaringBatchIterator.java          |     8 +-
 .../buffer/RunBatchIterator.java              |     4 +-
 .../roaringbitmap/buffer/package-info.java    |     3 -
 .../insights/BitmapAnalyser.java              |    11 +-
 .../insights/BitmapStatistics.java            |    52 +-
 .../insights/NaiveWriterRecommender.java      |    42 +-
 .../longlong/HighLowContainer.java            |    23 +-
 .../ImmutableLongBitmapDataProvider.java      |    17 +-
 .../longlong/LongBitmapDataProvider.java      |     1 -
 .../roaringbitmap/longlong/LongIterator.java  |     1 -
 .../org/roaringbitmap/longlong/LongUtils.java |    14 +-
 .../longlong/PeekableLongIterator.java        |     3 -
 .../longlong/Roaring64Bitmap.java             |    81 +-
 .../longlong/Roaring64NavigableMap.java       |   143 +-
 .../longlong/RoaringIntPacking.java           |     1 -
 .../roaringbitmap/longlong/package-info.java  |     3 -
 .../java/org/roaringbitmap/package-info.java  |     3 -
 .../roaringbitmap/CloneBatchIteratorTest.java |    12 +-
 .../ContainerBatchIteratorTest.java           |   282 +-
 .../test/java/org/roaringbitmap/KryoTest.java |   138 +-
 .../roaringbitmap/OrNotTruncationTest.java    |    68 +-
 .../ParallelAggregationTest.java              |   330 +-
 .../org/roaringbitmap/PreviousValueTest.java  |    13 +-
 .../org/roaringbitmap/RangeBitmapTest.java    |   712 +-
 .../org/roaringbitmap/RoaringArrayTest.java   |    20 +-
 .../org/roaringbitmap/RoaringBitSetTest.java  |   173 +-
 .../RoaringBitmapBatchIteratorTest.java       |   464 +-
 ...RoaringBitmapIntervalIntersectionTest.java |    70 +-
 .../RoaringBitmapSubsetTest.java              |   264 +-
 .../RoaringBitmapWriterRandomisedTest.java    |   273 +-
 .../org/roaringbitmap/SeededTestData.java     |    40 +-
 .../roaringbitmap/TestAdversarialInputs.java  |    98 +-
 .../org/roaringbitmap/TestArrayContainer.java |  1880 +--
 .../org/roaringbitmap/TestBitSetUtil.java     |    36 +-
 .../roaringbitmap/TestBitmapContainer.java    |   634 +-
 .../org/roaringbitmap/TestConcatenation.java  |    97 +-
 .../java/org/roaringbitmap/TestContainer.java |   241 +-
 .../TestEmptyRoaringBatchIterator.java        |    89 +-
 .../roaringbitmap/TestFastAggregation.java    |   446 +-
 .../org/roaringbitmap/TestForAllInRange.java  |    52 +-
 .../java/org/roaringbitmap/TestForEach.java   |    72 +-
 .../TestImmutableRoaringBitmap.java           |    99 +-
 .../TestIntIteratorFlyweight.java             |    44 +-
 .../org/roaringbitmap/TestIteratorMemory.java |    51 +-
 .../java/org/roaringbitmap/TestIterators.java |   101 +-
 .../java/org/roaringbitmap/TestMemory.java    |    11 +-
 .../java/org/roaringbitmap/TestRange.java     |   266 +-
 .../roaringbitmap/TestRangeCardinality.java   |    43 +-
 .../org/roaringbitmap/TestRankIterator.java   |    26 +-
 .../TestRankIteratorsOfContainers.java        |     8 +-
 .../TestReverseIteratorsOfContainers.java     |    26 +-
 .../org/roaringbitmap/TestRoaringBitmap.java  | 10897 ++++++++--------
 .../roaringbitmap/TestRoaringBitmapOrNot.java |    72 +-
 .../TestRoaringBitmapWriter.java              |   346 +-
 .../TestRoaringBitmapWriterWizard.java        |    17 +-
 .../TestRoaringBitmap_FastRank.java           |    44 +-
 .../org/roaringbitmap/TestRunContainer.java   |   635 +-
 .../org/roaringbitmap/TestSerialization.java  |    56 +-
 .../TestSerializationViaByteBuffer.java       |   152 +-
 .../org/roaringbitmap/TestSerializedSize.java |    41 +-
 .../java/org/roaringbitmap/TestStreams.java   |    51 +-
 .../test/java/org/roaringbitmap/TestUtil.java |   400 +-
 .../roaringbitmap/TestVeryLargeBitmap.java    |     4 +-
 ...eredRoaringBitmapWriterRandomisedTest.java |    95 +-
 .../ValidationRangeConsumer.java              |     6 +-
 .../org/roaringbitmap/art/Node16Test.java     |    14 +-
 .../org/roaringbitmap/art/Node48Test.java     |    31 +-
 .../java/org/roaringbitmap/art/Node4Test.java |     9 +-
 .../BufferContainerBatchIteratorTest.java     |   282 +-
 .../buffer/CloneBatchIteratorTest.java        |    18 +-
 ...mutableRoaringBitmapBatchIteratorTest.java |   455 +-
 .../buffer/MutableRoaringArrayTest.java       |     4 +-
 .../MutableRoaringBitmapSubsetTest.java       |   265 +-
 ...RoaringBitmapIntervalIntersectionTest.java |   110 +-
 .../roaringbitmap/buffer/TestBitSetUtil.java  |    18 +-
 .../buffer/TestBufferAdversarialInputs.java   |   202 +-
 .../buffer/TestBufferRangeCardinality.java    |    54 +-
 .../buffer/TestCompressionRates.java          |     4 +-
 .../roaringbitmap/buffer/TestContainer.java   |    98 +-
 .../roaringbitmap/buffer/TestExamples.java    |     6 +-
 .../buffer/TestFastAggregation.java           |   340 +-
 .../org/roaringbitmap/buffer/TestForEach.java |    67 +-
 .../buffer/TestImmutableRoaringBitmap.java    |   821 +-
 .../TestImmutableRoaringBitmapOrNot.java      |   671 +-
 .../buffer/TestIntIteratorFlyweight.java      |    41 +-
 .../roaringbitmap/buffer/TestIterators.java   |   144 +-
 .../buffer/TestMappeableArrayContainer.java   |   416 +-
 .../buffer/TestMappeableBitmapContainer.java  |   668 +-
 ...tMappeableBitmapContainerCharIterator.java |    56 +-
 .../buffer/TestMappeableRunContainer.java     |    50 +-
 .../org/roaringbitmap/buffer/TestMemory.java  |    11 +-
 .../buffer/TestMemoryMapping.java             |   172 +-
 .../org/roaringbitmap/buffer/TestRange.java   |   148 +-
 .../TestReverseMappeableRunContainer.java     |    95 +-
 .../buffer/TestRoaringBitmap.java             |  1818 +--
 .../buffer/TestRunContainer.java              |   531 +-
 .../TestSerializationViaByteBuffer.java       |   165 +-
 .../buffer/TestSerializedSize.java            |    17 +-
 .../org/roaringbitmap/buffer/TestUtil.java    |   201 +-
 .../buffer/TestVeryLargeBitmap.java           |     4 +-
 .../insights/BitmapAnalyserTest.java          |    23 +-
 .../insights/BitmapStatisticsTest.java        |    11 +-
 .../insights/NaiveWriterRecommenderTest.java  |    73 +-
 .../org/roaringbitmap/longlong/ArtTest.java   |   153 +-
 .../longlong/ContainersTest.java              |    26 +-
 .../longlong/IntegerUtilTest.java             |     8 +-
 .../org/roaringbitmap/longlong/Issue319.java  |   111 +-
 .../longlong/JolBenchmarksTest.java           |   234 +-
 .../longlong/TestRoaring64Bitmap.java         |   539 +-
 .../longlong/TestRoaring64NavigableMap.java   |   245 +-
 .../src/main/java/simplebenchmark.java        |   472 +-
 355 files changed, 22837 insertions(+), 20521 deletions(-)

diff --git a/.gitignore b/.gitignore
index f8309e05d..0d544b3ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ build/
 
 # OS X
 .DS_Store
+.java-version
 
 # intellij
 .idea
diff --git a/README.md b/README.md
index 4019bc6d6..c583fa4c7 100644
--- a/README.md
+++ b/README.md
@@ -646,8 +646,10 @@ it up in your favorite IDE.
 Contributing
 ------------
 
-Contributions are invited. We use the Google Java style (see `roaring_google_checks.xml`).
-Please do not reformat the code needlessly.
+Contributions are invited. We use the Google Java style (see `roaring_google_checks.xml`). It can be applied
+automatically to your code with `./gradlew spotlessApply`
+
+Please do not reformat the code needlessly (especially on comments/javadoc).
 
 FAQ
 ----
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java
index cd012fbce..b087d081d 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/BitmapSliceIndex.java
@@ -41,7 +41,6 @@ enum Operation {
 
   long getLongCardinality();
 
-
   /**
    * set value for bsi, setValue will set each bit slice according to the input value
    * given that we have bsi as follow
@@ -76,7 +75,8 @@ enum Operation {
    * and avoiding bsi expend slice array capacity.
    */
   @Deprecated
-  void setValues(List> values, Integer currentMaxValue, Integer currentMinValue);
+  void setValues(
+      List> values, Integer currentMaxValue, Integer currentMinValue);
 
   /**
    * Set a batch of values.
@@ -89,7 +89,4 @@ enum Operation {
   void serialize(DataOutput output) throws IOException;
 
   int serializedSizeInBytes();
-
-
 }
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/Pair.java b/bsi/src/main/java/org/roaringbitmap/bsi/Pair.java
index db471e453..270b5925b 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/Pair.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/Pair.java
@@ -18,8 +18,7 @@ public class Pair implements Serializable {
   /**
    * Default constructor.
    */
-  public Pair() {
-  }
+  public Pair() {}
 
   /**
    * Constructor
@@ -96,17 +95,16 @@ public void setSecond(T2 b) {
   @Override
   @SuppressWarnings("rawtypes")
   public boolean equals(Object other) {
-    return other instanceof Pair && equals(left, ((Pair) other).left) && equals(right, ((Pair) other).right);
+    return other instanceof Pair
+        && equals(left, ((Pair) other).left)
+        && equals(right, ((Pair) other).right);
   }
 
   @Override
   public int hashCode() {
-    if (left == null)
-      return (right == null) ? 0 : right.hashCode() + 1;
-    else if (right == null)
-      return left.hashCode() + 2;
-    else
-      return left.hashCode() * 17 + right.hashCode();
+    if (left == null) return (right == null) ? 0 : right.hashCode() + 1;
+    else if (right == null) return left.hashCode() + 2;
+    else return left.hashCode() * 17 + right.hashCode();
   }
 
   @Override
@@ -114,5 +112,3 @@ public String toString() {
     return "{" + getLeft() + "," + getRight() + "}";
   }
 }
-
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
index 6be414fd4..048e8a37d 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/RoaringBitmapSliceIndex.java
@@ -1,6 +1,5 @@
 package org.roaringbitmap.bsi;
 
-import java.util.Objects;
 import org.roaringbitmap.RoaringBitmap;
 
 import java.io.DataInput;
@@ -8,6 +7,7 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.IntStream;
 
 /**
@@ -34,7 +34,6 @@ public class RoaringBitmapSliceIndex implements BitmapSliceIndex {
    */
   private RoaringBitmap ebM;
 
-
   private Boolean runOptimized = false;
 
   /**
@@ -54,7 +53,6 @@ public RoaringBitmapSliceIndex(int minValue, int maxValue) {
     this.ebM = new RoaringBitmap();
   }
 
-
   /**
    * NewDefaultBSI constructs an auto-sized BSI
    */
@@ -62,7 +60,6 @@ public RoaringBitmapSliceIndex() {
     this(0, 0);
   }
 
-
   public void add(RoaringBitmapSliceIndex otherBsi) {
     if (null == otherBsi || otherBsi.ebM.isEmpty()) {
       return;
@@ -91,7 +88,6 @@ private void addDigit(RoaringBitmap foundSet, int i) {
       }
       this.addDigit(carry, i + 1);
     }
-
   }
 
   private int minValue() {
@@ -152,7 +148,6 @@ public void runOptimize() {
   /**
    * hasRunCompression returns true if the bitmap benefits from run compression
    */
-
   public boolean hasRunCompression() {
     return this.runOptimized;
   }
@@ -160,12 +155,10 @@ public boolean hasRunCompression() {
   /**
    * GetExistenceBitmap returns a pointer to the underlying existence bitmap of the BSI
    */
-
   public RoaringBitmap getExistenceBitmap() {
     return this.ebM;
   }
 
-
   public int bitCount() {
     return this.bA.length;
   }
@@ -174,7 +167,6 @@ public long getLongCardinality() {
     return this.ebM.getLongCardinality();
   }
 
-
   /**
    * GetValue gets the value at the column ID.  Second param will be false for non-existence values.
    */
@@ -187,7 +179,6 @@ public Pair getValue(int columnId) {
     return Pair.newPair(valueAt(columnId), true);
   }
 
-
   private void clear() {
     this.maxValue = 0;
     this.minValue = 0;
@@ -249,7 +240,6 @@ public void serialize(ByteBuffer buffer) {
     for (RoaringBitmap rb : this.bA) {
       rb.serialize(buffer);
     }
-
   }
 
   public void deserialize(ByteBuffer buffer) throws IOException {
@@ -285,7 +275,6 @@ public int serializedSizeInBytes() {
     return 4 + 4 + 1 + 4 + this.ebM.serializedSizeInBytes() + size;
   }
 
-
   /**
    * valueExists tests whether the value exists.
    */
@@ -348,8 +337,10 @@ private void grow(int newBitDepth) {
 
   @Override
   public void setValues(List> values) {
-    int maxValue = values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).max().getAsInt();
-    int minValue = values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).min().getAsInt();
+    int maxValue =
+        values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).max().getAsInt();
+    int minValue =
+        values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).min().getAsInt();
     ensureCapacityInternal(minValue, maxValue);
     for (Pair pair : values) {
       setValueInternal(pair.getKey(), pair.getValue());
@@ -360,9 +351,16 @@ public void setValues(List> values) {
    * Replaced by {@code setValues(values)}
    */
   @Deprecated
-  public void setValues(List> values, Integer currentMaxValue, Integer currentMinValue) {
-    int maxValue = currentMaxValue != null ? currentMaxValue : values.stream().mapToInt(Pair::getRight).max().getAsInt();
-    int minValue = currentMinValue != null ? currentMinValue : values.stream().mapToInt(Pair::getRight).min().getAsInt();
+  public void setValues(
+      List> values, Integer currentMaxValue, Integer currentMinValue) {
+    int maxValue =
+        currentMaxValue != null
+            ? currentMaxValue
+            : values.stream().mapToInt(Pair::getRight).max().getAsInt();
+    int minValue =
+        currentMinValue != null
+            ? currentMinValue
+            : values.stream().mapToInt(Pair::getRight).min().getAsInt();
     ensureCapacityInternal(minValue, maxValue);
     for (Pair pair : values) {
       this.setValue(pair.getKey(), pair.getValue());
@@ -404,7 +402,6 @@ public void merge(RoaringBitmapSliceIndex otherBsi) {
     this.minValue = Integer.min(this.minValue, otherBsi.minValue);
   }
 
-
   public RoaringBitmapSliceIndex clone() {
     RoaringBitmapSliceIndex bitSliceIndex = new RoaringBitmapSliceIndex();
     bitSliceIndex.minValue = this.minValue;
@@ -429,14 +426,14 @@ public RoaringBitmapSliceIndex clone() {
    * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
    * see https://github.com/lemire/BitSliceIndex/blob/master/src/main/java/org/roaringbitmap/circuits/comparator/BasicComparator.java
    */
-  private RoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation, int predicate, RoaringBitmap foundSet) {
+  private RoaringBitmap oNeilCompare(
+      BitmapSliceIndex.Operation operation, int predicate, RoaringBitmap foundSet) {
     RoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
 
     RoaringBitmap GT = new RoaringBitmap();
     RoaringBitmap LT = new RoaringBitmap();
     RoaringBitmap EQ = this.ebM;
 
-
     for (int i = this.bitCount() - 1; i >= 0; i--) {
       int bit = (predicate >> i) & 1;
       if (bit == 1) {
@@ -446,7 +443,6 @@ private RoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation, int pre
         GT = RoaringBitmap.or(GT, RoaringBitmap.and(EQ, this.bA[i]));
         EQ = RoaringBitmap.andNot(EQ, this.bA[i]);
       }
-
     }
     EQ = RoaringBitmap.and(fixedFoundSet, EQ);
     switch (operation) {
@@ -479,7 +475,8 @@ private RoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation, int pre
    * @param foundSet    columnId set we want compare,using RoaringBitmap to express
    * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
    */
-  public RoaringBitmap compare(BitmapSliceIndex.Operation operation, int startOrValue, int end, RoaringBitmap foundSet) {
+  public RoaringBitmap compare(
+      BitmapSliceIndex.Operation operation, int startOrValue, int end, RoaringBitmap foundSet) {
     RoaringBitmap result = compareUsingMinMax(operation, startOrValue, end, foundSet);
     if (result != null) {
       return result;
@@ -492,33 +489,36 @@ public RoaringBitmap compare(BitmapSliceIndex.Operation operation, int startOrVa
         return oNeilCompare(Operation.NEQ, startOrValue, foundSet);
       case GE:
         return oNeilCompare(Operation.GE, startOrValue, foundSet);
-      case GT: {
-        return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
-      }
+      case GT:
+        {
+          return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
+        }
       case LT:
         return oNeilCompare(BitmapSliceIndex.Operation.LT, startOrValue, foundSet);
 
       case LE:
         return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
 
-      case RANGE: {
-        if (startOrValue < minValue) {
-          startOrValue = minValue;
-        }
-        if (end > maxValue) {
-          end = maxValue;
+      case RANGE:
+        {
+          if (startOrValue < minValue) {
+            startOrValue = minValue;
+          }
+          if (end > maxValue) {
+            end = maxValue;
+          }
+          RoaringBitmap left = oNeilCompare(Operation.GE, startOrValue, foundSet);
+          RoaringBitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
+
+          return RoaringBitmap.and(left, right);
         }
-        RoaringBitmap left = oNeilCompare(Operation.GE, startOrValue, foundSet);
-        RoaringBitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
-
-        return RoaringBitmap.and(left, right);
-      }
       default:
         throw new IllegalArgumentException("not support operation!");
     }
   }
 
-  private RoaringBitmap compareUsingMinMax(BitmapSliceIndex.Operation operation, int startOrValue, int end, RoaringBitmap foundSet) {
+  private RoaringBitmap compareUsingMinMax(
+      BitmapSliceIndex.Operation operation, int startOrValue, int end, RoaringBitmap foundSet) {
     RoaringBitmap all = foundSet == null ? ebM.clone() : RoaringBitmap.and(ebM, foundSet);
     RoaringBitmap empty = new RoaringBitmap();
 
@@ -590,12 +590,11 @@ public Pair sum(RoaringBitmap foundSet) {
     }
     long count = foundSet.getLongCardinality();
 
-    Long sum = IntStream.range(0, this.bitCount())
-        .mapToLong(x -> (long) (1 << x) * RoaringBitmap.andCardinality(this.bA[x], foundSet))
-        .sum();
+    Long sum =
+        IntStream.range(0, this.bitCount())
+            .mapToLong(x -> (long) (1 << x) * RoaringBitmap.andCardinality(this.bA[x], foundSet))
+            .sum();
 
     return Pair.newPair(sum, count);
   }
-
 }
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/WritableUtils.java b/bsi/src/main/java/org/roaringbitmap/bsi/WritableUtils.java
index a56b85b45..6a1c248c9 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/WritableUtils.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/WritableUtils.java
@@ -73,7 +73,6 @@ public static void writeVLong(DataOutput stream, long i) throws IOException {
     }
   }
 
-
   /**
    * Reads a zero-compressed encoded long from input stream and returns it.
    *
@@ -136,4 +135,3 @@ public static int decodeVIntSize(byte value) {
     return -111 - value;
   }
 }
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
index b4d8d6593..b835fdc74 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/BitSliceIndexBase.java
@@ -1,10 +1,7 @@
-
 package org.roaringbitmap.bsi.buffer;
 
 import org.roaringbitmap.BatchIterator;
 import org.roaringbitmap.IntConsumer;
-import org.roaringbitmap.IntIterator;
-import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.bsi.BitmapSliceIndex;
 import org.roaringbitmap.bsi.BitmapSliceIndex.Operation;
 import org.roaringbitmap.bsi.Pair;
@@ -49,7 +46,6 @@ public class BitSliceIndexBase {
    */
   protected ImmutableRoaringBitmap ebM;
 
-
   public int bitCount() {
     return this.bA.length;
   }
@@ -75,7 +71,6 @@ public Pair getValue(int columnId) {
     return Pair.newPair(value, true);
   }
 
-
   /**
    * valueExists tests whether the value exists.
    */
@@ -83,9 +78,9 @@ public boolean valueExist(Long columnId) {
     return this.ebM.contains(columnId.intValue());
   }
 
-  //=====================================================================================
+  // =====================================================================================
   // parallel execute frame
-  //======================================================================================
+  // ======================================================================================
 
   /**
    * use java threadPool to parallel exec
@@ -96,10 +91,11 @@ public boolean valueExist(Long columnId) {
    * @param pool    threadPool to exec
    * @return a list of completable futures
    */
-  protected  List> parallelExec(Function func,
-                              int parallelism,
-                              ImmutableRoaringBitmap foundSet,
-                              ExecutorService pool) {
+  protected  List> parallelExec(
+      Function func,
+      int parallelism,
+      ImmutableRoaringBitmap foundSet,
+      ExecutorService pool) {
     int batchSize = foundSet.getCardinality() / parallelism;
     // fix when batchSize < parallelism
     batchSize = Math.max(batchSize, parallelism);
@@ -107,7 +103,6 @@ protected  List> parallelExec(Function func,
     // todo RoaringBitmap's batchIterator return max 2^16
     batchSize = Math.min(batchSize, 65536);
 
-
     List batches = new ArrayList<>();
 
     final BatchIterator batchIterator = foundSet.getBatchIterator();
@@ -127,9 +122,13 @@ protected  List> parallelExec(Function func,
 
     List> futures = new ArrayList<>();
     for (int[] batch : batches) {
-      CompletableFuture future = invokeAsync(() -> {
-        return func.apply(batch);
-      }, null, pool);
+      CompletableFuture future =
+          invokeAsync(
+              () -> {
+                return func.apply(batch);
+              },
+              null,
+              pool);
       futures.add(future);
     }
     return futures;
@@ -138,20 +137,19 @@ protected  List> parallelExec(Function func,
   protected  CompletableFuture> allOf(List> futuresList) {
     CompletableFuture allFuturesResult =
         CompletableFuture.allOf(futuresList.toArray(new CompletableFuture[0]));
-    return allFuturesResult.thenApply(v ->
-        futuresList.stream().
-            map(CompletableFuture::join).
-            collect(Collectors.toList())
-    );
+    return allFuturesResult.thenApply(
+        v -> futuresList.stream().map(CompletableFuture::join).collect(Collectors.toList()));
   }
 
-  protected ImmutableRoaringBitmap parallelMR(int parallelism,
-                        ImmutableRoaringBitmap foundSet,
-                        Function func,
-                        ExecutorService pool)
+  protected ImmutableRoaringBitmap parallelMR(
+      int parallelism,
+      ImmutableRoaringBitmap foundSet,
+      Function func,
+      ExecutorService pool)
       throws InterruptedException, ExecutionException {
 
-    List> futures = parallelExec(func, parallelism, foundSet, pool);
+    List> futures =
+        parallelExec(func, parallelism, foundSet, pool);
 
     allOf(futures);
 
@@ -163,19 +161,20 @@ protected ImmutableRoaringBitmap parallelMR(int parallelism,
     return MutableRoaringBitmap.or(rbs);
   }
 
-  protected  CompletableFuture invokeAsync(Supplier supplier,
-                           Function exceptionHandler,
-                           Executor forkJoinExecutor) {
-    return CompletableFuture.supplyAsync(() -> {
-      try {
-        return supplier.get();
-      } catch (Exception e) {
-        if (exceptionHandler == null) {
-          throw e;
-        }
-        return exceptionHandler.apply(e);
-      }
-    }, forkJoinExecutor);
+  protected  CompletableFuture invokeAsync(
+      Supplier supplier, Function exceptionHandler, Executor forkJoinExecutor) {
+    return CompletableFuture.supplyAsync(
+        () -> {
+          try {
+            return supplier.get();
+          } catch (Exception e) {
+            if (exceptionHandler == null) {
+              throw e;
+            }
+            return exceptionHandler.apply(e);
+          }
+        },
+        forkJoinExecutor);
   }
 
   /**
@@ -187,18 +186,16 @@ protected  CompletableFuture invokeAsync(Supplier supplier,
    * @return ImmutableRoaringBitmap
    * see https://github.com/lemire/BitSliceIndex/blob/master/src/main/java/org/roaringbitmap/circuits/comparator/BasicComparator.java
    */
-  private ImmutableRoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation,
-                        int predicate,
-                        ImmutableRoaringBitmap foundSet) {
+  private ImmutableRoaringBitmap oNeilCompare(
+      BitmapSliceIndex.Operation operation, int predicate, ImmutableRoaringBitmap foundSet) {
     ImmutableRoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
 
-    MutableRoaringBitmap GT = operation == Operation.GT || operation == Operation.GE
-        ? new MutableRoaringBitmap() : null;
-    MutableRoaringBitmap LT = operation == Operation.LT || operation == Operation.LE
-        ? new MutableRoaringBitmap() : null;
+    MutableRoaringBitmap GT =
+        operation == Operation.GT || operation == Operation.GE ? new MutableRoaringBitmap() : null;
+    MutableRoaringBitmap LT =
+        operation == Operation.LT || operation == Operation.LE ? new MutableRoaringBitmap() : null;
     ImmutableRoaringBitmap EQ = this.ebM;
 
-
     for (int i = this.bitCount() - 1; i >= 0; i--) {
       int bit = (predicate >> i) & 1;
       if (bit == 1) {
@@ -212,7 +209,6 @@ private ImmutableRoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation
         }
         EQ = ImmutableRoaringBitmap.andNot(EQ, this.bA[i]);
       }
-
     }
     if (operation != Operation.LT && operation != Operation.GT) {
       EQ = ImmutableRoaringBitmap.and(fixedFoundSet, EQ);
@@ -240,8 +236,7 @@ private ImmutableRoaringBitmap oNeilCompare(BitmapSliceIndex.Operation operation
    * @return ImmutableRoaringBitmap
    * see https://github.com/lemire/BitSliceIndex/blob/master/src/main/java/org/roaringbitmap/circuits/comparator/OwenComparator.java
    */
-  private ImmutableRoaringBitmap owenGreatEqual(int predicate,
-                          ImmutableRoaringBitmap foundSet) {
+  private ImmutableRoaringBitmap owenGreatEqual(int predicate, ImmutableRoaringBitmap foundSet) {
     ImmutableRoaringBitmap lastSpineGate = null;
     int beGtrThan = predicate - 1;
     List orInputs = new ArrayList<>();
@@ -250,21 +245,20 @@ private ImmutableRoaringBitmap owenGreatEqual(int predicate,
     for (int workingBit = this.bitCount() - 1; workingBit >= leastSignifZero; --workingBit) {
       if ((beGtrThan & (1L << workingBit)) == 0L) {
         if (lastSpineGate == null) // don't make a singleton AND!
-          orInputs.add(this.bA[workingBit]);
+        orInputs.add(this.bA[workingBit]);
         else {
           // really make the AND
           orInputs.add(MutableRoaringBitmap.and(lastSpineGate, this.bA[workingBit]));
         }
       } else {
-        if (lastSpineGate == null)
-          lastSpineGate = this.bA[workingBit];
-        else
-          lastSpineGate = ImmutableRoaringBitmap.and(lastSpineGate, this.bA[workingBit]);
+        if (lastSpineGate == null) lastSpineGate = this.bA[workingBit];
+        else lastSpineGate = ImmutableRoaringBitmap.and(lastSpineGate, this.bA[workingBit]);
       }
     }
 
-    ImmutableRoaringBitmap result = BufferFastAggregation.horizontal_or(orInputs.toArray(new ImmutableRoaringBitmap[0]));
-    //horizontal_or the performance is better
+    ImmutableRoaringBitmap result =
+        BufferFastAggregation.horizontal_or(orInputs.toArray(new ImmutableRoaringBitmap[0]));
+    // horizontal_or the performance is better
     // return BufferFastAggregation.or(orInputs.toArray(new ImmutableRoaringBitmap[0]))
 
     if (null == foundSet) {
@@ -274,18 +268,21 @@ private ImmutableRoaringBitmap owenGreatEqual(int predicate,
     }
   }
 
-  //------------------------------------------------------------------------------------------------------------
+  // ------------------------------------------------------------------------------------------------------------
   // See Bit-Sliced Index Arithmetic
-  // Finding the rows with the k largest values in a BSI. Given a BSI, S = S^P,S^(P-1)...S^1,S^0  over a table T
-  // and a positive integer k<= |T|, we wish to find the bitmap F (for "found set") of rows r with the k largest
+  // Finding the rows with the k largest values in a BSI. Given a BSI, S = S^P,S^(P-1)...S^1,S^0
+  // over a table T
+  // and a positive integer k<= |T|, we wish to find the bitmap F (for "found set") of rows r with
+  // the k largest
   // S-values, S(r), in T.
   // Algorithm 4.1. Find k rows with largest values in a BSI.
-  //------------------------------------------------------------------------------------------------------------
+  // ------------------------------------------------------------------------------------------------------------
   //  if (k > COUNT(EBM) or k < 0)            -- test if parameter k is valid
   //  Error ("k is invalid")              -- if not, exit; otherwise, kth largest S-value exists
   //  G = empty set; E = EBM;               -- G starts with no rows; E with all rows
   //  for (i = P; i >= 0; i--) {              -- i is a descending loop index for bit-slice number
-  //    X = G OR (E AND S^i)              -- X is trial set: G OR {rows in E with 1-bit in position i}
+  //    X = G OR (E AND S^i)              -- X is trial set: G OR {rows in E with 1-bit in position
+  // i}
   //    if ((n = COUNT(X) ) > k)            -- if n = COUNT(X) has more than k rows
   //        E = E AND S^i             -- E in next pass contains only rows r with bit i on in S(r)
   //    else if (n < k) {               -- if n = COUNT(X) has less than k rows
@@ -303,15 +300,16 @@ private ImmutableRoaringBitmap owenGreatEqual(int predicate,
   public MutableRoaringBitmap topK(ImmutableRoaringBitmap foundSet, int k) {
     ImmutableRoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
     if (k > fixedFoundSet.getLongCardinality() || k < 0) {
-      throw new IllegalArgumentException("TopK param error,cardinality:"
-          + fixedFoundSet.getLongCardinality() + " k:" + k);
+      throw new IllegalArgumentException(
+          "TopK param error,cardinality:" + fixedFoundSet.getLongCardinality() + " k:" + k);
     }
 
     MutableRoaringBitmap G = new MutableRoaringBitmap();
     ImmutableRoaringBitmap E = fixedFoundSet;
 
     for (int i = this.bitCount() - 1; i >= 0; i--) {
-      MutableRoaringBitmap X = ImmutableRoaringBitmap.or(G, ImmutableRoaringBitmap.and(E, this.bA[i]));
+      MutableRoaringBitmap X =
+          ImmutableRoaringBitmap.or(G, ImmutableRoaringBitmap.and(E, this.bA[i]));
       long n = X.getLongCardinality();
       if (n > k) {
         E = ImmutableRoaringBitmap.and(E, this.bA[i]);
@@ -326,12 +324,11 @@ public MutableRoaringBitmap topK(ImmutableRoaringBitmap foundSet, int k) {
 
     MutableRoaringBitmap F = ImmutableRoaringBitmap.or(G, E);
     long n = F.getLongCardinality() - k;
-    F.remove(0L,(long)F.select((int)n));
-    assert(F.getLongCardinality() == k);
+    F.remove(0L, (long) F.select((int) n));
+    assert (F.getLongCardinality() == k);
     return F;
   }
 
-
   /**
    * EQ: =
    *
@@ -348,7 +345,8 @@ public ImmutableRoaringBitmap rangeEQ(ImmutableRoaringBitmap foundSet, int predi
     }
 
     // https://github.com/RoaringBitmap/RoaringBitmap/issues/549
-    ImmutableRoaringBitmap result = compareUsingMinMax(BitmapSliceIndex.Operation.EQ, predicate, 0, foundSet);
+    ImmutableRoaringBitmap result =
+        compareUsingMinMax(BitmapSliceIndex.Operation.EQ, predicate, 0, foundSet);
     if (result != null) {
       return result;
     }
@@ -395,7 +393,6 @@ public ImmutableRoaringBitmap rangeGE(ImmutableRoaringBitmap foundSet, int predi
 
   public ImmutableRoaringBitmap range(ImmutableRoaringBitmap foundSet, int start, int end) {
     return compare(BitmapSliceIndex.Operation.RANGE, start, end, foundSet);
-
   }
 
   /**
@@ -410,7 +407,11 @@ public ImmutableRoaringBitmap range(ImmutableRoaringBitmap foundSet, int start,
    * @param foundSet   columnId set we want compare,using RoaringBitmap to express
    * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
    */
-  public ImmutableRoaringBitmap compare(BitmapSliceIndex.Operation operation, int startOrValue, int end, ImmutableRoaringBitmap foundSet) {
+  public ImmutableRoaringBitmap compare(
+      BitmapSliceIndex.Operation operation,
+      int startOrValue,
+      int end,
+      ImmutableRoaringBitmap foundSet) {
     ImmutableRoaringBitmap result = compareUsingMinMax(operation, startOrValue, end, foundSet);
     if (result != null) {
       return result;
@@ -423,34 +424,41 @@ public ImmutableRoaringBitmap compare(BitmapSliceIndex.Operation operation, int
         return rangeNEQ(foundSet, startOrValue);
       case GE:
         return owenGreatEqual(startOrValue, foundSet);
-      case GT: {
-        return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
-      }
+      case GT:
+        {
+          return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
+        }
       case LT:
         return oNeilCompare(BitmapSliceIndex.Operation.LT, startOrValue, foundSet);
 
       case LE:
         return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
 
-      case RANGE: {
-        if (startOrValue < minValue) {
-          startOrValue = minValue;
-        }
-        if (end > maxValue) {
-          end = maxValue;
+      case RANGE:
+        {
+          if (startOrValue < minValue) {
+            startOrValue = minValue;
+          }
+          if (end > maxValue) {
+            end = maxValue;
+          }
+          ImmutableRoaringBitmap left = owenGreatEqual(startOrValue, foundSet);
+          ImmutableRoaringBitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
+
+          return ImmutableRoaringBitmap.and(left, right);
         }
-        ImmutableRoaringBitmap left = owenGreatEqual(startOrValue, foundSet);
-        ImmutableRoaringBitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
-
-        return ImmutableRoaringBitmap.and(left, right);
-      }
       default:
         throw new IllegalArgumentException("not support operation!");
     }
   }
 
-  private ImmutableRoaringBitmap compareUsingMinMax(BitmapSliceIndex.Operation operation, int startOrValue, int end, ImmutableRoaringBitmap foundSet) {
-    ImmutableRoaringBitmap all = foundSet == null ? this.ebM.clone() : ImmutableRoaringBitmap.and(this.ebM, foundSet);
+  private ImmutableRoaringBitmap compareUsingMinMax(
+      BitmapSliceIndex.Operation operation,
+      int startOrValue,
+      int end,
+      ImmutableRoaringBitmap foundSet) {
+    ImmutableRoaringBitmap all =
+        foundSet == null ? this.ebM.clone() : ImmutableRoaringBitmap.and(this.ebM, foundSet);
     ImmutableRoaringBitmap empty = new MutableRoaringBitmap();
 
     switch (operation) {
@@ -521,27 +529,33 @@ public Pair sum(ImmutableRoaringBitmap foundSet) {
     }
     long count = foundSet.getLongCardinality();
 
-    Long sum = IntStream.range(0, this.bitCount())
-        .mapToLong(x -> (long) (1 << x) * ImmutableRoaringBitmap.andCardinality(this.bA[x], foundSet))
-        .sum();
+    Long sum =
+        IntStream.range(0, this.bitCount())
+            .mapToLong(
+                x -> (long) (1 << x) * ImmutableRoaringBitmap.andCardinality(this.bA[x], foundSet))
+            .sum();
 
     return Pair.newPair(sum, count);
   }
 
   public List> toPairList() {
     List> pairList = new ArrayList<>();
-    this.ebM.forEach((IntConsumer) cid -> {
-      pairList.add(Pair.newPair(cid, this.getValue(cid).getKey()));
-    });
+    this.ebM.forEach(
+        (IntConsumer)
+            cid -> {
+              pairList.add(Pair.newPair(cid, this.getValue(cid).getKey()));
+            });
     return pairList;
   }
 
   public List> toPairList(ImmutableRoaringBitmap foundSet) {
     List> pairList = new ArrayList<>();
     ImmutableRoaringBitmap bitmap = ImmutableRoaringBitmap.and(this.ebM, foundSet);
-    bitmap.forEach((IntConsumer) cid -> {
-      pairList.add(Pair.newPair(cid, this.getValue(cid).getKey()));
-    });
+    bitmap.forEach(
+        (IntConsumer)
+            cid -> {
+              pairList.add(Pair.newPair(cid, this.getValue(cid).getKey()));
+            });
     return pairList;
   }
 
@@ -572,17 +586,18 @@ protected MutableBitSliceIndex transposeWithCount(int[] batch) {
    * @param foundSet
    * @return the transpose
    */
-  public MutableBitSliceIndex parallelTransposeWithCount(ImmutableRoaringBitmap foundSet,
-                               int parallelism,
-                               ExecutorService pool)
+  public MutableBitSliceIndex parallelTransposeWithCount(
+      ImmutableRoaringBitmap foundSet, int parallelism, ExecutorService pool)
       throws ExecutionException, InterruptedException {
 
     ImmutableRoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
 
-    Function func = (int[] batch) -> {
-      return transposeWithCount(batch);
-    };
-    List> futures = parallelExec(func, parallelism, fixedFoundSet, pool);
+    Function func =
+        (int[] batch) -> {
+          return transposeWithCount(batch);
+        };
+    List> futures =
+        parallelExec(func, parallelism, fixedFoundSet, pool);
 
     allOf(futures);
 
@@ -605,23 +620,20 @@ public MutableBitSliceIndex parallelTransposeWithCount(ImmutableRoaringBitmap fo
    * @throws ExecutionException
    * @throws InterruptedException
    */
-  public ImmutableRoaringBitmap parallelIn(int parallelism,
-                       ImmutableRoaringBitmap foundSet,
-                       Set values,
-                       ExecutorService pool
-  ) throws ExecutionException, InterruptedException {
+  public ImmutableRoaringBitmap parallelIn(
+      int parallelism, ImmutableRoaringBitmap foundSet, Set values, ExecutorService pool)
+      throws ExecutionException, InterruptedException {
 
     ImmutableRoaringBitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
 
-    Function func = (int[] batch) -> {
-      return batchIn(batch, values);
-    };
+    Function func =
+        (int[] batch) -> {
+          return batchIn(batch, values);
+        };
 
     return parallelMR(parallelism, fixedFoundSet, func, pool);
-
   }
 
-
   protected ImmutableRoaringBitmap batchIn(int[] batch, Set values) {
 
     MutableRoaringBitmap result = new MutableRoaringBitmap();
@@ -635,4 +647,3 @@ protected ImmutableRoaringBitmap batchIn(int[] batch, Set values) {
     return result;
   }
 }
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java
index 9a03fff53..21849d852 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/ImmutableBitSliceIndex.java
@@ -28,16 +28,15 @@ public class ImmutableBitSliceIndex extends BitSliceIndexBase implements BitmapS
    * @param maxValue
    * @param minValue
    */
-
-  public ImmutableBitSliceIndex(int maxValue, int minValue, ImmutableRoaringBitmap[] bA, ImmutableRoaringBitmap ebM) {
+  public ImmutableBitSliceIndex(
+      int maxValue, int minValue, ImmutableRoaringBitmap[] bA, ImmutableRoaringBitmap ebM) {
     this.maxValue = maxValue;
     this.minValue = minValue;
     this.bA = bA;
     this.ebM = ebM;
   }
 
-  public ImmutableBitSliceIndex() {
-  }
+  public ImmutableBitSliceIndex() {}
 
   /**
    * constructs a BSI from byteBuffer
@@ -70,12 +69,10 @@ public ImmutableBitSliceIndex(ByteBuffer buffer) throws IOException {
     this.bA = ba;
   }
 
-
   public void addDigit(ImmutableRoaringBitmap foundSet, int i) {
     throw new UnsupportedOperationException("ImmutableBSI don't support setValue");
   }
 
-
   public ImmutableRoaringBitmap getExistenceBitmap() {
     return this.ebM;
   }
@@ -84,10 +81,9 @@ public void setValue(int cid, int value) {
     throw new UnsupportedOperationException("ImmutableBSI don't support setValue");
   }
 
-
   @Override
-  public void setValues(List> values,
-      Integer currentMaxValue, Integer currentMinValue) {
+  public void setValues(
+      List> values, Integer currentMaxValue, Integer currentMinValue) {
     throw new UnsupportedOperationException("ImmutableBSI don't support setValues");
   }
 
@@ -96,7 +92,6 @@ public void setValues(List> values) {
     throw new UnsupportedOperationException("ImmutableBSI does not support setting values");
   }
 
-
   public void add(BitmapSliceIndex otherBitmapSliceIndex) {
     throw new UnsupportedOperationException("ImmutableBSI don't support add");
   }
@@ -141,7 +136,6 @@ public void serialize(DataOutput output) throws IOException {
     }
   }
 
-
   public int serializedSizeInBytes() {
     int size = 0;
     for (ImmutableRoaringBitmap rb : this.bA) {
@@ -150,15 +144,15 @@ public int serializedSizeInBytes() {
     return 4 + 4 + 1 + 4 + this.ebM.serializedSizeInBytes() + size;
   }
 
-
   public MutableBitSliceIndex toMutableBitSliceIndex() {
     MutableRoaringBitmap[] ibA = new MutableRoaringBitmap[this.bA.length];
     for (int i = 0; i < this.bA.length; i++) {
       ibA[i] = this.bA[i].toMutableRoaringBitmap();
     }
 
-    MutableBitSliceIndex bsi = new MutableBitSliceIndex(
-        this.maxValue, this.minValue, ibA, this.ebM.toMutableRoaringBitmap());
+    MutableBitSliceIndex bsi =
+        new MutableBitSliceIndex(
+            this.maxValue, this.minValue, ibA, this.ebM.toMutableRoaringBitmap());
     return bsi;
   }
 
@@ -175,7 +169,4 @@ public ImmutableBitSliceIndex clone() {
 
     return bsi;
   }
-
-
 }
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java
index 6918db24a..a3940b2fc 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/buffer/MutableBitSliceIndex.java
@@ -1,17 +1,17 @@
 package org.roaringbitmap.bsi.buffer;
 
-import java.util.Objects;
-import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.bsi.BitmapSliceIndex;
 import org.roaringbitmap.bsi.Pair;
 import org.roaringbitmap.bsi.WritableUtils;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.List;
+import java.util.Objects;
 import java.util.OptionalInt;
 
 /**
@@ -29,15 +29,14 @@ public class MutableBitSliceIndex extends BitSliceIndexBase implements BitmapSli
    * @param bA  bit slices for this bsi.using MutableRoaringBitmap array express
    * @param ebM exits value bitmap,use MutableRoaringBitmap express
    */
-  public MutableBitSliceIndex(int maxValue, int minValue,
-      MutableRoaringBitmap[] bA, MutableRoaringBitmap ebM) {
+  public MutableBitSliceIndex(
+      int maxValue, int minValue, MutableRoaringBitmap[] bA, MutableRoaringBitmap ebM) {
     this.maxValue = maxValue;
     this.minValue = minValue;
     this.bA = bA;
     this.ebM = ebM;
   }
 
-
   /**
    * construct a new MutableBitSliceIndex.
    * Min/Max values are optional.  If set to 0 then the underlying BSI will be automatically sized.
@@ -101,7 +100,6 @@ private void grow(int newBitDepth) {
     this.bA = newBA;
   }
 
-
   /**
    * RunOptimize attempts to further compress the runs of consecutive values found in the bitmap
    */
@@ -160,13 +158,16 @@ private void setValueInternal(int columnId, int value) {
     this.getExistenceBitmap().add(columnId);
   }
 
-
-  public void setValues(List> values,
-      Integer currentMaxValue, Integer currentMinValue) {
-    OptionalInt maxValue = currentMaxValue != null
-        ? OptionalInt.of(currentMaxValue) : values.stream().mapToInt(Pair::getRight).max();
-    OptionalInt minValue = currentMinValue != null
-        ? OptionalInt.of(currentMinValue) : values.stream().mapToInt(Pair::getRight).min();
+  public void setValues(
+      List> values, Integer currentMaxValue, Integer currentMinValue) {
+    OptionalInt maxValue =
+        currentMaxValue != null
+            ? OptionalInt.of(currentMaxValue)
+            : values.stream().mapToInt(Pair::getRight).max();
+    OptionalInt minValue =
+        currentMinValue != null
+            ? OptionalInt.of(currentMinValue)
+            : values.stream().mapToInt(Pair::getRight).min();
 
     if (!maxValue.isPresent() || !minValue.isPresent()) {
       throw new IllegalArgumentException("wrong input values list");
@@ -176,7 +177,6 @@ public void setValues(List> values,
     for (Pair pair : values) {
       this.setValue(pair.getKey(), pair.getValue());
     }
-
   }
 
   /**
@@ -186,8 +186,10 @@ public void setValues(List> values,
    */
   @Override
   public void setValues(List> values) {
-    int maxValue = values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).max().getAsInt();
-    int minValue = values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).min().getAsInt();
+    int maxValue =
+        values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).max().getAsInt();
+    int minValue =
+        values.stream().mapToInt(Pair::getRight).filter(Objects::nonNull).min().getAsInt();
     ensureCapacityInternal(minValue, maxValue);
     for (Pair pair : values) {
       setValueInternal(pair.getKey(), pair.getValue());
@@ -281,10 +283,10 @@ public void merge(MutableBitSliceIndex otherBsi) {
     int bitDepth = Integer.max(this.bitCount(), otherBsi.bitCount());
     MutableRoaringBitmap[] newBA = new MutableRoaringBitmap[bitDepth];
     for (int i = 0; i < bitDepth; i++) {
-      MutableRoaringBitmap current = i < this.bA.length
-          ? this.getMutableSlice(i) : new MutableRoaringBitmap();
-      MutableRoaringBitmap other = i < otherBsi.bA.length
-          ? otherBsi.getMutableSlice(i) : new MutableRoaringBitmap();
+      MutableRoaringBitmap current =
+          i < this.bA.length ? this.getMutableSlice(i) : new MutableRoaringBitmap();
+      MutableRoaringBitmap other =
+          i < otherBsi.bA.length ? otherBsi.getMutableSlice(i) : new MutableRoaringBitmap();
       newBA[i] = MutableRoaringBitmap.or(current, other);
       if (this.runOptimized || otherBsi.runOptimized) {
         newBA[i].runOptimize();
@@ -310,7 +312,6 @@ public MutableBitSliceIndex clone() {
     bitSliceIndex.runOptimized = this.runOptimized;
 
     return bitSliceIndex;
-
   }
 
   public void serialize(ByteBuffer buffer) {
@@ -351,7 +352,6 @@ private void clear() {
     this.bA = null;
   }
 
-
   public void deserialize(ByteBuffer buffer) throws IOException {
     this.clear();
     // read meta
@@ -406,7 +406,7 @@ public int serializedSizeInBytes() {
       size += rb.serializedSizeInBytes();
     }
     return 4 + 4 + 1 + 4 + this.ebM.serializedSizeInBytes() + size;
-   }
+  }
 
   public ImmutableBitSliceIndex toImmutableBitSliceIndex() {
     ImmutableRoaringBitmap[] ibA = new ImmutableRoaringBitmap[this.bA.length];
@@ -414,9 +414,8 @@ public ImmutableBitSliceIndex toImmutableBitSliceIndex() {
       ibA[i] = this.bA[i];
     }
 
-    ImmutableBitSliceIndex bsi = new ImmutableBitSliceIndex(
-        this.maxValue, this.minValue, ibA, this.ebM);
+    ImmutableBitSliceIndex bsi =
+        new ImmutableBitSliceIndex(this.maxValue, this.minValue, ibA, this.ebM);
     return bsi;
   }
 }
-
diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
index a54db4b95..5b573e837 100644
--- a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
+++ b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64BitmapSliceIndex.java
@@ -34,7 +34,6 @@ public class Roaring64BitmapSliceIndex {
    */
   private Roaring64Bitmap ebM;
 
-
   private Boolean runOptimized = false;
 
   /**
@@ -89,7 +88,6 @@ private void addDigit(Roaring64Bitmap foundSet, int i) {
       }
       this.addDigit(carry, i + 1);
     }
-
   }
 
   private long minValue() {
@@ -150,7 +148,6 @@ public void runOptimize() {
   /**
    * hasRunCompression returns true if the bitmap benefits from run compression
    */
-
   public boolean hasRunCompression() {
     return this.runOptimized;
   }
@@ -158,7 +155,6 @@ public boolean hasRunCompression() {
   /**
    * GetExistenceBitmap returns a pointer to the underlying existence bitmap of the BSI
    */
-
   public Roaring64Bitmap getExistenceBitmap() {
     return this.ebM;
   }
@@ -183,7 +179,6 @@ public Pair getValue(long columnId) {
     return Pair.newPair(valueAt(columnId), true);
   }
 
-
   private void clear() {
     this.maxValue = 0;
     this.minValue = 0;
@@ -339,8 +334,10 @@ private void grow(int newBitDepth) {
   }
 
   public void setValues(List> values) {
-    long maxValue = values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).max().getAsLong();
-    long minValue = values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).min().getAsLong();
+    long maxValue =
+        values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).max().getAsLong();
+    long minValue =
+        values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).min().getAsLong();
     ensureCapacityInternal(minValue, maxValue);
     for (Pair pair : values) {
       setValueInternal(pair.getKey(), pair.getValue());
@@ -407,14 +404,14 @@ public Roaring64BitmapSliceIndex clone() {
    * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
    * see https://github.com/lemire/BitSliceIndex/blob/master/src/main/java/org/roaringbitmap/circuits/comparator/BasicComparator.java
    */
-  private Roaring64Bitmap oNeilCompare(BitmapSliceIndex.Operation operation, long predicate, Roaring64Bitmap foundSet) {
+  private Roaring64Bitmap oNeilCompare(
+      BitmapSliceIndex.Operation operation, long predicate, Roaring64Bitmap foundSet) {
     Roaring64Bitmap fixedFoundSet = foundSet == null ? this.ebM : foundSet;
 
     Roaring64Bitmap GT = new Roaring64Bitmap();
     Roaring64Bitmap LT = new Roaring64Bitmap();
     Roaring64Bitmap EQ = this.ebM;
 
-
     for (int i = this.bitCount() - 1; i >= 0; i--) {
       int bit = (int) ((predicate >> i) & 1);
       if (bit == 1) {
@@ -424,7 +421,6 @@ private Roaring64Bitmap oNeilCompare(BitmapSliceIndex.Operation operation, long
         GT = Roaring64Bitmap.or(GT, Roaring64Bitmap.and(EQ, this.bA[i]));
         EQ = Roaring64Bitmap.andNot(EQ, this.bA[i]);
       }
-
     }
     EQ = Roaring64Bitmap.and(fixedFoundSet, EQ);
     switch (operation) {
@@ -457,7 +453,8 @@ private Roaring64Bitmap oNeilCompare(BitmapSliceIndex.Operation operation, long
    * @param foundSet     columnId set we want compare,using RoaringBitmap to express
    * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express
    */
-  public Roaring64Bitmap compare(BitmapSliceIndex.Operation operation, long startOrValue, long end, Roaring64Bitmap foundSet) {
+  public Roaring64Bitmap compare(
+      BitmapSliceIndex.Operation operation, long startOrValue, long end, Roaring64Bitmap foundSet) {
     Roaring64Bitmap result = compareUsingMinMax(operation, startOrValue, end, foundSet);
     if (result != null) {
       return result;
@@ -470,33 +467,37 @@ public Roaring64Bitmap compare(BitmapSliceIndex.Operation operation, long startO
         return oNeilCompare(BitmapSliceIndex.Operation.NEQ, startOrValue, foundSet);
       case GE:
         return oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet);
-      case GT: {
-        return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
-      }
+      case GT:
+        {
+          return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet);
+        }
       case LT:
         return oNeilCompare(BitmapSliceIndex.Operation.LT, startOrValue, foundSet);
 
       case LE:
         return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet);
 
-      case RANGE: {
-        if (startOrValue < minValue) {
-          startOrValue = minValue;
-        }
-        if (end > maxValue) {
-          end = maxValue;
+      case RANGE:
+        {
+          if (startOrValue < minValue) {
+            startOrValue = minValue;
+          }
+          if (end > maxValue) {
+            end = maxValue;
+          }
+          Roaring64Bitmap left =
+              oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet);
+          Roaring64Bitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
+
+          return Roaring64Bitmap.and(left, right);
         }
-        Roaring64Bitmap left = oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet);
-        Roaring64Bitmap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet);
-
-        return Roaring64Bitmap.and(left, right);
-      }
       default:
         throw new IllegalArgumentException("not support operation!");
     }
   }
 
-  private Roaring64Bitmap compareUsingMinMax(BitmapSliceIndex.Operation operation, long startOrValue, long end, Roaring64Bitmap foundSet) {
+  private Roaring64Bitmap compareUsingMinMax(
+      BitmapSliceIndex.Operation operation, long startOrValue, long end, Roaring64Bitmap foundSet) {
     Roaring64Bitmap all = foundSet == null ? ebM.clone() : Roaring64Bitmap.and(ebM, foundSet);
     Roaring64Bitmap empty = new Roaring64Bitmap();
 
@@ -568,9 +569,10 @@ public Pair sum(Roaring64Bitmap foundSet) {
     }
     long count = foundSet.getLongCardinality();
 
-    Long sum = IntStream.range(0, this.bitCount())
-        .mapToLong(x -> (1L << x) * Roaring64Bitmap.andCardinality(this.bA[x], foundSet))
-        .sum();
+    Long sum =
+        IntStream.range(0, this.bitCount())
+            .mapToLong(x -> (1L << x) * Roaring64Bitmap.andCardinality(this.bA[x], foundSet))
+            .sum();
 
     return Pair.newPair(sum, count);
   }
@@ -601,22 +603,25 @@ public Roaring64Bitmap topK(Roaring64Bitmap foundSet, long k) {
 
   public Roaring64Bitmap transpose(Roaring64Bitmap foundSet) {
     Roaring64Bitmap re = new Roaring64Bitmap();
-    Roaring64Bitmap fixedFoundSet = foundSet == null ? this.ebM : Roaring64Bitmap.and(foundSet, this.ebM);
+    Roaring64Bitmap fixedFoundSet =
+        foundSet == null ? this.ebM : Roaring64Bitmap.and(foundSet, this.ebM);
     fixedFoundSet.forEach((long x) -> re.add(this.getValue(x).getKey()));
     return re;
   }
 
   public Roaring64BitmapSliceIndex transposeWithCount(Roaring64Bitmap foundSet) {
     Roaring64BitmapSliceIndex re = new Roaring64BitmapSliceIndex();
-    Roaring64Bitmap fixedFoundSet = foundSet == null ? this.ebM : Roaring64Bitmap.and(foundSet, this.ebM);
-    fixedFoundSet.forEach((long x) -> {
-      long nk = this.getValue(x).getKey();
-      if (re.valueExist(nk)) {
-        re.setValue(nk, re.getValue(nk).getKey() + 1);
-      } else {
-        re.setValue(nk, 1);
-      }
-    });
+    Roaring64Bitmap fixedFoundSet =
+        foundSet == null ? this.ebM : Roaring64Bitmap.and(foundSet, this.ebM);
+    fixedFoundSet.forEach(
+        (long x) -> {
+          long nk = this.getValue(x).getKey();
+          if (re.valueExist(nk)) {
+            re.setValue(nk, re.getValue(nk).getKey() + 1);
+          } else {
+            re.setValue(nk, 1);
+          }
+        });
     return re;
   }
 }
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java
index 02e794927..ac795f28c 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/BufferBSITest.java
@@ -1,20 +1,25 @@
- package org.roaringbitmap.bsi;
+package org.roaringbitmap.bsi;
 
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import org.roaringbitmap.IntIterator;
-import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.bsi.buffer.ImmutableBitSliceIndex;
 import org.roaringbitmap.bsi.buffer.MutableBitSliceIndex;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
-import java.io.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -27,404 +32,408 @@
  */
 public class BufferBSITest {
 
-    private Map testDataSet = new HashMap<>();
-
-    private MutableBitSliceIndex mBsi;
-
-    private ImmutableBitSliceIndex imBsi;
-
-
-    @BeforeEach
-    public void setup() {
-        IntStream.range(1, 100).forEach(x -> testDataSet.put(x, x));
-        mBsi = new MutableBitSliceIndex(1, 99);
-        testDataSet.forEach((k, v) -> {
-            mBsi.setValue(k, v);
-        });
-        imBsi = mBsi.toImmutableBitSliceIndex();
-    }
-
-    @Test
-    public void testSetAndGet() {
-        IntStream.range(1, 100).forEach(x -> {
-            Pair pair = mBsi.getValue(x);
-            Assertions.assertTrue(pair.getRight());
-            Assertions.assertTrue(pair.getKey() == x);
-        });
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair pair = imBsi.getValue(x);
-            Assertions.assertTrue(pair.getRight());
-            Assertions.assertTrue(pair.getKey() == x);
-        });
-    }
-
-    @Test
-    public void testMerge() {
-        MutableBitSliceIndex bsiA = new MutableBitSliceIndex();
-        IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
-        MutableBitSliceIndex bsiB = new MutableBitSliceIndex();
-        IntStream.range(100, 199).forEach(x -> bsiB.setValue(x, x));
-        Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99);
-        Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99);
-        bsiA.merge(bsiB);
-        IntStream.range(1, 199).forEach(x -> {
-            Pair bsiValue = bsiA.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
-
+  private Map testDataSet = new HashMap<>();
 
-    @Test
-    public void testClone() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        List> collect = testDataSet.entrySet()
-                .stream().map(x -> Pair.newPair(x.getKey(), x.getValue())).collect(Collectors.toList());
+  private MutableBitSliceIndex mBsi;
 
-        bsi.setValues(collect);
+  private ImmutableBitSliceIndex imBsi;
 
-        Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99);
-        final MutableBitSliceIndex clone = bsi.clone();
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = clone.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
+  @BeforeEach
+  public void setup() {
+    IntStream.range(1, 100).forEach(x -> testDataSet.put(x, x));
+    mBsi = new MutableBitSliceIndex(1, 99);
+    testDataSet.forEach(
+        (k, v) -> {
+          mBsi.setValue(k, v);
         });
-    }
-
-
-    @Test
-    public void testAdd() {
-        MutableBitSliceIndex bsiA = new MutableBitSliceIndex();
-        IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
-        MutableBitSliceIndex bsiB = new MutableBitSliceIndex();
-        IntStream.range(1, 120).forEach(x -> bsiB.setValue(x, x));
-
-        bsiA.add(bsiB);
-
-        IntStream.range(1, 120).forEach(x -> {
-            Pair bsiValue = bsiA.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            if (x < 100) {
+    imBsi = mBsi.toImmutableBitSliceIndex();
+  }
+
+  @Test
+  public void testSetAndGet() {
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair pair = mBsi.getValue(x);
+              Assertions.assertTrue(pair.getRight());
+              Assertions.assertTrue(pair.getKey() == x);
+            });
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair pair = imBsi.getValue(x);
+              Assertions.assertTrue(pair.getRight());
+              Assertions.assertTrue(pair.getKey() == x);
+            });
+  }
+
+  @Test
+  public void testMerge() {
+    MutableBitSliceIndex bsiA = new MutableBitSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    MutableBitSliceIndex bsiB = new MutableBitSliceIndex();
+    IntStream.range(100, 199).forEach(x -> bsiB.setValue(x, x));
+    Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99);
+    Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99);
+    bsiA.merge(bsiB);
+    IntStream.range(1, 199)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsiA.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
+
+  @Test
+  public void testClone() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    List> collect =
+        testDataSet.entrySet().stream()
+            .map(x -> Pair.newPair(x.getKey(), x.getValue()))
+            .collect(Collectors.toList());
+
+    bsi.setValues(collect);
+
+    Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99);
+    final MutableBitSliceIndex clone = bsi.clone();
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = clone.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
+
+  @Test
+  public void testAdd() {
+    MutableBitSliceIndex bsiA = new MutableBitSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    MutableBitSliceIndex bsiB = new MutableBitSliceIndex();
+    IntStream.range(1, 120).forEach(x -> bsiB.setValue(x, x));
+
+    bsiA.add(bsiB);
+
+    IntStream.range(1, 120)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsiA.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              if (x < 100) {
                 Assertions.assertEquals((int) bsiValue.getKey(), x * 2);
-            } else {
+              } else {
                 Assertions.assertEquals((int) bsiValue.getKey(), x);
-            }
-
-        });
-    }
-
-    @Test
-    public void testAddAndEvaluate() {
-        MutableBitSliceIndex bsiA = new MutableBitSliceIndex();
-        IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
-        MutableBitSliceIndex bsiB = new MutableBitSliceIndex();
-        IntStream.range(1, 120).forEach(x -> bsiB.setValue(120 - x, x));
-
-        bsiA.add(bsiB);
-
-        ImmutableRoaringBitmap result = bsiA.compare(BitmapSliceIndex.Operation.EQ, 120, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(result.toArray(), IntStream.range(1, 100).toArray());
-
-        result = bsiA.compare(BitmapSliceIndex.Operation.RANGE, 1, 20, null);
-        Assertions.assertTrue(result.getLongCardinality() == 20);
-        Assertions.assertArrayEquals(result.toArray(), IntStream.range(100, 120).toArray());
-    }
-
-
-    @Test
-    public void TestIO4Stream() throws IOException {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        DataOutputStream bdo = new DataOutputStream(bos);
-        bsi.serialize(bdo);
-        byte[] data = bos.toByteArray();
-
-        MutableBitSliceIndex newBsi = new MutableBitSliceIndex();
-
-        ByteArrayInputStream bis = new ByteArrayInputStream(data);
-        DataInputStream bdi = new DataInputStream(bis);
-        newBsi.deserialize(bdi);
-
-        Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = newBsi.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
-
-    @Test
-    public void testIO4Buffer() throws IOException {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-        ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
-        bsi.serialize(buffer);
-
-        byte[] data = buffer.array();
-        MutableBitSliceIndex newBsi = new MutableBitSliceIndex();
-        newBsi.deserialize(ByteBuffer.wrap(data));
-        Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = newBsi.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
-
-
-    @Test
-    public void testIOFromExternal() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-
-
-        ImmutableBitSliceIndex iBsi = bsi.toImmutableBitSliceIndex();
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = iBsi.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
-
-    // non parallel operation test
-    @Test
-    public void testSum() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-
-
-        ImmutableBitSliceIndex iBsi = bsi.toImmutableBitSliceIndex();
-
-        MutableRoaringBitmap foundSet = MutableRoaringBitmap.bitmapOf(IntStream.range(1, 51).toArray());
-
-        Pair sumPair = iBsi.sum(foundSet);
-
-        System.out.println("sum:" + sumPair.toString());
-
-        int sum = IntStream.range(1, 51).sum();
-        long count = IntStream.range(1, 51).count();
-
-        Assertions.assertTrue(sumPair.getLeft().intValue() == sum && sumPair.getRight() == count);
-
-    }
-
-    @Test
-    public void testEQ() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> {
-            if (x <= 50) {
+              }
+            });
+  }
+
+  @Test
+  public void testAddAndEvaluate() {
+    MutableBitSliceIndex bsiA = new MutableBitSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    MutableBitSliceIndex bsiB = new MutableBitSliceIndex();
+    IntStream.range(1, 120).forEach(x -> bsiB.setValue(120 - x, x));
+
+    bsiA.add(bsiB);
+
+    ImmutableRoaringBitmap result = bsiA.compare(BitmapSliceIndex.Operation.EQ, 120, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(result.toArray(), IntStream.range(1, 100).toArray());
+
+    result = bsiA.compare(BitmapSliceIndex.Operation.RANGE, 1, 20, null);
+    Assertions.assertTrue(result.getLongCardinality() == 20);
+    Assertions.assertArrayEquals(result.toArray(), IntStream.range(100, 120).toArray());
+  }
+
+  @Test
+  public void TestIO4Stream() throws IOException {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    DataOutputStream bdo = new DataOutputStream(bos);
+    bsi.serialize(bdo);
+    byte[] data = bos.toByteArray();
+
+    MutableBitSliceIndex newBsi = new MutableBitSliceIndex();
+
+    ByteArrayInputStream bis = new ByteArrayInputStream(data);
+    DataInputStream bdi = new DataInputStream(bis);
+    newBsi.deserialize(bdi);
+
+    Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = newBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
+
+  @Test
+  public void testIO4Buffer() throws IOException {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
+    bsi.serialize(buffer);
+
+    byte[] data = buffer.array();
+    MutableBitSliceIndex newBsi = new MutableBitSliceIndex();
+    newBsi.deserialize(ByteBuffer.wrap(data));
+    Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = newBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
+
+  @Test
+  public void testIOFromExternal() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+
+    ImmutableBitSliceIndex iBsi = bsi.toImmutableBitSliceIndex();
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = iBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
+
+  // non parallel operation test
+  @Test
+  public void testSum() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+
+    ImmutableBitSliceIndex iBsi = bsi.toImmutableBitSliceIndex();
+
+    MutableRoaringBitmap foundSet = MutableRoaringBitmap.bitmapOf(IntStream.range(1, 51).toArray());
+
+    Pair sumPair = iBsi.sum(foundSet);
+
+    System.out.println("sum:" + sumPair.toString());
+
+    int sum = IntStream.range(1, 51).sum();
+    long count = IntStream.range(1, 51).count();
+
+    Assertions.assertTrue(sumPair.getLeft().intValue() == sum && sumPair.getRight() == count);
+  }
+
+  @Test
+  public void testEQ() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              if (x <= 50) {
                 bsi.setValue(x, 1);
-            } else {
+              } else {
                 bsi.setValue(x, x);
-            }
-
-        });
-
-        ImmutableRoaringBitmap bitmap = bsi.toImmutableBitSliceIndex().rangeEQ(null, 1);
-        Assertions.assertTrue(bitmap.getLongCardinality() == 50L);
-        ImmutableRoaringBitmap bitmap129 = bsi.toImmutableBitSliceIndex().rangeEQ(null, 129);
-        Assertions.assertTrue(bitmap129.getLongCardinality() == 0L);
-
-        ImmutableRoaringBitmap bitmap99 = bsi.toImmutableBitSliceIndex().rangeEQ(null, 99);
-        Assertions.assertTrue(bitmap99.getLongCardinality() == 1L);
-        Assertions.assertTrue(bitmap99.contains(99));
-    }
-
-    @Test
-    public void testNotEQ() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex();
-        bsi.setValue(1, 99);
-        bsi.setValue(2, 1);
-        bsi.setValue(3, 50);
-
-        ImmutableRoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 2);
-        Assertions.assertArrayEquals(new int[]{2, 3}, result.toArray());
-
-        result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(new int[]{1, 2, 3}, result.toArray());
-
-        bsi = new MutableBitSliceIndex();
-        bsi.setValue(1, 99);
-        bsi.setValue(2, 99);
-        bsi.setValue(3, 99);
-
-        result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-
-        result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(new int[]{1, 2, 3}, result.toArray());
-    }
-
-
-    // parallel operation test
-
-    @Test
-    public void testGT()  {
-        ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.GT, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 49);
-        Assertions.assertArrayEquals(IntStream.range(51, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.GT, 0, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.GT, 99, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
-
-
-    @Test
-    public void testGE()  {
-        ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 50);
-        Assertions.assertArrayEquals(IntStream.range(50, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.GE, 1, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
-
-    @Test
-    public void testLT()  {
-        ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.LT, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 49);
-        Assertions.assertArrayEquals(IntStream.range(1, 50).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.LT, Integer.MAX_VALUE, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.LT, 1, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
-
-
-    @Test
-    public void testLE()  {
-        ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 50);
-        Assertions.assertArrayEquals(IntStream.range(1, 51).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
-
-    @Test
-    public void testRANGE()  {
-        ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.RANGE, 10, 20, null);
-        Assertions.assertTrue(result.getLongCardinality() == 11);
-        Assertions.assertArrayEquals(IntStream.range(10, 21).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.RANGE, 1, 200, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
-
-        result = imBsi.compare(BitmapSliceIndex.Operation.RANGE, 1000, 2000, null);
-        Assertions.assertTrue(result.isEmpty());
+              }
+            });
+
+    ImmutableRoaringBitmap bitmap = bsi.toImmutableBitSliceIndex().rangeEQ(null, 1);
+    Assertions.assertTrue(bitmap.getLongCardinality() == 50L);
+    ImmutableRoaringBitmap bitmap129 = bsi.toImmutableBitSliceIndex().rangeEQ(null, 129);
+    Assertions.assertTrue(bitmap129.getLongCardinality() == 0L);
+
+    ImmutableRoaringBitmap bitmap99 = bsi.toImmutableBitSliceIndex().rangeEQ(null, 99);
+    Assertions.assertTrue(bitmap99.getLongCardinality() == 1L);
+    Assertions.assertTrue(bitmap99.contains(99));
+  }
+
+  @Test
+  public void testNotEQ() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex();
+    bsi.setValue(1, 99);
+    bsi.setValue(2, 1);
+    bsi.setValue(3, 50);
+
+    ImmutableRoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 2);
+    Assertions.assertArrayEquals(new int[] {2, 3}, result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(new int[] {1, 2, 3}, result.toArray());
+
+    bsi = new MutableBitSliceIndex();
+    bsi.setValue(1, 99);
+    bsi.setValue(2, 99);
+    bsi.setValue(3, 99);
+
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(new int[] {1, 2, 3}, result.toArray());
+  }
+
+  // parallel operation test
+
+  @Test
+  public void testGT() {
+    ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.GT, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 49);
+    Assertions.assertArrayEquals(IntStream.range(51, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.GT, 0, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.GT, 99, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testGE() {
+    ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 50);
+    Assertions.assertArrayEquals(IntStream.range(50, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.GE, 1, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testLT() {
+    ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.LT, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 49);
+    Assertions.assertArrayEquals(IntStream.range(1, 50).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.LT, Integer.MAX_VALUE, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.LT, 1, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testLE() {
+    ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 50);
+    Assertions.assertArrayEquals(IntStream.range(1, 51).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testRANGE() {
+    ImmutableRoaringBitmap result = imBsi.compare(BitmapSliceIndex.Operation.RANGE, 10, 20, null);
+    Assertions.assertTrue(result.getLongCardinality() == 11);
+    Assertions.assertArrayEquals(IntStream.range(10, 21).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.RANGE, 1, 200, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+
+    result = imBsi.compare(BitmapSliceIndex.Operation.RANGE, 1000, 2000, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
+
+  @Test
+  public void testValueZero() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex();
+    bsi.setValue(0, 0);
+    bsi.setValue(1, 0);
+    bsi.setValue(2, 1);
+
+    ImmutableRoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 2);
+    Assertions.assertArrayEquals(new int[] {0, 1}, result.toArray());
+
+    result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 1);
+    Assertions.assertArrayEquals(new int[] {2}, result.toArray());
+  }
+
+  @Test
+  public void testIN() throws ExecutionException, InterruptedException {
+
+    Set values = new HashSet<>();
+    int[] valArr = new int[20];
+    for (int i = 0; i < 20; i++) {
+      values.add(i + 1);
+      valArr[i] = i + 1;
     }
 
-    @Test
-    public void testValueZero() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex();
-        bsi.setValue(0, 0);
-        bsi.setValue(1, 0);
-        bsi.setValue(2, 1);
-
-        ImmutableRoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 2);
-        Assertions.assertArrayEquals(new int[]{0, 1}, result.toArray());
-
-        result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 1);
-        Assertions.assertArrayEquals(new int[]{2}, result.toArray());
-    }
-
-    @Test
-    public void testIN() throws ExecutionException, InterruptedException {
-
-        Set values = new HashSet<>();
-        int[] valArr = new int[20];
-        for (int i = 0; i < 20; i++) {
-            values.add(i + 1);
-            valArr[i] = i + 1;
-        }
-
-
-        ExecutorService pool = Executors.newFixedThreadPool(2);
-        ImmutableRoaringBitmap result = imBsi.parallelIn(2,
-                null, values, pool);
-        Assertions.assertTrue(result.getLongCardinality() == values.size());
-        Assertions.assertArrayEquals(valArr, result.toArray());
-        pool.shutdownNow();
-    }
-
-
-    @Test
-    public void testTransposeWithCount() throws ExecutionException, InterruptedException {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> {
-            if (x <= 30) {
+    ExecutorService pool = Executors.newFixedThreadPool(2);
+    ImmutableRoaringBitmap result = imBsi.parallelIn(2, null, values, pool);
+    Assertions.assertTrue(result.getLongCardinality() == values.size());
+    Assertions.assertArrayEquals(valArr, result.toArray());
+    pool.shutdownNow();
+  }
+
+  @Test
+  public void testTransposeWithCount() throws ExecutionException, InterruptedException {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 99);
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              if (x <= 30) {
                 bsi.setValue(x, 1);
-            } else if (x <= 60) {
+              } else if (x <= 60) {
                 bsi.setValue(x, 2);
-            } else {
+              } else {
                 bsi.setValue(x, 3);
-            }
-
-        });
-
-        ExecutorService pool = Executors.newFixedThreadPool(2);
-        ImmutableBitSliceIndex iBsi = bsi.toImmutableBitSliceIndex();
-
-        final MutableBitSliceIndex result = iBsi.parallelTransposeWithCount(null, 2, pool);
-
-        List> pairs = result.toPairList();
-        pairs.forEach(System.out::println);
-
-        Assertions.assertEquals(30, (int) result.getValue(1).getKey());
-        Assertions.assertEquals(30, (int) result.getValue(2).getKey());
-        Assertions.assertEquals(39, (int) result.getValue(3).getKey());
-    }
-
-    @Test
-    public void testTopK() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 100001);
-        IntStream.range(1, 100001).forEach(x -> bsi.setValue(x, x));
-        long start = System.currentTimeMillis();
-        MutableRoaringBitmap top = bsi.topK(null, 20);
-        long end = System.currentTimeMillis();
-        System.out.println(top.toString() + " \ntime cost:" + (end - start));
-    }
-
-    @Test
-    public void testIssue745() {
-        MutableBitSliceIndex bsi = new MutableBitSliceIndex();
-        bsi.setValue(1, 1);
-        bsi.setValue(2, 1);
-        bsi.setValue(3, 1);
-        bsi.setValue(4, 1);
-        bsi.setValue(5, 1);
-        MutableRoaringBitmap top = bsi.topK(null, 1);
-        System.out.println(top);
-    }
-
+              }
+            });
+
+    ExecutorService pool = Executors.newFixedThreadPool(2);
+    ImmutableBitSliceIndex iBsi = bsi.toImmutableBitSliceIndex();
+
+    final MutableBitSliceIndex result = iBsi.parallelTransposeWithCount(null, 2, pool);
+
+    List> pairs = result.toPairList();
+    pairs.forEach(System.out::println);
+
+    Assertions.assertEquals(30, (int) result.getValue(1).getKey());
+    Assertions.assertEquals(30, (int) result.getValue(2).getKey());
+    Assertions.assertEquals(39, (int) result.getValue(3).getKey());
+  }
+
+  @Test
+  public void testTopK() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex(1, 100001);
+    IntStream.range(1, 100001).forEach(x -> bsi.setValue(x, x));
+    long start = System.currentTimeMillis();
+    MutableRoaringBitmap top = bsi.topK(null, 20);
+    long end = System.currentTimeMillis();
+    System.out.println(top.toString() + " \ntime cost:" + (end - start));
+  }
+
+  @Test
+  public void testIssue745() {
+    MutableBitSliceIndex bsi = new MutableBitSliceIndex();
+    bsi.setValue(1, 1);
+    bsi.setValue(2, 1);
+    bsi.setValue(3, 1);
+    bsi.setValue(4, 1);
+    bsi.setValue(5, 1);
+    MutableRoaringBitmap top = bsi.topK(null, 1);
+    System.out.println(top);
+  }
 }
-
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
index 44164dce1..b119e5a52 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/R64BSITest.java
@@ -1,10 +1,17 @@
 package org.roaringbitmap.bsi;
 
-import org.junit.jupiter.api.*;
 import org.roaringbitmap.bsi.longlong.Roaring64BitmapSliceIndex;
 import org.roaringbitmap.longlong.Roaring64Bitmap;
 
-import java.io.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.List;
@@ -22,24 +29,29 @@ public class R64BSITest {
   public void setup() {
     LongStream.range(1, 100).forEach(x -> testDataSet.put(x, x));
     bsi = new Roaring64BitmapSliceIndex(1, 99);
-    testDataSet.forEach((k, v) -> {
-      bsi.setValue(k, v);
-    });
+    testDataSet.forEach(
+        (k, v) -> {
+          bsi.setValue(k, v);
+        });
   }
 
   @Test
   public void testSetAndGet() {
-    LongStream.range(1, 100).forEach(x -> {
-      Pair pair = bsi.getValue(x);
-      Assertions.assertTrue(pair.getRight());
-      Assertions.assertEquals((long) pair.getKey(), x);
-    });
-
-    IntStream.range(1, 100).forEach(x -> {
-      Pair pair = bsi.getValue(x);
-      Assertions.assertTrue(pair.getRight());
-      Assertions.assertEquals((long) pair.getKey(), x);
-    });
+    LongStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair pair = bsi.getValue(x);
+              Assertions.assertTrue(pair.getRight());
+              Assertions.assertEquals((long) pair.getKey(), x);
+            });
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair pair = bsi.getValue(x);
+              Assertions.assertTrue(pair.getRight());
+              Assertions.assertEquals((long) pair.getKey(), x);
+            });
   }
 
   @Test
@@ -51,33 +63,37 @@ public void testMerge() {
     Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99);
     Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99);
     bsiA.merge(bsiB);
-    IntStream.range(1, 199).forEach(x -> {
-      Pair bsiValue = bsiA.getValue(x);
-      Assertions.assertTrue(bsiValue.getRight());
-      Assertions.assertEquals((long) bsiValue.getKey(), x);
-    });
+    IntStream.range(1, 199)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsiA.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((long) bsiValue.getKey(), x);
+            });
   }
 
-
   @Test
   public void testClone() {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
-    List> collect = testDataSet.entrySet()
-        .stream().map(x -> Pair.newPair(x.getKey(), x.getValue())).collect(Collectors.toList());
+    List> collect =
+        testDataSet.entrySet().stream()
+            .map(x -> Pair.newPair(x.getKey(), x.getValue()))
+            .collect(Collectors.toList());
 
     bsi.setValues(collect);
 
     Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99);
     final Roaring64BitmapSliceIndex clone = bsi.clone();
 
-    IntStream.range(1, 100).forEach(x -> {
-      Pair bsiValue = clone.getValue(x);
-      Assertions.assertTrue(bsiValue.getRight());
-      Assertions.assertEquals((long) bsiValue.getKey(), x);
-    });
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = clone.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((long) bsiValue.getKey(), x);
+            });
   }
 
-
   @Test
   public void testAdd() {
     Roaring64BitmapSliceIndex bsiA = new Roaring64BitmapSliceIndex();
@@ -87,16 +103,17 @@ public void testAdd() {
 
     bsiA.add(bsiB);
 
-    LongStream.range(1, 120).forEach(x -> {
-      Pair bsiValue = bsiA.getValue(x);
-      Assertions.assertTrue(bsiValue.getRight());
-      if (x < 100) {
-        Assertions.assertEquals((long) bsiValue.getKey(), x * 2);
-      } else {
-        Assertions.assertEquals((long) bsiValue.getKey(), x);
-      }
-
-    });
+    LongStream.range(1, 120)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsiA.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              if (x < 100) {
+                Assertions.assertEquals((long) bsiValue.getKey(), x * 2);
+              } else {
+                Assertions.assertEquals((long) bsiValue.getKey(), x);
+              }
+            });
   }
 
   @Test
@@ -117,7 +134,6 @@ public void testAddAndEvaluate() {
     Assertions.assertArrayEquals(result.toArray(), LongStream.range(100, 120).toArray());
   }
 
-
   @Test
   public void TestIO4Stream() throws IOException {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
@@ -135,11 +151,13 @@ public void TestIO4Stream() throws IOException {
 
     Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
 
-    LongStream.range(1, 100).forEach(x -> {
-      Pair bsiValue = newBsi.getValue(x);
-      Assertions.assertTrue(bsiValue.getRight());
-      Assertions.assertEquals((long) bsiValue.getKey(), x);
-    });
+    LongStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = newBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((long) bsiValue.getKey(), x);
+            });
   }
 
   @Test
@@ -154,42 +172,44 @@ public void testIO4Buffer() throws IOException {
     newBsi.deserialize(ByteBuffer.wrap(data));
     Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
 
-    LongStream.range(1, 100).forEach(x -> {
-      Pair bsiValue = newBsi.getValue(x);
-      Assertions.assertTrue(bsiValue.getRight());
-      Assertions.assertEquals((long) bsiValue.getKey(), x);
-    });
+    LongStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = newBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((long) bsiValue.getKey(), x);
+            });
   }
 
-
   @Test
   public void testIOFromExternal() {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
     LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
 
-    LongStream.range(1, 100).forEach(x -> {
-      Pair bsiValue = bsi.getValue(x);
-      Assertions.assertTrue(bsiValue.getRight());
-      Assertions.assertEquals((long) bsiValue.getKey(), x);
-    });
+    LongStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((long) bsiValue.getKey(), x);
+            });
   }
 
-
   @Test
   public void testEQ() {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex(1, 99);
-    LongStream.range(1, 100).forEach(x -> {
-      if (x <= 50) {
-        bsi.setValue(x, 1);
-      } else {
-        bsi.setValue(x, x);
-      }
-
-    });
+    LongStream.range(1, 100)
+        .forEach(
+            x -> {
+              if (x <= 50) {
+                bsi.setValue(x, 1);
+              } else {
+                bsi.setValue(x, x);
+              }
+            });
 
     Roaring64Bitmap bitmap = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
     Assertions.assertEquals(50L, bitmap.getLongCardinality());
-
   }
 
   @Test
@@ -201,11 +221,11 @@ public void testNotEQ() {
 
     Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
     Assertions.assertEquals(2, result.getLongCardinality());
-    Assertions.assertArrayEquals(new long[]{2, 3}, result.toArray());
+    Assertions.assertArrayEquals(new long[] {2, 3}, result.toArray());
 
     result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null);
     Assertions.assertEquals(3, result.getLongCardinality());
-    Assertions.assertArrayEquals(new long[]{1, 2, 3}, result.toArray());
+    Assertions.assertArrayEquals(new long[] {1, 2, 3}, result.toArray());
 
     bsi = new Roaring64BitmapSliceIndex();
     bsi.setValue(1, 99);
@@ -217,10 +237,9 @@ public void testNotEQ() {
 
     result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null);
     Assertions.assertEquals(3, result.getLongCardinality());
-    Assertions.assertArrayEquals(new long[]{1, 2, 3}, result.toArray());
+    Assertions.assertArrayEquals(new long[] {1, 2, 3}, result.toArray());
   }
 
-
   // parallel operation test
 
   @Test
@@ -237,7 +256,6 @@ public void testGT() {
     Assertions.assertTrue(result.isEmpty());
   }
 
-
   @Test
   public void testGE() {
     Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null);
@@ -266,7 +284,6 @@ public void testLT() {
     Assertions.assertTrue(result.isEmpty());
   }
 
-
   @Test
   public void testLE() {
     Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null);
@@ -321,11 +338,11 @@ public void testValueZero() {
 
     Roaring64Bitmap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null);
     Assertions.assertEquals(2, result.getLongCardinality());
-    Assertions.assertArrayEquals(new long[]{0, 1}, result.toArray());
+    Assertions.assertArrayEquals(new long[] {0, 1}, result.toArray());
 
     result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
     Assertions.assertEquals(1, result.getLongCardinality());
-    Assertions.assertArrayEquals(new long[]{2}, result.toArray());
+    Assertions.assertArrayEquals(new long[] {2}, result.toArray());
   }
 
   @Test
@@ -367,7 +384,6 @@ public void testTransposeWithCount() {
     Assertions.assertEquals(re.getValue(8).getKey(), 2);
   }
 
-
   @Test
   public void testIssue743() throws IOException {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex();
@@ -389,33 +405,48 @@ public void testIssue743() throws IOException {
   public void testIssue753() throws IOException {
     bsi = new Roaring64BitmapSliceIndex();
     LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getLongCardinality(), 56);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getLongCardinality(), 99);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getLongCardinality(), 99);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getLongCardinality(), 99);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getLongCardinality(), 0);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getLongCardinality(), 0);
-
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getLongCardinality(), 53);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getLongCardinality(), 96);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getLongCardinality(), 96);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getLongCardinality(), 96);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getLongCardinality(), 0);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getLongCardinality(), 0);
-
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getLongCardinality(), 0);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getLongCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getLongCardinality(), 56);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getLongCardinality(), 99);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getLongCardinality(), 99);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getLongCardinality(), 99);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getLongCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getLongCardinality(), 0);
+
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getLongCardinality(), 53);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getLongCardinality(), 96);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getLongCardinality(), 96);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getLongCardinality(), 96);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getLongCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getLongCardinality(), 0);
+
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getLongCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getLongCardinality(), 0);
   }
-  
+
   @Test
   public void testIssue755() throws IOException {
     Roaring64BitmapSliceIndex bsi = new Roaring64BitmapSliceIndex();
     bsi.setValue(100L, 3L);
-    bsi.setValue(1L, (long)Integer.MAX_VALUE * 2 + 23456);
-    bsi.setValue(2L, (long)Integer.MAX_VALUE + 23456);
+    bsi.setValue(1L, (long) Integer.MAX_VALUE * 2 + 23456);
+    bsi.setValue(2L, (long) Integer.MAX_VALUE + 23456);
     Assertions.assertEquals(bsi.getValue(100L).getKey(), 3L); // {{3,true}}
-    Assertions.assertEquals(bsi.getValue(1L).getKey(), (long)Integer.MAX_VALUE * 2 + 23456); // {23455,true}
-    Assertions.assertEquals(bsi.getValue(2L).getKey(), (long)Integer.MAX_VALUE + 23456); // {-2147460193,true}
+    Assertions.assertEquals(
+        bsi.getValue(1L).getKey(), (long) Integer.MAX_VALUE * 2 + 23456); // {23455,true}
+    Assertions.assertEquals(
+        bsi.getValue(2L).getKey(), (long) Integer.MAX_VALUE + 23456); // {-2147460193,true}
   }
 }
-
diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
index 6ae606144..18da0ffd9 100644
--- a/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
+++ b/bsi/src/test/java/org/roaringbitmap/bsi/RBBsiTest.java
@@ -1,9 +1,16 @@
 package org.roaringbitmap.bsi;
 
-import org.junit.jupiter.api.*;
 import org.roaringbitmap.RoaringBitmap;
 
-import java.io.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.List;
@@ -16,345 +23,356 @@
  * created by haihuang@alibaba-inc.com on 2021/6/6
  */
 public class RBBsiTest {
-    private Map testDataSet = new HashMap<>();
-
-    private RoaringBitmapSliceIndex bsi;
-
-    @BeforeEach
-    public void setup() {
-        IntStream.range(1, 100).forEach(x -> testDataSet.put(x, x));
-        bsi = new RoaringBitmapSliceIndex(1, 99);
-        testDataSet.forEach((k, v) -> {
-            bsi.setValue(k, v);
-        });
-    }
-
-    @Test
-    public void testSetAndGet() {
-        IntStream.range(1, 100).forEach(x -> {
-            Pair pair = bsi.getValue(x);
-            Assertions.assertTrue(pair.getRight());
-            Assertions.assertTrue(pair.getKey() == x);
-        });
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair pair = bsi.getValue(x);
-            Assertions.assertTrue(pair.getRight());
-            Assertions.assertTrue(pair.getKey() == x);
-        });
-    }
-
-    @Test
-    public void testMerge() {
-        RoaringBitmapSliceIndex bsiA = new RoaringBitmapSliceIndex();
-        IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
-        RoaringBitmapSliceIndex bsiB = new RoaringBitmapSliceIndex();
-        IntStream.range(100, 199).forEach(x -> bsiB.setValue(x, x));
-        Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99);
-        Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99);
-        bsiA.merge(bsiB);
-        IntStream.range(1, 199).forEach(x -> {
-            Pair bsiValue = bsiA.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
-
+  private Map testDataSet = new HashMap<>();
 
-    @Test
-    public void testClone() {
-        RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
-        List> collect = testDataSet.entrySet()
-                .stream().map(x -> Pair.newPair(x.getKey(), x.getValue())).collect(Collectors.toList());
+  private RoaringBitmapSliceIndex bsi;
 
-        bsi.setValues(collect);
-
-        Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99);
-        final RoaringBitmapSliceIndex clone = bsi.clone();
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = clone.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
+  @BeforeEach
+  public void setup() {
+    IntStream.range(1, 100).forEach(x -> testDataSet.put(x, x));
+    bsi = new RoaringBitmapSliceIndex(1, 99);
+    testDataSet.forEach(
+        (k, v) -> {
+          bsi.setValue(k, v);
         });
-    }
+  }
 
+  @Test
+  public void testSetAndGet() {
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair pair = bsi.getValue(x);
+              Assertions.assertTrue(pair.getRight());
+              Assertions.assertTrue(pair.getKey() == x);
+            });
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair pair = bsi.getValue(x);
+              Assertions.assertTrue(pair.getRight());
+              Assertions.assertTrue(pair.getKey() == x);
+            });
+  }
 
-    @Test
-    public void testAdd() {
-        RoaringBitmapSliceIndex bsiA = new RoaringBitmapSliceIndex();
-        IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
-        RoaringBitmapSliceIndex bsiB = new RoaringBitmapSliceIndex();
-        IntStream.range(1, 120).forEach(x -> bsiB.setValue(x, x));
+  @Test
+  public void testMerge() {
+    RoaringBitmapSliceIndex bsiA = new RoaringBitmapSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    RoaringBitmapSliceIndex bsiB = new RoaringBitmapSliceIndex();
+    IntStream.range(100, 199).forEach(x -> bsiB.setValue(x, x));
+    Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99);
+    Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99);
+    bsiA.merge(bsiB);
+    IntStream.range(1, 199)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsiA.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
 
-        bsiA.add(bsiB);
+  @Test
+  public void testClone() {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
+    List> collect =
+        testDataSet.entrySet().stream()
+            .map(x -> Pair.newPair(x.getKey(), x.getValue()))
+            .collect(Collectors.toList());
+
+    bsi.setValues(collect);
+
+    Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99);
+    final RoaringBitmapSliceIndex clone = bsi.clone();
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = clone.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
 
-        IntStream.range(1, 120).forEach(x -> {
-            Pair bsiValue = bsiA.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            if (x < 100) {
+  @Test
+  public void testAdd() {
+    RoaringBitmapSliceIndex bsiA = new RoaringBitmapSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    RoaringBitmapSliceIndex bsiB = new RoaringBitmapSliceIndex();
+    IntStream.range(1, 120).forEach(x -> bsiB.setValue(x, x));
+
+    bsiA.add(bsiB);
+
+    IntStream.range(1, 120)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsiA.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              if (x < 100) {
                 Assertions.assertEquals((int) bsiValue.getKey(), x * 2);
-            } else {
+              } else {
                 Assertions.assertEquals((int) bsiValue.getKey(), x);
-            }
-
-        });
-    }
-
-    @Test
-    public void testAddAndEvaluate() {
-        RoaringBitmapSliceIndex bsiA = new RoaringBitmapSliceIndex();
-        IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
-        RoaringBitmapSliceIndex bsiB = new RoaringBitmapSliceIndex();
-        IntStream.range(1, 120).forEach(x -> bsiB.setValue(120 - x, x));
-
-        bsiA.add(bsiB);
-
-        RoaringBitmap result = bsiA.compare(BitmapSliceIndex.Operation.EQ, 120, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(result.toArray(), IntStream.range(1, 100).toArray());
-
-        result = bsiA.compare(BitmapSliceIndex.Operation.RANGE, 1, 20, null);
-        Assertions.assertTrue(result.getLongCardinality() == 20);
-        Assertions.assertArrayEquals(result.toArray(), IntStream.range(100, 120).toArray());
-    }
-
+              }
+            });
+  }
 
-    @Test
-    public void TestIO4Stream() throws IOException {
-        RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        DataOutputStream bdo = new DataOutputStream(bos);
-        bsi.serialize(bdo);
-        byte[] data = bos.toByteArray();
+  @Test
+  public void testAddAndEvaluate() {
+    RoaringBitmapSliceIndex bsiA = new RoaringBitmapSliceIndex();
+    IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x));
+    RoaringBitmapSliceIndex bsiB = new RoaringBitmapSliceIndex();
+    IntStream.range(1, 120).forEach(x -> bsiB.setValue(120 - x, x));
 
-        RoaringBitmapSliceIndex newBsi = new RoaringBitmapSliceIndex();
+    bsiA.add(bsiB);
 
-        ByteArrayInputStream bis = new ByteArrayInputStream(data);
-        DataInputStream bdi = new DataInputStream(bis);
-        newBsi.deserialize(bdi);
+    RoaringBitmap result = bsiA.compare(BitmapSliceIndex.Operation.EQ, 120, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(result.toArray(), IntStream.range(1, 100).toArray());
 
-        Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+    result = bsiA.compare(BitmapSliceIndex.Operation.RANGE, 1, 20, null);
+    Assertions.assertTrue(result.getLongCardinality() == 20);
+    Assertions.assertArrayEquals(result.toArray(), IntStream.range(100, 120).toArray());
+  }
 
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = newBsi.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
-
-    @Test
-    public void testIO4Buffer() throws IOException {
-        RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-        ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
-        bsi.serialize(buffer);
-
-        byte[] data = buffer.array();
-        RoaringBitmapSliceIndex newBsi = new RoaringBitmapSliceIndex();
-        newBsi.deserialize(ByteBuffer.wrap(data));
-        Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
-
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = newBsi.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
+  @Test
+  public void TestIO4Stream() throws IOException {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    DataOutputStream bdo = new DataOutputStream(bos);
+    bsi.serialize(bdo);
+    byte[] data = bos.toByteArray();
+
+    RoaringBitmapSliceIndex newBsi = new RoaringBitmapSliceIndex();
+
+    ByteArrayInputStream bis = new ByteArrayInputStream(data);
+    DataInputStream bdi = new DataInputStream(bis);
+    newBsi.deserialize(bdi);
+
+    Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = newBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
 
+  @Test
+  public void testIO4Buffer() throws IOException {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    ByteBuffer buffer = ByteBuffer.allocate(bsi.serializedSizeInBytes());
+    bsi.serialize(buffer);
 
-    @Test
-    public void testIOFromExternal() {
-        RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    byte[] data = buffer.array();
+    RoaringBitmapSliceIndex newBsi = new RoaringBitmapSliceIndex();
+    newBsi.deserialize(ByteBuffer.wrap(data));
+    Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99);
+
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = newBsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
 
-        IntStream.range(1, 100).forEach(x -> {
-            Pair bsiValue = bsi.getValue(x);
-            Assertions.assertTrue(bsiValue.getRight());
-            Assertions.assertEquals((int) bsiValue.getKey(), x);
-        });
-    }
+  @Test
+  public void testIOFromExternal() {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
 
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              Pair bsiValue = bsi.getValue(x);
+              Assertions.assertTrue(bsiValue.getRight());
+              Assertions.assertEquals((int) bsiValue.getKey(), x);
+            });
+  }
 
-    @Test
-    public void testEQ() {
-        RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> {
-            if (x <= 50) {
+  @Test
+  public void testEQ() {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
+    IntStream.range(1, 100)
+        .forEach(
+            x -> {
+              if (x <= 50) {
                 bsi.setValue(x, 1);
-            } else {
+              } else {
                 bsi.setValue(x, x);
-            }
-
-        });
-
-        RoaringBitmap bitmap = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
-        Assertions.assertTrue(bitmap.getLongCardinality() == 50L);
-
-    }
+              }
+            });
 
-    @Test
-    public void testNotEQ() {
-        bsi = new RoaringBitmapSliceIndex();
-        bsi.setValue(1, 99);
-        bsi.setValue(2, 1);
-        bsi.setValue(3, 50);
-
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 2);
-        Assertions.assertArrayEquals(new int[]{2, 3}, result.toArray());
+    RoaringBitmap bitmap = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
+    Assertions.assertTrue(bitmap.getLongCardinality() == 50L);
+  }
 
-        result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(new int[]{1, 2, 3}, result.toArray());
+  @Test
+  public void testNotEQ() {
+    bsi = new RoaringBitmapSliceIndex();
+    bsi.setValue(1, 99);
+    bsi.setValue(2, 1);
+    bsi.setValue(3, 50);
 
-        bsi = new RoaringBitmapSliceIndex();
-        bsi.setValue(1, 99);
-        bsi.setValue(2, 99);
-        bsi.setValue(3, 99);
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 2);
+    Assertions.assertArrayEquals(new int[] {2, 3}, result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
-        Assertions.assertTrue(result.isEmpty());
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(new int[] {1, 2, 3}, result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(new int[]{1, 2, 3}, result.toArray());
-    }
+    bsi = new RoaringBitmapSliceIndex();
+    bsi.setValue(1, 99);
+    bsi.setValue(2, 99);
+    bsi.setValue(3, 99);
 
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null);
+    Assertions.assertTrue(result.isEmpty());
 
-    // parallel operation test
+    result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(new int[] {1, 2, 3}, result.toArray());
+  }
 
-    @Test
-    public void testGT() {
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.GT, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 49);
-        Assertions.assertArrayEquals(IntStream.range(51, 100).toArray(), result.toArray());
+  // parallel operation test
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GT, 0, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+  @Test
+  public void testGT() {
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.GT, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 49);
+    Assertions.assertArrayEquals(IntStream.range(51, 100).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GT, 99, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
+    result = bsi.compare(BitmapSliceIndex.Operation.GT, 0, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
 
+    result = bsi.compare(BitmapSliceIndex.Operation.GT, 99, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
 
-    @Test
-    public void testGE() {
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 50);
-        Assertions.assertArrayEquals(IntStream.range(50, 100).toArray(), result.toArray());
+  @Test
+  public void testGE() {
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 50);
+    Assertions.assertArrayEquals(IntStream.range(50, 100).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GE, 1, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, 1, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null);
-        Assertions.assertTrue(result.isEmpty());
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null);
+    Assertions.assertTrue(result.isEmpty());
 
-        RoaringBitmap foundSet = RoaringBitmap.bitmapOf(51, 52, 53);
+    RoaringBitmap foundSet = RoaringBitmap.bitmapOf(51, 52, 53);
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, foundSet);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(IntStream.range(51, 54).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, foundSet);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(IntStream.range(51, 54).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GE, 0, 0, foundSet);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(IntStream.range(51, 54).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, 0, 0, foundSet);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(IntStream.range(51, 54).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.GE, Integer.MAX_VALUE, 0, foundSet);
-        Assertions.assertTrue(result.isEmpty());
-    }
+    result = bsi.compare(BitmapSliceIndex.Operation.GE, Integer.MAX_VALUE, 0, foundSet);
+    Assertions.assertTrue(result.isEmpty());
+  }
 
-    @Test
-    public void testLT() {
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.LT, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 49);
-        Assertions.assertArrayEquals(IntStream.range(1, 50).toArray(), result.toArray());
+  @Test
+  public void testLT() {
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.LT, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 49);
+    Assertions.assertArrayEquals(IntStream.range(1, 50).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LT, Integer.MAX_VALUE, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.LT, Integer.MAX_VALUE, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LT, 1, 0, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
+    result = bsi.compare(BitmapSliceIndex.Operation.LT, 1, 0, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
 
+  @Test
+  public void testLE() {
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 50);
+    Assertions.assertArrayEquals(IntStream.range(1, 51).toArray(), result.toArray());
 
-    @Test
-    public void testLE() {
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 50);
-        Assertions.assertArrayEquals(IntStream.range(1, 51).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null);
+    Assertions.assertTrue(result.isEmpty());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null);
-        Assertions.assertTrue(result.isEmpty());
+    RoaringBitmap foundSet = RoaringBitmap.bitmapOf(1, 2, 3);
 
-        RoaringBitmap foundSet = RoaringBitmap.bitmapOf(1, 2, 3);
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, foundSet);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(IntStream.range(1, 4).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, foundSet);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(IntStream.range(1, 4).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, foundSet);
+    Assertions.assertTrue(result.getLongCardinality() == 3);
+    Assertions.assertArrayEquals(IntStream.range(1, 4).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, foundSet);
-        Assertions.assertTrue(result.getLongCardinality() == 3);
-        Assertions.assertArrayEquals(IntStream.range(1, 4).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, foundSet);
+    Assertions.assertTrue(result.isEmpty());
+  }
 
-        result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, foundSet);
-        Assertions.assertTrue(result.isEmpty());
-    }
+  @Test
+  public void testRANGE() {
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 10, 20, null);
+    Assertions.assertTrue(result.getLongCardinality() == 11);
+    Assertions.assertArrayEquals(IntStream.range(10, 21).toArray(), result.toArray());
 
-    @Test
-    public void testRANGE() {
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 10, 20, null);
-        Assertions.assertTrue(result.getLongCardinality() == 11);
-        Assertions.assertArrayEquals(IntStream.range(10, 21).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1, 200, null);
+    Assertions.assertTrue(result.getLongCardinality() == 99);
+    Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
 
-        result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1, 200, null);
-        Assertions.assertTrue(result.getLongCardinality() == 99);
-        Assertions.assertArrayEquals(IntStream.range(1, 100).toArray(), result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1000, 2000, null);
+    Assertions.assertTrue(result.isEmpty());
+  }
 
-        result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1000, 2000, null);
-        Assertions.assertTrue(result.isEmpty());
-    }
+  @Test
+  public void testSum() {
+    RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
+    IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
 
-    @Test
-    public void testSum() {
-        RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex(1, 99);
-        IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
+    RoaringBitmap foundSet = RoaringBitmap.bitmapOf(IntStream.range(1, 51).toArray());
 
-        RoaringBitmap foundSet = RoaringBitmap.bitmapOf(IntStream.range(1, 51).toArray());
+    Pair sumPair = bsi.sum(foundSet);
 
-        Pair sumPair = bsi.sum(foundSet);
+    System.out.println("sum:" + sumPair.toString());
 
-        System.out.println("sum:" + sumPair.toString());
+    int sum = IntStream.range(1, 51).sum();
+    long count = IntStream.range(1, 51).count();
 
-        int sum = IntStream.range(1, 51).sum();
-        long count = IntStream.range(1, 51).count();
+    Assertions.assertTrue(sumPair.getLeft().intValue() == sum && sumPair.getRight() == count);
+  }
 
-        Assertions.assertTrue(sumPair.getLeft().intValue() == sum && sumPair.getRight() == count);
-    }
+  @Test
+  public void testValueZero() {
+    bsi = new RoaringBitmapSliceIndex();
+    bsi.setValue(0, 0);
+    bsi.setValue(1, 0);
+    bsi.setValue(2, 1);
 
-    @Test
-    public void testValueZero() {
-        bsi = new RoaringBitmapSliceIndex();
-        bsi.setValue(0, 0);
-        bsi.setValue(1, 0);
-        bsi.setValue(2, 1);
+    RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 2);
+    Assertions.assertArrayEquals(new int[] {0, 1}, result.toArray());
 
-        RoaringBitmap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 2);
-        Assertions.assertArrayEquals(new int[]{0, 1}, result.toArray());
+    result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
+    Assertions.assertTrue(result.getLongCardinality() == 1);
+    Assertions.assertArrayEquals(new int[] {2}, result.toArray());
+  }
 
-        result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null);
-        Assertions.assertTrue(result.getLongCardinality() == 1);
-        Assertions.assertArrayEquals(new int[]{2}, result.toArray());
-    }
   @Test
   public void testIssue743() throws IOException {
     RoaringBitmapSliceIndex bsi = new RoaringBitmapSliceIndex();
@@ -372,26 +390,39 @@ public void testIssue743() throws IOException {
     Assertions.assertEquals(de_bsi.getValue(1), bsi.getValue(1));
   }
 
-@Test
-public void testIssue753() throws IOException {
+  @Test
+  public void testIssue753() throws IOException {
     bsi = new RoaringBitmapSliceIndex();
     IntStream.range(1, 100).forEach(x -> bsi.setValue(x, x));
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getCardinality(), 56);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getCardinality(), 99);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getCardinality(), 99);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getCardinality(), 99);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getCardinality(), 0);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getCardinality(), 0);
-
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getCardinality(), 53);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getCardinality(), 96);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getCardinality(), 96);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getCardinality(), 96);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getCardinality(), 0);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getCardinality(), 0);
-
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getCardinality(), 0);
-    Assertions.assertEquals(bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getCardinality(), 56);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getCardinality(), 99);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getCardinality(), 99);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getCardinality(), 99);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getCardinality(), 0);
+
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getCardinality(), 53);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getCardinality(), 96);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getCardinality(), 96);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getCardinality(), 96);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getCardinality(), 0);
+
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getCardinality(), 0);
+    Assertions.assertEquals(
+        bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getCardinality(), 0);
   }
 }
-
diff --git a/build.gradle.kts b/build.gradle.kts
index 3b975a8a4..c907a1224 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,10 +1,8 @@
-import java.net.URI
-import java.time.Duration
-
 plugins {
     id("net.researchgate.release") version "2.8.1"
     id("com.github.ben-manes.versions") version "0.38.0"
     id("maven-publish")
+    id("com.diffplug.spotless") version "6.25.0"
 }
 
 
@@ -54,6 +52,48 @@ subprojects {
             })
         }
     }
+
+    apply(plugin = "com.diffplug.spotless")
+
+    // You can format the codebase with `./gradlew spotlessApply`
+    // You check the codebase format with `./gradlew spotlessCheck`
+    spotless {
+        // Ratchetting from master means we check/apply only files which are changed relatively to master
+        // This is especially useful for performance, given the whole codebase has been formatted with Spotless.
+        ratchetFrom("origin/master")
+
+        java {
+            // Disbale javadoc formatting as most the javacode do not follow HTML syntax.
+            googleJavaFormat().reflowLongStrings().formatJavadoc(false)
+            formatAnnotations()
+
+            importOrder("\\#", "org.roaringbitmap", "", "java", "javax")
+            removeUnusedImports()
+
+            trimTrailingWhitespace()
+            endWithNewline()
+
+            // https://github.com/opensearch-project/opensearch-java/commit/2d6d5f86a8db9c7c9e7b8d0f54df97246f7b7d7e
+            // https://github.com/diffplug/spotless/issues/649
+            val wildcardImportRegex = Regex("""^import\s+(?:static\s+)?[^*\s]+\.\*;$""", RegexOption.MULTILINE)
+            custom("Refuse wildcard imports") { contents ->
+                // Wildcard imports can't be resolved by spotless itself.
+                // This will require the developer themselves to adhere to best practices.
+                val wildcardImports = wildcardImportRegex.findAll(contents)
+                if (wildcardImports.any()) {
+                    var msg = """
+                    Please replace the following wildcard imports with explicit imports ('spotlessApply' cannot resolve this issue):
+                """.trimIndent()
+                    wildcardImports.forEach {
+                        msg += "\n\t- ${it.value}"
+                    }
+                    msg += "\n"
+                    throw AssertionError(msg)
+                }
+                contents
+            }
+        }
+    }
 }
 
 subprojects.filter { listOf("roaringbitmap", "bsi").contains(it.name) }.forEach { project ->
@@ -137,13 +177,6 @@ subprojects.filter { listOf("roaringbitmap", "bsi").contains(it.name) }.forEach
     }
 }
 
-
-tasks {
-    register("build") {
-        // dummy build task to appease release plugin
-    }
-}
-
 release {
     // for some odd reason, we used to have our tags be of the form roaringbitmap-0.1.0
     // instead of just 0.1.0 or v0.1.0.
diff --git a/examples/src/main/java/Basic.java b/examples/src/main/java/Basic.java
index a091a371a..e4d59e67b 100644
--- a/examples/src/main/java/Basic.java
+++ b/examples/src/main/java/Basic.java
@@ -1,23 +1,22 @@
-
 import org.roaringbitmap.RoaringBitmap;
 
 public class Basic {
 
   public static void main(String[] args) {
-        RoaringBitmap rr = RoaringBitmap.bitmapOf(1,2,3,1000);
-        RoaringBitmap rr2 = new RoaringBitmap();
-        rr2.add(4000L,4255L);
+    RoaringBitmap rr = RoaringBitmap.bitmapOf(1, 2, 3, 1000);
+    RoaringBitmap rr2 = new RoaringBitmap();
+    rr2.add(4000L, 4255L);
 
-        RoaringBitmap rror = RoaringBitmap.or(rr, rr2);// new bitmap
-        rr.or(rr2); //in-place computation
-        boolean equals = rror.equals(rr);// true
-        if(!equals) throw new RuntimeException("bug");
-        // number of values stored?
-        long cardinality = rr.getLongCardinality();
-        System.out.println(cardinality);
-        // a "forEach" is faster than this loop, but a loop is possible:
-        for(int i : rr) {
-          System.out.println(i);
-        }
+    RoaringBitmap rror = RoaringBitmap.or(rr, rr2); // new bitmap
+    rr.or(rr2); // in-place computation
+    boolean equals = rror.equals(rr); // true
+    if (!equals) throw new RuntimeException("bug");
+    // number of values stored?
+    long cardinality = rr.getLongCardinality();
+    System.out.println(cardinality);
+    // a "forEach" is faster than this loop, but a loop is possible:
+    for (int i : rr) {
+      System.out.println(i);
+    }
   }
 }
diff --git a/examples/src/main/java/Bitmap64.java b/examples/src/main/java/Bitmap64.java
index 85e38a937..ad412dfea 100644
--- a/examples/src/main/java/Bitmap64.java
+++ b/examples/src/main/java/Bitmap64.java
@@ -1,13 +1,15 @@
-import org.roaringbitmap.longlong.*;
+import org.roaringbitmap.longlong.LongBitmapDataProvider;
+import org.roaringbitmap.longlong.LongIterator;
+import org.roaringbitmap.longlong.Roaring64NavigableMap;
 
 public class Bitmap64 {
 
   public static void main(String[] args) {
-      LongBitmapDataProvider r = Roaring64NavigableMap.bitmapOf(1,2,100,1000);
-      r.addLong(1234);
-      System.out.println(r.contains(1)); // true
-      System.out.println(r.contains(3)); // false
-      LongIterator i = r.getLongIterator();
-      while(i.hasNext()) System.out.println(i.next());
+    LongBitmapDataProvider r = Roaring64NavigableMap.bitmapOf(1, 2, 100, 1000);
+    r.addLong(1234);
+    System.out.println(r.contains(1)); // true
+    System.out.println(r.contains(3)); // false
+    LongIterator i = r.getLongIterator();
+    while (i.hasNext()) System.out.println(i.next());
   }
 }
diff --git a/examples/src/main/java/CompressionResults.java b/examples/src/main/java/CompressionResults.java
index 88fd33922..b716211e6 100644
--- a/examples/src/main/java/CompressionResults.java
+++ b/examples/src/main/java/CompressionResults.java
@@ -1,5 +1,5 @@
-
 import org.roaringbitmap.RoaringBitmap;
+
 import java.text.DecimalFormat;
 
 public class CompressionResults {
@@ -7,56 +7,72 @@ public class CompressionResults {
   public static DecimalFormat F = new DecimalFormat("0.000");
 
   public static void testSuperSparse() {
-    System.out.println("Sparse case... universe = [0,"+universe_size+")");
+    System.out.println("Sparse case... universe = [0," + universe_size + ")");
     RoaringBitmap r = new RoaringBitmap();
     int howmany = 100;
     int gap = universe_size / howmany;
-    System.out.println("Adding "+howmany+" values separated by gaps of "+gap+ "...");
+    System.out.println("Adding " + howmany + " values separated by gaps of " + gap + "...");
     System.out.println("As a bitmap it would look like 1000...001000... ");
     for (int i = 1; i < howmany; i++) {
       r.add(i * gap);
     }
-    System.out.println("Bits used per value = "+F.format(r.getSizeInBytes()*8.0/howmany));
+    System.out.println("Bits used per value = " + F.format(r.getSizeInBytes() * 8.0 / howmany));
     r.runOptimize();
-    System.out.println("Bits used per value after run optimize = "+F.format(r.getSizeInBytes()*8.0/howmany));
-    System.out.println("An uncompressed bitset might use "+F.format(universe_size*1.0/howmany)+" bits per value set");
+    System.out.println(
+        "Bits used per value after run optimize = " + F.format(r.getSizeInBytes() * 8.0 / howmany));
+    System.out.println(
+        "An uncompressed bitset might use "
+            + F.format(universe_size * 1.0 / howmany)
+            + " bits per value set");
     System.out.println();
-
   }
 
   public static void testSuperDense() {
-    System.out.println("Sparse case... universe = [0,"+universe_size+")");
+    System.out.println("Sparse case... universe = [0," + universe_size + ")");
     RoaringBitmap r = new RoaringBitmap();
     long howmany = 100;
     long gap = universe_size / howmany;
     for (long i = 1; i < howmany; i++) {
-      r.add(i * gap + 1,((i + 1) * gap));
+      r.add(i * gap + 1, ((i + 1) * gap));
     }
-    System.out.println("Adding "+r.getCardinality()+" values partionned by "+howmany+" gaps of 1 ...");
+    System.out.println(
+        "Adding " + r.getCardinality() + " values partionned by " + howmany + " gaps of 1 ...");
     System.out.println("As a bitmap it would look like 01111...11011111... ");
 
-    System.out.println("Bits used per value = "+F.format(r.getSizeInBytes()*8.0/r.getCardinality()));
+    System.out.println(
+        "Bits used per value = " + F.format(r.getSizeInBytes() * 8.0 / r.getCardinality()));
     r.runOptimize();
-    System.out.println("Bits used per value after run optimize = "+F.format(r.getSizeInBytes()*8.0/r.getCardinality()));
-    System.out.println("Bits used per gap after run optimize = "+F.format(r.getSizeInBytes()*8.0/howmany));
+    System.out.println(
+        "Bits used per value after run optimize = "
+            + F.format(r.getSizeInBytes() * 8.0 / r.getCardinality()));
+    System.out.println(
+        "Bits used per gap after run optimize = " + F.format(r.getSizeInBytes() * 8.0 / howmany));
 
-    System.out.println("An uncompressed bitset might use "+F.format(universe_size*1.0/r.getCardinality())+" bits per value set");
+    System.out.println(
+        "An uncompressed bitset might use "
+            + F.format(universe_size * 1.0 / r.getCardinality())
+            + " bits per value set");
     System.out.println();
   }
 
   public static void testAlternating() {
-    System.out.println("Alternating case... universe = [0,"+universe_size+")");
+    System.out.println("Alternating case... universe = [0," + universe_size + ")");
     RoaringBitmap r = new RoaringBitmap();
     for (int i = 1; i < universe_size; i++) {
-      if(i%2 == 0)
-        r.add(i);
+      if (i % 2 == 0) r.add(i);
     }
     System.out.println("Adding all even values in the universe");
     System.out.println("As a bitmap it would look like 01010101... ");
-    System.out.println("Bits used per value = "+F.format(r.getSizeInBytes()*8.0/r.getCardinality()));
+    System.out.println(
+        "Bits used per value = " + F.format(r.getSizeInBytes() * 8.0 / r.getCardinality()));
     r.runOptimize();
-    System.out.println("Bits used per value after run optimize = "+F.format(r.getSizeInBytes()*8.0/r.getCardinality()));
-    System.out.println("An uncompressed bitset might use "+F.format(universe_size*1.0/r.getCardinality())+" bits per value set");
+    System.out.println(
+        "Bits used per value after run optimize = "
+            + F.format(r.getSizeInBytes() * 8.0 / r.getCardinality()));
+    System.out.println(
+        "An uncompressed bitset might use "
+            + F.format(universe_size * 1.0 / r.getCardinality())
+            + " bits per value set");
     System.out.println();
   }
 
diff --git a/examples/src/main/java/ForEachExample.java b/examples/src/main/java/ForEachExample.java
index b9fe6e596..d3eb7d66e 100644
--- a/examples/src/main/java/ForEachExample.java
+++ b/examples/src/main/java/ForEachExample.java
@@ -1,37 +1,37 @@
 /**
-* This example shows how to serialize a Roaring bitmap to a file.
-*
-*
-*
-*/
-import org.roaringbitmap.*;
-import java.io.*;
-import java.nio.*;
-import java.util.*;
+ * This example shows how to serialize a Roaring bitmap to a file.
+ *
+ *
+ *
+ */
+import org.roaringbitmap.IntConsumer;
+import org.roaringbitmap.RoaringBitmap;
 
-public class ForEachExample {
+import java.io.IOException;
 
+public class ForEachExample {
 
-    public static void main(String[] args) throws IOException {
-        RoaringBitmap rb = new RoaringBitmap();
-        for (int k = 0; k < 100000; k+= 1000) {
-            rb.add(k);
-        }
-        for (int k = 100000; k < 200000; ++k) {
-            rb.add(3*k);
-        }
-        for (int k = 700000; k < 800000; ++k) {
-            rb.add(k);
-        }
-        final int[] count = {0};
-        rb.forEach(new IntConsumer() {
-            @Override
-            public void accept(int value) {
-                if((value % 1500) == 0) {
-                    count[0] ++;
-                }
+  public static void main(String[] args) throws IOException {
+    RoaringBitmap rb = new RoaringBitmap();
+    for (int k = 0; k < 100000; k += 1000) {
+      rb.add(k);
+    }
+    for (int k = 100000; k < 200000; ++k) {
+      rb.add(3 * k);
+    }
+    for (int k = 700000; k < 800000; ++k) {
+      rb.add(k);
+    }
+    final int[] count = {0};
+    rb.forEach(
+        new IntConsumer() {
+          @Override
+          public void accept(int value) {
+            if ((value % 1500) == 0) {
+              count[0]++;
             }
+          }
         });
-        System.out.println("There are "+count[0]+" values divisible by 1500.");
-    }
+    System.out.println("There are " + count[0] + " values divisible by 1500.");
+  }
 }
diff --git a/examples/src/main/java/ImmutableRoaringBitmapExample.java b/examples/src/main/java/ImmutableRoaringBitmapExample.java
index 85a01747a..f25511a37 100644
--- a/examples/src/main/java/ImmutableRoaringBitmapExample.java
+++ b/examples/src/main/java/ImmutableRoaringBitmapExample.java
@@ -1,24 +1,27 @@
-import org.roaringbitmap.buffer.*;
-import java.io.*;
-import java.nio.*;
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
 
 public class ImmutableRoaringBitmapExample {
-   public static void main(String[] args) throws IOException {
-        MutableRoaringBitmap rr1 = MutableRoaringBitmap.bitmapOf(1, 2, 3, 1000);
-        MutableRoaringBitmap rr2 = MutableRoaringBitmap.bitmapOf( 2, 3, 1010);
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        DataOutputStream dos = new DataOutputStream(bos);
-        // If there were runs of consecutive values, you could
-        // call rr1.runOptimize(); or rr2.runOptimize(); to improve compression
-        rr1.serialize(dos);
-        rr2.serialize(dos);
-        dos.close();
-        ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
-        ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb);
-        bb.position(bb.position() + rrback1.serializedSizeInBytes());
-        ImmutableRoaringBitmap rrback2 = new ImmutableRoaringBitmap(bb);
-        System.out.println(rrback1);
-        System.out.println(rrback2);
-   }
-}
\ No newline at end of file
+  public static void main(String[] args) throws IOException {
+    MutableRoaringBitmap rr1 = MutableRoaringBitmap.bitmapOf(1, 2, 3, 1000);
+    MutableRoaringBitmap rr2 = MutableRoaringBitmap.bitmapOf(2, 3, 1010);
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    DataOutputStream dos = new DataOutputStream(bos);
+    // If there were runs of consecutive values, you could
+    // call rr1.runOptimize(); or rr2.runOptimize(); to improve compression
+    rr1.serialize(dos);
+    rr2.serialize(dos);
+    dos.close();
+    ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
+    ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb);
+    bb.position(bb.position() + rrback1.serializedSizeInBytes());
+    ImmutableRoaringBitmap rrback2 = new ImmutableRoaringBitmap(bb);
+    System.out.println(rrback1);
+    System.out.println(rrback2);
+  }
+}
diff --git a/examples/src/main/java/IntervalCheck.java b/examples/src/main/java/IntervalCheck.java
index 87575d534..bca34ee11 100644
--- a/examples/src/main/java/IntervalCheck.java
+++ b/examples/src/main/java/IntervalCheck.java
@@ -1,20 +1,19 @@
-
 import org.roaringbitmap.RoaringBitmap;
 
 public class IntervalCheck {
 
   public static void main(String[] args) {
-        // some bitmap
-        RoaringBitmap rr = RoaringBitmap.bitmapOf(1,2,3,1000);
+    // some bitmap
+    RoaringBitmap rr = RoaringBitmap.bitmapOf(1, 2, 3, 1000);
 
-        // we want to check if it intersects a given range [10,1000]
-        int low = 10;
-        int high = 1000;
-        RoaringBitmap range = new RoaringBitmap();
-        range.add((long)low, (long)high + 1);
-        //
-        //
+    // we want to check if it intersects a given range [10,1000]
+    int low = 10;
+    int high = 1000;
+    RoaringBitmap range = new RoaringBitmap();
+    range.add((long) low, (long) high + 1);
+    //
+    //
 
-        System.out.println(RoaringBitmap.intersects(rr,range)); // prints true if they intersect
+    System.out.println(RoaringBitmap.intersects(rr, range)); // prints true if they intersect
   }
 }
diff --git a/examples/src/main/java/MemoryMappingExample.java b/examples/src/main/java/MemoryMappingExample.java
index b8cbff3b4..d77809220 100644
--- a/examples/src/main/java/MemoryMappingExample.java
+++ b/examples/src/main/java/MemoryMappingExample.java
@@ -1,44 +1,53 @@
-import org.roaringbitmap.buffer.*;
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
-import java.io.*;
-import java.nio.*;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 
-
 public class MemoryMappingExample {
 
-    public static void main(String[] args) throws IOException {
-        File tmpfile = File.createTempFile("roaring", "bin");
-        tmpfile.deleteOnExit();
-        final FileOutputStream fos = new FileOutputStream(tmpfile);
-        MutableRoaringBitmap Bitmap1 = MutableRoaringBitmap.bitmapOf(0, 2, 55,
-                                64, 1 << 30);
-        System.out.println("Created the bitmap "+Bitmap1);
-        MutableRoaringBitmap Bitmap2 = MutableRoaringBitmap.bitmapOf(0, 2, 55,
-                                654, 1 << 31);
-        System.out.println("Created the bitmap "+Bitmap2);
-        int pos1 = 0; // bitmap 1 is at offset 0
-        // If there were runs of consecutive values, you could
-        // call Bitmap1.runOptimize(); to improve compression
-        Bitmap1.serialize(new DataOutputStream(fos));
-        int pos2 = Bitmap1.serializedSizeInBytes(); // bitmap 2 will be right after it
-        // If there were runs of consecutive values, you could
-        // call Bitmap2.runOptimize(); to improve compression
-        Bitmap2.serialize(new DataOutputStream(fos));
-        long totalcount = fos.getChannel().position();
-        if(totalcount != Bitmap1.serializedSizeInBytes() + Bitmap2.serializedSizeInBytes())
-           throw new RuntimeException("This will not happen.");
-        System.out.println("Serialized total count = "+totalcount+" bytes");
-        fos.close();
-        RandomAccessFile memoryMappedFile = new RandomAccessFile(tmpfile, "r");
-        ByteBuffer bb = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, totalcount); // even though we have two bitmaps, we have one map, maps are expensive!!!
-        memoryMappedFile.close(); // we can safely close
-        bb.position(pos1);
-        ImmutableRoaringBitmap mapped1 = new ImmutableRoaringBitmap(bb);
-        System.out.println("Mapped the bitmap "+mapped1);
-        bb.position(pos2);
-        ImmutableRoaringBitmap mapped2 = new ImmutableRoaringBitmap(bb);
-        System.out.println("Mapped the bitmap "+mapped2);
-        if(!mapped2.equals(Bitmap2)) throw new RuntimeException("This will not happen");
-    }
+  public static void main(String[] args) throws IOException {
+    File tmpfile = File.createTempFile("roaring", "bin");
+    tmpfile.deleteOnExit();
+    final FileOutputStream fos = new FileOutputStream(tmpfile);
+    MutableRoaringBitmap Bitmap1 = MutableRoaringBitmap.bitmapOf(0, 2, 55, 64, 1 << 30);
+    System.out.println("Created the bitmap " + Bitmap1);
+    MutableRoaringBitmap Bitmap2 = MutableRoaringBitmap.bitmapOf(0, 2, 55, 654, 1 << 31);
+    System.out.println("Created the bitmap " + Bitmap2);
+    int pos1 = 0; // bitmap 1 is at offset 0
+    // If there were runs of consecutive values, you could
+    // call Bitmap1.runOptimize(); to improve compression
+    Bitmap1.serialize(new DataOutputStream(fos));
+    int pos2 = Bitmap1.serializedSizeInBytes(); // bitmap 2 will be right after it
+    // If there were runs of consecutive values, you could
+    // call Bitmap2.runOptimize(); to improve compression
+    Bitmap2.serialize(new DataOutputStream(fos));
+    long totalcount = fos.getChannel().position();
+    if (totalcount != Bitmap1.serializedSizeInBytes() + Bitmap2.serializedSizeInBytes())
+      throw new RuntimeException("This will not happen.");
+    System.out.println("Serialized total count = " + totalcount + " bytes");
+    fos.close();
+    RandomAccessFile memoryMappedFile = new RandomAccessFile(tmpfile, "r");
+    ByteBuffer bb =
+        memoryMappedFile
+            .getChannel()
+            .map(
+                FileChannel.MapMode.READ_ONLY,
+                0,
+                totalcount); // even though we have two bitmaps, we have one map, maps are
+    // expensive!!!
+    memoryMappedFile.close(); // we can safely close
+    bb.position(pos1);
+    ImmutableRoaringBitmap mapped1 = new ImmutableRoaringBitmap(bb);
+    System.out.println("Mapped the bitmap " + mapped1);
+    bb.position(pos2);
+    ImmutableRoaringBitmap mapped2 = new ImmutableRoaringBitmap(bb);
+    System.out.println("Mapped the bitmap " + mapped2);
+    if (!mapped2.equals(Bitmap2)) throw new RuntimeException("This will not happen");
+  }
 }
diff --git a/examples/src/main/java/PagedIterator.java b/examples/src/main/java/PagedIterator.java
index 2cfe8d36f..a570aea7f 100644
--- a/examples/src/main/java/PagedIterator.java
+++ b/examples/src/main/java/PagedIterator.java
@@ -1,23 +1,23 @@
-
-import org.roaringbitmap.*;
+import org.roaringbitmap.IntIterator;
+import org.roaringbitmap.RoaringBitmap;
 
 // demonstrates how to iterator over blocks of pageSize integers efficiently
 public class PagedIterator {
 
   public static void main(String[] args) {
-        RoaringBitmap rr = new RoaringBitmap();
-        for(int k = 0; k < 100; k++) {
-          rr.add(k * 4 + 31);
-        }
+    RoaringBitmap rr = new RoaringBitmap();
+    for (int k = 0; k < 100; k++) {
+      rr.add(k * 4 + 31);
+    }
 
-        IntIterator i = rr.getIntIterator();
-        final int pageSize = 10;
-        while(i.hasNext()) {
-          // we print a page
-          for(int k = 0; (k < pageSize) && i.hasNext() ; k++) {
-            System.out.print(i.next()+" ");
-          }
-          System.out.println();
-        }
+    IntIterator i = rr.getIntIterator();
+    final int pageSize = 10;
+    while (i.hasNext()) {
+      // we print a page
+      for (int k = 0; (k < pageSize) && i.hasNext(); k++) {
+        System.out.print(i.next() + " ");
+      }
+      System.out.println();
+    }
   }
 }
diff --git a/examples/src/main/java/SerializeToByteArrayExample.java b/examples/src/main/java/SerializeToByteArrayExample.java
index 6d4ac6830..ed60cdbde 100644
--- a/examples/src/main/java/SerializeToByteArrayExample.java
+++ b/examples/src/main/java/SerializeToByteArrayExample.java
@@ -4,9 +4,11 @@
 /***************
  * for performance considerations, see https://github.com/RoaringBitmap/RoaringBitmap/issues/319
  **************/
+
 import org.roaringbitmap.RoaringBitmap;
-import java.io.*;
-import java.nio.*;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
 
 public class SerializeToByteArrayExample {
 
@@ -19,12 +21,10 @@ public static void main(String[] args) {
     RoaringBitmap ret = new RoaringBitmap();
     try {
       ret.deserialize(ByteBuffer.wrap(array));
-    } catch(IOException ioe) {
+    } catch (IOException ioe) {
       ioe.printStackTrace(); // should not happen
     }
-    if (!ret.equals(mrb))
-      throw new RuntimeException("bug");
+    if (!ret.equals(mrb)) throw new RuntimeException("bug");
     System.out.println("decoded from byte array : " + ret);
-
   }
 }
diff --git a/examples/src/main/java/SerializeToByteBufferExample.java b/examples/src/main/java/SerializeToByteBufferExample.java
index ab47ddf75..7ed621446 100644
--- a/examples/src/main/java/SerializeToByteBufferExample.java
+++ b/examples/src/main/java/SerializeToByteBufferExample.java
@@ -1,23 +1,23 @@
 /**
-* This example shows how to serialize a Roaring bitmap to a ByteBuffer
-*/
-import org.roaringbitmap.buffer.*;
-import java.io.*;
-import java.nio.*;
+ * This example shows how to serialize a Roaring bitmap to a ByteBuffer
+ */
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
-public class SerializeToByteBufferExample {
+import java.io.IOException;
+import java.nio.ByteBuffer;
 
-    public static void main(String[] args) throws IOException{
-        MutableRoaringBitmap mrb = MutableRoaringBitmap.bitmapOf(1,2,3,1000);
-        System.out.println("starting with  bitmap "+ mrb);
-        mrb.runOptimize(); //to improve compression
-        ByteBuffer outbb = ByteBuffer.allocate(mrb.serializedSizeInBytes());
-        mrb.serialize(outbb);
-        outbb.flip();
-        ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(outbb);
-        System.out.println("read bitmap "+ irb);
-        if( ! irb.equals(mrb) ) throw new RuntimeException("bug");
+public class SerializeToByteBufferExample {
 
-    }
+  public static void main(String[] args) throws IOException {
+    MutableRoaringBitmap mrb = MutableRoaringBitmap.bitmapOf(1, 2, 3, 1000);
+    System.out.println("starting with  bitmap " + mrb);
+    mrb.runOptimize(); // to improve compression
+    ByteBuffer outbb = ByteBuffer.allocate(mrb.serializedSizeInBytes());
+    mrb.serialize(outbb);
+    outbb.flip();
+    ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(outbb);
+    System.out.println("read bitmap " + irb);
+    if (!irb.equals(mrb)) throw new RuntimeException("bug");
+  }
 }
-
diff --git a/examples/src/main/java/SerializeToDiskExample.java b/examples/src/main/java/SerializeToDiskExample.java
index 382769209..61fe47983 100644
--- a/examples/src/main/java/SerializeToDiskExample.java
+++ b/examples/src/main/java/SerializeToDiskExample.java
@@ -1,47 +1,49 @@
 /**
-* This example shows how to serialize a Roaring bitmap to a file.
-*
-*
-*
-*/
-import org.roaringbitmap.*;
-import java.io.*;
-import java.nio.*;
-import java.util.*;
+ * This example shows how to serialize a Roaring bitmap to a file.
+ *
+ *
+ *
+ */
+import org.roaringbitmap.RoaringBitmap;
 
-public class SerializeToDiskExample {
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 
+public class SerializeToDiskExample {
 
-    public static void main(String[] args) throws IOException {
-        RoaringBitmap rb = new RoaringBitmap();
-        for (int k = 0; k < 100000; k+= 1000) {
-            rb.add(k);
-        }
-        for (int k = 100000; k < 200000; ++k) {
-            rb.add(3*k);
-        }
-        for (int k = 700000; k < 800000; ++k) {
-            rb.add(k);
-        }
-        String file1 = "bitmapwithoutruns.bin";
-        try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file1))) {
-          rb.serialize(out);
-        }
-        rb.runOptimize();
-        String file2 = "bitmapwithruns.bin";
-        try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file2))) {
-          rb.serialize(out);
-        }
-        // verify
-        RoaringBitmap rbtest = new RoaringBitmap();
-        try (DataInputStream in = new DataInputStream(new FileInputStream(file1))) {
-          rbtest.deserialize(in);
-        }
-        if(!rbtest.equals(rb)) throw new RuntimeException("bug!");
-        try (DataInputStream in = new DataInputStream(new FileInputStream(file2))) {
-          rbtest.deserialize(in);
-        }
-        if(!rbtest.equals(rb)) throw new RuntimeException("bug!");
-        System.out.println("Serialized bitmaps to "+file1+" and "+file2);
+  public static void main(String[] args) throws IOException {
+    RoaringBitmap rb = new RoaringBitmap();
+    for (int k = 0; k < 100000; k += 1000) {
+      rb.add(k);
+    }
+    for (int k = 100000; k < 200000; ++k) {
+      rb.add(3 * k);
+    }
+    for (int k = 700000; k < 800000; ++k) {
+      rb.add(k);
+    }
+    String file1 = "bitmapwithoutruns.bin";
+    try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file1))) {
+      rb.serialize(out);
+    }
+    rb.runOptimize();
+    String file2 = "bitmapwithruns.bin";
+    try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file2))) {
+      rb.serialize(out);
+    }
+    // verify
+    RoaringBitmap rbtest = new RoaringBitmap();
+    try (DataInputStream in = new DataInputStream(new FileInputStream(file1))) {
+      rbtest.deserialize(in);
+    }
+    if (!rbtest.equals(rb)) throw new RuntimeException("bug!");
+    try (DataInputStream in = new DataInputStream(new FileInputStream(file2))) {
+      rbtest.deserialize(in);
     }
+    if (!rbtest.equals(rb)) throw new RuntimeException("bug!");
+    System.out.println("Serialized bitmaps to " + file1 + " and " + file2);
+  }
 }
diff --git a/examples/src/main/java/SerializeToStringExample.java b/examples/src/main/java/SerializeToStringExample.java
index 10b8fcfaf..ef52d2430 100644
--- a/examples/src/main/java/SerializeToStringExample.java
+++ b/examples/src/main/java/SerializeToStringExample.java
@@ -1,34 +1,33 @@
 /**
-* This example shows how to serialize a Roaring bitmap to a String (Java 8)
-*
-*
-* It is not difficult to encode a byte array to a String so that it can be later recovered.
-* A standard way is to use Base 64 : https://en.wikipedia.org/wiki/Base64
-*
-*/
-import org.roaringbitmap.buffer.*;
-import java.io.*;
-import java.nio.*;
-import java.util.*;
-
-public class SerializeToStringExample {
-
+ * This example shows how to serialize a Roaring bitmap to a String (Java 8)
+ *
+ *
+ * It is not difficult to encode a byte array to a String so that it can be later recovered.
+ * A standard way is to use Base 64 : https://en.wikipedia.org/wiki/Base64
+ *
+ */
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Base64;
 
+public class SerializeToStringExample {
 
-    // This example uses the Base64 class introduced in Java 8. Any byte[] to String encoder would do
-    public static void main(String[] args) throws IOException{
-        MutableRoaringBitmap mrb = MutableRoaringBitmap.bitmapOf(1,2,3,1000);
-        System.out.println("starting with  bitmap "+ mrb);
-        ByteBuffer outbb = ByteBuffer.allocate(mrb.serializedSizeInBytes());
-        // If there were runs of consecutive values, you could
-        // call mrb.runOptimize(); to improve compression
-        mrb.serialize(outbb);
-        //
-        outbb.flip();
-        String serializedstring = Base64.getEncoder().encodeToString(outbb.array());
-        ByteBuffer newbb = ByteBuffer.wrap(Base64.getDecoder().decode(serializedstring));
-        ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(newbb);
-        System.out.println("read bitmap "+ irb);
-    }
+  // This example uses the Base64 class introduced in Java 8. Any byte[] to String encoder would do
+  public static void main(String[] args) throws IOException {
+    MutableRoaringBitmap mrb = MutableRoaringBitmap.bitmapOf(1, 2, 3, 1000);
+    System.out.println("starting with  bitmap " + mrb);
+    ByteBuffer outbb = ByteBuffer.allocate(mrb.serializedSizeInBytes());
+    // If there were runs of consecutive values, you could
+    // call mrb.runOptimize(); to improve compression
+    mrb.serialize(outbb);
+    //
+    outbb.flip();
+    String serializedstring = Base64.getEncoder().encodeToString(outbb.array());
+    ByteBuffer newbb = ByteBuffer.wrap(Base64.getDecoder().decode(serializedstring));
+    ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(newbb);
+    System.out.println("read bitmap " + irb);
+  }
 }
diff --git a/examples/src/main/java/VeryLargeBitmap.java b/examples/src/main/java/VeryLargeBitmap.java
index 93e1486e8..f9f31e76e 100644
--- a/examples/src/main/java/VeryLargeBitmap.java
+++ b/examples/src/main/java/VeryLargeBitmap.java
@@ -1,15 +1,12 @@
-
 import org.roaringbitmap.RoaringBitmap;
-import java.text.DecimalFormat;
 
 public class VeryLargeBitmap {
 
   public static void main(String[] args) {
-      RoaringBitmap rb = new RoaringBitmap();
-      rb.add(0L, 1L << 32);// the biggest bitmap we can create
-      System.out.println("memory usage: "+ rb.getSizeInBytes()*1.0/(1L << 32)+" byte per value");
-      if(rb.getLongCardinality() != ( 1L << 32))
-        throw new RuntimeException("bug!");
-
+    RoaringBitmap rb = new RoaringBitmap();
+    rb.add(0L, 1L << 32); // the biggest bitmap we can create
+    System.out.println(
+        "memory usage: " + rb.getSizeInBytes() * 1.0 / (1L << 32) + " byte per value");
+    if (rb.getLongCardinality() != (1L << 32)) throw new RuntimeException("bug!");
   }
 }
diff --git a/fuzz-tests/src/test/java/org/roaringbitmap/BufferFuzzer.java b/fuzz-tests/src/test/java/org/roaringbitmap/BufferFuzzer.java
index 417ac0e48..d76160116 100644
--- a/fuzz-tests/src/test/java/org/roaringbitmap/BufferFuzzer.java
+++ b/fuzz-tests/src/test/java/org/roaringbitmap/BufferFuzzer.java
@@ -1,21 +1,26 @@
 package org.roaringbitmap;
 
-import com.google.common.collect.ImmutableMap;
-import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.roaringbitmap.RandomisedTestData.ITERATIONS;
+import static org.roaringbitmap.Util.toUnsignedLong;
+
 import org.roaringbitmap.buffer.BufferFastAggregation;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
+import com.google.common.collect.ImmutableMap;
+import org.junit.jupiter.api.Test;
+
 import java.util.BitSet;
 import java.util.concurrent.ThreadLocalRandom;
-import java.util.function.*;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.IntStream;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.roaringbitmap.RandomisedTestData.ITERATIONS;
-import static org.roaringbitmap.Util.toUnsignedLong;
-
 public class BufferFuzzer {
 
   @FunctionalInterface
@@ -31,9 +36,10 @@ interface RangeBitmapPredicate {
   public static void verifyInvariance(String testName, int maxKeys, RangeBitmapPredicate pred) {
     ThreadLocalRandom random = ThreadLocalRandom.current();
     IntStream.range(0, ITERATIONS)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .forEach(
+            bitmap -> {
               long min = random.nextLong(1L << 32);
               long max = random.nextLong(min, 1L << 32);
               try {
@@ -45,24 +51,27 @@ public static void verifyInvariance(String testName, int maxKeys, RangeBitmapPre
             });
   }
 
-  public static  void verifyInvariance(String testName,
-                                          Predicate validity,
-                                          Function left,
-                                          Function right) {
+  public static  void verifyInvariance(
+      String testName,
+      Predicate validity,
+      Function left,
+      Function right) {
     verifyInvariance(testName, ITERATIONS, 1 << 8, validity, left, right);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          int count,
-                                          int maxKeys,
-                                          Predicate validity,
-                                          Function left,
-                                          Function right) {
+  public static  void verifyInvariance(
+      String testName,
+      int count,
+      int maxKeys,
+      Predicate validity,
+      Function left,
+      Function right) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .filter(validity)
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .filter(validity)
+        .forEach(
+            bitmap -> {
               try {
                 assertEquals(left.apply(bitmap), right.apply(bitmap));
               } catch (Throwable t) {
@@ -72,11 +81,13 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static void verifyInvariance(String testName, int maxKeys, Predicate pred) {
+  public static void verifyInvariance(
+      String testName, int maxKeys, Predicate pred) {
     IntStream.range(0, ITERATIONS)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .forEach(
+            bitmap -> {
               try {
                 assertTrue(pred.test(bitmap));
               } catch (Throwable e) {
@@ -86,37 +97,41 @@ public static void verifyInvariance(String testName, int maxKeys, Predicate void verifyInvariance(String testName,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      BiFunction left,
+      BiFunction right) {
     verifyInvariance(testName, ITERATIONS, 1 << 8, left, right);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      BiFunction left,
+      BiFunction right) {
     verifyInvariance(testName, validity, ITERATIONS, 1 << 8, left, right);
   }
 
-
-  public static  void verifyInvariance(String testName,
-                                          int count,
-                                          int maxKeys,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      int count,
+      int maxKeys,
+      BiFunction left,
+      BiFunction right) {
     verifyInvariance(testName, (l, r) -> true, count, maxKeys, left, right);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          int count,
-                                          int maxKeys,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      int count,
+      int maxKeys,
+      BiFunction left,
+      BiFunction right) {
     IntStream.range(0, count)
-            .parallel()
-            .forEach(i -> {
+        .parallel()
+        .forEach(
+            i -> {
               MutableRoaringBitmap one = randomBitmap(maxKeys);
               MutableRoaringBitmap two = randomBitmap(maxKeys);
               if (validity.test(one, two)) {
@@ -130,22 +145,23 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static void verifyInvariance(String testName,
-                                      Predicate validity,
-                                      IntBitmapPredicate predicate) {
+  public static void verifyInvariance(
+      String testName, Predicate validity, IntBitmapPredicate predicate) {
     verifyInvariance(testName, validity, ITERATIONS, 1 << 3, predicate);
   }
 
-  public static void verifyInvariance(String testName,
-                                      Predicate validity,
-                                      int count,
-                                      int maxKeys,
-                                      IntBitmapPredicate predicate) {
+  public static void verifyInvariance(
+      String testName,
+      Predicate validity,
+      int count,
+      int maxKeys,
+      IntBitmapPredicate predicate) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .filter(validity)
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .filter(validity)
+        .forEach(
+            bitmap -> {
               for (int i = 0; i < bitmap.getCardinality(); ++i) {
                 try {
                   assertTrue(predicate.test(i, bitmap));
@@ -157,19 +173,18 @@ public static void verifyInvariance(String testName,
             });
   }
 
-  public static  void verifyInvariance(String testName, T value, Function func) {
+  public static  void verifyInvariance(
+      String testName, T value, Function func) {
     verifyInvariance(testName, ITERATIONS, 1 << 9, value, func);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          int count,
-                                          int maxKeys,
-                                          T value,
-                                          Function func) {
+  public static  void verifyInvariance(
+      String testName, int count, int maxKeys, T value, Function func) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .forEach(
+            bitmap -> {
               try {
                 assertEquals(value, func.apply(bitmap));
               } catch (Throwable t) {
@@ -179,22 +194,24 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          int maxKeys,
-                                          BiPredicate test) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      int maxKeys,
+      BiPredicate test) {
     verifyInvariance(testName, validity, ITERATIONS, maxKeys, test);
   }
 
-
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          int count,
-                                          int maxKeys,
-                                          BiPredicate test) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      int count,
+      int maxKeys,
+      BiPredicate test) {
     IntStream.range(0, count)
-            .parallel()
-            .forEach(i -> {
+        .parallel()
+        .forEach(
+            i -> {
               MutableRoaringBitmap one = randomBitmap(maxKeys);
               MutableRoaringBitmap two = randomBitmap(maxKeys);
               if (validity.test(one, two)) {
@@ -208,119 +225,148 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static void verifyInvariance(Predicate validity,
-                                      Consumer action) {
+  public static void verifyInvariance(
+      Predicate validity, Consumer action) {
     verifyInvariance(validity, ITERATIONS, 1 << 3, action);
   }
 
-  public static void verifyInvariance(Predicate validity,
-                                      int count,
-                                      int maxKeys,
-                                      Consumer action) {
+  public static void verifyInvariance(
+      Predicate validity,
+      int count,
+      int maxKeys,
+      Consumer action) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .filter(validity)
-            .forEach(action);
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .filter(validity)
+        .forEach(action);
   }
 
   @Test
   public void rankSelectInvariance() {
-    verifyInvariance("rankSelectInvariance", bitmap -> !bitmap.isEmpty(), (i, rb) -> rb.rank(rb.select(i)) == i + 1);
+    verifyInvariance(
+        "rankSelectInvariance",
+        bitmap -> !bitmap.isEmpty(),
+        (i, rb) -> rb.rank(rb.select(i)) == i + 1);
   }
 
   @Test
   public void selectContainsInvariance() {
-    verifyInvariance("selectContainsInvariance", bitmap -> !bitmap.isEmpty(), (i, rb) -> rb.contains(rb.select(i)));
+    verifyInvariance(
+        "selectContainsInvariance",
+        bitmap -> !bitmap.isEmpty(),
+        (i, rb) -> rb.contains(rb.select(i)));
   }
 
   @Test
   public void firstSelect0Invariance() {
-    verifyInvariance("firstSelect0Invariance",
-            bitmap -> !bitmap.isEmpty(),
-            b -> b.first(),
-            bitmap -> bitmap.select(0));
+    verifyInvariance(
+        "firstSelect0Invariance",
+        bitmap -> !bitmap.isEmpty(),
+        b -> b.first(),
+        bitmap -> bitmap.select(0));
   }
 
   @Test
   public void lastSelectCardinalityInvariance() {
-    verifyInvariance("lastSelectCardinalityInvariance",
-            bitmap -> !bitmap.isEmpty(),
-            bitmap -> bitmap.last(),
-            bitmap -> bitmap.select(bitmap.getCardinality() - 1));
+    verifyInvariance(
+        "lastSelectCardinalityInvariance",
+        bitmap -> !bitmap.isEmpty(),
+        bitmap -> bitmap.last(),
+        bitmap -> bitmap.select(bitmap.getCardinality() - 1));
   }
 
   @Test
   public void intersectsRangeFirstLastInvariance() {
-    verifyInvariance("intersectsRangeFirstLastInvariance", true,
-            rb -> rb.intersects(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
+    verifyInvariance(
+        "intersectsRangeFirstLastInvariance",
+        true,
+        rb -> rb.intersects(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
   }
 
   @Test
   public void containsRangeFirstLastInvariance() {
-    verifyInvariance("containsRangeFirstLastInvariance", true,
-            rb -> MutableRoaringBitmap.add(rb.clone(), toUnsignedLong(rb.first()), toUnsignedLong(rb.last()))
-                    .contains(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
+    verifyInvariance(
+        "containsRangeFirstLastInvariance",
+        true,
+        rb ->
+            MutableRoaringBitmap.add(
+                    rb.clone(), toUnsignedLong(rb.first()), toUnsignedLong(rb.last()))
+                .contains(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
   }
 
   @Test
   public void andCardinalityInvariance() {
-    verifyInvariance("andCardinalityInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> MutableRoaringBitmap.and(l, r).getCardinality(),
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r));
+    verifyInvariance(
+        "andCardinalityInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> MutableRoaringBitmap.and(l, r).getCardinality(),
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r));
   }
 
   @Test
   public void orCardinalityInvariance() {
-    verifyInvariance("orCardinalityInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> MutableRoaringBitmap.or(l, r).getCardinality(),
-            (l, r) -> MutableRoaringBitmap.orCardinality(l, r));
+    verifyInvariance(
+        "orCardinalityInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> MutableRoaringBitmap.or(l, r).getCardinality(),
+        (l, r) -> MutableRoaringBitmap.orCardinality(l, r));
   }
 
   @Test
   public void xorCardinalityInvariance() {
-    verifyInvariance("xorCardinalityInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> MutableRoaringBitmap.xor(l, r).getCardinality(),
-            (l, r) -> MutableRoaringBitmap.xorCardinality(l, r));
+    verifyInvariance(
+        "xorCardinalityInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> MutableRoaringBitmap.xor(l, r).getCardinality(),
+        (l, r) -> MutableRoaringBitmap.xorCardinality(l, r));
   }
 
   @Test
   public void containsContainsInvariance() {
-    verifyInvariance("containsContainsInvariance",
-            (l, r) -> l.contains(r) && !r.equals(l),
-            (l, r) -> false,
-            (l, r) -> !r.contains(l));
+    verifyInvariance(
+        "containsContainsInvariance",
+        (l, r) -> l.contains(r) && !r.equals(l),
+        (l, r) -> false,
+        (l, r) -> !r.contains(l));
   }
 
   @Test
   public void containsAndInvariance() {
-    verifyInvariance("containsAndInvariance",
-            (l, r) -> l.contains(r),
-            (l, r) -> MutableRoaringBitmap.and(l, r).equals(r));
+    verifyInvariance(
+        "containsAndInvariance",
+        (l, r) -> l.contains(r),
+        (l, r) -> MutableRoaringBitmap.and(l, r).equals(r));
   }
 
   @Test
   public void andCardinalityContainsInvariance() {
-    verifyInvariance("andCardinalityContainsInvariance",
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r) == 0,
-            (l, r) -> false,
-            (l, r) -> l.contains(r) || r.contains(l));
+    verifyInvariance(
+        "andCardinalityContainsInvariance",
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r) == 0,
+        (l, r) -> false,
+        (l, r) -> l.contains(r) || r.contains(l));
   }
 
   @Test
   public void sizeOfUnionOfDisjointSetsEqualsSumOfSizes() {
-    verifyInvariance("sizeOfUnionOfDisjointSetsEqualsSumOfSizes",
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r) == 0,
-            (l, r) -> l.getCardinality() + r.getCardinality(),
-            (l, r) -> MutableRoaringBitmap.orCardinality(l, r));
+    verifyInvariance(
+        "sizeOfUnionOfDisjointSetsEqualsSumOfSizes",
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r) == 0,
+        (l, r) -> l.getCardinality() + r.getCardinality(),
+        (l, r) -> MutableRoaringBitmap.orCardinality(l, r));
   }
 
   @Test
   public void sizeOfDifferenceOfDisjointSetsEqualsSumOfSizes() {
-    verifyInvariance("sizeOfDifferenceOfDisjointSetsEqualsSumOfSizes",
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r) == 0,
-            (l, r) -> l.getCardinality() + r.getCardinality(),
-            (l, r) -> MutableRoaringBitmap.xorCardinality(l, r));
+    verifyInvariance(
+        "sizeOfDifferenceOfDisjointSetsEqualsSumOfSizes",
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r) == 0,
+        (l, r) -> l.getCardinality() + r.getCardinality(),
+        (l, r) -> MutableRoaringBitmap.xorCardinality(l, r));
   }
 
   @Test
@@ -330,171 +376,201 @@ public void equalsSymmetryInvariance() {
 
   @Test
   public void orOfDisjunction() {
-    verifyInvariance("orOfDisjunction", ITERATIONS, 1 << 8,
-            (l, r) -> l,
-            (l, r) -> MutableRoaringBitmap.or(l, MutableRoaringBitmap.and(l, r)));
+    verifyInvariance(
+        "orOfDisjunction",
+        ITERATIONS,
+        1 << 8,
+        (l, r) -> l,
+        (l, r) -> MutableRoaringBitmap.or(l, MutableRoaringBitmap.and(l, r)));
   }
 
   @Test
   public void orCoversXor() {
-    verifyInvariance("orCoversXor", ITERATIONS, 1 << 8,
-            (l, r) -> MutableRoaringBitmap.or(l, r),
-            (l, r) -> MutableRoaringBitmap.or(l, MutableRoaringBitmap.xor(l, r)));
+    verifyInvariance(
+        "orCoversXor",
+        ITERATIONS,
+        1 << 8,
+        (l, r) -> MutableRoaringBitmap.or(l, r),
+        (l, r) -> MutableRoaringBitmap.or(l, MutableRoaringBitmap.xor(l, r)));
   }
 
   @Test
   public void xorInvariance() {
-    verifyInvariance("xorInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> MutableRoaringBitmap.xor(l, r),
-            (l, r) -> MutableRoaringBitmap.andNot(MutableRoaringBitmap.or(l, r), MutableRoaringBitmap.and(l, r)));
+    verifyInvariance(
+        "xorInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> MutableRoaringBitmap.xor(l, r),
+        (l, r) ->
+            MutableRoaringBitmap.andNot(
+                MutableRoaringBitmap.or(l, r), MutableRoaringBitmap.and(l, r)));
   }
 
   @Test
   public void rangeCardinalityVsMaterialisedRange() {
-    verifyInvariance("rangeCardinalityVsMaterialisedRange", 1 << 9,
-            (min, max, bitmap) -> {
-              MutableRoaringBitmap range = new MutableRoaringBitmap();
-              range.add(min, max);
-              return bitmap.rangeCardinality(min, max) == ImmutableRoaringBitmap.andCardinality(range, bitmap);
-            });
+    verifyInvariance(
+        "rangeCardinalityVsMaterialisedRange",
+        1 << 9,
+        (min, max, bitmap) -> {
+          MutableRoaringBitmap range = new MutableRoaringBitmap();
+          range.add(min, max);
+          return bitmap.rangeCardinality(min, max)
+              == ImmutableRoaringBitmap.andCardinality(range, bitmap);
+        });
   }
 
   @Test
   public void intersectsUpperBoundary() {
-    verifyInvariance("intersectsUpperBoundary", 1 << 9,
-            bitmap -> {
-              long max = bitmap.last() & 0xFFFFFFFFL;
-              return max == 0xFFFFFFFFL || bitmap.intersects(max - 1, max + 1);
-            });
+    verifyInvariance(
+        "intersectsUpperBoundary",
+        1 << 9,
+        bitmap -> {
+          long max = bitmap.last() & 0xFFFFFFFFL;
+          return max == 0xFFFFFFFFL || bitmap.intersects(max - 1, max + 1);
+        });
   }
 
   @Test
   public void intersectsLowerBoundary() {
-    verifyInvariance("intersectsLowerBoundary", 1 << 9,
-            bitmap -> {
-              long min = bitmap.first() & 0xFFFFFFFFL;
-              return min == 0 || bitmap.intersects(min - 1, min + 1);
-            });
+    verifyInvariance(
+        "intersectsLowerBoundary",
+        1 << 9,
+        bitmap -> {
+          long min = bitmap.first() & 0xFFFFFFFFL;
+          return min == 0 || bitmap.intersects(min - 1, min + 1);
+        });
   }
 
   @Test
   public void notIntersectsDisjointUpperBoundary() {
-    verifyInvariance("notIntersectsDisjointUpperBoundary", 1 << 9,
-            bitmap -> {
-              long max = (bitmap.last() & 0xFFFFFFFFL) + 1;
-              return !bitmap.intersects(max, 0xFFFFFFFFL);
-            });
+    verifyInvariance(
+        "notIntersectsDisjointUpperBoundary",
+        1 << 9,
+        bitmap -> {
+          long max = (bitmap.last() & 0xFFFFFFFFL) + 1;
+          return !bitmap.intersects(max, 0xFFFFFFFFL);
+        });
   }
 
   @Test
   public void notIntersectsDisjointLowerBoundary() {
-    verifyInvariance("notIntersectsDisjointLowerBoundary", 1 << 9,
-            bitmap -> {
-              long min = bitmap.first() & 0xFFFFFFFFL;
-              return !bitmap.intersects(0, min);
-            });
+    verifyInvariance(
+        "notIntersectsDisjointLowerBoundary",
+        1 << 9,
+        bitmap -> {
+          long min = bitmap.first() & 0xFFFFFFFFL;
+          return !bitmap.intersects(0, min);
+        });
   }
 
   @Test
   public void removeIntersection() {
-    verifyInvariance("removeIntersection",
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r) > 0,
-            1 << 12,
-            (l, r) -> {
-              int intersection = MutableRoaringBitmap.andCardinality(l, r);
-              MutableRoaringBitmap and = MutableRoaringBitmap.and(l, r);
-              IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
-              int removed = 0;
-              while (it.hasNext()) {
-                l.remove(it.next());
-                ++removed;
-              }
-              return removed == intersection;
-            });
+    verifyInvariance(
+        "removeIntersection",
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r) > 0,
+        1 << 12,
+        (l, r) -> {
+          int intersection = MutableRoaringBitmap.andCardinality(l, r);
+          MutableRoaringBitmap and = MutableRoaringBitmap.and(l, r);
+          IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
+          int removed = 0;
+          while (it.hasNext()) {
+            l.remove(it.next());
+            ++removed;
+          }
+          return removed == intersection;
+        });
   }
 
   @Test
   public void dontContainAfterRemoval() {
-    verifyInvariance("dontIntersectAfterRemoval",
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r) > 0,
-            1 << 12,
-            (l, r) -> {
-              int intersection = MutableRoaringBitmap.andCardinality(l, r);
-              MutableRoaringBitmap and = MutableRoaringBitmap.and(l, r);
-              long first = and.first() & 0xFFFFFFFFL;
-              int[] values = and.toArray();
-              int removed = 0;
-              for (int next : values) {
-                if (!l.intersects(toUnsignedLong(next) - 1, toUnsignedLong(next) + 1)) {
-                  return false;
-                }
-                l.remove(next);
-                if (l.contains(next)) {
-                  return false;
-                }
-                if (first != next && l.contains(first, toUnsignedLong(next))) {
-                  return false;
-                }
-                ++removed;
-              }
-              return removed == intersection;
-            });
+    verifyInvariance(
+        "dontIntersectAfterRemoval",
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r) > 0,
+        1 << 12,
+        (l, r) -> {
+          int intersection = MutableRoaringBitmap.andCardinality(l, r);
+          MutableRoaringBitmap and = MutableRoaringBitmap.and(l, r);
+          long first = and.first() & 0xFFFFFFFFL;
+          int[] values = and.toArray();
+          int removed = 0;
+          for (int next : values) {
+            if (!l.intersects(toUnsignedLong(next) - 1, toUnsignedLong(next) + 1)) {
+              return false;
+            }
+            l.remove(next);
+            if (l.contains(next)) {
+              return false;
+            }
+            if (first != next && l.contains(first, toUnsignedLong(next))) {
+              return false;
+            }
+            ++removed;
+          }
+          return removed == intersection;
+        });
   }
 
   @Test
   public void intersectsContainsRemove() {
-    verifyInvariance("intersectsContainsRemove",
-            (l, r) -> MutableRoaringBitmap.andCardinality(l, r) > 0,
-            1 << 12,
-            (l, r) -> {
-              MutableRoaringBitmap and = MutableRoaringBitmap.and(l, r);
-              if (!(l.contains(and) && r.contains(and))) {
-                return false;
-              }
-              long first = and.first() & 0xFFFFFFFFL;
-              long last = and.last() & 0xFFFFFFFFL;
-              IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
-              l.remove(first, last + 1);
-              while (it.hasNext()) {
-                long next = toUnsignedLong(it.next());
-                if (l.intersects(first, next) || (first != next && !r.intersects(first, next))) {
-                  return false;
-                }
-                if (l.contains(first, next)) {
-                  return false;
-                }
-              }
-              return !l.contains(and);
-            });
+    verifyInvariance(
+        "intersectsContainsRemove",
+        (l, r) -> MutableRoaringBitmap.andCardinality(l, r) > 0,
+        1 << 12,
+        (l, r) -> {
+          MutableRoaringBitmap and = MutableRoaringBitmap.and(l, r);
+          if (!(l.contains(and) && r.contains(and))) {
+            return false;
+          }
+          long first = and.first() & 0xFFFFFFFFL;
+          long last = and.last() & 0xFFFFFFFFL;
+          IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
+          l.remove(first, last + 1);
+          while (it.hasNext()) {
+            long next = toUnsignedLong(it.next());
+            if (l.intersects(first, next) || (first != next && !r.intersects(first, next))) {
+              return false;
+            }
+            if (l.contains(first, next)) {
+              return false;
+            }
+          }
+          return !l.contains(and);
+        });
   }
 
   @Test
   public void absentValuesConsistentWithBitSet() {
-    int[] offsets = new int[]{0, 1, -1, 10, -10, 100, -100};
-
-    // Size limit to avoid out of memory errors; r.last() > 0 to avoid bitmaps with last > Integer.MAX_VALUE
-    verifyInvariance(r -> r.isEmpty() || (r.last() > 0 && r.last() < 1 << 30), bitmap -> {
-      BitSet reference = new BitSet();
-      bitmap.forEach((IntConsumer) reference::set);
-
-      for (int next : bitmap) {
-        for (int offset : offsets) {
-          int pos = next + offset;
-          if (pos >= 0) {
-            assertEquals(reference.nextClearBit(pos), bitmap.nextAbsentValue(pos));
-            assertEquals(reference.previousClearBit(pos), bitmap.previousAbsentValue(pos));
+    int[] offsets = new int[] {0, 1, -1, 10, -10, 100, -100};
+
+    // Size limit to avoid out of memory errors; r.last() > 0 to avoid bitmaps with last >
+    // Integer.MAX_VALUE
+    verifyInvariance(
+        r -> r.isEmpty() || (r.last() > 0 && r.last() < 1 << 30),
+        bitmap -> {
+          BitSet reference = new BitSet();
+          bitmap.forEach((IntConsumer) reference::set);
+
+          for (int next : bitmap) {
+            for (int offset : offsets) {
+              int pos = next + offset;
+              if (pos >= 0) {
+                assertEquals(reference.nextClearBit(pos), bitmap.nextAbsentValue(pos));
+                assertEquals(reference.previousClearBit(pos), bitmap.previousAbsentValue(pos));
+              }
+            }
           }
-        }
-      }
-    });
+        });
   }
 
   @Test
   public void testFastAggregationAnd() {
     IntStream.range(0, ITERATIONS)
-            .parallel()
-            .forEach(i -> {
-              MutableRoaringBitmap[] bitmaps = new MutableRoaringBitmap[ThreadLocalRandom.current().nextInt(2, 20)];
+        .parallel()
+        .forEach(
+            i -> {
+              MutableRoaringBitmap[] bitmaps =
+                  new MutableRoaringBitmap[ThreadLocalRandom.current().nextInt(2, 20)];
               for (int j = 0; j < bitmaps.length; ++j) {
                 bitmaps[j] = randomBitmap(512);
               }
diff --git a/fuzz-tests/src/test/java/org/roaringbitmap/Fuzzer.java b/fuzz-tests/src/test/java/org/roaringbitmap/Fuzzer.java
index 2e73df0d3..493d18bae 100644
--- a/fuzz-tests/src/test/java/org/roaringbitmap/Fuzzer.java
+++ b/fuzz-tests/src/test/java/org/roaringbitmap/Fuzzer.java
@@ -1,21 +1,23 @@
 package org.roaringbitmap;
 
-import com.google.common.collect.ImmutableMap;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.roaringbitmap.RandomisedTestData.ITERATIONS;
+import static org.roaringbitmap.RandomisedTestData.randomBitmap;
+import static org.roaringbitmap.Util.toUnsignedLong;
 
+import com.google.common.collect.ImmutableMap;
 import org.junit.jupiter.api.Test;
 
 import java.util.BitSet;
 import java.util.concurrent.ThreadLocalRandom;
-import java.util.function.*;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.IntStream;
 
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.roaringbitmap.RandomisedTestData.ITERATIONS;
-import static org.roaringbitmap.RandomisedTestData.randomBitmap;
-import static org.roaringbitmap.Util.toUnsignedLong;
-
 public class Fuzzer {
 
   @FunctionalInterface
@@ -28,19 +30,18 @@ interface RangeBitmapPredicate {
     boolean test(long min, long max, RoaringBitmap bitmap);
   }
 
-  public static  void verifyInvariance(String testName, T value, Function func) {
+  public static  void verifyInvariance(
+      String testName, T value, Function func) {
     verifyInvariance(testName, ITERATIONS, 1 << 9, value, func);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          int count,
-                                          int maxKeys,
-                                          T value,
-                                          Function func) {
+  public static  void verifyInvariance(
+      String testName, int count, int maxKeys, T value, Function func) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .forEach(
+            bitmap -> {
               try {
                 assertEquals(value, func.apply(bitmap));
               } catch (Throwable e) {
@@ -50,12 +51,12 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-
   public static void verifyInvariance(String testName, int maxKeys, RangeBitmapPredicate pred) {
     IntStream.range(0, ITERATIONS)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .forEach(
+            bitmap -> {
               long min = ThreadLocalRandom.current().nextLong(1L << 32);
               long max = ThreadLocalRandom.current().nextLong(min, 1L << 32);
               try {
@@ -69,9 +70,10 @@ public static void verifyInvariance(String testName, int maxKeys, RangeBitmapPre
 
   public static void verifyInvariance(String testName, int maxKeys, Predicate pred) {
     IntStream.range(0, ITERATIONS)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .forEach(
+            bitmap -> {
               try {
                 assertTrue(pred.test(bitmap));
               } catch (Throwable e) {
@@ -81,24 +83,27 @@ public static void verifyInvariance(String testName, int maxKeys, Predicate void verifyInvariance(String testName,
-                                          Predicate validity,
-                                          Function left,
-                                          Function right) {
+  public static  void verifyInvariance(
+      String testName,
+      Predicate validity,
+      Function left,
+      Function right) {
     verifyInvariance(testName, ITERATIONS, 1 << 8, validity, left, right);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          int count,
-                                          int maxKeys,
-                                          Predicate validity,
-                                          Function left,
-                                          Function right) {
+  public static  void verifyInvariance(
+      String testName,
+      int count,
+      int maxKeys,
+      Predicate validity,
+      Function left,
+      Function right) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .filter(validity)
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .filter(validity)
+        .forEach(
+            bitmap -> {
               try {
                 assertEquals(left.apply(bitmap), right.apply(bitmap));
               } catch (Throwable e) {
@@ -108,37 +113,41 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      BiFunction left,
+      BiFunction right) {
     verifyInvariance(testName, ITERATIONS, 1 << 8, left, right);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      BiFunction left,
+      BiFunction right) {
     verifyInvariance(testName, validity, ITERATIONS, 1 << 8, left, right);
   }
 
-
-  public static  void verifyInvariance(String testName,
-                                          int count,
-                                          int maxKeys,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      int count,
+      int maxKeys,
+      BiFunction left,
+      BiFunction right) {
     verifyInvariance(testName, (l, r) -> true, count, maxKeys, left, right);
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          int count,
-                                          int maxKeys,
-                                          BiFunction left,
-                                          BiFunction right) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      int count,
+      int maxKeys,
+      BiFunction left,
+      BiFunction right) {
     IntStream.range(0, count)
-            .parallel()
-            .forEach(i -> {
+        .parallel()
+        .forEach(
+            i -> {
               RoaringBitmap one = randomBitmap(maxKeys);
               RoaringBitmap two = randomBitmap(maxKeys);
               if (validity.test(one, two)) {
@@ -152,22 +161,24 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          int maxKeys,
-                                          BiPredicate test) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      int maxKeys,
+      BiPredicate test) {
     verifyInvariance(testName, validity, ITERATIONS, maxKeys, test);
   }
 
-
-  public static  void verifyInvariance(String testName,
-                                          BiPredicate validity,
-                                          int count,
-                                          int maxKeys,
-                                          BiPredicate test) {
+  public static  void verifyInvariance(
+      String testName,
+      BiPredicate validity,
+      int count,
+      int maxKeys,
+      BiPredicate test) {
     IntStream.range(0, count)
-            .parallel()
-            .forEach(i -> {
+        .parallel()
+        .forEach(
+            i -> {
               RoaringBitmap one = randomBitmap(maxKeys);
               RoaringBitmap two = randomBitmap(maxKeys);
               if (validity.test(one, two)) {
@@ -181,22 +192,23 @@ public static  void verifyInvariance(String testName,
             });
   }
 
-  public static void verifyInvariance(String testName,
-                                      Predicate validity,
-                                      IntBitmapPredicate predicate) {
+  public static void verifyInvariance(
+      String testName, Predicate validity, IntBitmapPredicate predicate) {
     verifyInvariance(testName, validity, ITERATIONS, 1 << 3, predicate);
   }
 
-  public static void verifyInvariance(String testName,
-                                      Predicate validity,
-                                      int count,
-                                      int maxKeys,
-                                      IntBitmapPredicate predicate) {
+  public static void verifyInvariance(
+      String testName,
+      Predicate validity,
+      int count,
+      int maxKeys,
+      IntBitmapPredicate predicate) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .filter(validity)
-            .forEach(bitmap -> {
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .filter(validity)
+        .forEach(
+            bitmap -> {
               for (int i = 0; i < bitmap.getCardinality(); ++i) {
                 try {
                   assertTrue(predicate.test(i, bitmap));
@@ -208,103 +220,132 @@ public static void verifyInvariance(String testName,
             });
   }
 
-  public static void verifyInvariance(Predicate validity,
-                                      Consumer action) {
+  public static void verifyInvariance(
+      Predicate validity, Consumer action) {
     verifyInvariance(validity, ITERATIONS, 1 << 3, action);
   }
 
-  public static void verifyInvariance(Predicate validity,
-                                      int count,
-                                      int maxKeys,
-                                      Consumer action) {
+  public static void verifyInvariance(
+      Predicate validity, int count, int maxKeys, Consumer action) {
     IntStream.range(0, count)
-            .parallel()
-            .mapToObj(i -> randomBitmap(maxKeys))
-            .filter(validity)
-            .forEach(action);
+        .parallel()
+        .mapToObj(i -> randomBitmap(maxKeys))
+        .filter(validity)
+        .forEach(action);
   }
 
   @Test
   public void rankSelectInvariance() {
-    verifyInvariance("rankSelectInvariance", bitmap -> !bitmap.isEmpty(), (i, rb) -> rb.rank(rb.select(i)) == i + 1);
+    verifyInvariance(
+        "rankSelectInvariance",
+        bitmap -> !bitmap.isEmpty(),
+        (i, rb) -> rb.rank(rb.select(i)) == i + 1);
   }
 
   @Test
   public void selectContainsInvariance() {
-    verifyInvariance("rankSelectInvariance", bitmap -> !bitmap.isEmpty(), (i, rb) -> rb.contains(rb.select(i)));
+    verifyInvariance(
+        "rankSelectInvariance", bitmap -> !bitmap.isEmpty(), (i, rb) -> rb.contains(rb.select(i)));
   }
 
   @Test
   public void firstSelect0Invariance() {
-    verifyInvariance("rankSelectInvariance", bitmap -> !bitmap.isEmpty(),
-            l -> l.first(),
-            bitmap -> bitmap.select(0));
+    verifyInvariance(
+        "rankSelectInvariance",
+        bitmap -> !bitmap.isEmpty(),
+        l -> l.first(),
+        bitmap -> bitmap.select(0));
   }
 
   @Test
   public void lastSelectCardinalityInvariance() {
-    verifyInvariance("rankSelectInvariance", bitmap -> !bitmap.isEmpty(),
-            l -> l.last(),
-            bitmap -> bitmap.select(bitmap.getCardinality() - 1));
+    verifyInvariance(
+        "rankSelectInvariance",
+        bitmap -> !bitmap.isEmpty(),
+        l -> l.last(),
+        bitmap -> bitmap.select(bitmap.getCardinality() - 1));
   }
 
   @Test
   public void andCardinalityInvariance() {
-    verifyInvariance("andCardinalityInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> RoaringBitmap.and(l, r).getCardinality(),
-            (l, r) -> RoaringBitmap.andCardinality(l, r));
+    verifyInvariance(
+        "andCardinalityInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> RoaringBitmap.and(l, r).getCardinality(),
+        (l, r) -> RoaringBitmap.andCardinality(l, r));
   }
 
   @Test
   public void orCardinalityInvariance() {
-    verifyInvariance("orCardinalityInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> RoaringBitmap.or(l, r).getCardinality(),
-            (l, r) -> RoaringBitmap.orCardinality(l, r));
+    verifyInvariance(
+        "orCardinalityInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> RoaringBitmap.or(l, r).getCardinality(),
+        (l, r) -> RoaringBitmap.orCardinality(l, r));
   }
 
   @Test
   public void xorCardinalityInvariance() {
-    verifyInvariance("xorCardinalityInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> RoaringBitmap.xor(l, r).getCardinality(),
-            (l, r) -> RoaringBitmap.xorCardinality(l, r));
+    verifyInvariance(
+        "xorCardinalityInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> RoaringBitmap.xor(l, r).getCardinality(),
+        (l, r) -> RoaringBitmap.xorCardinality(l, r));
   }
 
   @Test
   public void containsContainsInvariance() {
-    verifyInvariance("containsContainsInvariance", (l, r) -> l.contains(r) && !r.equals(l),
-            (l, r) -> false,
-            (l, r) -> !r.contains(l));
+    verifyInvariance(
+        "containsContainsInvariance",
+        (l, r) -> l.contains(r) && !r.equals(l),
+        (l, r) -> false,
+        (l, r) -> !r.contains(l));
   }
 
   @Test
   public void containsAndInvariance() {
-    verifyInvariance("containsAndInvariance", (l, r) -> l.contains(r), (l, r) -> RoaringBitmap.and(l, r).equals(r));
+    verifyInvariance(
+        "containsAndInvariance",
+        (l, r) -> l.contains(r),
+        (l, r) -> RoaringBitmap.and(l, r).equals(r));
   }
 
-
   @Test
   public void limitCardinalityEqualsSelf() {
-    verifyInvariance("limitCardinalityEqualsSelf", true, rb -> rb.equals(rb.limit(rb.getCardinality())));
+    verifyInvariance(
+        "limitCardinalityEqualsSelf", true, rb -> rb.equals(rb.limit(rb.getCardinality())));
   }
 
   @Test
   public void limitCardinalityXorCardinalityInvariance() {
-    verifyInvariance("limitCardinalityXorCardinalityInvariance", rb -> true,
-            l -> l.getCardinality(),
-            rb -> rb.getCardinality() / 2
-                    + RoaringBitmap.xorCardinality(rb, rb.limit(rb.getCardinality() / 2)));
+    verifyInvariance(
+        "limitCardinalityXorCardinalityInvariance",
+        rb -> true,
+        l -> l.getCardinality(),
+        rb ->
+            rb.getCardinality() / 2
+                + RoaringBitmap.xorCardinality(rb, rb.limit(rb.getCardinality() / 2)));
   }
 
   @Test
   public void containsRangeFirstLastInvariance() {
-    verifyInvariance("containsRangeFirstLastInvariance", true,
-            rb -> RoaringBitmap.add(rb.clone(), toUnsignedLong(rb.first()), toUnsignedLong(rb.last()))
-                    .contains(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
+    verifyInvariance(
+        "containsRangeFirstLastInvariance",
+        true,
+        rb ->
+            RoaringBitmap.add(rb.clone(), toUnsignedLong(rb.first()), toUnsignedLong(rb.last()))
+                .contains(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
   }
 
   @Test
   public void intersectsRangeFirstLastInvariance() {
-    verifyInvariance("intersectsRangeFirstLastInvariance", true, rb -> rb.intersects(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
+    verifyInvariance(
+        "intersectsRangeFirstLastInvariance",
+        true,
+        rb -> rb.intersects(toUnsignedLong(rb.first()), toUnsignedLong(rb.last())));
   }
 
   @Test
@@ -319,23 +360,29 @@ public void containsSubset() {
 
   @Test
   public void andCardinalityContainsInvariance() {
-    verifyInvariance("andCardinalityContainsInvariance", (l, r) -> RoaringBitmap.andCardinality(l, r) == 0,
-            (l, r) -> false,
-            (l, r) -> l.contains(r) || r.contains(l));
+    verifyInvariance(
+        "andCardinalityContainsInvariance",
+        (l, r) -> RoaringBitmap.andCardinality(l, r) == 0,
+        (l, r) -> false,
+        (l, r) -> l.contains(r) || r.contains(l));
   }
 
   @Test
   public void sizeOfUnionOfDisjointSetsEqualsSumOfSizes() {
-    verifyInvariance("sizeOfUnionOfDisjointSetsEqualsSumOfSizes", (l, r) -> RoaringBitmap.andCardinality(l, r) == 0,
-            (l, r) -> l.getCardinality() + r.getCardinality(),
-            (l, r) -> RoaringBitmap.orCardinality(l, r));
+    verifyInvariance(
+        "sizeOfUnionOfDisjointSetsEqualsSumOfSizes",
+        (l, r) -> RoaringBitmap.andCardinality(l, r) == 0,
+        (l, r) -> l.getCardinality() + r.getCardinality(),
+        (l, r) -> RoaringBitmap.orCardinality(l, r));
   }
 
   @Test
   public void sizeOfDifferenceOfDisjointSetsEqualsSumOfSizes() {
-    verifyInvariance("sizeOfDifferenceOfDisjointSetsEqualsSumOfSizes", (l, r) -> RoaringBitmap.andCardinality(l, r) == 0,
-            (l, r) -> l.getCardinality() + r.getCardinality(),
-            (l, r) -> RoaringBitmap.xorCardinality(l, r));
+    verifyInvariance(
+        "sizeOfDifferenceOfDisjointSetsEqualsSumOfSizes",
+        (l, r) -> RoaringBitmap.andCardinality(l, r) == 0,
+        (l, r) -> l.getCardinality() + r.getCardinality(),
+        (l, r) -> RoaringBitmap.xorCardinality(l, r));
   }
 
   @Test
@@ -345,220 +392,254 @@ public void equalsSymmetryInvariance() {
 
   @Test
   public void orOfDisjunction() {
-    verifyInvariance("orOfDisjunction", ITERATIONS, 1 << 8,
-            (l, r) -> l,
-            (l, r) -> RoaringBitmap.or(l, RoaringBitmap.and(l, r)));
+    verifyInvariance(
+        "orOfDisjunction",
+        ITERATIONS,
+        1 << 8,
+        (l, r) -> l,
+        (l, r) -> RoaringBitmap.or(l, RoaringBitmap.and(l, r)));
   }
 
   @Test
   public void orCoversXor() {
-    verifyInvariance("orCoversXor", ITERATIONS, 1 << 8,
-            (l, r) -> RoaringBitmap.or(l, r),
-            (l, r) -> RoaringBitmap.or(l, RoaringBitmap.xor(l, r)));
+    verifyInvariance(
+        "orCoversXor",
+        ITERATIONS,
+        1 << 8,
+        (l, r) -> RoaringBitmap.or(l, r),
+        (l, r) -> RoaringBitmap.or(l, RoaringBitmap.xor(l, r)));
   }
 
   @Test
   public void xorInvariance() {
-    verifyInvariance("xorInvariance", ITERATIONS, 1 << 9,
-            (l, r) -> RoaringBitmap.xor(l, r),
-            (l, r) -> RoaringBitmap.andNot(RoaringBitmap.or(l, r), RoaringBitmap.and(l, r)));
+    verifyInvariance(
+        "xorInvariance",
+        ITERATIONS,
+        1 << 9,
+        (l, r) -> RoaringBitmap.xor(l, r),
+        (l, r) -> RoaringBitmap.andNot(RoaringBitmap.or(l, r), RoaringBitmap.and(l, r)));
   }
 
   @Test
   public void rangeCardinalityVsMaterialisedRange() {
-    verifyInvariance("rangeCardinalityVsMaterialisedRange", 1 << 9,
-            (min, max, bitmap) -> {
-              RoaringBitmap range = new RoaringBitmap();
-              range.add(min, max);
-              return bitmap.rangeCardinality(min, max) == RoaringBitmap.andCardinality(range, bitmap);
-            });
+    verifyInvariance(
+        "rangeCardinalityVsMaterialisedRange",
+        1 << 9,
+        (min, max, bitmap) -> {
+          RoaringBitmap range = new RoaringBitmap();
+          range.add(min, max);
+          return bitmap.rangeCardinality(min, max) == RoaringBitmap.andCardinality(range, bitmap);
+        });
   }
 
   @Test
   public void intersectsUpperBoundary() {
-    verifyInvariance("intersectsUpperBoundary", 1 << 9,
-            (RoaringBitmap bitmap) -> {
-              long max = bitmap.last() & 0xFFFFFFFFL;
-              return max == 0xFFFFFFFFL || bitmap.intersects(max - 1, max + 1);
-            });
+    verifyInvariance(
+        "intersectsUpperBoundary",
+        1 << 9,
+        (RoaringBitmap bitmap) -> {
+          long max = bitmap.last() & 0xFFFFFFFFL;
+          return max == 0xFFFFFFFFL || bitmap.intersects(max - 1, max + 1);
+        });
   }
 
   @Test
   public void intersectsLowerBoundary() {
-    verifyInvariance("intersectsLowerBoundary", 1 << 9,
-            (RoaringBitmap bitmap) -> {
-              long min = bitmap.first() & 0xFFFFFFFFL;
-              return min == 0 || bitmap.intersects(min - 1, min + 1);
-            });
+    verifyInvariance(
+        "intersectsLowerBoundary",
+        1 << 9,
+        (RoaringBitmap bitmap) -> {
+          long min = bitmap.first() & 0xFFFFFFFFL;
+          return min == 0 || bitmap.intersects(min - 1, min + 1);
+        });
   }
 
   @Test
   public void notIntersectsDisjointUpperBoundary() {
-    verifyInvariance("notIntersectsDisjointUpperBoundary", 1 << 9,
-            (RoaringBitmap bitmap) -> {
-              long max = (bitmap.last() & 0xFFFFFFFFL) + 1;
-              return !bitmap.intersects(max, 0xFFFFFFFFL);
-            });
+    verifyInvariance(
+        "notIntersectsDisjointUpperBoundary",
+        1 << 9,
+        (RoaringBitmap bitmap) -> {
+          long max = (bitmap.last() & 0xFFFFFFFFL) + 1;
+          return !bitmap.intersects(max, 0xFFFFFFFFL);
+        });
   }
 
   @Test
   public void notIntersectsDisjointLowerBoundary() {
-    verifyInvariance("notIntersectsDisjointLowerBoundary", 1 << 9,
-            (RoaringBitmap bitmap) -> {
-              long min = bitmap.first() & 0xFFFFFFFFL;
-              return !bitmap.intersects(0, min);
-            });
+    verifyInvariance(
+        "notIntersectsDisjointLowerBoundary",
+        1 << 9,
+        (RoaringBitmap bitmap) -> {
+          long min = bitmap.first() & 0xFFFFFFFFL;
+          return !bitmap.intersects(0, min);
+        });
   }
 
   @Test
   public void removeIntersection() {
-    verifyInvariance("removeIntersection",
-            (l, r) -> RoaringBitmap.andCardinality(l, r) > 0,
-            1 << 12,
-            (l, r) -> {
-              int intersection = RoaringBitmap.andCardinality(l, r);
-              RoaringBitmap and = RoaringBitmap.and(l, r);
-              IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
-              int removed = 0;
-              while (it.hasNext()) {
-                l.remove(it.next());
-                ++removed;
-              }
-              return removed == intersection;
-            });
+    verifyInvariance(
+        "removeIntersection",
+        (l, r) -> RoaringBitmap.andCardinality(l, r) > 0,
+        1 << 12,
+        (l, r) -> {
+          int intersection = RoaringBitmap.andCardinality(l, r);
+          RoaringBitmap and = RoaringBitmap.and(l, r);
+          IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
+          int removed = 0;
+          while (it.hasNext()) {
+            l.remove(it.next());
+            ++removed;
+          }
+          return removed == intersection;
+        });
   }
 
   @Test
   public void dontContainAfterRemoval() {
-    verifyInvariance("dontIntersectAfterRemoval",
-            (l, r) -> RoaringBitmap.andCardinality(l, r) > 0,
-            1 << 12,
-            (l, r) -> {
-              int intersection = RoaringBitmap.andCardinality(l, r);
-              RoaringBitmap and = RoaringBitmap.and(l, r);
-              long first = and.first() & 0xFFFFFFFFL;
-              int[] values = and.toArray();
-              int removed = 0;
-              for (int next : values) {
-                if (!l.intersects(toUnsignedLong(next) - 1, toUnsignedLong(next) + 1)) {
-                  return false;
-                }
-                l.remove(next);
-                if (l.contains(next)) {
-                  return false;
-                }
-                if (first != next && l.contains(first, toUnsignedLong(next))) {
-                  return false;
-                }
-                ++removed;
-              }
-              return removed == intersection;
-            });
+    verifyInvariance(
+        "dontIntersectAfterRemoval",
+        (l, r) -> RoaringBitmap.andCardinality(l, r) > 0,
+        1 << 12,
+        (l, r) -> {
+          int intersection = RoaringBitmap.andCardinality(l, r);
+          RoaringBitmap and = RoaringBitmap.and(l, r);
+          long first = and.first() & 0xFFFFFFFFL;
+          int[] values = and.toArray();
+          int removed = 0;
+          for (int next : values) {
+            if (!l.intersects(toUnsignedLong(next) - 1, toUnsignedLong(next) + 1)) {
+              return false;
+            }
+            l.remove(next);
+            if (l.contains(next)) {
+              return false;
+            }
+            if (first != next && l.contains(first, toUnsignedLong(next))) {
+              return false;
+            }
+            ++removed;
+          }
+          return removed == intersection;
+        });
   }
 
   @Test
   public void intersectsContainsRemove() {
-    verifyInvariance("intersectsContainsRemove",
-            (l, r) -> RoaringBitmap.andCardinality(l, r) > 0,
-            1 << 12,
-            (l, r) -> {
-              RoaringBitmap and = RoaringBitmap.and(l, r);
-              if (!(l.contains(and) && r.contains(and))) {
-                return false;
-              }
-              long first = and.first() & 0xFFFFFFFFL;
-              long last = and.last() & 0xFFFFFFFFL;
-              IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
-              l.remove(first, last + 1);
-              while (it.hasNext()) {
-                long next = toUnsignedLong(it.next());
-                if (l.intersects(first, next) || (first != next && !r.intersects(first, next))) {
-                  return false;
-                }
-                if (l.contains(first, next)) {
-                  return false;
-                }
-              }
-              return !l.contains(and);
-            });
+    verifyInvariance(
+        "intersectsContainsRemove",
+        (l, r) -> RoaringBitmap.andCardinality(l, r) > 0,
+        1 << 12,
+        (l, r) -> {
+          RoaringBitmap and = RoaringBitmap.and(l, r);
+          if (!(l.contains(and) && r.contains(and))) {
+            return false;
+          }
+          long first = and.first() & 0xFFFFFFFFL;
+          long last = and.last() & 0xFFFFFFFFL;
+          IntIterator it = and.getBatchIterator().asIntIterator(new int[16]);
+          l.remove(first, last + 1);
+          while (it.hasNext()) {
+            long next = toUnsignedLong(it.next());
+            if (l.intersects(first, next) || (first != next && !r.intersects(first, next))) {
+              return false;
+            }
+            if (l.contains(first, next)) {
+              return false;
+            }
+          }
+          return !l.contains(and);
+        });
   }
 
   @Test
   public void orNotDoesNotTruncate() {
-    verifyInvariance("orNotDoesNotTruncate",
-            (l, r) -> !l.isEmpty() && (r.isEmpty() || l.last() > r.last()),
-            1 << 12,
-            (l, r) -> {
-              int last = l.last();
-              if (last > 1) {
-                long rangeEnd = ThreadLocalRandom.current().nextLong(0, last - 1);
-                l.orNot(r, rangeEnd);
-                return l.contains(last);
-              }
-              return true;
-            });
+    verifyInvariance(
+        "orNotDoesNotTruncate",
+        (l, r) -> !l.isEmpty() && (r.isEmpty() || l.last() > r.last()),
+        1 << 12,
+        (l, r) -> {
+          int last = l.last();
+          if (last > 1) {
+            long rangeEnd = ThreadLocalRandom.current().nextLong(0, last - 1);
+            l.orNot(r, rangeEnd);
+            return l.contains(last);
+          }
+          return true;
+        });
   }
 
   @Test
   public void orNot() {
-    verifyInvariance("orNot", ITERATIONS, 1 << 9,
-            (RoaringBitmap l, RoaringBitmap r) -> {
-              RoaringBitmap x = l.clone();
-              long max = (x.last() & 0xFFFFFFFFL) + 1;
-              x.orNot(r, max);
-              return x;
-            },
-            (RoaringBitmap l, RoaringBitmap r) -> {
-              RoaringBitmap range = new RoaringBitmap();
-              long limit = toUnsignedLong(l.last()) + 1;
-              range.add(0, limit);
-              range.andNot(r);
-              return RoaringBitmap.or(l, range);
-            });
+    verifyInvariance(
+        "orNot",
+        ITERATIONS,
+        1 << 9,
+        (RoaringBitmap l, RoaringBitmap r) -> {
+          RoaringBitmap x = l.clone();
+          long max = (x.last() & 0xFFFFFFFFL) + 1;
+          x.orNot(r, max);
+          return x;
+        },
+        (RoaringBitmap l, RoaringBitmap r) -> {
+          RoaringBitmap range = new RoaringBitmap();
+          long limit = toUnsignedLong(l.last()) + 1;
+          range.add(0, limit);
+          range.andNot(r);
+          return RoaringBitmap.or(l, range);
+        });
   }
 
   @Test
   public void orNotStatic() {
-    verifyInvariance("orNot", ITERATIONS, 1 << 9,
-            (RoaringBitmap l, RoaringBitmap r) -> {
-              RoaringBitmap x = l.clone();
-              long max = (x.last() & 0xFFFFFFFFL) + 1;
-              x.orNot(r, max);
-              return x;
-            },
-            (RoaringBitmap l, RoaringBitmap r) -> {
-              RoaringBitmap x = l.clone();
-              long max = (x.last() & 0xFFFFFFFFL) + 1;
-              return RoaringBitmap.orNot(l, r, max);
-            });
+    verifyInvariance(
+        "orNot",
+        ITERATIONS,
+        1 << 9,
+        (RoaringBitmap l, RoaringBitmap r) -> {
+          RoaringBitmap x = l.clone();
+          long max = (x.last() & 0xFFFFFFFFL) + 1;
+          x.orNot(r, max);
+          return x;
+        },
+        (RoaringBitmap l, RoaringBitmap r) -> {
+          RoaringBitmap x = l.clone();
+          long max = (x.last() & 0xFFFFFFFFL) + 1;
+          return RoaringBitmap.orNot(l, r, max);
+        });
   }
 
   @Test
   public void absentValuesConsistentWithBitSet() {
-    int[] offsets = new int[]{0, 1, -1, 10, -10, 100, -100};
-    // Size limit to avoid out of memory errors; r.last() > 0 to avoid bitmaps with last > Integer.MAX_VALUE
-    verifyInvariance(r -> r.isEmpty() || (r.last() > 0 && r.last() < 1 << 30), bitmap -> {
-      BitSet reference = new BitSet();
-      bitmap.forEach((IntConsumer) reference::set);
-
-      for (int next : bitmap) {
-        for (int offset : offsets) {
-          int pos = next + offset;
-          if (pos >= 0) {
-            assertEquals(reference.nextClearBit(pos), bitmap.nextAbsentValue(pos));
-            assertEquals(reference.previousClearBit(pos), bitmap.previousAbsentValue(pos));
+    int[] offsets = new int[] {0, 1, -1, 10, -10, 100, -100};
+    // Size limit to avoid out of memory errors; r.last() > 0 to avoid bitmaps with last >
+    // Integer.MAX_VALUE
+    verifyInvariance(
+        r -> r.isEmpty() || (r.last() > 0 && r.last() < 1 << 30),
+        bitmap -> {
+          BitSet reference = new BitSet();
+          bitmap.forEach((IntConsumer) reference::set);
+
+          for (int next : bitmap) {
+            for (int offset : offsets) {
+              int pos = next + offset;
+              if (pos >= 0) {
+                assertEquals(reference.nextClearBit(pos), bitmap.nextAbsentValue(pos));
+                assertEquals(reference.previousClearBit(pos), bitmap.previousAbsentValue(pos));
+              }
+            }
           }
-        }
-      }
-    });
+        });
   }
 
   @Test
   public void testFastAggregationAnd() {
     IntStream.range(0, ITERATIONS)
-            .parallel()
-            .forEach(i -> {
-              RoaringBitmap[] bitmaps = new RoaringBitmap[ThreadLocalRandom.current().nextInt(2, 20)];
+        .parallel()
+        .forEach(
+            i -> {
+              RoaringBitmap[] bitmaps =
+                  new RoaringBitmap[ThreadLocalRandom.current().nextInt(2, 20)];
               for (int j = 0; j < bitmaps.length; ++j) {
                 bitmaps[j] = randomBitmap(512);
               }
diff --git a/fuzz-tests/src/test/java/org/roaringbitmap/RandomisedTestData.java b/fuzz-tests/src/test/java/org/roaringbitmap/RandomisedTestData.java
index 4e25cb1ad..1b8bbb869 100644
--- a/fuzz-tests/src/test/java/org/roaringbitmap/RandomisedTestData.java
+++ b/fuzz-tests/src/test/java/org/roaringbitmap/RandomisedTestData.java
@@ -1,42 +1,44 @@
 package org.roaringbitmap;
 
+import static java.lang.Integer.parseInt;
+import static org.roaringbitmap.RoaringBitmapWriter.writer;
+
 import java.util.Arrays;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.stream.IntStream;
 
-import static java.lang.Integer.parseInt;
-import static org.roaringbitmap.RoaringBitmapWriter.writer;
-
 public class RandomisedTestData {
 
-  public static final int ITERATIONS = parseInt(System.getProperty("org.roaringbitmap.fuzz.iterations", "10000"));
+  public static final int ITERATIONS =
+      parseInt(System.getProperty("org.roaringbitmap.fuzz.iterations", "10000"));
 
   private static final ThreadLocal bits = ThreadLocal.withInitial(() -> new long[1 << 10]);
   private static final ThreadLocal runs = ThreadLocal.withInitial(() -> new int[4096]);
 
   public static RoaringBitmap randomBitmap(int maxKeys, double rleLimit, double denseLimit) {
-    return randomBitmap(maxKeys, rleLimit, denseLimit,  writer().initialCapacity(maxKeys).optimiseForArrays().get());
+    return randomBitmap(
+        maxKeys, rleLimit, denseLimit, writer().initialCapacity(maxKeys).optimiseForArrays().get());
   }
 
   public static RoaringBitmap randomBitmap(int maxKeys) {
-      double rleLimit = ThreadLocalRandom.current().nextDouble();
-      double denseLimit = ThreadLocalRandom.current().nextDouble(rleLimit, 1D);
-      return randomBitmap(maxKeys, rleLimit, denseLimit);
+    double rleLimit = ThreadLocalRandom.current().nextDouble();
+    double denseLimit = ThreadLocalRandom.current().nextDouble(rleLimit, 1D);
+    return randomBitmap(maxKeys, rleLimit, denseLimit);
   }
 
-  public static  T randomBitmap(int maxKeys, RoaringBitmapWriter writer) {
-      double rleLimit = ThreadLocalRandom.current().nextDouble();
-      double denseLimit = ThreadLocalRandom.current().nextDouble(rleLimit, 1D);
-      return randomBitmap(maxKeys, rleLimit, denseLimit, writer);
+  public static  T randomBitmap(
+      int maxKeys, RoaringBitmapWriter writer) {
+    double rleLimit = ThreadLocalRandom.current().nextDouble();
+    double denseLimit = ThreadLocalRandom.current().nextDouble(rleLimit, 1D);
+    return randomBitmap(maxKeys, rleLimit, denseLimit, writer);
   }
 
-  private static  T randomBitmap(int maxKeys,
-                                                       double rleLimit,
-                                                       double denseLimit,
-                                                       RoaringBitmapWriter writer) {
+  private static  T randomBitmap(
+      int maxKeys, double rleLimit, double denseLimit, RoaringBitmapWriter writer) {
     int[] keys = createSorted16BitInts(ThreadLocalRandom.current().nextInt(1, maxKeys));
     IntStream.of(keys)
-            .forEach(key -> {
+        .forEach(
+            key -> {
               double choice = ThreadLocalRandom.current().nextDouble();
               final IntStream stream;
               if (choice < rleLimit) {
@@ -59,17 +61,17 @@ private static IntStream rleRegion() {
     int start = ThreadLocalRandom.current().nextInt(64);
     int run = 0;
     while (minRequiredCardinality > 0 && start < 0xFFFF && run < 2 * maxNumRuns) {
-        int runLength = ThreadLocalRandom.current().nextInt(1, minRequiredCardinality + 1);
-        values[run++] = start;
-        values[run++] = Math.min(start + runLength, 0x10000 - start);
-        start += runLength + ThreadLocalRandom.current().nextInt(64);
-        minRequiredCardinality -= runLength;
-        ++totalRuns;
+      int runLength = ThreadLocalRandom.current().nextInt(1, minRequiredCardinality + 1);
+      values[run++] = start;
+      values[run++] = Math.min(start + runLength, 0x10000 - start);
+      start += runLength + ThreadLocalRandom.current().nextInt(64);
+      minRequiredCardinality -= runLength;
+      ++totalRuns;
     }
     return IntStream.range(0, totalRuns)
-            .map(i -> i * 2)
-            .mapToObj(i -> IntStream.range(values[i], values[i + 1]))
-            .flatMapToInt(i -> i);
+        .map(i -> i * 2)
+        .mapToObj(i -> IntStream.range(values[i], values[i + 1]))
+        .flatMapToInt(i -> i);
   }
 
   private static IntStream sparseRegion() {
diff --git a/fuzz-tests/src/test/java/org/roaringbitmap/Reporter.java b/fuzz-tests/src/test/java/org/roaringbitmap/Reporter.java
index 2613542ec..a5a5d7033 100644
--- a/fuzz-tests/src/test/java/org/roaringbitmap/Reporter.java
+++ b/fuzz-tests/src/test/java/org/roaringbitmap/Reporter.java
@@ -1,5 +1,7 @@
 package org.roaringbitmap;
 
+import static java.util.stream.Collectors.toList;
+
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.io.ByteArrayDataOutput;
 import com.google.common.io.ByteStreams;
@@ -8,16 +10,23 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.*;
-
-import static java.util.stream.Collectors.toList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.UUID;
 
 public class Reporter {
 
-  private static final String OUTPUT_DIR = System.getProperty("org.roaringbitmap.fuzz.output", System.getProperty("user.dir"));
+  private static final String OUTPUT_DIR =
+      System.getProperty("org.roaringbitmap.fuzz.output", System.getProperty("user.dir"));
   private static final ObjectMapper MAPPER = new ObjectMapper();
 
-  public static synchronized void report(String testName, Map context, Throwable error, ImmutableBitmapDataProvider... bitmaps) {
+  public static synchronized void report(
+      String testName,
+      Map context,
+      Throwable error,
+      ImmutableBitmapDataProvider... bitmaps) {
     try {
       Map output = new LinkedHashMap<>();
       output.put("testName", testName);
@@ -25,7 +34,8 @@ public static synchronized void report(String testName, Map cont
       output.putAll(context);
       String[] base64 = new String[bitmaps.length];
       for (int i = 0; i < bitmaps.length; ++i) {
-        ByteArrayDataOutput serialised = ByteStreams.newDataOutput(bitmaps[i].serializedSizeInBytes());
+        ByteArrayDataOutput serialised =
+            ByteStreams.newDataOutput(bitmaps[i].serializedSizeInBytes());
         bitmaps[i].serialize(serialised);
         base64[i] = Base64.getEncoder().encodeToString(serialised.toByteArray());
       }
@@ -34,13 +44,17 @@ public static synchronized void report(String testName, Map cont
       if (!Files.exists(dir)) {
         Files.createDirectory(dir);
       }
-      Files.write(dir.resolve(testName + "-" + UUID.randomUUID() + ".json"), MAPPER.writeValueAsBytes(output));
+      Files.write(
+          dir.resolve(testName + "-" + UUID.randomUUID() + ".json"),
+          MAPPER.writeValueAsBytes(output));
     } catch (IOException e) {
       e.printStackTrace();
     }
   }
 
   private static String getStackTrace(Throwable t) {
-    return String.join("\n\t", Arrays.stream(t.getStackTrace()).map(StackTraceElement::toString).collect(toList()));
+    return String.join(
+        "\n\t",
+        Arrays.stream(t.getStackTrace()).map(StackTraceElement::toString).collect(toList()));
   }
 }
diff --git a/jmh/build.gradle.kts b/jmh/build.gradle.kts
index 4964a0f48..7affcbc64 100644
--- a/jmh/build.gradle.kts
+++ b/jmh/build.gradle.kts
@@ -1,5 +1,3 @@
-import java.net.URI
-
 plugins {
     id("me.champeau.gradle.jmh") version "0.5.0"
     id("com.github.johnrengelman.shadow") version "6.0.0"
diff --git a/jmh/src/jmh/java/org/roaringbitmap/AbstractBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/AbstractBenchmarkState.java
index 5f61c09f1..436246407 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/AbstractBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/AbstractBenchmarkState.java
@@ -22,18 +22,18 @@
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.newRoaringWithRunBitmap;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.newWahBitmap;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
 import org.roaringbitmap.realdata.wrapper.Bitmap;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.Lists;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
 
 @State(Scope.Benchmark)
 public abstract class AbstractBenchmarkState {
@@ -48,24 +48,27 @@ public abstract class AbstractBenchmarkState {
   public AbstractBenchmarkState() {}
 
   public void setup(final String dataset, String type, boolean immutable) throws Exception {
-    if (ROARING_ONLY.equals(System.getProperty(BITMAP_TYPES)) && !ROARING.equals(type)
+    if (ROARING_ONLY.equals(System.getProperty(BITMAP_TYPES))
+        && !ROARING.equals(type)
         && !ROARING_WITH_RUN.equals(type)) {
       throw new RuntimeException(String.format("Skipping non Roaring type %s", type));
     }
 
     bitmaps = new ArrayList();
 
-    List ints = DATASET_CACHE.get(dataset, new Callable>() {
+    List ints =
+        DATASET_CACHE.get(
+            dataset,
+            new Callable>() {
 
-      @Override
-      public List call() throws Exception {
-        System.out.println("Loading" + dataset);
-        ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
-
-        return Lists.newArrayList(dataRetriever.fetchBitPositions());
-      }
-    });
+              @Override
+              public List call() throws Exception {
+                System.out.println("Loading" + dataset);
+                ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
 
+                return Lists.newArrayList(dataRetriever.fetchBitPositions());
+              }
+            });
 
     for (int[] data : ints) {
       Bitmap bitmap = null;
@@ -114,7 +117,6 @@ public List call() throws Exception {
       }
 
       bitmaps.add(bitmap);
-
     }
   }
 
@@ -122,5 +124,4 @@ public List call() throws Exception {
   public void tearDown() {
     cleanup();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java
index b7e2290cb..8d68960d0 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/AddOffsetBenchmark.java
@@ -1,6 +1,17 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 
 import java.util.concurrent.TimeUnit;
 
@@ -9,21 +20,24 @@
 @Measurement(iterations = 10, timeUnit = TimeUnit.MILLISECONDS, time = 5000)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
 @State(Scope.Benchmark)
-@Fork(value = 1, jvmArgsPrepend =
-    {
-        "-XX:-TieredCompilation",
-        "-XX:+UseSerialGC", // "-XX:+UseParallelGC",
-        "-mx2G",
-        "-ms2G",
-        "-XX:+AlwaysPreTouch"
+@Fork(
+    value = 1,
+    jvmArgsPrepend = {
+      "-XX:-TieredCompilation",
+      "-XX:+UseSerialGC", // "-XX:+UseParallelGC",
+      "-mx2G",
+      "-ms2G",
+      "-XX:+AlwaysPreTouch"
     })
 public class AddOffsetBenchmark {
   @Param({
-      "ARRAY_ALL_IN_LOW", "ARRAY_HALF_TO_HALF", "ARRAY_ALL_SHIFTED_TO_HIGH",
-      // all variant provided for completeness only, original and current implementation are the same
-      // "RUN_ALL_IN_LOW", "RUN_HALF_TO_HALF", "RUN_ALL_SHIFTED_TO_HIGH",
-      // "BITMAP_ALL_IN_LOW", "BITMAP_HALF_TO_HALF", "BITMAP_ALL_SHIFTED_TO_HIGH",
-      // "BITMAP_HALF_TO_HALF_MULTIPLE_OF_LONG", "BITMAP_ALL_SHIFTED_TO_HIGH_MULTIPLE_OF_LONG",
+    "ARRAY_ALL_IN_LOW",
+    "ARRAY_HALF_TO_HALF",
+    "ARRAY_ALL_SHIFTED_TO_HIGH",
+    // all variant provided for completeness only, original and current implementation are the same
+    // "RUN_ALL_IN_LOW", "RUN_HALF_TO_HALF", "RUN_ALL_SHIFTED_TO_HIGH",
+    // "BITMAP_ALL_IN_LOW", "BITMAP_HALF_TO_HALF", "BITMAP_ALL_SHIFTED_TO_HIGH",
+    // "BITMAP_HALF_TO_HALF_MULTIPLE_OF_LONG", "BITMAP_ALL_SHIFTED_TO_HIGH_MULTIPLE_OF_LONG",
   })
   Scenario scenario;
 
@@ -86,7 +100,8 @@ public Container createContainer() {
         }
         return bc;
       }
-    }, ARRAY {
+    },
+    ARRAY {
       @Override
       public Container createContainer() {
         ArrayContainer ac = new ArrayContainer();
@@ -106,7 +121,6 @@ public Container createContainer() {
   public Container container;
   public char offsets;
 
-
   @Setup(Level.Invocation)
   public void setUp() {
     container = scenario.createContainer();
@@ -149,7 +163,7 @@ public static Container[] addOffsetOriginal(Container source, char offsets) {
           high.content[high.cardinality++] = (char) val;
         }
       }
-      return new Container[]{low, high};
+      return new Container[] {low, high};
     } else if (source instanceof BitmapContainer) {
       BitmapContainer c = (BitmapContainer) source;
       BitmapContainer low = new BitmapContainer();
@@ -167,13 +181,11 @@ public static Container[] addOffsetOriginal(Container source, char offsets) {
           low.bitmap[b + k] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64 - i));
         }
         for (int k = 1024 - b; k < 1024; k++) {
-          high.bitmap[k - (1024 - b)] =
-              (c.bitmap[k] << i)
-                  | (c.bitmap[k - 1] >>> (64 - i));
+          high.bitmap[k - (1024 - b)] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64 - i));
         }
         high.bitmap[b] = (c.bitmap[1024 - 1] >>> (64 - i));
       }
-      return new Container[]{low.repairAfterLazy(), high.repairAfterLazy()};
+      return new Container[] {low.repairAfterLazy(), high.repairAfterLazy()};
     } else if (source instanceof RunContainer) {
       RunContainer input = (RunContainer) source;
       RunContainer low = new RunContainer();
@@ -193,7 +205,7 @@ public static Container[] addOffsetOriginal(Container source, char offsets) {
           high.smartAppend((char) val, input.getLength(k));
         }
       }
-      return new Container[]{low, high};
+      return new Container[] {low, high};
     }
     throw new RuntimeException("unknown container type"); // never happens
   }
@@ -218,8 +230,8 @@ private static Container[] addOffsetIncrementField(ArrayContainer source, char o
       }
       low.cardinality = source.cardinality;
     } else {
-      int splitIndex = Util.unsignedBinarySearch(source.content, 0, source.cardinality,
-          (char) ~offsets);
+      int splitIndex =
+          Util.unsignedBinarySearch(source.content, 0, source.cardinality, (char) ~offsets);
       if (splitIndex < 0) {
         splitIndex = -splitIndex - 1;
       }
@@ -234,6 +246,6 @@ private static Container[] addOffsetIncrementField(ArrayContainer source, char o
         high.content[high.cardinality++] = (char) val;
       }
     }
-    return new Container[]{low, high};
+    return new Container[] {low, high};
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java
index 48f5f7500..e8ea2b7e6 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/AdvanceIfNeededBenchmark.java
@@ -1,9 +1,19 @@
 package org.roaringbitmap;
 
-import com.google.common.primitives.Ints;
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
+import com.google.common.primitives.Ints;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
 import java.util.Arrays;
 import java.util.LinkedHashSet;
 import java.util.Random;
@@ -15,40 +25,41 @@
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
 @State(Scope.Benchmark)
 public class AdvanceIfNeededBenchmark {
-    public static MutableRoaringBitmap c2;
-    public static PeekableIntIterator it;
-
-    private static int[] takeSortedAndDistinct(Random source, int count) {
-        LinkedHashSet ints = new LinkedHashSet<>(count);
-        for (int size = 0; size < count; size++) {
-            int next;
-            do {
-                next = source.nextInt(1000000);
-            } while (!ints.add(next));
-        }
-        // we add a range of continuous values
-        for(int k = 1000; k < 10000; ++k) {
-            ints.add(k);
-        }
-        int[] unboxed = Ints.toArray(ints);
-        Arrays.sort(unboxed);
-        return unboxed;
-    }
-    static {
-        final Random source = new Random(0xcb000a2b9b5bdfb6L);
-        final int[] data = takeSortedAndDistinct(source, 450000);
-        c2 = MutableRoaringBitmap.bitmapOf(data);
+  public static MutableRoaringBitmap c2;
+  public static PeekableIntIterator it;
 
+  private static int[] takeSortedAndDistinct(Random source, int count) {
+    LinkedHashSet ints = new LinkedHashSet<>(count);
+    for (int size = 0; size < count; size++) {
+      int next;
+      do {
+        next = source.nextInt(1000000);
+      } while (!ints.add(next));
     }
-    @Setup(Level.Iteration)
-    public void setup() {
-        it = c2.getIntIterator();
-        c2.first();
+    // we add a range of continuous values
+    for (int k = 1000; k < 10000; ++k) {
+      ints.add(k);
     }
+    int[] unboxed = Ints.toArray(ints);
+    Arrays.sort(unboxed);
+    return unboxed;
+  }
 
-    @Benchmark
-    public MutableRoaringBitmap advanceIfNeeded() {
-        it.advanceIfNeeded((char) (59 + 15 * 64));
-        return c2;
-    }
+  static {
+    final Random source = new Random(0xcb000a2b9b5bdfb6L);
+    final int[] data = takeSortedAndDistinct(source, 450000);
+    c2 = MutableRoaringBitmap.bitmapOf(data);
+  }
+
+  @Setup(Level.Iteration)
+  public void setup() {
+    it = c2.getIntIterator();
+    c2.first();
+  }
+
+  @Benchmark
+  public MutableRoaringBitmap advanceIfNeeded() {
+    it.advanceIfNeeded((char) (59 + 15 * 64));
+    return c2;
+  }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/BasicBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/BasicBenchmark.java
index 0d7721efb..de89a85a3 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/BasicBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/BasicBenchmark.java
@@ -1,5 +1,17 @@
 package org.roaringbitmap;
 
+import org.roaringbitmap.buffer.BufferFastAggregation;
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import com.zaxxer.sparsebits.SparseBitSet;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -12,18 +24,6 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.BufferFastAggregation;
-import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
-
-import com.zaxxer.sparsebits.SparseBitSet;
-
 /**
  * Created by Borislav Ivanov on 4/2/15.
  */
@@ -232,11 +232,8 @@ public StandardState() {
 
       for (int k = 1; k < N; k += 10) {
         ors_standard.add(Arrays.copyOf(ewah_standard, k + 1));
-
       }
-
     }
-
   }
 
   @State(Scope.Benchmark)
@@ -256,7 +253,6 @@ public MutableState() {
           ewah_mutable[k].add(x * (N - k + 2));
         }
         ewah_mutable[k].trim();
-
       }
 
       ors_mutable = new ArrayList();
@@ -264,9 +260,7 @@ public MutableState() {
       for (int k = 1; k < N; k += 10) {
         ors_mutable.add(Arrays.copyOf(ewah_mutable, k + 1));
       }
-
     }
-
   }
 
   @State(Scope.Benchmark)
@@ -285,7 +279,6 @@ public ImmutableState() {
       /**
        * Mutable & Immutable
        */
-
       for (int k = 0; k < N; ++k) {
         ewah_mutable[k] = new MutableRoaringBitmap();
         for (int x = 0; x < M; ++x) {
@@ -302,9 +295,7 @@ public ImmutableState() {
       ors_immutable = new ArrayList();
       for (int k = 1; k < N; k += 10) {
         ors_immutable.add(Arrays.copyOf(ewah_immutable, k + 1));
-
       }
-
     }
 
     private ImmutableRoaringBitmap convertToMappedBitmap(MutableRoaringBitmap orig)
@@ -321,6 +312,5 @@ private ImmutableRoaringBitmap convertToMappedBitmap(MutableRoaringBitmap orig)
       memoryMappedFile.close();
       return new ImmutableRoaringBitmap(bb);
     }
-
   }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/BitSetUtilBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/BitSetUtilBenchmark.java
index 3c0950eeb..e6be1e255 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/BitSetUtilBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/BitSetUtilBenchmark.java
@@ -1,6 +1,12 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
 import java.io.DataInputStream;
 import java.io.IOException;
@@ -22,7 +28,6 @@ public long BitSetToRoaringByAddingBitByBit(Data d) {
     return bogus;
   }
 
-
   @Benchmark
   public long BitSetToRoaringUsingBitSetUtil(Data d) {
     long bogus = 0;
@@ -32,16 +37,16 @@ public long BitSetToRoaringUsingBitSetUtil(Data d) {
     return bogus;
   }
 
-  private static final ThreadLocal WORD_BLOCK = ThreadLocal.withInitial(() ->
-      new long[BitSetUtil.BLOCK_LENGTH]);
+  private static final ThreadLocal WORD_BLOCK =
+      ThreadLocal.withInitial(() -> new long[BitSetUtil.BLOCK_LENGTH]);
 
   /*
-    Given an uncompressed bitset represented as a byte array (basically, as read on wire)
-    Below benchmarks the perf difference you will get when:
-    1. ByteArrayToRoaring - Directly convert the byte array to a roaring bitmap by wrapping it in a ByteBuffer
-    2. ByteArrayToBitsetToRoaring - Convert the byte array to a BitSet and then create the bitmap using it
-    3. ByteArrayToRoaringWithCachedBuffer - Directly convert and use a cached reused buffer
-   */
+   Given an uncompressed bitset represented as a byte array (basically, as read on wire)
+   Below benchmarks the perf difference you will get when:
+   1. ByteArrayToRoaring - Directly convert the byte array to a roaring bitmap by wrapping it in a ByteBuffer
+   2. ByteArrayToBitsetToRoaring - Convert the byte array to a BitSet and then create the bitmap using it
+   3. ByteArrayToRoaringWithCachedBuffer - Directly convert and use a cached reused buffer
+  */
 
   @Benchmark
   public long ByteArrayToRoaring(Data d) {
@@ -63,7 +68,6 @@ public long ByteArrayToRoaringWithCachedBuffer(Data d) {
     return bogus;
   }
 
-
   @Benchmark
   public long ByteArrayToBitsetToRoaring(Data d) {
     long bogus = 0;
@@ -86,14 +90,12 @@ private static RoaringBitmap bitmapTheNaiveWay(final long[] words) {
     long word = 0;
     int index = 0;
     for (int i = 0, socket = 0; i < words.length && index < cardinality; i++, socket += Long.SIZE) {
-      if (words[i] == 0)
-        continue;
+      if (words[i] == 0) continue;
 
       // for each bit, unless updated word has become 0 (no more bits left) or we already have
       // reached cardinality
       word = words[i];
-      for (int bitIndex = 0; word != 0 && bitIndex < Long.SIZE; word >>=
-          1, bitIndex++) {
+      for (int bitIndex = 0; word != 0 && bitIndex < Long.SIZE; word >>= 1, bitIndex++) {
         if ((word & 1l) != 0) {
           bitmap.add(socket + bitIndex);
         }
@@ -125,18 +127,20 @@ private byte[][] bitsetsAsBytes(long[][] bitsets) {
     }
 
     private long[][] deserialize(final String bitsetResource) throws IOException {
-      final DataInputStream dos = new DataInputStream(
-          new GZIPInputStream(this.getClass().getResourceAsStream(bitsetResource)));
+      final DataInputStream dos =
+          new DataInputStream(
+              new GZIPInputStream(this.getClass().getResourceAsStream(bitsetResource)));
       try {
         /* Change this value to see number for small vs large bitsets
-           wordSize = 64 represents 4096 bits (512 bytes)
-           wordSize = 512 represents 32768 bits (~4kb)
-           wordSize = 8192 represents 524288 bits (~64kb)
-           wordSize = 131072 represents 8388608 bits (~8.3 million, ~1mb)
-         */
+          wordSize = 64 represents 4096 bits (512 bytes)
+          wordSize = 512 represents 32768 bits (~4kb)
+          wordSize = 8192 represents 524288 bits (~64kb)
+          wordSize = 131072 represents 8388608 bits (~8.3 million, ~1mb)
+        */
         final int minTotalWordSize = 512;
         // Try to keep size of bitsets created below 1 gb
-        final int bitsetCnt = Math.min((1024 * 1024 * 1024) / (minTotalWordSize * 8), dos.readInt());
+        final int bitsetCnt =
+            Math.min((1024 * 1024 * 1024) / (minTotalWordSize * 8), dos.readInt());
 
         final long[][] bitset = new long[bitsetCnt][];
         for (int i = 0; i < bitsetCnt; i++) {
@@ -150,8 +154,8 @@ private long[][] deserialize(final String bitsetResource) throws IOException {
           }
 
           // duplicate long[] n times to the right
-          for(int j = 0; j < clone; j++) {
-            System.arraycopy(words, 0, words, (j+1)*wordSize, wordSize);
+          for (int j = 0; j < clone; j++) {
+            System.arraycopy(words, 0, words, (j + 1) * wordSize, wordSize);
           }
           bitset[i] = words;
         }
@@ -161,5 +165,4 @@ private long[][] deserialize(final String bitsetResource) throws IOException {
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java
index acfc63396..97fed49ea 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/BitmapOfRangeBenchmark.java
@@ -1,6 +1,14 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 
 import java.util.concurrent.TimeUnit;
 
@@ -10,14 +18,16 @@
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
 @State(Scope.Benchmark)
 public class BitmapOfRangeBenchmark {
-  @Param({"0", // from the beginning
-      "100000" // from some offset
+  @Param({
+    "0", // from the beginning
+    "100000" // from some offset
   })
   int from;
 
-  @Param({"10",
-      "100000", // ~ 100 kBi
-      "10000000",// ~ 10 MBi
+  @Param({
+    "10",
+    "100000", // ~ 100 kBi
+    "10000000", // ~ 10 MBi
   })
   int length;
 
@@ -36,4 +46,4 @@ public static RoaringBitmap bitmapOfRangeOriginal(long min, long max) {
     bitmap.add(min, max);
     return bitmap;
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java
index 3a9d59e5c..ddd941f06 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/CheckedAddBenchmark.java
@@ -1,6 +1,16 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 
 import java.util.concurrent.TimeUnit;
 
@@ -120,11 +130,11 @@ public boolean checkedAddOriginal(final int x) {
         return true;
       }
     } else {
-      @SuppressWarnings("SpellCheckingInspection") final ArrayContainer newac =
-          new ArrayContainer();
+      @SuppressWarnings("SpellCheckingInspection")
+      final ArrayContainer newac = new ArrayContainer();
       bitmap.highLowContainer.insertNewKeyValueAt(-i - 1, hb, newac.add(Util.lowbits(x)));
       return true;
     }
     return false;
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/IntermediateByteArrayBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/IntermediateByteArrayBenchmark.java
index 89c871020..6e74be7e3 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/IntermediateByteArrayBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/IntermediateByteArrayBenchmark.java
@@ -1,8 +1,16 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.longlong.LongUtils;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
 import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
@@ -12,27 +20,27 @@
 @State(Scope.Benchmark)
 public class IntermediateByteArrayBenchmark {
 
-    public long firstV = 0xaa_b3_41_23_22_25_33_43L; // some random value
+  public long firstV = 0xaa_b3_41_23_22_25_33_43L; // some random value
 
-    @Benchmark
-    public int original() {
-        byte[] firtBytes = LongUtils.toBDBytes(firstV);
-        int unsignedIdx = 0;
-        for (int i = 0; i < 8; i++) {
-            byte v = firtBytes[i];
-            unsignedIdx += Byte.toUnsignedInt(v);
-            // some other stuff...
-        }
-        return unsignedIdx;
+  @Benchmark
+  public int original() {
+    byte[] firtBytes = LongUtils.toBDBytes(firstV);
+    int unsignedIdx = 0;
+    for (int i = 0; i < 8; i++) {
+      byte v = firtBytes[i];
+      unsignedIdx += Byte.toUnsignedInt(v);
+      // some other stuff...
     }
+    return unsignedIdx;
+  }
 
-    @Benchmark
-    public int optimized() {
-        int unsignedIdx = 0;
-        for (int i = 0; i < 8; i++) {
-            unsignedIdx += Byte.toUnsignedInt((byte) (firstV >>> ((7 - i) << 3)));
-            // some other stuff...
-        }
-        return unsignedIdx;
+  @Benchmark
+  public int optimized() {
+    int unsignedIdx = 0;
+    for (int i = 0; i < 8; i++) {
+      unsignedIdx += Byte.toUnsignedInt((byte) (firstV >>> ((7 - i) << 3)));
+      // some other stuff...
     }
+    return unsignedIdx;
+  }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/RadixSort.java b/jmh/src/jmh/java/org/roaringbitmap/RadixSort.java
index 81a92f892..8a8ad670c 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/RadixSort.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/RadixSort.java
@@ -1,6 +1,12 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
 
 import java.util.SplittableRandom;
 
@@ -34,18 +40,14 @@ public void setup() {
     }
   }
 
-
   @TearDown(Level.Invocation)
   public void restore() {
     System.arraycopy(input, 0, data, 0, input.length);
   }
 
-
   @Benchmark
   public int[] partialSort() {
     Util.partialRadixSort(data);
     return data;
   }
-
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/RandomData.java b/jmh/src/jmh/java/org/roaringbitmap/RandomData.java
index d44ce5dc0..6516d518d 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/RandomData.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/RandomData.java
@@ -11,7 +11,8 @@ public class RandomData {
   private static final ThreadLocal bits = ThreadLocal.withInitial(() -> new long[1 << 10]);
   private static final ThreadLocal runs = ThreadLocal.withInitial(() -> new int[4096]);
 
-  public static RoaringBitmap randomContiguousBitmap(int startKey, int numKeys, double rleLimit, double denseLimit) {
+  public static RoaringBitmap randomContiguousBitmap(
+      int startKey, int numKeys, double rleLimit, double denseLimit) {
     int[] keys = new int[numKeys];
     for (int i = 0; i < numKeys; ++i) {
       keys[i] = i + startKey;
@@ -39,9 +40,9 @@ public static IntStream rleRegion() {
       ++totalRuns;
     }
     return IntStream.range(0, totalRuns)
-            .map(i -> i * 2)
-            .mapToObj(i -> IntStream.range(values[i], values[i + 1]))
-            .flatMapToInt(i -> i);
+        .map(i -> i * 2)
+        .mapToObj(i -> IntStream.range(values[i], values[i + 1]))
+        .flatMapToInt(i -> i);
   }
 
   public static IntStream sparseRegion() {
@@ -77,9 +78,11 @@ private static int[] createSorted16BitInts(int howMany) {
   }
 
   private static RoaringBitmap forKeys(int[] keys, double rleLimit, double denseLimit) {
-    RoaringBitmapWriter writer = RoaringBitmapWriter.writer().optimiseForArrays().get();
+    RoaringBitmapWriter writer =
+        RoaringBitmapWriter.writer().optimiseForArrays().get();
     IntStream.of(keys)
-            .forEach(key -> {
+        .forEach(
+            key -> {
               double choice = RANDOM.nextDouble();
               final IntStream stream;
               if (choice < rleLimit) {
diff --git a/jmh/src/jmh/java/org/roaringbitmap/RangeOperationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/RangeOperationBenchmark.java
index 06c41d60c..fe8516104 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/RangeOperationBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/RangeOperationBenchmark.java
@@ -75,7 +75,6 @@ public int inotBig(BenchmarkState state) {
     return result.getCardinality();
   }
 
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
     BitmapContainer emptyBC = new BitmapContainer();
@@ -84,8 +83,7 @@ public static class BenchmarkState {
 
     public BenchmarkState() {
       for (int i = 100; i < 15000; i++) {
-        if (i % 5 != 0)
-          bc.add((char) i);
+        if (i % 5 != 0) bc.add((char) i);
       }
     }
   }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/RoaringOnlyBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/RoaringOnlyBenchmarkState.java
index fa04ffbcd..f7fb4d29d 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/RoaringOnlyBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/RoaringOnlyBenchmarkState.java
@@ -1,19 +1,18 @@
 package org.roaringbitmap;
 
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.Lists;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
 import org.openjdk.jmh.annotations.TearDown;
-import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
 
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.*;
-
 @State(Scope.Benchmark)
 public abstract class RoaringOnlyBenchmarkState {
 
@@ -44,24 +43,26 @@ public void setup(final String dataset) throws Exception {
     immutableOnlyRunContainers = new ArrayList<>();
     immutableOnlyBitmapContainers = new ArrayList<>();
 
-    List ints = DATASET_CACHE.get(dataset, new Callable>() {
+    List ints =
+        DATASET_CACHE.get(
+            dataset,
+            new Callable>() {
 
-      @Override
-      public List call() throws Exception {
-        System.out.println("Loading" + dataset);
-        ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
-        return Lists.newArrayList(dataRetriever.fetchBitPositions());
-      }
-    });
+              @Override
+              public List call() throws Exception {
+                System.out.println("Loading" + dataset);
+                ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
+                return Lists.newArrayList(dataRetriever.fetchBitPositions());
+              }
+            });
 
     for (int[] data : ints) {
       RoaringBitmap roaring = RoaringBitmap.bitmapOf(data);
       roaring.runOptimize();
       bitmaps.add(roaring);
       immutableBitmaps.add(roaring.toMutableRoaringBitmap());
-
     }
-    //Add bitmaps with only RunContainers preserved
+    // Add bitmaps with only RunContainers preserved
     for (RoaringBitmap rb : bitmaps) {
       RoaringBitmap runOnly = new RoaringBitmap();
       ContainerPointer cp = rb.getContainerPointer();
@@ -75,11 +76,11 @@ public List call() throws Exception {
       immutableOnlyRunContainers.add(runOnly.toMutableRoaringBitmap());
     }
 
-    //Add bitmaps with only ArrayContainers preserved
+    // Add bitmaps with only ArrayContainers preserved
     for (RoaringBitmap rb : bitmaps) {
       RoaringBitmap clone = rb.clone();
       RoaringBitmap arrayOnly = new RoaringBitmap();
-      clone.removeRunCompression(); //more containers preserved
+      clone.removeRunCompression(); // more containers preserved
       ContainerPointer cp = clone.getContainerPointer();
       while (cp.getContainer() != null) {
         if (!cp.isBitmapContainer()) {
@@ -91,11 +92,11 @@ public List call() throws Exception {
       immutableOnlyArrayContainers.add(arrayOnly.toMutableRoaringBitmap());
     }
 
-    //Add bitmaps with only BitmapContainers preserved
+    // Add bitmaps with only BitmapContainers preserved
     for (RoaringBitmap rb : bitmaps) {
       RoaringBitmap clone = rb.clone();
       RoaringBitmap bitmapOnly = new RoaringBitmap();
-      clone.removeRunCompression(); //more containers preserved
+      clone.removeRunCompression(); // more containers preserved
       ContainerPointer cp = clone.getContainerPointer();
       while (cp.getContainer() != null) {
         if (cp.isBitmapContainer()) {
@@ -106,12 +107,8 @@ public List call() throws Exception {
       onlyBitmapContainers.add(bitmapOnly);
       immutableOnlyBitmapContainers.add(bitmapOnly.toMutableRoaringBitmap());
     }
-
-
   }
 
   @TearDown
-  public void tearDown() {
-  }
-
+  public void tearDown() {}
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java
index a43e05ec8..9525228bc 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/SelectTopValuesBenchmark.java
@@ -1,8 +1,19 @@
 package org.roaringbitmap;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
 import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
@@ -40,7 +51,6 @@ public MutableRoaringBitmap limit() {
     return bitmap.limit(n);
   }
 
-
   @Benchmark
   public MutableRoaringBitmap add() {
     IntIterator it = bitmap.getIntIterator();
@@ -122,4 +132,4 @@ public MutableRoaringBitmap batchIteratorAddAtOnceIncludingAndNot() {
     bitmap.andNot(turnoff);
     return bitmap;
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/UtilBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/UtilBenchmark.java
index f06f18bbc..2b0885a2d 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/UtilBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/UtilBenchmark.java
@@ -1,8 +1,6 @@
 package org.roaringbitmap;
 
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
+import me.lemire.integercompression.synth.ClusteredDataGenerator;
 import org.apache.commons.math3.distribution.IntegerDistribution;
 import org.apache.commons.math3.distribution.UniformIntegerDistribution;
 import org.apache.commons.math3.random.Well19937c;
@@ -15,7 +13,8 @@
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 
-import me.lemire.integercompression.synth.ClusteredDataGenerator;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
 
 /**
  * The experiment to test the threshold when it is worth to use galloping strategy of intersecting
@@ -30,11 +29,14 @@ public class UtilBenchmark {
 
   @Param({"0"}) // use {"0", "1"} to test both uniform and clustered combinations
   public int smallType; // 0 - uniform, 1 - clustered
+
   @Param({"0"}) // use {"0", "1"} to test both uniform and clustered combinations
   public int bigType; // 0 - uniform, 1 - clustered
+
   @Param({"0"}) // use {"0", "1", "2"} for three experiments. Update GENERATE_EXAMPLES if changing
-                // this
+  // this
   public int index;
+
   @Param({"25"}) // use {"20", "25", "30"} to check different thresholds
   public int param;
 
@@ -50,20 +52,19 @@ public void setup() {
   public void galloping() {
     BenchmarkContainer small = data.small[index];
     BenchmarkContainer big = data.big[index];
-    Util.unsignedOneSidedGallopingIntersect2by2(small.content, small.length, big.content,
-        big.length, data.dest);
+    Util.unsignedOneSidedGallopingIntersect2by2(
+        small.content, small.length, big.content, big.length, data.dest);
   }
 
   @Benchmark
   public void local() {
     BenchmarkContainer small = data.small[index];
     BenchmarkContainer big = data.big[index];
-    Util.unsignedLocalIntersect2by2(small.content, small.length, big.content, big.length,
-        data.dest);
+    Util.unsignedLocalIntersect2by2(
+        small.content, small.length, big.content, big.length, data.dest);
   }
 }
 
-
 class BenchmarkData {
   BenchmarkData(BenchmarkContainer[] small, BenchmarkContainer[] big) {
     this.small = small;
@@ -76,7 +77,6 @@ class BenchmarkData {
   final char[] dest;
 }
 
-
 class BenchmarkContainer {
   BenchmarkContainer(char[] content) {
     this.content = content;
@@ -87,17 +87,18 @@ class BenchmarkContainer {
   final int length;
 }
 
-
 /**
  * Deterministic generator for benchmark data. For given *param* it generates *howmany* entries
  */
 class BenchmarkDataGenerator {
   static BenchmarkData generate(int param, int howMany, int smallType, int bigType) {
-    IntegerDistribution ud = new UniformIntegerDistribution(new Well19937c(param + 17),
-        Short.MIN_VALUE, Short.MAX_VALUE);
+    IntegerDistribution ud =
+        new UniformIntegerDistribution(
+            new Well19937c(param + 17), Short.MIN_VALUE, Short.MAX_VALUE);
     ClusteredDataGenerator cd = new ClusteredDataGenerator();
-    IntegerDistribution p = new UniformIntegerDistribution(new Well19937c(param + 123),
-        SMALLEST_ARRAY, BIGGEST_ARRAY / param);
+    IntegerDistribution p =
+        new UniformIntegerDistribution(
+            new Well19937c(param + 123), SMALLEST_ARRAY, BIGGEST_ARRAY / param);
     BenchmarkContainer[] smalls = new BenchmarkContainer[howMany];
     BenchmarkContainer[] bigs = new BenchmarkContainer[howMany];
     for (int i = 0; i < howMany; i++) {
@@ -138,8 +139,6 @@ private static char[] generateUniform(IntegerDistribution ud, int howMany) {
     return intArrayToShortArraySorted(ud.sample(howMany));
   }
 
-  private final static int SMALLEST_ARRAY = 2;
-  private final static int BIGGEST_ARRAY = 4096;
+  private static final int SMALLEST_ARRAY = 2;
+  private static final int BIGGEST_ARRAY = 4096;
 }
-
-
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/FastAggregationRLEStressTest.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/FastAggregationRLEStressTest.java
index 8d8de2fc5..ea5f59cd5 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/FastAggregationRLEStressTest.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/FastAggregationRLEStressTest.java
@@ -1,12 +1,18 @@
 package org.roaringbitmap.aggregation;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.FastAggregation;
 import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.RoaringBitmapWriter;
 import org.roaringbitmap.buffer.BufferFastAggregation;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.Arrays;
 import java.util.SplittableRandom;
 
@@ -20,19 +26,16 @@ public enum ConstructionStrategy {
       CONSTANT_MEMORY {
         @Override
         public RoaringBitmapWriter create() {
-          return RoaringBitmapWriter.writer()
-                  .constantMemory()
-                  .get();
+          return RoaringBitmapWriter.writer().constantMemory().get();
         }
       },
       CONTAINER_APPENDER {
         @Override
         public RoaringBitmapWriter create() {
-          return RoaringBitmapWriter.writer()
-                  .get();
+          return RoaringBitmapWriter.writer().get();
         }
-      }
-      ;
+      };
+
       public abstract RoaringBitmapWriter create();
     }
 
@@ -48,8 +51,7 @@ public RoaringBitmapWriter create() {
     @Param({"0.01", "0.1", "0.5"})
     double probability;
 
-    @Param
-    ConstructionStrategy constructionStrategy;
+    @Param ConstructionStrategy constructionStrategy;
 
     @Param("99999")
     long seed;
@@ -64,12 +66,12 @@ public void createBitmaps() {
       RoaringBitmapWriter bitmapWriter = constructionStrategy.create();
       bitmaps = new RoaringBitmap[count];
       bufferBitmaps = new ImmutableRoaringBitmap[count];
-      double p = Math.pow(probability, 1D/count);
+      double p = Math.pow(probability, 1D / count);
       for (int i = 0; i < count; ++i) {
-        for (int j = (int)(Math.log(random.nextDouble())/Math.log(1-p));
-             j < size;
-             j += (int)(Math.log(random.nextDouble())/Math.log(1-p)) + 1) {
-            bitmapWriter.add(j);
+        for (int j = (int) (Math.log(random.nextDouble()) / Math.log(1 - p));
+            j < size;
+            j += (int) (Math.log(random.nextDouble()) / Math.log(1 - p)) + 1) {
+          bitmapWriter.add(j);
         }
         bitmaps[i] = bitmapWriter.get();
         bufferBitmaps[i] = bitmaps[i].toMutableRoaringBitmap();
@@ -78,7 +80,6 @@ public void createBitmaps() {
     }
   }
 
-
   @Benchmark
   public RoaringBitmap and(BitmapState state) {
     return FastAggregation.and(state.buffer, state.bitmaps);
@@ -91,13 +92,13 @@ public ImmutableRoaringBitmap andBuffer(BitmapState state) {
 
   @Benchmark
   public RoaringBitmap andMemoryShy(BitmapState state) {
-    Arrays.fill(state.buffer,0);
+    Arrays.fill(state.buffer, 0);
     return FastAggregation.workAndMemoryShyAnd(state.buffer, state.bitmaps);
   }
 
   @Benchmark
   public ImmutableRoaringBitmap andBufferMemoryShy(BitmapState state) {
-    Arrays.fill(state.buffer,0);
+    Arrays.fill(state.buffer, 0);
     return BufferFastAggregation.workAndMemoryShyAnd(state.buffer, state.bufferBitmaps);
   }
 
@@ -111,7 +112,6 @@ public int andCardinalityMaterialize(BitmapState state) {
     return FastAggregation.and(state.bitmaps).getCardinality();
   }
 
-
   @Benchmark
   public int andCardinalityBuffer(BitmapState state) {
     return BufferFastAggregation.andCardinality(state.bufferBitmaps);
@@ -132,7 +132,6 @@ public int orCardinalityMaterialize(BitmapState state) {
     return FastAggregation.or(state.bitmaps).getCardinality();
   }
 
-
   @Benchmark
   public int orCardinalityBuffer(BitmapState state) {
     return BufferFastAggregation.orCardinality(state.bufferBitmaps);
@@ -142,5 +141,4 @@ public int orCardinalityBuffer(BitmapState state) {
   public int orCardinalityBufferMaterialize(BitmapState state) {
     return BufferFastAggregation.or(state.bufferBitmaps).getCardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/BitmapContainerAndBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/BitmapContainerAndBenchmark.java
index e94253f95..0efc0bcfc 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/BitmapContainerAndBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/BitmapContainerAndBenchmark.java
@@ -1,17 +1,23 @@
 package org.roaringbitmap.aggregation.and;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.BitmapContainer;
 import org.roaringbitmap.Container;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.SplittableRandom;
-import java.util.concurrent.ThreadLocalRandom;
 
 @State(Scope.Benchmark)
 public class BitmapContainerAndBenchmark {
 
   @Param({"0.1", "0.5"})
   double thisDensity;
+
   @Param({"0.1", "0.5"})
   double thatDensity;
 
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/Roaring64BitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/Roaring64BitmapBenchmark.java
index 11c46dc0d..eaf5add4e 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/Roaring64BitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/Roaring64BitmapBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.aggregation.and.bestcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class Roaring64BitmapBenchmark {
@@ -51,5 +53,4 @@ public Roaring64Bitmap inplace_and() {
   public Roaring64Bitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/RoaringBitmapBenchmark.java
index 42ad6f415..8614f59a3 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/bestcase/RoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.aggregation.and.bestcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
@@ -58,5 +59,4 @@ public RoaringBitmap inplace_and() {
   public RoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/Roaring64BitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/Roaring64BitmapBenchmark.java
index d25027f74..be83caa6f 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/Roaring64BitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/Roaring64BitmapBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.aggregation.and.identical;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class Roaring64BitmapBenchmark {
@@ -44,5 +46,4 @@ public Roaring64Bitmap inplace_and() {
   public Roaring64Bitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/RoaringBitmapBenchmark.java
index 0b132aa98..a940d58fb 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/identical/RoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.aggregation.and.identical;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public RoaringBitmap inplace_and() {
   public RoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/Roaring64BitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/Roaring64BitmapBenchmark.java
index 8cae9235b..3bf1f007f 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/Roaring64BitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/Roaring64BitmapBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.aggregation.and.worstcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class Roaring64BitmapBenchmark {
@@ -44,5 +46,4 @@ public Roaring64Bitmap inplace_and() {
   public Roaring64Bitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/RoaringBitmapBenchmark.java
index 44f02c153..644297f62 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/and/worstcase/RoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.aggregation.and.worstcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public RoaringBitmap inplace_and() {
   public RoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/Roaring64BitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/Roaring64BitmapBenchmark.java
index bd202284c..425fbffc8 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/Roaring64BitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/Roaring64BitmapBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.aggregation.andnot.bestcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class Roaring64BitmapBenchmark {
@@ -52,5 +54,4 @@ public Roaring64Bitmap inplace_andNot() {
   public Roaring64Bitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/RoaringBitmapBenchmark.java
index a29c897d7..5509ae0af 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/bestcase/RoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.aggregation.andnot.bestcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
@@ -58,5 +59,4 @@ public RoaringBitmap inplace_andNot() {
   public RoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/Roaring64BitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/Roaring64BitmapBenchmark.java
index c3eac37d7..e2385f5a4 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/Roaring64BitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/Roaring64BitmapBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.aggregation.andnot.identical;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class Roaring64BitmapBenchmark {
@@ -44,5 +46,4 @@ public Roaring64Bitmap inplace_andNot() {
   public Roaring64Bitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/RoaringBitmapBenchmark.java
index 8a0bc59a7..a9b02eff6 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/identical/RoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.aggregation.andnot.identical;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public RoaringBitmap inplace_andNot() {
   public RoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/Roaring64BitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/Roaring64BitmapBenchmark.java
index 6c32bd719..9d1d097db 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/Roaring64BitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/Roaring64BitmapBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.aggregation.andnot.worstcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class Roaring64BitmapBenchmark {
@@ -44,5 +46,4 @@ public Roaring64Bitmap inplace_andNot() {
   public Roaring64Bitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/RoaringBitmapBenchmark.java
index f10f56fbd..9af145f41 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/andnot/worstcase/RoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.aggregation.andnot.worstcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public RoaringBitmap inplace_andNot() {
   public RoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/BitmapContainerOrBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/BitmapContainerOrBenchmark.java
index c55007268..c6981b6f9 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/BitmapContainerOrBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/BitmapContainerOrBenchmark.java
@@ -1,17 +1,23 @@
 package org.roaringbitmap.aggregation.or;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.BitmapContainer;
 import org.roaringbitmap.Container;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.SplittableRandom;
-import java.util.concurrent.ThreadLocalRandom;
 
 @State(Scope.Benchmark)
 public class BitmapContainerOrBenchmark {
 
   @Param({"0.1", "0.5"})
   double thisDensity;
+
   @Param({"0.1", "0.5"})
   double thatDensity;
 
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/RoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/RoaringBitmapBenchmark.java
index 47fc28a60..9fdf4d759 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/RoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/or/RoaringBitmapBenchmark.java
@@ -1,5 +1,9 @@
 package org.roaringbitmap.aggregation.or;
 
+import org.roaringbitmap.FastAggregation;
+import org.roaringbitmap.RandomData;
+import org.roaringbitmap.RoaringBitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -8,9 +12,6 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.FastAggregation;
-import org.roaringbitmap.RandomData;
-import org.roaringbitmap.RoaringBitmap;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -19,32 +20,32 @@
 @State(Scope.Benchmark)
 public class RoaringBitmapBenchmark {
 
-    @Param({"10", "50", "100"})
-    int bitmapSize;
-    private List bitmaps = new ArrayList<>();
+  @Param({"10", "50", "100"})
+  int bitmapSize;
 
-    @Setup
-    public void setup() {
-        for (int n = 0; n < bitmapSize; n++) {
-            bitmaps.add(RandomData.randomBitmap(1 << 12, 1 / 3.0, 1 / 3.0));
-        }
-    }
+  private List bitmaps = new ArrayList<>();
 
-    @Benchmark
-    @BenchmarkMode(Mode.AverageTime)
-    @OutputTimeUnit(TimeUnit.MICROSECONDS)
-    public void or() {
-        RoaringBitmap b1 = new RoaringBitmap();
-        for (int n = 0; n < bitmapSize; n++) {
-            b1.or(bitmaps.get(n));
-        }
+  @Setup
+  public void setup() {
+    for (int n = 0; n < bitmapSize; n++) {
+      bitmaps.add(RandomData.randomBitmap(1 << 12, 1 / 3.0, 1 / 3.0));
     }
-
-    @Benchmark
-    @BenchmarkMode(Mode.AverageTime)
-    @OutputTimeUnit(TimeUnit.MICROSECONDS)
-    public void lazyor() {
-        FastAggregation.naive_or(bitmaps.iterator());
+  }
+
+  @Benchmark
+  @BenchmarkMode(Mode.AverageTime)
+  @OutputTimeUnit(TimeUnit.MICROSECONDS)
+  public void or() {
+    RoaringBitmap b1 = new RoaringBitmap();
+    for (int n = 0; n < bitmapSize; n++) {
+      b1.or(bitmaps.get(n));
     }
-
+  }
+
+  @Benchmark
+  @BenchmarkMode(Mode.AverageTime)
+  @OutputTimeUnit(TimeUnit.MICROSECONDS)
+  public void lazyor() {
+    FastAggregation.naive_or(bitmaps.iterator());
+  }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/aggregation/xor/BitmapContainerXorBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/aggregation/xor/BitmapContainerXorBenchmark.java
index 42d03378a..257cab65c 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/aggregation/xor/BitmapContainerXorBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/aggregation/xor/BitmapContainerXorBenchmark.java
@@ -1,9 +1,15 @@
 package org.roaringbitmap.aggregation.xor;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.BitmapContainer;
 import org.roaringbitmap.Container;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.concurrent.ThreadLocalRandom;
 
 @State(Scope.Benchmark)
@@ -11,6 +17,7 @@ public class BitmapContainerXorBenchmark {
 
   @Param({"0.1", "0.5"})
   double thisDensity;
+
   @Param({"0.1", "0.5"})
   double thatDensity;
 
diff --git a/jmh/src/jmh/java/org/roaringbitmap/arraycontainer/AddBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/arraycontainer/AddBenchmark.java
index bb160621e..475851998 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/arraycontainer/AddBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/arraycontainer/AddBenchmark.java
@@ -1,9 +1,12 @@
 package org.roaringbitmap.arraycontainer;
 
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.ZipRealDataRangeRetriever;
+import org.roaringbitmap.buffer.MappeableArrayContainer;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.Lists;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -11,12 +14,11 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.ZipRealDataRangeRetriever;
-import org.roaringbitmap.buffer.MappeableArrayContainer;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class AddBenchmark {
@@ -32,17 +34,20 @@ public void setup() throws ExecutionException {
     ac1 = new ArrayContainer();
     mac1 = new MappeableArrayContainer();
     DATASET_CACHE = CacheBuilder.newBuilder().maximumSize(1).build();
-    ints = DATASET_CACHE.get(dataset, new Callable>() {
+    ints =
+        DATASET_CACHE.get(
+            dataset,
+            new Callable>() {
 
-      @Override
-      public List call() throws Exception {
-        System.out.println("Loading" + dataset);
-        ZipRealDataRangeRetriever dataRetriever =
-            new ZipRealDataRangeRetriever<>(dataset, "/random-generated-data/");
+              @Override
+              public List call() throws Exception {
+                System.out.println("Loading" + dataset);
+                ZipRealDataRangeRetriever dataRetriever =
+                    new ZipRealDataRangeRetriever<>(dataset, "/random-generated-data/");
 
-        return Lists.newArrayList(dataRetriever.fetchNextRange());
-      }
-    });
+                return Lists.newArrayList(dataRetriever.fetchNextRange());
+              }
+            });
   }
 
   @Benchmark
diff --git a/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java
index d48d2e900..613795f35 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/bithacking/SelectBenchmark.java
@@ -1,8 +1,5 @@
 package org.roaringbitmap.bithacking;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -11,6 +8,9 @@
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class SelectBenchmark {
@@ -24,47 +24,45 @@ public void setup() {
     bitmap = new long[N];
     key = new int[N];
     for (int k = 0; k < bitmap.length; ++k) {
-      while (bitmap[k] == 0)
-        bitmap[k] = r.nextInt();
+      while (bitmap[k] == 0) bitmap[k] = r.nextInt();
     }
-    for (int k = 0; k < key.length; ++k)
-      key[k] = r.nextInt() % (Long.bitCount(bitmap[k]));
+    for (int k = 0; k < key.length; ++k) key[k] = r.nextInt() % (Long.bitCount(bitmap[k]));
     for (int k = 0; k < 64; ++k) {
-      if (select(0xFFFFFFFFFFFFFFFFL, k) != k)
-        throw new RuntimeException("bug " + k);
+      if (select(0xFFFFFFFFFFFFFFFFL, k) != k) throw new RuntimeException("bug " + k);
     }
     for (int k = 0; k < 64; ++k) {
-      if (selectBitPosition(0xFFFFFFFFFFFFFFFFL, k) != k)
-        throw new RuntimeException("bug " + k);
+      if (selectBitPosition(0xFFFFFFFFFFFFFFFFL, k) != k) throw new RuntimeException("bug " + k);
     }
 
     for (int k = 0; k < bitmap.length; ++k)
       if (selectBitPosition(bitmap[k], key[k]) != select(bitmap[k], key[k]))
-        throw new RuntimeException("bug " + bitmap[k] + " " + key[k] + " : "
-            + selectBitPosition(bitmap[k], key[k]) + " : " + select(bitmap[k], key[k]));
+        throw new RuntimeException(
+            "bug "
+                + bitmap[k]
+                + " "
+                + key[k]
+                + " : "
+                + selectBitPosition(bitmap[k], key[k])
+                + " : "
+                + select(bitmap[k], key[k]));
   }
 
   @Benchmark
   @BenchmarkMode(Mode.AverageTime)
   public int onefunction() {
     int answer = 0;
-    for (int k = 0; k < bitmap.length; ++k)
-      answer += selectBitPosition(bitmap[k], key[k]);
+    for (int k = 0; k < bitmap.length; ++k) answer += selectBitPosition(bitmap[k], key[k]);
     return answer;
   }
 
-
-
   @Benchmark
   @BenchmarkMode(Mode.AverageTime)
   public int manyfunctions() {
     int answer = 0;
-    for (int k = 0; k < bitmap.length; ++k)
-      answer += select(bitmap[k], key[k]);
+    for (int k = 0; k < bitmap.length; ++k) answer += select(bitmap[k], key[k]);
     return answer;
   }
 
-
   public static int selectBitPosition(long w, int j) {
     int seen = 0;
     // Divide 64bit
@@ -144,7 +142,6 @@ public static int select(int w, int j) {
     }
   }
 
-
   /**
    * Given a word w, return the position of the jth true bit.
    *
@@ -156,12 +153,9 @@ public static int select(short w, int j) {
     int sumtotal = 0;
     for (int counter = 0; counter < 16; ++counter) {
       sumtotal += (w >> counter) & 1;
-      if (sumtotal > j)
-        return counter;
+      if (sumtotal > j) return counter;
     }
     throw new IllegalArgumentException(
         "cannot locate " + j + "th bit in " + w + " weight is " + Integer.bitCount(w));
   }
-
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/bithacking/UnsignedVSFlip.java b/jmh/src/jmh/java/org/roaringbitmap/bithacking/UnsignedVSFlip.java
index 15ef0dfbf..4af9d68fb 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/bithacking/UnsignedVSFlip.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/bithacking/UnsignedVSFlip.java
@@ -1,8 +1,5 @@
 package org.roaringbitmap.bithacking;
 
-
-import java.util.concurrent.TimeUnit;
-
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -11,13 +8,14 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
 
+import java.util.concurrent.TimeUnit;
+
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
 public class UnsignedVSFlip {
   @Param({"1", "31", "65", "101", "103"})
   public short key;
 
-
   @Benchmark
   @BenchmarkMode(Mode.Throughput)
   public int Time() {
@@ -36,7 +34,6 @@ public int flipTime() {
     return key ^ Short.MIN_VALUE;
   }
 
-
   @Benchmark
   @BenchmarkMode(Mode.AverageTime)
   public int flipTimeAvg() {
@@ -54,5 +51,4 @@ public short flipTimeShort() {
   public short flipTimeShortAvg() {
     return (short) (key ^ Short.MIN_VALUE);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java
index dbb80ea45..106bc91a9 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/bitmapcontainer/SelectBenchmark.java
@@ -1,9 +1,19 @@
 package org.roaringbitmap.bitmapcontainer;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.BitmapContainer;
 import org.roaringbitmap.buffer.MappeableBitmapContainer;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
 import java.util.Random;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/BufferUtilBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/BufferUtilBenchmark.java
index 625e8e51a..227f845c2 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/BufferUtilBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/BufferUtilBenchmark.java
@@ -1,9 +1,6 @@
 package org.roaringbitmap.buffer;
 
-import java.nio.CharBuffer;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
+import me.lemire.integercompression.synth.ClusteredDataGenerator;
 import org.apache.commons.math3.distribution.IntegerDistribution;
 import org.apache.commons.math3.distribution.UniformIntegerDistribution;
 import org.apache.commons.math3.random.Well19937c;
@@ -16,7 +13,9 @@
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 
-import me.lemire.integercompression.synth.ClusteredDataGenerator;
+import java.nio.CharBuffer;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
 
 /**
  * The experiment to test the threshold when it is worth to use galloping strategy of intersecting
@@ -31,11 +30,14 @@ public class BufferUtilBenchmark {
 
   @Param({"0"}) // use {"0", "1"} to test both uniform and clustered combinations
   public int smallType; // 0 - uniform, 1 - clustered
+
   @Param({"0"}) // use {"0", "1"} to test both uniform and clustered combinations
   public int bigType; // 0 - uniform, 1 - clustered
+
   @Param({"0"}) // use {"0", "1", "2"} for three experiments. Update GENERATE_EXAMPLES if changing
-                // this
+  // this
   public int index;
+
   @Param({"35"}) // use {"20", "25", "30"} to check different thresholds
   public int param;
 
@@ -51,20 +53,19 @@ public void setup() {
   public void galloping() {
     BenchmarkContainer small = data.small[index];
     BenchmarkContainer big = data.big[index];
-    BufferUtil.unsignedOneSidedGallopingIntersect2by2(small.content, small.length, big.content,
-        big.length, data.dest);
+    BufferUtil.unsignedOneSidedGallopingIntersect2by2(
+        small.content, small.length, big.content, big.length, data.dest);
   }
 
   @Benchmark
   public void local() {
     BenchmarkContainer small = data.small[index];
     BenchmarkContainer big = data.big[index];
-    BufferUtil.unsignedLocalIntersect2by2(small.content, small.length, big.content, big.length,
-        data.dest);
+    BufferUtil.unsignedLocalIntersect2by2(
+        small.content, small.length, big.content, big.length, data.dest);
   }
 }
 
-
 class BenchmarkData {
   BenchmarkData(BenchmarkContainer[] small, BenchmarkContainer[] big) {
     this.small = small;
@@ -77,7 +78,6 @@ class BenchmarkData {
   final char[] dest;
 }
 
-
 class BenchmarkContainer {
   BenchmarkContainer(char[] content) {
     this.content = CharBuffer.wrap(content);
@@ -88,17 +88,18 @@ class BenchmarkContainer {
   final int length;
 }
 
-
 /**
  * Deterministic generator for benchmark data. For given *param* it generates *howmany* entries
  */
 class BenchmarkDataGenerator {
   static BenchmarkData generate(int param, int howMany, int smallType, int bigType) {
-    IntegerDistribution ud = new UniformIntegerDistribution(new Well19937c(param + 17),
-        Short.MIN_VALUE, Short.MAX_VALUE);
+    IntegerDistribution ud =
+        new UniformIntegerDistribution(
+            new Well19937c(param + 17), Short.MIN_VALUE, Short.MAX_VALUE);
     ClusteredDataGenerator cd = new ClusteredDataGenerator();
-    IntegerDistribution p = new UniformIntegerDistribution(new Well19937c(param + 123),
-        SMALLEST_ARRAY, BIGGEST_ARRAY / param);
+    IntegerDistribution p =
+        new UniformIntegerDistribution(
+            new Well19937c(param + 123), SMALLEST_ARRAY, BIGGEST_ARRAY / param);
     BenchmarkContainer[] smalls = new BenchmarkContainer[howMany];
     BenchmarkContainer[] bigs = new BenchmarkContainer[howMany];
     for (int i = 0; i < howMany; i++) {
@@ -139,8 +140,6 @@ private static char[] generateUniform(IntegerDistribution ud, int howMany) {
     return intArrayToShortArraySorted(ud.sample(howMany));
   }
 
-  private final static int SMALLEST_ARRAY = 2;
-  private final static int BIGGEST_ARRAY = 4096;
+  private static final int SMALLEST_ARRAY = 2;
+  private static final int BIGGEST_ARRAY = 4096;
 }
-
-
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/bestcase/MutableRoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/bestcase/MutableRoaringBitmapBenchmark.java
index af7a6ec76..f846ed403 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/bestcase/MutableRoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/bestcase/MutableRoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.buffer.aggregation.and.bestcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class MutableRoaringBitmapBenchmark {
@@ -58,5 +59,4 @@ public MutableRoaringBitmap inplace_and() {
   public MutableRoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/identical/MutableRoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/identical/MutableRoaringBitmapBenchmark.java
index 95bd10213..ba2f9dd65 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/identical/MutableRoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/identical/MutableRoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.buffer.aggregation.and.identical;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class MutableRoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public MutableRoaringBitmap inplace_and() {
   public MutableRoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/worstcase/MutableRoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/worstcase/MutableRoaringBitmapBenchmark.java
index 1edc461c1..119a65e3b 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/worstcase/MutableRoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/and/worstcase/MutableRoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.buffer.aggregation.and.worstcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class MutableRoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public MutableRoaringBitmap inplace_and() {
   public MutableRoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/bestcase/MutableRoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/bestcase/MutableRoaringBitmapBenchmark.java
index a5c2a343d..9f81dc3fe 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/bestcase/MutableRoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/bestcase/MutableRoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.buffer.aggregation.andnot.bestcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class MutableRoaringBitmapBenchmark {
@@ -58,5 +59,4 @@ public MutableRoaringBitmap inplace_andNot() {
   public MutableRoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/identical/MutableRoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/identical/MutableRoaringBitmapBenchmark.java
index 7cc51ec0a..e5b154036 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/identical/MutableRoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/identical/MutableRoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.buffer.aggregation.andnot.identical;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class MutableRoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public MutableRoaringBitmap inplace_andNot() {
   public MutableRoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/worstcase/MutableRoaringBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/worstcase/MutableRoaringBitmapBenchmark.java
index 6e08ed28e..dc596b68e 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/worstcase/MutableRoaringBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/buffer/aggregation/andnot/worstcase/MutableRoaringBitmapBenchmark.java
@@ -1,6 +1,6 @@
 package org.roaringbitmap.buffer.aggregation.andnot.worstcase;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,7 +9,8 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 public class MutableRoaringBitmapBenchmark {
@@ -50,5 +51,4 @@ public MutableRoaringBitmap inplace_andNot() {
   public MutableRoaringBitmap justclone() {
     return bitmap1.clone();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Cardinality64Benchmark.java b/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Cardinality64Benchmark.java
index a165b5d86..8820a1c0c 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Cardinality64Benchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Cardinality64Benchmark.java
@@ -1,7 +1,7 @@
 // https://github.com/RoaringBitmap/RoaringBitmap/pull/176
 package org.roaringbitmap.cardinality64;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64NavigableMap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -13,7 +13,8 @@
 import org.openjdk.jmh.runner.options.Options;
 import org.openjdk.jmh.runner.options.OptionsBuilder;
 import org.openjdk.jmh.runner.options.TimeValue;
-import org.roaringbitmap.longlong.Roaring64NavigableMap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -100,10 +101,15 @@ public CacheCardinalitiesBenchmarkState() {
   public static final int MEASUREMENTS_ITERATIONS = 3;
 
   public static void main(String... args) throws Exception {
-    Options opts = new OptionsBuilder().include(".*Cardinality64Benchmark.*")
-        .warmupTime(new TimeValue(1, TimeUnit.SECONDS)).warmupIterations(3)
-        .measurementTime(new TimeValue(1, TimeUnit.SECONDS)).measurementIterations(3).forks(1)
-        .build();
+    Options opts =
+        new OptionsBuilder()
+            .include(".*Cardinality64Benchmark.*")
+            .warmupTime(new TimeValue(1, TimeUnit.SECONDS))
+            .warmupIterations(3)
+            .measurementTime(new TimeValue(1, TimeUnit.SECONDS))
+            .measurementIterations(3)
+            .forks(1)
+            .build();
 
     new Runner(opts).run();
   }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Roaring64BmpCardinalityBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Roaring64BmpCardinalityBenchmark.java
index dcc04ea71..b974d91a8 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Roaring64BmpCardinalityBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/cardinality64/Roaring64BmpCardinalityBenchmark.java
@@ -1,6 +1,7 @@
 package org.roaringbitmap.cardinality64;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
@@ -11,7 +12,8 @@
 import org.openjdk.jmh.runner.options.Options;
 import org.openjdk.jmh.runner.options.OptionsBuilder;
 import org.openjdk.jmh.runner.options.TimeValue;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -42,10 +44,15 @@ public CacheCardinalitiesBenchmarkState() {
   }
 
   public static void main(String... args) throws Exception {
-    Options opts = new OptionsBuilder().include(".*Roaring64BmpCardinalityBenchmark.*")
-        .warmupTime(new TimeValue(1, TimeUnit.SECONDS)).warmupIterations(3)
-        .measurementTime(new TimeValue(1, TimeUnit.SECONDS)).measurementIterations(3).forks(1)
-        .build();
+    Options opts =
+        new OptionsBuilder()
+            .include(".*Roaring64BmpCardinalityBenchmark.*")
+            .warmupTime(new TimeValue(1, TimeUnit.SECONDS))
+            .warmupIterations(3)
+            .measurementTime(new TimeValue(1, TimeUnit.SECONDS))
+            .measurementIterations(3)
+            .forks(1)
+            .build();
 
     new Runner(opts).run();
   }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/combinedcardinality/CombinedCardinalityBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/combinedcardinality/CombinedCardinalityBenchmark.java
index 51fce4e22..f5f31a70e 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/combinedcardinality/CombinedCardinalityBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/combinedcardinality/CombinedCardinalityBenchmark.java
@@ -1,102 +1,113 @@
 package org.roaringbitmap.combinedcardinality;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.RandomData;
 import org.roaringbitmap.RoaringBitmap;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.concurrent.TimeUnit;
 
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 @BenchmarkMode(Mode.AverageTime)
-@Fork(value = 1, jvmArgsPrepend =
-        {
-                "-XX:-TieredCompilation",
-                "-XX:+UseParallelGC",
-                "-mx2G",
-                "-ms2G",
-                "-XX:+AlwaysPreTouch"
-        })
+@Fork(
+    value = 1,
+    jvmArgsPrepend = {
+      "-XX:-TieredCompilation",
+      "-XX:+UseParallelGC",
+      "-mx2G",
+      "-ms2G",
+      "-XX:+AlwaysPreTouch"
+    })
 @State(Scope.Benchmark)
 public class CombinedCardinalityBenchmark {
 
-    public enum Scenario {
-        EQUAL {
-            @Override
-            RoaringBitmap[] bitmaps() {
-                RoaringBitmap bitmap = RandomData.randomBitmap(1 << 12, 0.2, 0.3);
-                return new RoaringBitmap[] {bitmap, bitmap.clone()};
-            }
-        },
-        SHIFTED {
-            @Override
-            RoaringBitmap[] bitmaps() {
-                RoaringBitmap bitmap = RandomData.randomBitmap(1 << 12, 0.2, 0.3);
-                return new RoaringBitmap[] {bitmap, RoaringBitmap.addOffset(bitmap, 1 << 16)};
-            }
-        },
-        SMALL_LARGE {
-            @Override
-            RoaringBitmap[] bitmaps() {
-                return new RoaringBitmap[] {
-                        RandomData.randomBitmap(1 << 4, 0.2, 0.3),
-                        RandomData.randomBitmap(1 << 12, 0.2, 0.3)
-                };
-            }
-        },
-        LARGE_SMALL {
-            @Override
-            RoaringBitmap[] bitmaps() {
-                return new RoaringBitmap[] {
-                        RandomData.randomBitmap(1 << 12, 0.2, 0.3),
-                        RandomData.randomBitmap(1 << 4, 0.2, 0.3)
-                };
-            }
-        }
-        ;
-        abstract RoaringBitmap[] bitmaps();
-    }
+  public enum Scenario {
+    EQUAL {
+      @Override
+      RoaringBitmap[] bitmaps() {
+        RoaringBitmap bitmap = RandomData.randomBitmap(1 << 12, 0.2, 0.3);
+        return new RoaringBitmap[] {bitmap, bitmap.clone()};
+      }
+    },
+    SHIFTED {
+      @Override
+      RoaringBitmap[] bitmaps() {
+        RoaringBitmap bitmap = RandomData.randomBitmap(1 << 12, 0.2, 0.3);
+        return new RoaringBitmap[] {bitmap, RoaringBitmap.addOffset(bitmap, 1 << 16)};
+      }
+    },
+    SMALL_LARGE {
+      @Override
+      RoaringBitmap[] bitmaps() {
+        return new RoaringBitmap[] {
+          RandomData.randomBitmap(1 << 4, 0.2, 0.3), RandomData.randomBitmap(1 << 12, 0.2, 0.3)
+        };
+      }
+    },
+    LARGE_SMALL {
+      @Override
+      RoaringBitmap[] bitmaps() {
+        return new RoaringBitmap[] {
+          RandomData.randomBitmap(1 << 12, 0.2, 0.3), RandomData.randomBitmap(1 << 4, 0.2, 0.3)
+        };
+      }
+    };
 
-    @Param
-    Scenario scenario;
+    abstract RoaringBitmap[] bitmaps();
+  }
 
-    RoaringBitmap left;
-    RoaringBitmap right;
+  @Param Scenario scenario;
 
-    @Setup(Level.Trial)
-    public void init() {
-        RoaringBitmap[] bitmaps = scenario.bitmaps();
-        left = bitmaps[0];
-        right = bitmaps[1];
-    }
+  RoaringBitmap left;
+  RoaringBitmap right;
 
+  @Setup(Level.Trial)
+  public void init() {
+    RoaringBitmap[] bitmaps = scenario.bitmaps();
+    left = bitmaps[0];
+    right = bitmaps[1];
+  }
 
-    @Benchmark
-    public int xorCardinality() {
-        return RoaringBitmap.xorCardinality(left, right);
-    }
+  @Benchmark
+  public int xorCardinality() {
+    return RoaringBitmap.xorCardinality(left, right);
+  }
 
-    @Benchmark
-    public int xorCardinalityBaseline() {
-        return left.getCardinality() + right.getCardinality() - 2 * RoaringBitmap.andCardinality(left, right);
-    }
+  @Benchmark
+  public int xorCardinalityBaseline() {
+    return left.getCardinality()
+        + right.getCardinality()
+        - 2 * RoaringBitmap.andCardinality(left, right);
+  }
 
-    @Benchmark
-    public int andNotCardinality() {
-        return RoaringBitmap.andNotCardinality(left, right);
-    }
+  @Benchmark
+  public int andNotCardinality() {
+    return RoaringBitmap.andNotCardinality(left, right);
+  }
 
-    @Benchmark
-    public int andNotCardinalityBaseline() {
-        return left.getCardinality() - RoaringBitmap.andCardinality(left, right);
-    }
+  @Benchmark
+  public int andNotCardinalityBaseline() {
+    return left.getCardinality() - RoaringBitmap.andCardinality(left, right);
+  }
 
-    @Benchmark
-    public int orCardinality() {
-        return RoaringBitmap.orCardinality(left, right);
-    }
+  @Benchmark
+  public int orCardinality() {
+    return RoaringBitmap.orCardinality(left, right);
+  }
 
-    @Benchmark
-    public int orCardinalityBaseline() {
-        return left.getCardinality() + right.getCardinality() - RoaringBitmap.andCardinality(left, right);
-    }
+  @Benchmark
+  public int orCardinalityBaseline() {
+    return left.getCardinality()
+        + right.getCardinality()
+        - RoaringBitmap.andCardinality(left, right);
+  }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/contains/ContainsBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/contains/ContainsBenchmark.java
index 8b4fed0c5..1bca28e5a 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/contains/ContainsBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/contains/ContainsBenchmark.java
@@ -1,29 +1,29 @@
-
 // https://github.com/RoaringBitmap/RoaringBitmap/pull/374
 package org.roaringbitmap.contains;
 
-import org.openjdk.jmh.annotations.*;
-import org.roaringbitmap.*;
-
-import java.util.Arrays;
-
 import static java.util.concurrent.TimeUnit.MICROSECONDS;
 import static org.openjdk.jmh.annotations.Mode.AverageTime;
 
+import org.roaringbitmap.RandomData;
+import org.roaringbitmap.RoaringBitmap;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 @BenchmarkMode(AverageTime)
 @OutputTimeUnit(MICROSECONDS)
 public class ContainsBenchmark {
 
-
-
-
   @Benchmark
   public boolean containsBitmaps(EqualBitmapsState state) {
     return state.left.contains(state.right);
   }
 
-
-
   @State(Scope.Benchmark)
   public static class EqualBitmapsState {
 
@@ -36,7 +36,4 @@ public void init() {
       right = RandomData.randomBitmap(50, 0.5, 0.5);
     }
   }
-
-
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java
index e3e28085f..7b702952b 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/deserialization/BitmapContainersDeserializationBenchmark.java
@@ -1,9 +1,17 @@
 package org.roaringbitmap.deserialization;
 
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 import org.openjdk.jmh.infra.Blackhole;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
@@ -46,9 +54,9 @@ public void deserialize(Blackhole blackhole) throws IOException {
 
   private static byte[] serialise(MutableRoaringBitmap input) throws IOException {
     try (ByteArrayOutputStream bos = new ByteArrayOutputStream(input.serializedSizeInBytes());
-         DataOutputStream dos = new DataOutputStream(bos)) {
+        DataOutputStream dos = new DataOutputStream(bos)) {
       input.serialize(dos);
       return bos.toByteArray();
     }
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/equals/EqualsBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/equals/EqualsBenchmark.java
index bc249831d..2f461503e 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/equals/EqualsBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/equals/EqualsBenchmark.java
@@ -1,19 +1,30 @@
 // https://github.com/RoaringBitmap/RoaringBitmap/issues/161
 package org.roaringbitmap.equals;
 
-import org.openjdk.jmh.annotations.*;
-import org.roaringbitmap.*;
-
-import java.util.Arrays;
-
 import static java.util.concurrent.TimeUnit.MICROSECONDS;
 import static org.openjdk.jmh.annotations.Mode.AverageTime;
 
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RandomData;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.RunContainer;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+
 @BenchmarkMode(AverageTime)
 @OutputTimeUnit(MICROSECONDS)
 public class EqualsBenchmark {
 
-
   @Benchmark
   public boolean runVsArrayEquals_FewRuns(EqualsFewRunsBenchmarkState benchmarkState) {
     return benchmarkState.runContainer.equals(benchmarkState.arrayContainer);
@@ -47,11 +58,9 @@ public EqualsFewRunsBenchmarkState() {
       arrayContainer = addRange(arrayContainer, 501, 1500);
       runContainer = addRange(runContainer, 501, 1500);
 
-
       arrayContainer = addRange(arrayContainer, 3000, 4500);
       runContainer = addRange(runContainer, 3000, 4500);
     }
-
   }
 
   @State(Scope.Benchmark)
@@ -67,11 +76,11 @@ public void init() {
     }
   }
 
-
   @State(Scope.Benchmark)
   public static class EqualArrayContainersBenchmarkState {
     @Param({"20", "200", "1000", "2000"})
     int size;
+
     @Param({"0.1", "0.5", "0.9", "1"})
     float firstMismatch;
 
@@ -111,10 +120,8 @@ public EqualsManyRunsBenchmarkState() {
         runStart += runLength + shift;
       }
     }
-
   }
 
-
   private static char[] array(int size) {
     if (size >= 4096) {
       throw new IllegalStateException();
@@ -129,5 +136,4 @@ private static char[] array(int size) {
   static Container addRange(Container c, int min, int sup) {
     return c.iadd(min, sup);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/BatchIteratorBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/BatchIteratorBenchmark.java
index 189cc4a08..cda7db004 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/BatchIteratorBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/BatchIteratorBenchmark.java
@@ -1,8 +1,20 @@
 package org.roaringbitmap.iteration;
 
+import org.roaringbitmap.IntIterator;
+import org.roaringbitmap.PeekableIntIterator;
+import org.roaringbitmap.RandomData;
+import org.roaringbitmap.RoaringBatchIterator;
+import org.roaringbitmap.RoaringBitmap;
 
-import org.openjdk.jmh.annotations.*;
-import org.roaringbitmap.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
 import java.util.concurrent.TimeUnit;
 
@@ -11,7 +23,6 @@
 @State(Scope.Benchmark)
 public class BatchIteratorBenchmark {
 
-
   @Param({"64", "128", "256", "512"})
   int bufferSize;
 
@@ -65,5 +76,4 @@ public int batchIterateAsIntIterator() {
     }
     return blackhole;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapIteratorBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapIteratorBenchmark.java
index b765a50b8..98383c9b0 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapIteratorBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapIteratorBenchmark.java
@@ -1,7 +1,5 @@
 package org.roaringbitmap.iteration;
 
-
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.BitmapContainer;
 import org.roaringbitmap.CharIterator;
 import org.roaringbitmap.Container;
@@ -9,6 +7,16 @@
 import org.roaringbitmap.buffer.MappeableBitmapContainer;
 import org.roaringbitmap.buffer.MappeableContainer;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.nio.LongBuffer;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
@@ -19,7 +27,6 @@
 @Fork(jvmArgsPrepend = "-XX:-TieredCompilation")
 public class BitmapIteratorBenchmark {
 
-
   @Param({"0.1", "0.2", "0.3", "0.4", "0.5"})
   double density;
 
@@ -30,7 +37,7 @@ public class BitmapIteratorBenchmark {
   public void init() {
     long[] bitmap = new long[1024];
     int cardinality = 0;
-    int targetCardinality = (int)(density * 65536);
+    int targetCardinality = (int) (density * 65536);
     ThreadLocalRandom random = ThreadLocalRandom.current();
     while (cardinality < targetCardinality) {
       int index = random.nextInt(65536);
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapNextBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapNextBenchmark.java
index 602ced8a5..9403e1189 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapNextBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/BitmapNextBenchmark.java
@@ -1,10 +1,18 @@
 package org.roaringbitmap.iteration;
 
+import org.roaringbitmap.RoaringBitmap;
 
-import org.openjdk.jmh.annotations.*;
-import org.roaringbitmap.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
-import java.util.*;
+import java.util.BitSet;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 
@@ -14,7 +22,6 @@
 @Fork(jvmArgsPrepend = "-XX:-TieredCompilation")
 public class BitmapNextBenchmark {
 
-
   @Param({"0.1", "0.2", "0.3", "0.4", "0.5"})
   double density;
 
@@ -31,12 +38,12 @@ public void init() {
     long target_cardinality = Math.round(density * size);
     long actual_cardinality = 0;
     ThreadLocalRandom random = ThreadLocalRandom.current();
-    while(actual_cardinality < target_cardinality) {
+    while (actual_cardinality < target_cardinality) {
       int x = random.nextInt(size);
       actual_cardinality += bitmap.checkedAdd(x) ? 1 : 0;
       bs.set(x);
     }
-    for(int k = 0; k < random_size; k++) {
+    for (int k = 0; k < random_size; k++) {
       random_array[k] = random.nextInt(size);
     }
   }
@@ -44,8 +51,8 @@ public void init() {
   @Benchmark
   public long bitset_count() {
     long count = 0;
-    for(int k = 0; k < random_size; k++) {
-      count = count + (long)bs.nextSetBit(random_array[k]);
+    for (int k = 0; k < random_size; k++) {
+      count = count + (long) bs.nextSetBit(random_array[k]);
     }
     return count;
   }
@@ -53,10 +60,9 @@ public long bitset_count() {
   @Benchmark
   public long roaring_count() {
     long count = 0;
-    for(int k = 0; k < random_size; k++) {
-      count = count + (long)bitmap.nextValue(random_array[k]);
+    for (int k = 0; k < random_size; k++) {
+      count = count + (long) bitmap.nextValue(random_array[k]);
     }
     return count;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/Concatenation.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/Concatenation.java
index 598689f60..b91c5d759 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/Concatenation.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/Concatenation.java
@@ -1,54 +1,67 @@
 package org.roaringbitmap.iteration;
 
-import org.openjdk.jmh.annotations.*;
-import org.roaringbitmap.*;
+import static org.roaringbitmap.RoaringBitmapWriter.writer;
+
+import org.roaringbitmap.IntConsumer;
+import org.roaringbitmap.PeekableIntIterator;
+import org.roaringbitmap.RandomData;
+import org.roaringbitmap.RoaringBatchIterator;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.RoaringBitmapWriter;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
 import java.util.BitSet;
 import java.util.stream.IntStream;
 
-import static org.roaringbitmap.RoaringBitmapWriter.writer;
-
 @State(Scope.Benchmark)
-@Fork(value = 1, jvmArgsPrepend =
-        {
-                "-XX:+UseG1GC",
-                "-XX:-TieredCompilation",
-                "-XX:+AlwaysPreTouch",
-                "-ms4G",
-                "-mx4G"
-        })
+@Fork(
+    value = 1,
+    jvmArgsPrepend = {
+      "-XX:+UseG1GC",
+      "-XX:-TieredCompilation",
+      "-XX:+AlwaysPreTouch",
+      "-ms4G",
+      "-mx4G"
+    })
 public class Concatenation {
 
   /**
-  * Using lots and lots of parameter sets is clever, but it takes a long
-  * time to run, produces results that are difficult to interpret.
-  * When we want a ballpark result... a single set of parameters is more than
-  * enough.
-  * Using a long, long time to run each and every benchmark makes you less
-  * likely to run benchmarks which makes you less likely to work with hard
-  * numbers.
-  *
-  */
-
+   * Using lots and lots of parameter sets is clever, but it takes a long
+   * time to run, produces results that are difficult to interpret.
+   * When we want a ballpark result... a single set of parameters is more than
+   * enough.
+   * Using a long, long time to run each and every benchmark makes you less
+   * likely to run benchmarks which makes you less likely to work with hard
+   * numbers.
+   *
+   */
   @Param({"16"})
   int count;
 
   @Param({"8"})
   int size;
 
-
   @Setup(Level.Trial)
   public void init() {
-    bitSets = IntStream.range(0, count)
-            .mapToObj(i -> {
-              RoaringBitmap rb = RandomData.randomContiguousBitmap(0, size, 0.1, 0.8);
-              return new BitSetWithOffset(rb, toBitSet(rb), i * size * 65536);
-            }).toArray(BitSetWithOffset[]::new);
+    bitSets =
+        IntStream.range(0, count)
+            .mapToObj(
+                i -> {
+                  RoaringBitmap rb = RandomData.randomContiguousBitmap(0, size, 0.1, 0.8);
+                  return new BitSetWithOffset(rb, toBitSet(rb), i * size * 65536);
+                })
+            .toArray(BitSetWithOffset[]::new);
   }
 
   private BitSetWithOffset[] bitSets;
 
-
   private static class BitSetWithOffset {
     public final RoaringBitmap bitmap;
     public final BitSet bitset;
@@ -64,10 +77,10 @@ public BitSetWithOffset(RoaringBitmap bitmap, BitSet bitset, int offset) {
   @Benchmark
   public BitSet bitset() {
     BitSet result = new BitSet();
-    for(int i = 0; i < bitSets.length; ++i) {
+    for (int i = 0; i < bitSets.length; ++i) {
       BitSetWithOffset bit = bitSets[i];
       int currentBit = bit.bitset.nextSetBit(0);
-      while(currentBit != -1) {
+      while (currentBit != -1) {
         result.set(currentBit + bit.offset);
         currentBit = bit.bitset.nextSetBit(currentBit + 1);
       }
@@ -78,10 +91,10 @@ public BitSet bitset() {
   @Benchmark
   public RoaringBitmap roaringNaive() {
     RoaringBitmap result = new RoaringBitmap();
-    for(int i = 0; i < bitSets.length; ++i) {
+    for (int i = 0; i < bitSets.length; ++i) {
       BitSetWithOffset bit = bitSets[i];
       PeekableIntIterator peekableIter = bit.bitmap.getIntIterator();
-      while(peekableIter.hasNext()){
+      while (peekableIter.hasNext()) {
         int currentBit = peekableIter.next();
         result.add(currentBit + bit.offset);
       }
@@ -92,7 +105,7 @@ public RoaringBitmap roaringNaive() {
   @Benchmark
   public RoaringBitmap roaringOffset() {
     RoaringBitmap result = new RoaringBitmap();
-    for(int i = 0; i < bitSets.length; ++i) {
+    for (int i = 0; i < bitSets.length; ++i) {
       BitSetWithOffset bit = bitSets[i];
       RoaringBitmap shifted = RoaringBitmap.addOffset(bit.bitmap, bit.offset);
       result.or(shifted);
@@ -104,15 +117,15 @@ public RoaringBitmap roaringOffset() {
   public RoaringBitmap roaringBatchOrderedWriter() {
     int[] buffer = new int[256];
     RoaringBitmapWriter writer = writer().constantMemory().get();
-      for(int i = 0; i < bitSets.length; ++i) {
-        BitSetWithOffset bit = bitSets[i];
-        RoaringBatchIterator iterator = bit.bitmap.getBatchIterator();
-        while (iterator.hasNext()) {
-          int count = iterator.nextBatch(buffer);
-          for (int j = 0; j < count; ++j) {
-            writer.add(buffer[j] + bit.offset);
-          }
+    for (int i = 0; i < bitSets.length; ++i) {
+      BitSetWithOffset bit = bitSets[i];
+      RoaringBatchIterator iterator = bit.bitmap.getBatchIterator();
+      while (iterator.hasNext()) {
+        int count = iterator.nextBatch(buffer);
+        for (int j = 0; j < count; ++j) {
+          writer.add(buffer[j] + bit.offset);
         }
+      }
     }
     writer.flush();
     return writer.getUnderlying();
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark32.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark32.java
index e81bd9bce..3c4ccc6fa 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark32.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark32.java
@@ -1,10 +1,9 @@
 package org.roaringbitmap.iteration;
 
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.IntIterator;
+import org.roaringbitmap.IntIteratorFlyweight;
+import org.roaringbitmap.ReverseIntIteratorFlyweight;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,7 +11,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.*;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Created by Borislav Ivanov on 4/2/15.
@@ -27,7 +31,6 @@ public int testBoxed_a(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
   }
@@ -39,10 +42,8 @@ public int testStandard_a(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -55,10 +56,8 @@ public int testFlyweight_a(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -67,12 +66,10 @@ public int testBoxed_b(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
   }
 
-
   @Benchmark
   public int testStandard_b(BenchmarkState benchmarkState) {
 
@@ -80,10 +77,8 @@ public int testStandard_b(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -96,10 +91,8 @@ public int testFlyweight_b(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -108,12 +101,10 @@ public int testBoxed_c(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
   }
 
-
   @Benchmark
   public int testStandard_c(BenchmarkState benchmarkState) {
 
@@ -121,10 +112,8 @@ public int testStandard_c(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -137,10 +126,8 @@ public int testFlyweight_c(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -150,10 +137,8 @@ public int testReverseStandard_a(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -166,10 +151,8 @@ public int testReverseFlyweight_a(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -179,10 +162,8 @@ public int testReverseStandard_b(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -195,10 +176,8 @@ public int testReverseFlyweight_b(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -208,10 +187,8 @@ public int testReverseStandard_c(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -224,13 +201,10 @@ public int testReverseFlyweight_c(BenchmarkState benchmarkState) {
     int result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
 
@@ -250,13 +224,10 @@ public BenchmarkState() {
       bitmap_a = RoaringBitmap.bitmapOf(data);
 
       bitmap_b = new RoaringBitmap();
-      for (int k = 0; k < (1 << 30); k += 32)
-        bitmap_b.add(k);
+      for (int k = 0; k < (1 << 30); k += 32) bitmap_b.add(k);
 
       bitmap_c = new RoaringBitmap();
-      for (int k = 0; k < (1 << 30); k += 3)
-        bitmap_c.add(k);
-
+      for (int k = 0; k < (1 << 30); k += 3) bitmap_c.add(k);
     }
 
     private int[] takeSortedAndDistinct(Random source, int count) {
@@ -284,5 +255,4 @@ private int[] toArray(LinkedHashSet integers) {
       return ints;
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark64.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark64.java
index 0c45f7d1a..bb33abac1 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark64.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmark64.java
@@ -1,10 +1,7 @@
 package org.roaringbitmap.iteration;
 
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.LongIterator;
+import org.roaringbitmap.longlong.Roaring64NavigableMap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,8 +9,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.LongIterator;
-import org.roaringbitmap.longlong.Roaring64NavigableMap;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Created by Borislav Ivanov on 4/2/15.
@@ -28,7 +29,6 @@ public long testBoxed_a(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
   }
@@ -40,10 +40,8 @@ public long testStandard_a(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -52,7 +50,6 @@ public long testBoxed_b(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
   }
@@ -64,10 +61,8 @@ public long testStandard_b(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -76,7 +71,6 @@ public long testBoxed_c(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
   }
@@ -88,10 +82,8 @@ public long testStandard_c(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -101,10 +93,8 @@ public long testReverseStandard_a(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -114,10 +104,8 @@ public long testReverseStandard_b(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -127,10 +115,8 @@ public long testReverseStandard_c(BenchmarkState benchmarkState) {
     long result = 0;
     while (intIterator.hasNext()) {
       result = intIterator.next();
-
     }
     return result;
-
   }
 
   @State(Scope.Benchmark)
@@ -148,13 +134,10 @@ public BenchmarkState() {
       bitmap_a = Roaring64NavigableMap.bitmapOf(data);
 
       bitmap_b = new Roaring64NavigableMap();
-      for (int k = 0; k < (1 << 30); k += 32)
-        bitmap_b.addLong(k);
+      for (int k = 0; k < (1 << 30); k += 32) bitmap_b.addLong(k);
 
       bitmap_c = new Roaring64NavigableMap();
-      for (int k = 0; k < (1 << 30); k += 3)
-        bitmap_c.addLong(k);
-
+      for (int k = 0; k < (1 << 30); k += 3) bitmap_c.addLong(k);
     }
 
     private long[] takeSortedAndDistinct(Random source, int count) {
diff --git a/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmarkRoaring64Bmp.java b/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmarkRoaring64Bmp.java
index 30f0290e0..0c33d2ae9 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmarkRoaring64Bmp.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/iteration/IteratorsBenchmarkRoaring64Bmp.java
@@ -1,18 +1,20 @@
 package org.roaringbitmap.iteration;
 
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.longlong.LongIterator;
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.LongIterator;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode({Mode.SampleTime, Mode.Throughput, Mode.AverageTime})
 @OutputTimeUnit(TimeUnit.MILLISECONDS)
@@ -24,7 +26,6 @@ public long testBoxed_a(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
   }
@@ -36,10 +37,8 @@ public long testStandard_a(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -48,7 +47,6 @@ public long testBoxed_b(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
   }
@@ -60,10 +58,8 @@ public long testStandard_b(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -72,7 +68,6 @@ public long testBoxed_c(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
   }
@@ -84,10 +79,8 @@ public long testStandard_c(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -97,7 +90,6 @@ public long testReverseStandard_a(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
   }
@@ -109,10 +101,8 @@ public long testReverseStandard_b(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
-
   }
 
   @Benchmark
@@ -122,10 +112,8 @@ public long testReverseStandard_c(BenchmarkState benchmarkState) {
     long result = 0;
     while (longIterator.hasNext()) {
       result = longIterator.next();
-
     }
     return result;
-
   }
 
   @State(Scope.Benchmark)
@@ -143,13 +131,10 @@ public BenchmarkState() {
       bitmap_a = Roaring64Bitmap.bitmapOf(data);
 
       bitmap_b = new Roaring64Bitmap();
-      for (int k = 0; k < (1 << 30); k += 32)
-        bitmap_b.addLong(k);
+      for (int k = 0; k < (1 << 30); k += 32) bitmap_b.addLong(k);
 
       bitmap_c = new Roaring64Bitmap();
-      for (int k = 0; k < (1 << 30); k += 3)
-        bitmap_c.addLong(k);
-
+      for (int k = 0; k < (1 << 30); k += 3) bitmap_c.addLong(k);
     }
 
     private long[] takeSortedAndDistinct(Random source, int count) {
diff --git a/jmh/src/jmh/java/org/roaringbitmap/longlong/ShiftLeftFromSpecifiedPositionBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/longlong/ShiftLeftFromSpecifiedPositionBenchmark.java
index 0554a0948..f36fe57b2 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/longlong/ShiftLeftFromSpecifiedPositionBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/longlong/ShiftLeftFromSpecifiedPositionBenchmark.java
@@ -1,6 +1,14 @@
 package org.roaringbitmap.longlong;
 
-import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 import org.openjdk.jmh.infra.Blackhole;
 
 import java.util.concurrent.TimeUnit;
@@ -35,4 +43,4 @@ public static int shiftLeftFromSpecifiedPosition(int v, int pos, int count) {
     System.arraycopy(initialVal, pos + 1, initialVal, pos, count);
     return IntegerUtil.fromBDBytes(initialVal);
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/map/MapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/map/MapBenchmark.java
index e5594aee5..8aa4d89f1 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/map/MapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/map/MapBenchmark.java
@@ -1,8 +1,9 @@
 // https://github.com/RoaringBitmap/RoaringBitmap/issues/160
 package org.roaringbitmap.map;
 
-import java.util.BitSet;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.BitSetUtil;
+import org.roaringbitmap.IntConsumer;
+import org.roaringbitmap.RoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -10,10 +11,9 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.BitSetUtil;
-import org.roaringbitmap.IntConsumer;
-import org.roaringbitmap.RoaringBitmap;
 
+import java.util.BitSet;
+import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -27,30 +27,30 @@ public static int inttointmap(int x) {
   @Benchmark
   public RoaringBitmap testMap(BenchmarkState benchmarkState) {
     final RoaringBitmap answer = new RoaringBitmap();
-    benchmarkState.bitmap.forEach(new IntConsumer() {
-      @Override
-      public void accept(int value) {
-        answer.add(inttointmap(value));
-      }
-    });
+    benchmarkState.bitmap.forEach(
+        new IntConsumer() {
+          @Override
+          public void accept(int value) {
+            answer.add(inttointmap(value));
+          }
+        });
     return answer;
   }
 
-
   @BenchmarkMode(Mode.AverageTime)
   @Benchmark
   public RoaringBitmap testMapViaBitset(BenchmarkState benchmarkState) {
     final BitSet altRes = new java.util.BitSet();
-    benchmarkState.bitmap.forEach(new IntConsumer() {
-      @Override
-      public void accept(int value) {
-        altRes.set(inttointmap(value));
-      }
-    });
+    benchmarkState.bitmap.forEach(
+        new IntConsumer() {
+          @Override
+          public void accept(int value) {
+            altRes.set(inttointmap(value));
+          }
+        });
     return BitSetUtil.bitmapOf(altRes);
   }
 
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
 
@@ -58,12 +58,9 @@ public static class BenchmarkState {
 
     public BenchmarkState() {
       bitmap.add(10L, 100000L);
-      for (long k = 100000L; k < 2 * 100000L; k += 2)
-        bitmap.add((int) k);
-      for (long k = 2 * 100000L; k < 200 * 100000L; k += 100000L)
-        bitmap.add((int) k);
+      for (long k = 100000L; k < 2 * 100000L; k += 2) bitmap.add((int) k);
+      for (long k = 2 * 100000L; k < 200 * 100000L; k += 100000L) bitmap.add((int) k);
       bitmap.runOptimize();
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/RandomAccess.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/RandomAccess.java
index 3f1d8b09c..589eeb879 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/RandomAccess.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/RandomAccess.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.needwork;
 
-
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.needwork.state.NeedWorkBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,8 +11,9 @@
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 import org.openjdk.jmh.infra.Blackhole;
-import org.roaringbitmap.needwork.state.NeedWorkBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -31,8 +31,6 @@ public void binarySearch(BenchmarkState bs, Blackhole bh) {
   @State(Scope.Benchmark)
   public static class BenchmarkState extends NeedWorkBenchmarkState {
 
-
-
     int[] queries = new int[1024];
 
     public BenchmarkState() {}
@@ -45,15 +43,10 @@ public void setup() throws Exception {
       int universe = 0;
       for (Bitmap bitmap : bitmaps) {
         int lv = bitmap.last();
-        if (lv > universe)
-          universe = lv;
+        if (lv > universe) universe = lv;
       }
       Random rand = new Random(123);
-      for (int k = 0; k < queries.length; ++k)
-        queries[k] = rand.nextInt(universe + 1);
-
+      for (int k = 0; k < queries.length; ++k) queries[k] = rand.nextInt(universe + 1);
     }
-
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate1.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate1.java
index 157176a37..0dc27fc07 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate1.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate1.java
@@ -1,5 +1,17 @@
 package org.roaringbitmap.needwork;
 
+import org.roaringbitmap.ZipRealDataRetriever;
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
 import java.io.DataOutputStream;
 import java.io.File;
@@ -12,18 +24,6 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ZipRealDataRetriever;
-import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
-
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class SlowMappedORaggregate1 {
@@ -34,12 +34,11 @@ public MutableRoaringBitmap RoaringWithRun(BenchmarkState benchmarkState) {
     return answer;
   }
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "wikileaks-noquotes",})
+    @Param({ // putting the data sets in alpha. order
+      "wikileaks-noquotes",
+    })
     String dataset;
 
     public List convertToImmutableRoaring(List source)
@@ -49,8 +48,7 @@ public List convertToImmutableRoaring(List convertToImmutableRoaring(List convertToImmutableRoaring(List rc;
 
     public BenchmarkState() {}
@@ -91,6 +87,5 @@ public void setup() throws Exception {
       }
       rc = convertToImmutableRoaring(tmprc);
     }
-
   }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate2.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate2.java
index 65162b873..7e87e3640 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate2.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowMappedORaggregate2.java
@@ -1,5 +1,17 @@
 package org.roaringbitmap.needwork;
 
+import org.roaringbitmap.ZipRealDataRetriever;
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
 import java.io.DataOutputStream;
 import java.io.File;
@@ -12,18 +24,6 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ZipRealDataRetriever;
-import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
-
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class SlowMappedORaggregate2 {
@@ -34,12 +34,11 @@ public MutableRoaringBitmap RoaringWithRun(BenchmarkState benchmarkState) {
     return answer;
   }
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "census1881_srt",})
+    @Param({ // putting the data sets in alpha. order
+      "census1881_srt",
+    })
     String dataset;
 
     public List convertToImmutableRoaring(List source)
@@ -49,8 +48,7 @@ public List convertToImmutableRoaring(List convertToImmutableRoaring(List convertToImmutableRoaring(List rc;
 
     public BenchmarkState() {}
@@ -91,6 +87,5 @@ public void setup() throws Exception {
       }
       rc = convertToImmutableRoaring(tmprc);
     }
-
   }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate1.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate1.java
index b32f9d4d9..5482ee2a8 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate1.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate1.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.needwork;
 
-
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.ZipRealDataRetriever;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,8 +11,9 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.ZipRealDataRetriever;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -25,15 +25,13 @@ public RoaringBitmap RoaringWithRun(BenchmarkState benchmarkState) {
     return answer;
   }
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "wikileaks-noquotes",})
+    @Param({ // putting the data sets in alpha. order
+      "wikileaks-noquotes",
+    })
     String dataset;
 
-
     ArrayList rc = new ArrayList();
 
     public BenchmarkState() {}
@@ -51,6 +49,5 @@ public void setup() throws Exception {
       }
       System.out.println("loaded " + rc.size() + " bitmaps");
     }
-
   }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate2.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate2.java
index 73c1c6db5..a8fe81ebb 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate2.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate2.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.needwork;
 
-
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.ZipRealDataRetriever;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,8 +11,9 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.ZipRealDataRetriever;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -25,15 +25,13 @@ public RoaringBitmap RoaringWithRun(BenchmarkState benchmarkState) {
     return answer;
   }
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "census1881_srt",})
+    @Param({ // putting the data sets in alpha. order
+      "census1881_srt",
+    })
     String dataset;
 
-
     ArrayList rc = new ArrayList();
 
     public BenchmarkState() {}
@@ -51,6 +49,5 @@ public void setup() throws Exception {
       }
       System.out.println("loaded " + rc.size() + " bitmaps");
     }
-
   }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate3.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate3.java
index fda496c5a..c9f18b95a 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate3.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/SlowORaggregate3.java
@@ -1,8 +1,8 @@
 package org.roaringbitmap.needwork;
 
-
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.FastAggregation;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.ZipRealDataRetriever;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,9 +12,9 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.FastAggregation;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.ZipRealDataRetriever;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -26,15 +26,13 @@ public RoaringBitmap RoaringWithRun(BenchmarkState benchmarkState) {
     return answer;
   }
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "weather_sept_85_srt",})
+    @Param({ // putting the data sets in alpha. order
+      "weather_sept_85_srt",
+    })
     String dataset;
 
-
     ArrayList rc = new ArrayList();
 
     public BenchmarkState() {}
@@ -52,6 +50,5 @@ public void setup() throws Exception {
       }
       System.out.println("loaded " + rc.size() + " bitmaps");
     }
-
   }
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/needwork/state/NeedWorkBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/needwork/state/NeedWorkBenchmarkState.java
index 6063ea33c..f4d872ff8 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/needwork/state/NeedWorkBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/needwork/state/NeedWorkBenchmarkState.java
@@ -15,19 +15,30 @@
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING_WITH_RUN;
 
+import org.roaringbitmap.AbstractBenchmarkState;
+
 import org.openjdk.jmh.annotations.Param;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.AbstractBenchmarkState;
 
 @State(Scope.Benchmark)
 public class NeedWorkBenchmarkState extends AbstractBenchmarkState {
 
-  @Param({// putting the data sets in alpha. order
-      CENSUS_INCOME, CENSUS1881, DIMENSION_008, DIMENSION_003, DIMENSION_033, USCENSUS2000,
-      WEATHER_SEPT_85, WIKILEAKS_NOQUOTES, CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT,
-      WIKILEAKS_NOQUOTES_SRT})
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME,
+    CENSUS1881,
+    DIMENSION_008,
+    DIMENSION_003,
+    DIMENSION_033,
+    USCENSUS2000,
+    WEATHER_SEPT_85,
+    WIKILEAKS_NOQUOTES,
+    CENSUS_INCOME_SRT,
+    CENSUS1881_SRT,
+    WEATHER_SEPT_85_SRT,
+    WIKILEAKS_NOQUOTES_SRT
+  })
   public String dataset;
 
   @Param({ROARING, ROARING_WITH_RUN})
@@ -36,12 +47,10 @@ public class NeedWorkBenchmarkState extends AbstractBenchmarkState {
   @Param({"false", "true"})
   public boolean immutable;
 
-
   public NeedWorkBenchmarkState() {}
 
   @Setup
   public void setup() throws Exception {
     super.setup(dataset, type, immutable);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java b/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java
index 936d695b0..715d925e0 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/range/ContainsRange.java
@@ -1,23 +1,33 @@
 package org.roaringbitmap.range;
 
-
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.RandomData;
 import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.Util;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.concurrent.TimeUnit;
 
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 @BenchmarkMode(Mode.AverageTime)
-@Fork(value = 1, jvmArgsPrepend =
-        {
-                "-XX:-TieredCompilation",
-                "-XX:+UseSerialGC",
-                "-mx2G",
-                "-ms2G",
-                "-XX:+AlwaysPreTouch"
-        })
+@Fork(
+    value = 1,
+    jvmArgsPrepend = {
+      "-XX:-TieredCompilation",
+      "-XX:+UseSerialGC",
+      "-mx2G",
+      "-ms2G",
+      "-XX:+AlwaysPreTouch"
+    })
 @State(Scope.Benchmark)
 public class ContainsRange {
 
@@ -53,7 +63,9 @@ long getSup(RoaringBitmap bitmap) {
         return Util.toUnsignedLong(bitmap.last()) - 1;
       }
     };
+
     abstract long getMin(RoaringBitmap bitmap);
+
     abstract long getSup(RoaringBitmap bitmap);
   }
 
@@ -62,7 +74,6 @@ long getSup(RoaringBitmap bitmap) {
   private long min;
   private long sup;
 
-
   @Setup(Level.Trial)
   public void init() {
     bitmap = RandomData.randomBitmap(keys, 0.3, 0.2);
@@ -71,7 +82,7 @@ public void init() {
     if (match) {
       bitmap.add(min, sup);
     } else if (bitmap.contains(min, sup)) {
-      bitmap.flip((int)((min + sup) / 2));
+      bitmap.flip((int) ((min + sup) / 2));
       assert !bitmap.contains(min, sup);
     }
   }
@@ -83,13 +94,11 @@ public boolean contains() {
 
   @Benchmark
   public boolean containsViaRank() {
-    if (!bitmap.contains((int)min) || ! bitmap.contains((int)(sup - 1))) {
+    if (!bitmap.contains((int) min) || !bitmap.contains((int) (sup - 1))) {
       return false;
     }
-    int startRank = bitmap.rank((int)min);
-    int endRank = bitmap.rank((int)(sup - 1));
+    int startRank = bitmap.rank((int) min);
+    int endRank = bitmap.rank((int) (sup - 1));
     return endRank - startRank + 1 == sup - min;
   }
-
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/rangebitmap/RangeBitmapBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/rangebitmap/RangeBitmapBenchmark.java
index 2852ebc47..cc143d0eb 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/rangebitmap/RangeBitmapBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/rangebitmap/RangeBitmapBenchmark.java
@@ -1,12 +1,22 @@
 package org.roaringbitmap.rangebitmap;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.RangeBitmap;
 import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.RoaringBitmapWriter;
 import org.roaringbitmap.bsi.BitmapSliceIndex;
 import org.roaringbitmap.bsi.RoaringBitmapSliceIndex;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.Arrays;
 import java.util.Random;
 import java.util.SplittableRandom;
@@ -15,13 +25,14 @@
 
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 @BenchmarkMode(Mode.AverageTime)
-@Fork(value = 1, jvmArgsPrepend =
-    {
-        "-XX:-TieredCompilation",
-        "-XX:+UseSerialGC",
-        "-mx2G",
-        "-ms2G",
-        "-XX:+AlwaysPreTouch"
+@Fork(
+    value = 1,
+    jvmArgsPrepend = {
+      "-XX:-TieredCompilation",
+      "-XX:+UseSerialGC",
+      "-mx2G",
+      "-ms2G",
+      "-XX:+AlwaysPreTouch"
     })
 @State(Scope.Benchmark)
 public class RangeBitmapBenchmark {
@@ -51,7 +62,8 @@ public void setup() {
       maxValue = Math.max(values[i], maxValue);
     }
     bsi = new RoaringBitmapSliceIndex();
-    Base2ReferenceImplementation.Builder referenceImplementationBuilder = Base2ReferenceImplementation.builder();
+    Base2ReferenceImplementation.Builder referenceImplementationBuilder =
+        Base2ReferenceImplementation.builder();
     RangeBitmap.Appender appender = RangeBitmap.appender(maxValue);
     int lz = Long.numberOfLeadingZeros(maxValue);
     long mask = (1L << lz) - 1;
@@ -59,7 +71,7 @@ public void setup() {
     for (long value : values) {
       referenceImplementationBuilder.add(value);
       appender.add(value);
-      bsi.setValue(rid++, (int)(value & mask));
+      bsi.setValue(rid++, (int) (value & mask));
     }
     this.referenceImplementation = referenceImplementationBuilder.seal();
     this.rangeBitmap = appender.build();
@@ -75,7 +87,7 @@ public RoaringBitmap referenceBase2() {
   @Benchmark
   public RoaringBitmap bsi() {
     // this is about as good as a user can do from outside the library
-    return bsi.compare(BitmapSliceIndex.Operation.LE, (int)threshold, 0, null);
+    return bsi.compare(BitmapSliceIndex.Operation.LE, (int) threshold, 0, null);
   }
 
   @Benchmark
@@ -202,12 +214,12 @@ LongSupplier of(long seed, double... params) {
     public static LongSupplier parse(long seed, String spec) {
       int paramsStart = spec.indexOf('(');
       int paramsEnd = spec.indexOf(')');
-      double[] params = Arrays.stream(spec.substring(paramsStart + 1, paramsEnd).split(","))
-          .mapToDouble(s -> Double.parseDouble(s.trim()))
-          .toArray();
+      double[] params =
+          Arrays.stream(spec.substring(paramsStart + 1, paramsEnd).split(","))
+              .mapToDouble(s -> Double.parseDouble(s.trim()))
+              .toArray();
       String dist = spec.substring(0, paramsStart).toUpperCase();
       return Distribution.valueOf(dist).of(seed, params);
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/ParallelAggregatorBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/ParallelAggregatorBenchmark.java
index 5d81668d6..69785c5dd 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/ParallelAggregatorBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/ParallelAggregatorBenchmark.java
@@ -1,8 +1,18 @@
 package org.roaringbitmap.realdata;
 
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import org.openjdk.jmh.annotations.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import org.roaringbitmap.FastAggregation;
 import org.roaringbitmap.ParallelAggregation;
 import org.roaringbitmap.RoaringBitmap;
@@ -12,25 +22,43 @@
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.StreamSupport;
 
-import static org.roaringbitmap.RealDataset.*;
-
 @State(Scope.Benchmark)
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class ParallelAggregatorBenchmark {
 
   private static final Cache DATASET_CACHE =
-          CacheBuilder.newBuilder().maximumSize(1).build();
-
-  @Param({// putting the data sets in alpha. order
-          CENSUS_INCOME, CENSUS1881, DIMENSION_008,
-          DIMENSION_003, DIMENSION_033, USCENSUS2000,
-          WEATHER_SEPT_85, WIKILEAKS_NOQUOTES, CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT,
-          WIKILEAKS_NOQUOTES_SRT
+      CacheBuilder.newBuilder().maximumSize(1).build();
+
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME,
+    CENSUS1881,
+    DIMENSION_008,
+    DIMENSION_003,
+    DIMENSION_033,
+    USCENSUS2000,
+    WEATHER_SEPT_85,
+    WIKILEAKS_NOQUOTES,
+    CENSUS_INCOME_SRT,
+    CENSUS1881_SRT,
+    WEATHER_SEPT_85_SRT,
+    WIKILEAKS_NOQUOTES_SRT
   })
   public String dataset;
 
@@ -39,14 +67,19 @@ public class ParallelAggregatorBenchmark {
 
   @Setup(Level.Trial)
   public void setup() throws Exception {
-    bitmaps = DATASET_CACHE.get(dataset, () -> {
-      System.out.println("Loading" + dataset);
-      ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
-      return StreamSupport.stream(dataRetriever.fetchBitPositions().spliterator(), false)
-              .map(RoaringBitmap::bitmapOf)
-              .toArray(RoaringBitmap[]::new);
-    });
-    immutableRoaringBitmaps = Arrays.stream(bitmaps).map(RoaringBitmap::toMutableRoaringBitmap)
+    bitmaps =
+        DATASET_CACHE.get(
+            dataset,
+            () -> {
+              System.out.println("Loading" + dataset);
+              ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
+              return StreamSupport.stream(dataRetriever.fetchBitPositions().spliterator(), false)
+                  .map(RoaringBitmap::bitmapOf)
+                  .toArray(RoaringBitmap[]::new);
+            });
+    immutableRoaringBitmaps =
+        Arrays.stream(bitmaps)
+            .map(RoaringBitmap::toMutableRoaringBitmap)
             .toArray(ImmutableRoaringBitmap[]::new);
   }
 
@@ -80,7 +113,6 @@ public RoaringBitmap fastXor() {
     return FastAggregation.xor(bitmaps);
   }
 
-
   @Benchmark
   public MutableRoaringBitmap bufferParallelOr() {
     return BufferParallelAggregation.or(immutableRoaringBitmaps);
@@ -105,5 +137,4 @@ public MutableRoaringBitmap bufferFastOr() {
   public MutableRoaringBitmap bufferFastXor() {
     return BufferFastAggregation.xor(immutableRoaringBitmaps);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAnd.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAnd.java
index 16afeb031..d4ba4e245 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAnd.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAnd.java
@@ -1,12 +1,13 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -20,5 +21,4 @@ public int pairwiseAnd(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNot.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNot.java
index 5b02a4c10..76ec7af24 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNot.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNot.java
@@ -1,12 +1,13 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -20,5 +21,4 @@ public int pairwiseAndNot(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkCardinality.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkCardinality.java
index 647be5402..d362368db 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkCardinality.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkCardinality.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkContains.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkContains.java
index c14de6143..4e0372bf8 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkContains.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkContains.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.realdata;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -12,8 +11,10 @@
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 import org.openjdk.jmh.infra.Blackhole;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -48,5 +49,4 @@ public void setup() throws Exception {
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkForEach.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkForEach.java
index b4b0eaaf3..ed4cda616 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkForEach.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkForEach.java
@@ -1,14 +1,15 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.IntConsumer;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.IntConsumer;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -32,5 +33,4 @@ public void accept(int value) {
       total += value;
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIOr.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIOr.java
index 83c053bd0..91b5978eb 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIOr.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIOr.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -21,5 +22,4 @@ public int pairwiseIOr(RealDataBenchmarkState bs) {
     }
     return bitmap.cardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkInot.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkInot.java
index a492b5d19..7f3209d9b 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkInot.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkInot.java
@@ -1,12 +1,13 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -20,5 +21,4 @@ public int flipLargeRange(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIterate.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIterate.java
index cc4fbb37f..b37722b58 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIterate.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkIterate.java
@@ -1,14 +1,15 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
+import org.roaringbitmap.realdata.wrapper.BitmapIterator;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
-import org.roaringbitmap.realdata.wrapper.BitmapIterator;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -26,5 +27,4 @@ public int iterate(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOr.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOr.java
index cecc26420..3e38f6eec 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOr.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOr.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.BitmapIterator;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.BitmapIterator;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -33,5 +34,4 @@ public int pairwiseOr_NoCardinality(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOrNot.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOrNot.java
index a37c73057..4a58505ca 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOrNot.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkOrNot.java
@@ -1,17 +1,18 @@
 package org.roaringbitmap.realdata;
 
+import static org.roaringbitmap.Util.toUnsignedLong;
+
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.realdata.state.RealDataRoaringBitmaps;
+
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.infra.Blackhole;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.realdata.state.RealDataRoaringBitmaps;
 
 import java.util.concurrent.TimeUnit;
 
-import static org.roaringbitmap.Util.toUnsignedLong;
-
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class RealDataBenchmarkOrNot {
@@ -21,8 +22,9 @@ public void pairwiseOrNot(RealDataRoaringBitmaps state, Blackhole bh) {
     RoaringBitmap[] bitmaps = state.getBitmaps();
     for (int k = 0; k + 1 < bitmaps.length; ++k) {
       RoaringBitmap bitmap = bitmaps[k].clone();
-      bitmap.orNot(bitmaps[k+1], bitmap.last());
-      bh.consume(RoaringBitmap.orNot(bitmaps[k], bitmaps[k + 1], toUnsignedLong(bitmaps[k].last())));
+      bitmap.orNot(bitmaps[k + 1], bitmap.last());
+      bh.consume(
+          RoaringBitmap.orNot(bitmaps[k], bitmaps[k + 1], toUnsignedLong(bitmaps[k].last())));
     }
   }
 
@@ -33,7 +35,7 @@ public void pairwiseOrNotExternal(RealDataRoaringBitmaps state, Blackhole bh) {
       long limit = toUnsignedLong(bitmaps[k].last());
       RoaringBitmap range = new RoaringBitmap();
       range.add(0, limit);
-      RoaringBitmap bitmap = RoaringBitmap.and(range, bitmaps[k+1]);
+      RoaringBitmap bitmap = RoaringBitmap.and(range, bitmaps[k + 1]);
       bitmap.flip(0L, limit);
       bitmap.or(RoaringBitmap.and(range, bitmaps[k]));
       bh.consume(bitmap);
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterate.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterate.java
index a51b6faf0..4c1c7da22 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterate.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterate.java
@@ -1,14 +1,15 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.Bitmap;
+import org.roaringbitmap.realdata.wrapper.BitmapIterator;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.Bitmap;
-import org.roaringbitmap.realdata.wrapper.BitmapIterator;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -26,5 +27,4 @@ public int reverseIterate(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaive.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaive.java
index a13e3eecb..54d61e2a7 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaive.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaive.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -18,5 +19,4 @@ public int wideAnd_naive(RealDataBenchmarkState bs) {
     BitmapAggregator aggregator = bs.bitmaps.get(0).naiveAndAggregator();
     return aggregator.aggregate(bs.bitmaps).cardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaive.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaive.java
index 405d8c5d2..ad7528118 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaive.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaive.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -18,5 +19,4 @@ public int wideOr_naive(RealDataBenchmarkState bs) {
     BitmapAggregator aggregator = bs.bitmaps.get(0).naiveOrAggregator();
     return aggregator.aggregate(bs.bitmaps).cardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPq.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPq.java
index b9a73d986..c1cd0f7b1 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPq.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPq.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -18,5 +19,4 @@ public int wideOr_pq(RealDataBenchmarkState bs) {
     BitmapAggregator aggregator = bs.bitmaps.get(0).priorityQueueOrAggregator();
     return aggregator.aggregate(bs.bitmaps).cardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkXor.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkXor.java
index 53727aea8..d3e961208 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkXor.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataBenchmarkXor.java
@@ -1,12 +1,13 @@
 package org.roaringbitmap.realdata;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -20,5 +21,4 @@ public int pairwiseXor(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java
index 2d63f941f..c6e6eea7c 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/RealDataSerializationBenchmark.java
@@ -13,15 +13,9 @@
 import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
 import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.StreamSupport;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.ZipRealDataRetriever;
+import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.Level;
@@ -35,9 +29,16 @@
 import org.openjdk.jmh.runner.options.Options;
 import org.openjdk.jmh.runner.options.OptionsBuilder;
 import org.openjdk.jmh.runner.options.TimeValue;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.ZipRealDataRetriever;
-import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.StreamSupport;
 
 /**
  *
@@ -46,40 +47,47 @@
  */
 public class RealDataSerializationBenchmark {
 
-	 public void
-	    launchBenchmark() throws Exception {
-
-	            Options opt = new OptionsBuilder()
-	                // Specify which benchmarks to run.
-	                // You can be more specific if you'd like to run only one benchmark per test.
-	                .include(this.getClass().getName() + ".*")
-	                // Set the following options as needed
-	                .mode (Mode.AverageTime)
-	                .timeUnit(TimeUnit.MICROSECONDS)
-	                .warmupTime(TimeValue.seconds(1))
-	                .warmupIterations(2)
-	                .measurementTime(TimeValue.seconds(10))
-	                .measurementIterations(5)
-	                .threads(1)
-	                .forks(1)
-	                .shouldFailOnError(true)
-	                .shouldDoGC(true)
-	                //.jvmArgs("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining")
-	                //.addProfiler(WinPerfAsmProfiler.class)
-	                .build();
-
-	            new Runner(opt).run();
-	        }
+  public void launchBenchmark() throws Exception {
+
+    Options opt =
+        new OptionsBuilder()
+            // Specify which benchmarks to run.
+            // You can be more specific if you'd like to run only one benchmark per test.
+            .include(this.getClass().getName() + ".*")
+            // Set the following options as needed
+            .mode(Mode.AverageTime)
+            .timeUnit(TimeUnit.MICROSECONDS)
+            .warmupTime(TimeValue.seconds(1))
+            .warmupIterations(2)
+            .measurementTime(TimeValue.seconds(10))
+            .measurementIterations(5)
+            .threads(1)
+            .forks(1)
+            .shouldFailOnError(true)
+            .shouldDoGC(true)
+            // .jvmArgs("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining")
+            // .addProfiler(WinPerfAsmProfiler.class)
+            .build();
+
+    new Runner(opt).run();
+  }
 
   @State(Scope.Benchmark)
   public static class BenchmarkState {
 
-
     @Param({
-            CENSUS_INCOME, CENSUS1881, DIMENSION_008,
-            DIMENSION_003, DIMENSION_033, USCENSUS2000,
-            WEATHER_SEPT_85, WIKILEAKS_NOQUOTES, CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT,
-            WIKILEAKS_NOQUOTES_SRT
+      CENSUS_INCOME,
+      CENSUS1881,
+      DIMENSION_008,
+      DIMENSION_003,
+      DIMENSION_033,
+      USCENSUS2000,
+      WEATHER_SEPT_85,
+      WIKILEAKS_NOQUOTES,
+      CENSUS_INCOME_SRT,
+      CENSUS1881_SRT,
+      WEATHER_SEPT_85_SRT,
+      WIKILEAKS_NOQUOTES_SRT
     })
     public String dataset;
 
@@ -91,7 +99,8 @@ public static class BenchmarkState {
     @Setup(Level.Trial)
     public void setup() throws Exception {
       ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
-      RoaringBitmap[] bitmaps = StreamSupport.stream(dataRetriever.fetchBitPositions().spliterator(), false)
+      RoaringBitmap[] bitmaps =
+          StreamSupport.stream(dataRetriever.fetchBitPositions().spliterator(), false)
               .map(RoaringBitmap::bitmapOf)
               .toArray(RoaringBitmap[]::new);
       buffers = new byte[bitmaps.length][];
@@ -107,19 +116,19 @@ public void setup() throws Exception {
     }
   }
 
-
   @Benchmark
   public void bufferBackedDataInput(BenchmarkState state, Blackhole bh) throws IOException {
-      byte[][] buffers = state.buffers;
-      for (int i = 0; i < buffers.length; ++i) {
-          RoaringBitmap bitmap = new RoaringBitmap();
-          bitmap.deserialize(new BufferDataInput(ByteBuffer.wrap(state.buffers[i])));
-          bh.consume(bitmap);
-      }
+    byte[][] buffers = state.buffers;
+    for (int i = 0; i < buffers.length; ++i) {
+      RoaringBitmap bitmap = new RoaringBitmap();
+      bitmap.deserialize(new BufferDataInput(ByteBuffer.wrap(state.buffers[i])));
+      bh.consume(bitmap);
+    }
   }
 
   @Benchmark
-  public void streamBackedDataInputWithBuffer(BenchmarkState state, Blackhole bh) throws IOException {
+  public void streamBackedDataInputWithBuffer(BenchmarkState state, Blackhole bh)
+      throws IOException {
     byte[][] buffers = state.buffers;
     for (int i = 0; i < buffers.length; ++i) {
       RoaringBitmap bitmap = new RoaringBitmap();
@@ -154,7 +163,8 @@ public void directToBuffer(BenchmarkState state, Blackhole bh) throws IOExceptio
   public void viaImmutable(BenchmarkState state, Blackhole bh) {
     byte[][] buffers = state.buffers;
     for (int i = 0; i < buffers.length; ++i) {
-      RoaringBitmap bitmap = new ImmutableRoaringBitmap(ByteBuffer.wrap(state.buffers[i])).toRoaringBitmap();
+      RoaringBitmap bitmap =
+          new ImmutableRoaringBitmap(ByteBuffer.wrap(state.buffers[i])).toRoaringBitmap();
       bh.consume(bitmap);
     }
   }
@@ -243,5 +253,4 @@ public String readUTF() throws IOException {
       return null;
     }
   }
-
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataBenchmarkState.java
index de95a766b..ac68fe7e0 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataBenchmarkState.java
@@ -27,10 +27,20 @@
 @State(Scope.Benchmark)
 public class RealDataBenchmarkState extends org.roaringbitmap.AbstractBenchmarkState {
 
-  @Param({// putting the data sets in alpha. order
-      CENSUS_INCOME, CENSUS1881, DIMENSION_008, DIMENSION_003, DIMENSION_033, USCENSUS2000,
-      WEATHER_SEPT_85, WIKILEAKS_NOQUOTES, CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT,
-      WIKILEAKS_NOQUOTES_SRT})
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME,
+    CENSUS1881,
+    DIMENSION_008,
+    DIMENSION_003,
+    DIMENSION_033,
+    USCENSUS2000,
+    WEATHER_SEPT_85,
+    WIKILEAKS_NOQUOTES,
+    CENSUS_INCOME_SRT,
+    CENSUS1881_SRT,
+    WEATHER_SEPT_85_SRT,
+    WIKILEAKS_NOQUOTES_SRT
+  })
   public String dataset;
 
   @Param({CONCISE, WAH, EWAH, EWAH32, ROARING, ROARING_WITH_RUN})
@@ -39,12 +49,10 @@ public class RealDataBenchmarkState extends org.roaringbitmap.AbstractBenchmarkS
   @Param({"false", "true"})
   public boolean immutable;
 
-
   public RealDataBenchmarkState() {}
 
   @Setup
   public void setup() throws Exception {
     super.setup(dataset, type, immutable);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringBitmaps.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringBitmaps.java
index 15f19d5b5..f62f48259 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringBitmaps.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringBitmaps.java
@@ -1,23 +1,47 @@
 package org.roaringbitmap.realdata.state;
 
-import org.openjdk.jmh.annotations.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.ZipRealDataRetriever;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
 import java.util.Arrays;
 import java.util.stream.StreamSupport;
 
-import static org.roaringbitmap.RealDataset.*;
-
 @State(Scope.Benchmark)
 public class RealDataRoaringBitmaps {
 
-  @Param({// putting the data sets in alpha. order
-          CENSUS_INCOME, CENSUS1881, DIMENSION_008,
-          DIMENSION_003, DIMENSION_033, USCENSUS2000,
-          WEATHER_SEPT_85, WIKILEAKS_NOQUOTES, CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT,
-          WIKILEAKS_NOQUOTES_SRT
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME,
+    CENSUS1881,
+    DIMENSION_008,
+    DIMENSION_003,
+    DIMENSION_033,
+    USCENSUS2000,
+    WEATHER_SEPT_85,
+    WIKILEAKS_NOQUOTES,
+    CENSUS_INCOME_SRT,
+    CENSUS1881_SRT,
+    WEATHER_SEPT_85_SRT,
+    WIKILEAKS_NOQUOTES_SRT
   })
   public String dataset;
 
@@ -27,10 +51,13 @@ public class RealDataRoaringBitmaps {
   @Setup(Level.Trial)
   public void setup() throws Exception {
     ZipRealDataRetriever dataRetriever = new ZipRealDataRetriever(dataset);
-    bitmaps = StreamSupport.stream(dataRetriever.fetchBitPositions().spliterator(), false)
+    bitmaps =
+        StreamSupport.stream(dataRetriever.fetchBitPositions().spliterator(), false)
             .map(RoaringBitmap::bitmapOf)
             .toArray(RoaringBitmap[]::new);
-    immutableRoaringBitmaps = Arrays.stream(bitmaps).map(RoaringBitmap::toMutableRoaringBitmap)
+    immutableRoaringBitmaps =
+        Arrays.stream(bitmaps)
+            .map(RoaringBitmap::toMutableRoaringBitmap)
             .toArray(ImmutableRoaringBitmap[]::new);
   }
 
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringOnlyBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringOnlyBenchmarkState.java
index 4f3e7a15e..f8fb77c3a 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringOnlyBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/state/RealDataRoaringOnlyBenchmarkState.java
@@ -1,25 +1,40 @@
 package org.roaringbitmap.realdata.state;
 
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import org.openjdk.jmh.annotations.Param;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 
-import static org.roaringbitmap.RealDataset.*;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH32;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING_WITH_RUN;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
-
 @State(Scope.Benchmark)
 public class RealDataRoaringOnlyBenchmarkState extends org.roaringbitmap.RoaringOnlyBenchmarkState {
 
-  @Param({// putting the data sets in alpha. order
-      CENSUS_INCOME, CENSUS1881, DIMENSION_008, DIMENSION_003, DIMENSION_033, USCENSUS2000,
-      WEATHER_SEPT_85, WIKILEAKS_NOQUOTES, CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT,
-      WIKILEAKS_NOQUOTES_SRT})
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME,
+    CENSUS1881,
+    DIMENSION_008,
+    DIMENSION_003,
+    DIMENSION_033,
+    USCENSUS2000,
+    WEATHER_SEPT_85,
+    WIKILEAKS_NOQUOTES,
+    CENSUS_INCOME_SRT,
+    CENSUS1881_SRT,
+    WEATHER_SEPT_85_SRT,
+    WIKILEAKS_NOQUOTES_SRT
+  })
   public String dataset;
 
   public RealDataRoaringOnlyBenchmarkState() {}
@@ -28,5 +43,4 @@ public RealDataRoaringOnlyBenchmarkState() {}
   public void setup() throws Exception {
     super.setup(dataset);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Bitmap.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Bitmap.java
index 4dc78d90e..ca4703376 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Bitmap.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Bitmap.java
@@ -1,10 +1,10 @@
 package org.roaringbitmap.realdata.wrapper;
 
+import org.roaringbitmap.IntConsumer;
+
 import java.io.DataOutputStream;
 import java.io.IOException;
 
-import org.roaringbitmap.IntConsumer;
-
 public interface Bitmap {
 
   boolean contains(int i);
@@ -40,5 +40,4 @@ public interface Bitmap {
   void serialize(DataOutputStream dos) throws IOException;
 
   Bitmap clone();
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapAggregator.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapAggregator.java
index 71538f0e9..c54087c26 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapAggregator.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapAggregator.java
@@ -3,5 +3,4 @@
 public interface BitmapAggregator {
 
   Bitmap aggregate(Iterable bitmaps);
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapFactory.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapFactory.java
index f44e52201..74f9b1138 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapFactory.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapFactory.java
@@ -1,23 +1,16 @@
 package org.roaringbitmap.realdata.wrapper;
 
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.List;
-
-import io.druid.extendedset.intset.ConciseSet;
-import io.druid.extendedset.intset.ImmutableConciseSet;
 import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
 import com.googlecode.javaewah.EWAHCompressedBitmap;
 import com.googlecode.javaewah32.EWAHCompressedBitmap32;
+import io.druid.extendedset.intset.ConciseSet;
+import io.druid.extendedset.intset.ImmutableConciseSet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.nio.ByteBuffer;
 
 public final class BitmapFactory {
 
@@ -119,7 +112,6 @@ private static Bitmap newImmutableRoaringBitmap(Bitmap bitmap) throws Exception
     return new ImmutableRoaringBitmapWrapper(roaring);
   }
 
-
   private static ByteBuffer toByteBuffer(Bitmap bitmap) throws Exception {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     DataOutputStream dos = new DataOutputStream(baos);
@@ -128,5 +120,4 @@ private static ByteBuffer toByteBuffer(Bitmap bitmap) throws Exception {
   }
 
   public static void cleanup() {}
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapIterator.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapIterator.java
index 95a9dda43..439b593cb 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapIterator.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/BitmapIterator.java
@@ -5,5 +5,4 @@ public interface BitmapIterator {
   boolean hasNext();
 
   int next();
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetIteratorWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetIteratorWrapper.java
index c62dabfd8..2879e7294 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetIteratorWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetIteratorWrapper.java
@@ -19,5 +19,4 @@ public boolean hasNext() {
   public int next() {
     return iterator.next();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetWrapper.java
index 303b69ad4..aff924339 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ConciseSetWrapper.java
@@ -1,5 +1,8 @@
 package org.roaringbitmap.realdata.wrapper;
 
+import org.roaringbitmap.IntConsumer;
+
+import io.druid.extendedset.intset.ConciseSet;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -7,9 +10,6 @@
 import java.util.Iterator;
 import java.util.PriorityQueue;
 
-import io.druid.extendedset.intset.ConciseSet;
-import org.roaringbitmap.IntConsumer;
-
 final class ConciseSetWrapper implements Bitmap {
 
   private final ConciseSet bitmap;
@@ -69,11 +69,8 @@ public Bitmap flip(int rStart, int rEnd) {
     // put this back, but have to hunt down the JMH param setting
     // so the comparison does not abort.
     return new ConciseSetWrapper(bitmap); // wrong result
-
   }
 
-
-
   @Override
   public Bitmap andNot(Bitmap other) {
     return new ConciseSetWrapper(bitmap.difference(((ConciseSetWrapper) other).bitmap));
@@ -115,13 +112,15 @@ public BitmapAggregator priorityQueueOrAggregator() {
       @Override
       public Bitmap aggregate(Iterable bitmaps) {
         PriorityQueue pq =
-            new PriorityQueue(128, new Comparator() {
-              @Override
-              public int compare(ConciseSet a, ConciseSet b) {
-                return (int) (a.size() * a.collectionCompressionRatio())
-                    - (int) (b.size() * b.collectionCompressionRatio());
-              }
-            });
+            new PriorityQueue(
+                128,
+                new Comparator() {
+                  @Override
+                  public int compare(ConciseSet a, ConciseSet b) {
+                    return (int) (a.size() * a.collectionCompressionRatio())
+                        - (int) (b.size() * b.collectionCompressionRatio());
+                  }
+                });
         for (Bitmap bitmap1 : bitmaps) {
           pq.add(((ConciseSetWrapper) bitmap1).bitmap);
         }
@@ -155,5 +154,4 @@ public void serialize(DataOutputStream dos) throws IOException {
   public Bitmap clone() {
     return new ConciseSetWrapper(bitmap.clone());
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Ewah32BitmapWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Ewah32BitmapWrapper.java
index c502ca72e..b5360691e 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Ewah32BitmapWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/Ewah32BitmapWrapper.java
@@ -1,14 +1,14 @@
 package org.roaringbitmap.realdata.wrapper;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-
 import org.roaringbitmap.IntConsumer;
 
 import com.googlecode.javaewah32.EWAHCompressedBitmap32;
 import com.googlecode.javaewah32.FastAggregation32;
 
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
 final class Ewah32BitmapWrapper implements Bitmap {
 
   private final EWAHCompressedBitmap32 bitmap;
@@ -84,8 +84,6 @@ public Bitmap flip(int rangeStart, int rangeEnd) {
     return new Ewah32BitmapWrapper(temp);
   }
 
-
-
   @Override
   public Bitmap andNot(Bitmap other) {
     return new Ewah32BitmapWrapper(bitmap.andNot(((Ewah32BitmapWrapper) other).bitmap));
@@ -126,27 +124,25 @@ public BitmapAggregator priorityQueueOrAggregator() {
     return new BitmapAggregator() {
       @Override
       public Bitmap aggregate(final Iterable bitmaps) {
-        Iterator iterator = new Iterator() {
-          final Iterator i = bitmaps.iterator();
-
-          @Override
-          public boolean hasNext() {
-            return i.hasNext();
-          }
-
-          @Override
-          public EWAHCompressedBitmap32 next() {
-            return ((Ewah32BitmapWrapper) i.next()).bitmap;
-          }
-
-
-          @Override
-          public void remove() {
-            throw new UnsupportedOperationException();
-          }
-
-
-        };
+        Iterator iterator =
+            new Iterator() {
+              final Iterator i = bitmaps.iterator();
+
+              @Override
+              public boolean hasNext() {
+                return i.hasNext();
+              }
+
+              @Override
+              public EWAHCompressedBitmap32 next() {
+                return ((Ewah32BitmapWrapper) i.next()).bitmap;
+              }
+
+              @Override
+              public void remove() {
+                throw new UnsupportedOperationException();
+              }
+            };
         return new Ewah32BitmapWrapper(FastAggregation32.or(iterator));
       }
     };
@@ -170,5 +166,4 @@ public Bitmap clone() {
       throw new RuntimeException(e);
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahBitmapWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahBitmapWrapper.java
index 314ad39db..36d62a5cd 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahBitmapWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahBitmapWrapper.java
@@ -1,14 +1,14 @@
 package org.roaringbitmap.realdata.wrapper;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-
 import org.roaringbitmap.IntConsumer;
 
 import com.googlecode.javaewah.EWAHCompressedBitmap;
 import com.googlecode.javaewah.FastAggregation;
 
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
 final class EwahBitmapWrapper implements Bitmap {
 
   private final EWAHCompressedBitmap bitmap;
@@ -85,8 +85,6 @@ public Bitmap flip(int rangeStart, int rangeEnd) {
     return new EwahBitmapWrapper(temp);
   }
 
-
-
   @Override
   public Bitmap andNot(Bitmap other) {
     return new EwahBitmapWrapper(bitmap.andNot(((EwahBitmapWrapper) other).bitmap));
@@ -127,24 +125,25 @@ public BitmapAggregator priorityQueueOrAggregator() {
     return new BitmapAggregator() {
       @Override
       public Bitmap aggregate(final Iterable bitmaps) {
-        Iterator iterator = new Iterator() {
-          final Iterator i = bitmaps.iterator();
-
-          @Override
-          public boolean hasNext() {
-            return i.hasNext();
-          }
-
-          @Override
-          public EWAHCompressedBitmap next() {
-            return ((EwahBitmapWrapper) i.next()).bitmap;
-          }
-
-          @Override
-          public void remove() {
-            throw new UnsupportedOperationException();
-          }
-        };
+        Iterator iterator =
+            new Iterator() {
+              final Iterator i = bitmaps.iterator();
+
+              @Override
+              public boolean hasNext() {
+                return i.hasNext();
+              }
+
+              @Override
+              public EWAHCompressedBitmap next() {
+                return ((EwahBitmapWrapper) i.next()).bitmap;
+              }
+
+              @Override
+              public void remove() {
+                throw new UnsupportedOperationException();
+              }
+            };
         return new EwahBitmapWrapper(FastAggregation.or(iterator));
       }
     };
@@ -168,5 +167,4 @@ public Bitmap clone() {
       throw new RuntimeException(e);
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahIteratorWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahIteratorWrapper.java
index 8cc28e129..7722351f6 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahIteratorWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/EwahIteratorWrapper.java
@@ -19,5 +19,4 @@ public boolean hasNext() {
   public int next() {
     return iterator.next();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableConciseSetWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableConciseSetWrapper.java
index 97859281a..c458b908b 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableConciseSetWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableConciseSetWrapper.java
@@ -1,18 +1,18 @@
 package org.roaringbitmap.realdata.wrapper;
 
+import static io.druid.extendedset.intset.ImmutableConciseSet.intersection;
+import static io.druid.extendedset.intset.ImmutableConciseSet.union;
+
+import org.roaringbitmap.IntConsumer;
+
+import io.druid.extendedset.intset.ImmutableConciseSet;
+
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.PriorityQueue;
 
-import io.druid.extendedset.intset.ImmutableConciseSet;
-import org.roaringbitmap.IntConsumer;
-
-import static io.druid.extendedset.intset.ImmutableConciseSet.intersection;
-import static io.druid.extendedset.intset.ImmutableConciseSet.union;
-
-
 final class ImmutableConciseSetWrapper implements Bitmap {
 
   private final ImmutableConciseSet bitmap;
@@ -55,10 +55,8 @@ public Bitmap and(Bitmap other) {
   @Override
   public Bitmap flip(int s, int e) {
     ImmutableConciseSet temp = ImmutableConciseSet.complement(bitmap, e);
-    if (e == 0)
-      return new ImmutableConciseSetWrapper(temp);
-    else
-      return new ImmutableConciseSetWrapper(ImmutableConciseSet.complement(temp, e - 1));
+    if (e == 0) return new ImmutableConciseSetWrapper(temp);
+    else return new ImmutableConciseSetWrapper(ImmutableConciseSet.complement(temp, e - 1));
   }
 
   @Override
@@ -121,8 +119,6 @@ public ImmutableConciseSet next() {
       public void remove() {
         throw new UnsupportedOperationException();
       }
-
-
     };
   }
 
@@ -132,12 +128,14 @@ public BitmapAggregator priorityQueueOrAggregator() {
       @Override
       public Bitmap aggregate(Iterable bitmaps) {
         PriorityQueue pq =
-            new PriorityQueue(128, new Comparator() {
-              @Override
-              public int compare(ImmutableConciseSet a, ImmutableConciseSet b) {
-                return a.getLastWordIndex() - b.getLastWordIndex();
-              }
-            });
+            new PriorityQueue(
+                128,
+                new Comparator() {
+                  @Override
+                  public int compare(ImmutableConciseSet a, ImmutableConciseSet b) {
+                    return a.getLastWordIndex() - b.getLastWordIndex();
+                  }
+                });
         for (Bitmap bitmap1 : bitmaps) {
           pq.add(((ImmutableConciseSetWrapper) bitmap1).bitmap);
         }
@@ -171,5 +169,4 @@ public void serialize(DataOutputStream dos) throws IOException {
   public Bitmap clone() {
     throw new UnsupportedOperationException("Not implemented in ImmutableConciseSet");
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableRoaringBitmapWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableRoaringBitmapWrapper.java
index a56ace739..9f6343777 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableRoaringBitmapWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/ImmutableRoaringBitmapWrapper.java
@@ -1,13 +1,13 @@
 package org.roaringbitmap.realdata.wrapper;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-
 import org.roaringbitmap.IntConsumer;
 import org.roaringbitmap.buffer.BufferFastAggregation;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
 final class ImmutableRoaringBitmapWrapper implements Bitmap {
 
   private final ImmutableRoaringBitmap bitmap;
@@ -64,14 +64,12 @@ public Bitmap xor(Bitmap other) {
         ImmutableRoaringBitmap.xor(bitmap, ((ImmutableRoaringBitmapWrapper) other).bitmap));
   }
 
-
   @Override
   public Bitmap flip(int rangeStart, int rangeEnd) {
     return new ImmutableRoaringBitmapWrapper(
-        ImmutableRoaringBitmap.flip(bitmap, (long)rangeStart, (long)rangeEnd));
+        ImmutableRoaringBitmap.flip(bitmap, (long) rangeStart, (long) rangeEnd));
   }
 
-
   @Override
   public Bitmap andNot(Bitmap other) {
     return new ImmutableRoaringBitmapWrapper(
@@ -147,5 +145,4 @@ public void serialize(DataOutputStream dos) throws IOException {
   public Bitmap clone() {
     return new ImmutableRoaringBitmapWrapper(bitmap.clone());
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringBitmapWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringBitmapWrapper.java
index d59ec7629..213646f94 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringBitmapWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringBitmapWrapper.java
@@ -1,13 +1,13 @@
 package org.roaringbitmap.realdata.wrapper;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-
 import org.roaringbitmap.FastAggregation;
 import org.roaringbitmap.IntConsumer;
 import org.roaringbitmap.RoaringBitmap;
 
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
 final class RoaringBitmapWrapper implements Bitmap {
 
   private final RoaringBitmap bitmap;
@@ -61,11 +61,9 @@ public Bitmap ior(Bitmap other) {
 
   @Override
   public Bitmap flip(int rangeStart, int rangeEnd) {
-    return new RoaringBitmapWrapper(RoaringBitmap.flip(bitmap, (long)rangeStart, (long)rangeEnd));
+    return new RoaringBitmapWrapper(RoaringBitmap.flip(bitmap, (long) rangeStart, (long) rangeEnd));
   }
 
-
-
   @Override
   public Bitmap xor(Bitmap other) {
     return new RoaringBitmapWrapper(
@@ -120,13 +118,11 @@ public boolean hasNext() {
         return i.hasNext();
       }
 
-
       @Override
       public void remove() {
         throw new UnsupportedOperationException();
       }
 
-
       @Override
       public RoaringBitmap next() {
         return ((RoaringBitmapWrapper) i.next()).bitmap;
@@ -148,5 +144,4 @@ public void serialize(DataOutputStream dos) throws IOException {
   public Bitmap clone() {
     return new RoaringBitmapWrapper(bitmap.clone());
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringIteratorWrapper.java b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringIteratorWrapper.java
index d5c106c8b..b9338985e 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringIteratorWrapper.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/realdata/wrapper/RoaringIteratorWrapper.java
@@ -19,5 +19,4 @@ public boolean hasNext() {
   public int next() {
     return iterator.next();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/AllRunHorizontalOrBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/AllRunHorizontalOrBenchmark.java
index b50cd6891..d07b9eb72 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/AllRunHorizontalOrBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/AllRunHorizontalOrBenchmark.java
@@ -1,10 +1,10 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RoaringBitmap;
 
+import com.googlecode.javaewah.EWAHCompressedBitmap;
+import com.googlecode.javaewah32.EWAHCompressedBitmap32;
 import io.druid.extendedset.intset.ConciseSet;
 import io.druid.extendedset.intset.ImmutableConciseSet;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -13,11 +13,11 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RoaringBitmap;
 
-import com.googlecode.javaewah.EWAHCompressedBitmap;
-import com.googlecode.javaewah32.EWAHCompressedBitmap32;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -31,7 +31,6 @@ static ConciseSet toConcise(int[] dat) {
     return ans;
   }
 
-
   static ConciseSet toWAH(int[] dat) {
     ConciseSet ans = new ConciseSet(true);
     for (int i : dat) {
@@ -43,8 +42,7 @@ static ConciseSet toWAH(int[] dat) {
   @Benchmark
   public int OrConcise(BenchmarkState benchmarkState) {
     ConciseSet base = benchmarkState.cc.get(0);
-    for (int k = 1; k < benchmarkState.cc.size(); ++k)
-      base.union(benchmarkState.cc.get(k));
+    for (int k = 1; k < benchmarkState.cc.size(); ++k) base.union(benchmarkState.cc.get(k));
     return base.size();
   }
 
@@ -57,8 +55,7 @@ public int OrImmutableConcise(BenchmarkState benchmarkState) {
   @Benchmark
   public int OrWAH(BenchmarkState benchmarkState) {
     ConciseSet base = benchmarkState.wah.get(0);
-    for (int k = 1; k < benchmarkState.wah.size(); ++k)
-      base.union(benchmarkState.wah.get(k));
+    for (int k = 1; k < benchmarkState.wah.size(); ++k) base.union(benchmarkState.wah.get(k));
     return base.size();
   }
 
@@ -67,7 +64,6 @@ public int horizontalOr_Roaringwithrun(BenchmarkState benchmarkState) {
     return RoaringBitmap.or(benchmarkState.rc.iterator()).getCardinality();
   }
 
-
   @Benchmark
   public int horizontalOr_Roaring(BenchmarkState benchmarkState) {
     return RoaringBitmap.or(benchmarkState.ac.iterator()).getCardinality();
@@ -79,7 +75,6 @@ public int horizontalOr_EWAH(BenchmarkState benchmarkState) {
     EWAHCompressedBitmap bitmapor = EWAHCompressedBitmap.or(benchmarkState.ewah.toArray(a));
     int answer = bitmapor.cardinality();
     return answer;
-
   }
 
   @Benchmark
@@ -90,8 +85,6 @@ public int horizontalOr_EWAH32(BenchmarkState benchmarkState) {
     return answer;
   }
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
 
@@ -106,7 +99,6 @@ public static class BenchmarkState {
     Random rand = new Random();
     Container aggregate;
 
-
     public BenchmarkState() {
       int N = 30;
       Random rand = new Random(1234);
@@ -116,7 +108,7 @@ public BenchmarkState() {
 
         for (int z = 0; z < 50; ++z) {
           int end = start + rand.nextInt(10000);
-          rb.add((long)start, (long)end);
+          rb.add((long) start, (long) end);
           start = end + rand.nextInt(1000);
         }
         ConciseSet ccs = toConcise(rb.toArray());
@@ -131,9 +123,7 @@ public BenchmarkState() {
         rc.add(rb);
         ewah.add(EWAHCompressedBitmap.bitmapOf(rb.toArray()));
         ewah32.add(EWAHCompressedBitmap32.bitmapOf(rb.toArray()));
-
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/ArrayContainerAndNotRunContainerBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/ArrayContainerAndNotRunContainerBenchmark.java
index d9d810568..0e1192e8c 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/ArrayContainerAndNotRunContainerBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/ArrayContainerAndNotRunContainerBenchmark.java
@@ -1,13 +1,13 @@
 package org.roaringbitmap.runcontainer;
 
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Mode;
 import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.RoaringOnlyBenchmarkState;
 import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
 import org.roaringbitmap.realdata.state.RealDataRoaringOnlyBenchmarkState;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+
 @BenchmarkMode(Mode.Throughput)
 public class ArrayContainerAndNotRunContainerBenchmark {
 
@@ -24,7 +24,9 @@ public RoaringBitmap pairwiseACAndNotRC(RealDataRoaringOnlyBenchmarkState bs) {
   public ImmutableRoaringBitmap immutablePairwiseACAndNotRC(RealDataRoaringOnlyBenchmarkState bs) {
     ImmutableRoaringBitmap last = null;
     for (int k = 0; k + 1 < bs.immutableBitmaps.size(); ++k) {
-      last = ImmutableRoaringBitmap.andNot(bs.immutableOnlyArrayContainers.get(k), bs.immutableOnlyRunContainers.get(k + 1));
+      last =
+          ImmutableRoaringBitmap.andNot(
+              bs.immutableOnlyArrayContainers.get(k), bs.immutableOnlyRunContainers.get(k + 1));
     }
     return last;
   }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndContainerBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndContainerBenchmark.java
index 332e4c481..dc085e579 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndContainerBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndContainerBenchmark.java
@@ -1,7 +1,9 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.BitmapContainer;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,14 +11,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.BitmapContainer;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RunContainer;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
-
 public class BasicAndContainerBenchmark {
 
   @Benchmark
@@ -31,7 +31,6 @@ public int andBitmapContainerVSBitmapContainer(BenchmarkState benchmarkState) {
     return benchmarkState.ac1.and(benchmarkState.ac2).getCardinality();
   }
 
-
   @Benchmark
   public int part2_andRunContainerVSRunContainerContainer(BenchmarkState benchmarkState) {
     if (benchmarkState.rc2.serializedSizeInBytes() > benchmarkState.ac2.serializedSizeInBytes())
@@ -58,7 +57,6 @@ public int part3_andArrayContainerVSBitmapContainer(BenchmarkState benchmarkStat
     return benchmarkState.ac4.and(benchmarkState.ac2).getCardinality();
   }
 
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
     public int offvalues = 32;
@@ -68,7 +66,6 @@ public static class BenchmarkState {
     Container rc1, rc2, rc3, ac1, ac2, ac3, ac4;
     Random rand = new Random();
 
-
     public BenchmarkState() {
       final int max = 1 << 16;
       final int howmanywords = (1 << 16) / 64;
@@ -77,7 +74,6 @@ public BenchmarkState() {
       int[] values3 = RandomUtil.generateCrazyRun(rand, max);
       int[] values4 = RandomUtil.generateUniformHash(rand, bitsetperword3 * howmanywords, max);
 
-
       rc1 = new RunContainer();
       rc1 = RandomUtil.fillMeUp(rc1, values1);
 
@@ -93,34 +89,26 @@ public BenchmarkState() {
       if (!(ac1 instanceof BitmapContainer))
         throw new RuntimeException("expected bitmap container");
 
-
       ac2 = new ArrayContainer();
       ac2 = RandomUtil.fillMeUp(ac2, values2);
 
       if (!(ac2 instanceof BitmapContainer))
         throw new RuntimeException("expected bitmap container");
 
-
       ac3 = new ArrayContainer();
       ac3 = RandomUtil.fillMeUp(ac3, values3);
 
       ac4 = new ArrayContainer();
       ac4 = RandomUtil.fillMeUp(ac4, values4);
 
-      if (!(ac4 instanceof ArrayContainer))
-        throw new RuntimeException("expected array container");
+      if (!(ac4 instanceof ArrayContainer)) throw new RuntimeException("expected array container");
 
-      if (!rc1.equals(ac1))
-        throw new RuntimeException("first containers do not match");
+      if (!rc1.equals(ac1)) throw new RuntimeException("first containers do not match");
 
-      if (!rc2.equals(ac2))
-        throw new RuntimeException("second containers do not match");
+      if (!rc2.equals(ac2)) throw new RuntimeException("second containers do not match");
 
-      if (!rc1.and(rc2).equals(ac1.and(ac2)))
-        throw new RuntimeException("ands do not match");
-      if (!ac1.and(rc2).equals(ac1.and(ac2)))
-        throw new RuntimeException("ands do not match");
+      if (!rc1.and(rc2).equals(ac1.and(ac2))) throw new RuntimeException("ands do not match");
+      if (!ac1.and(rc2).equals(ac1.and(ac2))) throw new RuntimeException("ands do not match");
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndNotContainerBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndNotContainerBenchmark.java
index 8c1bc9c00..99b9851e7 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndNotContainerBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicAndNotContainerBenchmark.java
@@ -1,7 +1,9 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.BitmapContainer;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,10 +11,9 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.BitmapContainer;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RunContainer;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
@@ -124,7 +125,9 @@ public BenchmarkState() {
       rc3 = new RunContainer();
       rc3 = RandomUtil.fillMeUp(rc3, values3);
 
-      rc4 = new RunContainer(new char[]{4, 500, 2000, 1000, 5000, 3000, 16000, 10000, 32000, 600}, 5);
+      rc4 =
+          new RunContainer(
+              new char[] {4, 500, 2000, 1000, 5000, 3000, 16000, 10000, 32000, 600}, 5);
 
       ac1 = new ArrayContainer();
       ac1 = RandomUtil.fillMeUp(ac1, values1);
@@ -144,14 +147,11 @@ public BenchmarkState() {
       ac4 = new ArrayContainer();
       ac4 = RandomUtil.fillMeUp(ac4, values4);
 
-      if (!(ac4 instanceof ArrayContainer))
-        throw new RuntimeException("expected array container");
+      if (!(ac4 instanceof ArrayContainer)) throw new RuntimeException("expected array container");
 
-      if (!rc1.equals(ac1))
-        throw new RuntimeException("first containers do not match");
+      if (!rc1.equals(ac1)) throw new RuntimeException("first containers do not match");
 
-      if (!rc2.equals(ac2))
-        throw new RuntimeException("second containers do not match");
+      if (!rc2.equals(ac2)) throw new RuntimeException("second containers do not match");
 
       if (!rc1.andNot(rc2).equals(ac1.andNot(ac2)))
         throw new RuntimeException("andNots do not match");
@@ -161,8 +161,6 @@ public BenchmarkState() {
         throw new RuntimeException("andNots do not match");
       if (!rc2.andNot(ac1).equals(ac2.andNot(ac1)))
         throw new RuntimeException("andNots do not match");
-
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicHorizontalOrBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicHorizontalOrBenchmark.java
index c599a0765..f01798c17 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicHorizontalOrBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicHorizontalOrBenchmark.java
@@ -1,9 +1,9 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.BitmapContainer;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -11,36 +11,31 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.BitmapContainer;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RunContainer;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class BasicHorizontalOrBenchmark {
 
   private static Container horizontal_or(Iterator i) {
-    if (!i.hasNext())
-      throw new RuntimeException("please provide data");
+    if (!i.hasNext()) throw new RuntimeException("please provide data");
     Container c = i.next();
-    if (!i.hasNext())
-      throw new RuntimeException("please provide more than one container");
+    if (!i.hasNext()) throw new RuntimeException("please provide more than one container");
     Container c2 = i.next();
     c = c.lazyOR(c2);
-    while (i.hasNext())
-      c = c.lazyIOR(i.next());
+    while (i.hasNext()) c = c.lazyIOR(i.next());
     c = c.repairAfterLazy();
     return c;
   }
 
-
-
   @Benchmark
   public int horizontalOrRunContainer(BenchmarkState benchmarkState) {
     Container answer = horizontal_or(benchmarkState.rc.iterator());
-    if (!answer.equals(benchmarkState.aggregate))
-      throw new RuntimeException("bug");
+    if (!answer.equals(benchmarkState.aggregate)) throw new RuntimeException("bug");
     return answer.getCardinality();
   }
 
@@ -53,20 +48,17 @@ public int horizontalOrRunContainer_withconversion(BenchmarkState benchmarkState
       c = (BitmapContainer) c.lazyIOR(benchmarkState.rc.get(k));
     }
     c = (BitmapContainer) c.repairAfterLazy();
-    if (!c.equals(benchmarkState.aggregate))
-      throw new RuntimeException("bug");
+    if (!c.equals(benchmarkState.aggregate)) throw new RuntimeException("bug");
     return c.getCardinality();
   }
 
   @Benchmark
   public int horizontalOrBitmapContainer(BenchmarkState benchmarkState) {
     Container answer = horizontal_or(benchmarkState.ac.iterator());
-    if (!answer.equals(benchmarkState.aggregate))
-      throw new RuntimeException("bug");
+    if (!answer.equals(benchmarkState.aggregate)) throw new RuntimeException("bug");
     return answer.getCardinality();
   }
 
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
     public int bitsetperword = 63;
@@ -76,7 +68,6 @@ public static class BenchmarkState {
     Random rand = new Random();
     Container aggregate;
 
-
     public BenchmarkState() {
       final int max = 1 << 16;
       final int howmanywords = (1 << 16) / 64;
@@ -85,15 +76,13 @@ public BenchmarkState() {
         int[] values = RandomUtil.generateUniformHash(rand, bitsetperword * howmanywords, max);
         Container rct = new RunContainer();
         rct = RandomUtil.fillMeUp(rct, values);
-        if (!(rct instanceof RunContainer))
-          throw new RuntimeException("unexpected container type");
+        if (!(rct instanceof RunContainer)) throw new RuntimeException("unexpected container type");
 
         Container act = new ArrayContainer();
         act = RandomUtil.fillMeUp(act, values);
         if (!(act instanceof BitmapContainer))
           throw new RuntimeException("unexpected container type");
-        if (!act.equals(rct))
-          throw new RuntimeException("unequal containers");
+        if (!act.equals(rct)) throw new RuntimeException("unequal containers");
         if (act.serializedSizeInBytes() < rct.serializedSizeInBytes())
           throw new RuntimeException("You cannot win");
         rc.add(rct);
@@ -101,8 +90,7 @@ public BenchmarkState() {
       }
       Container b1 = rc.get(0);
       Container b2 = ac.get(0);
-      if (!b1.equals(b2))
-        throw new RuntimeException("bug 0");
+      if (!b1.equals(b2)) throw new RuntimeException("bug 0");
       for (int k = 1; k < N; ++k) {
         b1 = b1.lazyIOR(rc.get(1));
         b2 = b2.lazyIOR(ac.get(1));
@@ -113,5 +101,4 @@ public BenchmarkState() {
       aggregate = horizontal_or(rc.iterator());
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicIteratorBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicIteratorBenchmark.java
index 698ecff41..c8c56e413 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicIteratorBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicIteratorBenchmark.java
@@ -1,7 +1,9 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.CharIterator;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,14 +11,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.CharIterator;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RunContainer;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
-
 public class BasicIteratorBenchmark {
 
   @Benchmark
@@ -25,8 +25,7 @@ public int iteratorRunContainer(BenchmarkState benchmarkState) {
       throw new RuntimeException("Can't expect run containers to win if they are larger.");
     CharIterator si = benchmarkState.rc2.getCharIterator();
     int answer = 0;
-    while (si.hasNext())
-      answer += si.next() & 0xFFFF;
+    while (si.hasNext()) answer += si.next() & 0xFFFF;
     return answer;
   }
 
@@ -34,8 +33,7 @@ public int iteratorRunContainer(BenchmarkState benchmarkState) {
   public int iteratorBitmapContainer(BenchmarkState benchmarkState) {
     CharIterator si = benchmarkState.ac2.getCharIterator();
     int answer = 0;
-    while (si.hasNext())
-      answer += si.next() & 0xFFFF;
+    while (si.hasNext()) answer += si.next() & 0xFFFF;
     return answer;
   }
 
@@ -51,20 +49,13 @@ public BenchmarkState() {
       final int howmanywords = (1 << 16) / 64;
       int[] values2 = RandomUtil.generateUniformHash(rand, bitsetperword2 * howmanywords, max);
 
-
-
       rc2 = new RunContainer();
       rc2 = RandomUtil.fillMeUp(rc2, values2);
 
-
       ac2 = new ArrayContainer();
       ac2 = RandomUtil.fillMeUp(ac2, values2);
 
-
-      if (!rc2.equals(ac2))
-        throw new RuntimeException("second containers do not match");
-
+      if (!rc2.equals(ac2)) throw new RuntimeException("second containers do not match");
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicOrContainerBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicOrContainerBenchmark.java
index 447bcc9d1..f4fe450b1 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicOrContainerBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicOrContainerBenchmark.java
@@ -1,7 +1,9 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.BitmapContainer;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,14 +11,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.BitmapContainer;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RunContainer;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
-
 public class BasicOrContainerBenchmark {
 
   @Benchmark
@@ -66,7 +66,6 @@ public static class BenchmarkState {
     Container rc1, rc2, rc3, ac1, ac2, ac3, ac4;
     Random rand = new Random();
 
-
     public BenchmarkState() {
       final int max = 1 << 16;
       final int howmanywords = (1 << 16) / 64;
@@ -75,7 +74,6 @@ public BenchmarkState() {
       int[] values3 = RandomUtil.generateCrazyRun(rand, max);
       int[] values4 = RandomUtil.generateUniformHash(rand, bitsetperword3 * howmanywords, max);
 
-
       rc1 = new RunContainer();
       rc1 = RandomUtil.fillMeUp(rc1, values1);
 
@@ -91,34 +89,26 @@ public BenchmarkState() {
       if (!(ac1 instanceof BitmapContainer))
         throw new RuntimeException("expected bitmap container");
 
-
       ac2 = new ArrayContainer();
       ac2 = RandomUtil.fillMeUp(ac2, values2);
 
       if (!(ac2 instanceof BitmapContainer))
         throw new RuntimeException("expected bitmap container");
 
-
       ac3 = new ArrayContainer();
       ac3 = RandomUtil.fillMeUp(ac3, values3);
 
       ac4 = new ArrayContainer();
       ac4 = RandomUtil.fillMeUp(ac4, values4);
 
-      if (!(ac4 instanceof ArrayContainer))
-        throw new RuntimeException("expected array container");
+      if (!(ac4 instanceof ArrayContainer)) throw new RuntimeException("expected array container");
 
-      if (!rc1.equals(ac1))
-        throw new RuntimeException("first containers do not match");
+      if (!rc1.equals(ac1)) throw new RuntimeException("first containers do not match");
 
-      if (!rc2.equals(ac2))
-        throw new RuntimeException("second containers do not match");
+      if (!rc2.equals(ac2)) throw new RuntimeException("second containers do not match");
 
-      if (!rc1.or(rc2).equals(ac1.or(ac2)))
-        throw new RuntimeException("ors do not match");
-      if (!ac1.or(rc2).equals(ac1.or(ac2)))
-        throw new RuntimeException("ors do not match");
+      if (!rc1.or(rc2).equals(ac1.or(ac2))) throw new RuntimeException("ors do not match");
+      if (!ac1.or(rc2).equals(ac1.or(ac2))) throw new RuntimeException("ors do not match");
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicXorContainerBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicXorContainerBenchmark.java
index b8421cd9b..038498f35 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicXorContainerBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BasicXorContainerBenchmark.java
@@ -1,7 +1,9 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ArrayContainer;
+import org.roaringbitmap.BitmapContainer;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,14 +11,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ArrayContainer;
-import org.roaringbitmap.BitmapContainer;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RunContainer;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
-
 public class BasicXorContainerBenchmark {
 
   @Benchmark
@@ -31,7 +31,6 @@ public int xorBitmapContainerVSBitmapContainer(BenchmarkState benchmarkState) {
     return benchmarkState.ac1.xor(benchmarkState.ac2).getCardinality();
   }
 
-
   @Benchmark
   public int part2_xorRunContainerVSRunContainerContainer(BenchmarkState benchmarkState) {
     if (benchmarkState.rc2.serializedSizeInBytes() > benchmarkState.ac2.serializedSizeInBytes())
@@ -73,7 +72,6 @@ public static class BenchmarkState {
     Container rc1, rc2, rc3, ac1, ac2, ac3, ac4;
     Random rand = new Random();
 
-
     public BenchmarkState() {
       final int max = 1 << 16;
       final int howmanywords = (1 << 16) / 64;
@@ -82,7 +80,6 @@ public BenchmarkState() {
       int[] values3 = RandomUtil.generateCrazyRun(rand, max);
       int[] values4 = RandomUtil.generateUniformHash(rand, bitsetperword3 * howmanywords, max);
 
-
       rc1 = new RunContainer();
       rc1 = RandomUtil.fillMeUp(rc1, values1);
 
@@ -98,34 +95,26 @@ public BenchmarkState() {
       if (!(ac1 instanceof BitmapContainer))
         throw new RuntimeException("expected bitmap container");
 
-
       ac2 = new ArrayContainer();
       ac2 = RandomUtil.fillMeUp(ac2, values2);
 
       if (!(ac2 instanceof BitmapContainer))
         throw new RuntimeException("expected bitmap container");
 
-
       ac3 = new ArrayContainer();
       ac3 = RandomUtil.fillMeUp(ac3, values3);
 
       ac4 = new ArrayContainer();
       ac4 = RandomUtil.fillMeUp(ac4, values4);
 
-      if (!(ac4 instanceof ArrayContainer))
-        throw new RuntimeException("expected array container");
+      if (!(ac4 instanceof ArrayContainer)) throw new RuntimeException("expected array container");
 
-      if (!rc1.equals(ac1))
-        throw new RuntimeException("first containers do not match");
+      if (!rc1.equals(ac1)) throw new RuntimeException("first containers do not match");
 
-      if (!rc2.equals(ac2))
-        throw new RuntimeException("second containers do not match");
+      if (!rc2.equals(ac2)) throw new RuntimeException("second containers do not match");
 
-      if (!rc1.xor(rc2).equals(ac1.xor(ac2)))
-        throw new RuntimeException("xors do not match");
-      if (!ac1.xor(rc2).equals(ac1.xor(ac2)))
-        throw new RuntimeException("xors do not match");
+      if (!rc1.xor(rc2).equals(ac1.xor(ac2))) throw new RuntimeException("xors do not match");
+      if (!ac1.xor(rc2).equals(ac1.xor(ac2))) throw new RuntimeException("xors do not match");
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java
index 22df8bc22..c757980e1 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/BitmapToRuncontainerConversions.java
@@ -1,7 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.BitmapContainer;
+import org.roaringbitmap.RunContainer;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -9,12 +9,12 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.BitmapContainer;
-import org.roaringbitmap.RunContainer;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.NANOSECONDS)
-
 public class BitmapToRuncontainerConversions {
 
   /*
@@ -46,13 +46,11 @@ public int numberOfRunsLowerBound1281(BenchmarkState benchmarkState) {
     return benchmarkState.ac1.numberOfRunsLowerBound(1000);
   }
 
-
   @Benchmark
   public int numberOfRunsLowerBound1282(BenchmarkState benchmarkState) {
     return benchmarkState.ac2.numberOfRunsLowerBound(1000);
   }
 
-
   /*
    * soon to be deleted...
    *
@@ -69,7 +67,6 @@ public int numberOfRunsAdjustment(BenchmarkState benchmarkState) {
     return benchmarkState.ac2.numberOfRunsAdjustment();
   }
 
-
   /*
    * soon to be deleted...
    *
@@ -94,8 +91,6 @@ public int numberOfRunsLowerBoundThreshold1000(BenchmarkState benchmarkState) {
     return benchmarkState.ac2.numberOfRunsLowerBound(1000);
   }
 
-
-
   @Benchmark
   public int runOptimize(BenchmarkState benchmarkState) {
     return benchmarkState.ac2.runOptimize() instanceof RunContainer ? 1 : 0;
@@ -118,8 +113,6 @@ public int runOptimize1(BenchmarkState benchmarkState) {
    *
    */
 
-
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
     public int offvalues = 32;
@@ -129,7 +122,6 @@ public static class BenchmarkState {
     BitmapContainer ac1, ac2;
     Random rand = new Random();
 
-
     public BenchmarkState() {
       final int max = 1 << 16;
       final int howmanywords = (1 << 16) / 64;
@@ -141,8 +133,6 @@ public BenchmarkState() {
 
       ac2 = new BitmapContainer();
       ac2 = (BitmapContainer) RandomUtil.fillMeUp(ac2, values2);
-
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/GetCardinalityMappeableContainerBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/GetCardinalityMappeableContainerBenchmark.java
index dbd09623f..903525730 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/GetCardinalityMappeableContainerBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/GetCardinalityMappeableContainerBenchmark.java
@@ -1,9 +1,17 @@
 package org.roaringbitmap.runcontainer;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.buffer.MappeableContainer;
 import org.roaringbitmap.buffer.MappeableRunContainer;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
 
@@ -54,10 +62,18 @@ public BenchmarkState() {
       mc3 = new MappeableRunContainer();
       mc4 = new MappeableRunContainer();
 
-      for (int i : values1) { mc1.add((char) i); }
-      for (int i : values2) { mc2.add((char) i); }
-      for (int i : values3) { mc3.add((char) i); }
-      for (int i : values4) { mc4.add((char) i); }
+      for (int i : values1) {
+        mc1.add((char) i);
+      }
+      for (int i : values2) {
+        mc2.add((char) i);
+      }
+      for (int i : values3) {
+        mc3.add((char) i);
+      }
+      for (int i : values4) {
+        mc4.add((char) i);
+      }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/MappedRunContainerRealDataBenchmarkRunOptimize.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/MappedRunContainerRealDataBenchmarkRunOptimize.java
index cd67a06d5..9793bc109 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/MappedRunContainerRealDataBenchmarkRunOptimize.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/MappedRunContainerRealDataBenchmarkRunOptimize.java
@@ -1,12 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.ZipRealDataRetriever;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -16,8 +11,13 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.ZipRealDataRetriever;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -81,7 +81,6 @@ public int mutable_serializeToBAOSNoClonePreOpti(BenchmarkState benchmarkState)
     return bos.size();
   }
 
-
   @Benchmark
   public int mutable_runOptimizeAndserializeToBAOSFromClone(BenchmarkState benchmarkState)
       throws IOException {
@@ -98,10 +97,20 @@ public int mutable_runOptimizeAndserializeToBAOSFromClone(BenchmarkState benchma
 
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "census-income", "census1881", "dimension_008", "dimension_003", "dimension_033",
-        "uscensus2000", "weather_sept_85", "wikileaks-noquotes", "census-income_srt",
-        "census1881_srt", "weather_sept_85_srt", "wikileaks-noquotes_srt"})
+    @Param({ // putting the data sets in alpha. order
+      "census-income",
+      "census1881",
+      "dimension_008",
+      "dimension_003",
+      "dimension_033",
+      "uscensus2000",
+      "weather_sept_85",
+      "wikileaks-noquotes",
+      "census-income_srt",
+      "census1881_srt",
+      "weather_sept_85_srt",
+      "wikileaks-noquotes_srt"
+    })
     String dataset;
 
     List mac = new ArrayList();
@@ -123,7 +132,5 @@ public void setup() throws Exception {
         mrc.add(mopti);
       }
     }
-
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RandomUtil.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RandomUtil.java
index af83d947d..9613e0c92 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RandomUtil.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RandomUtil.java
@@ -1,29 +1,26 @@
 package org.roaringbitmap.runcontainer;
 
+import org.roaringbitmap.Container;
+
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Random;
 
-import org.roaringbitmap.Container;
-
 public class RandomUtil {
   /**
    * generates randomly N distinct integers from 0 to Max.
    */
   static int[] generateUniformHash(Random rand, int N, int Max) {
-    if (N > Max)
-      throw new RuntimeException("not possible");
+    if (N > Max) throw new RuntimeException("not possible");
     if (N > Max / 2) {
       return negate(generateUniformHash(rand, Max - N, Max), Max);
     }
     int[] ans = new int[N];
     HashSet s = new HashSet();
-    while (s.size() < N)
-      s.add(rand.nextInt(Max));
+    while (s.size() < N) s.add(rand.nextInt(Max));
     Iterator i = s.iterator();
-    for (int k = 0; k < N; ++k)
-      ans[k] = i.next().intValue();
+    for (int k = 0; k < N; ++k) ans[k] = i.next().intValue();
     Arrays.sort(ans);
     return ans;
   }
@@ -31,8 +28,7 @@ static int[] generateUniformHash(Random rand, int N, int Max) {
   static int[] generateCrazyRun(Random rand, int Max) {
     int[] answer = new int[Max / 2];
     int start = Max / 3;
-    for (int k = 0; k < answer.length; ++k)
-      answer[k] = k + start;
+    for (int k = 0; k < answer.length; ++k) answer[k] = k + start;
     return answer;
   }
 
@@ -45,25 +41,19 @@ static int[] negate(int[] x, int Max) {
     int c = 0;
     for (int j = 0; j < x.length; ++j) {
       int v = x[j];
-      for (; i < v; ++i)
-        ans[c++] = i;
+      for (; i < v; ++i) ans[c++] = i;
       ++i;
     }
-    while (c < ans.length)
-      ans[c++] = i++;
+    while (c < ans.length) ans[c++] = i++;
     return ans;
   }
 
   public static Container fillMeUp(Container c, int[] values) {
-    if (c.getCardinality() != 0)
-      throw new RuntimeException("Please provide an empty container. ");
+    if (c.getCardinality() != 0) throw new RuntimeException("Please provide an empty container. ");
     if (values.length == 0)
       throw new RuntimeException("You are trying to create an empty bitmap! ");
-    for (int k = 0; k < values.length; ++k)
-      c = c.add((char) values[k]);
-    if (c.getCardinality() != values.length)
-      throw new RuntimeException("add failure");
+    for (int k = 0; k < values.length; ++k) c = c.add((char) values[k]);
+    if (c.getCardinality() != values.length) throw new RuntimeException("add failure");
     return c;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndBenchmark.java
index c3a002547..dd0da2f17 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndBenchmark.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.ArrayList;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RoaringBitmap;
 
 import io.druid.extendedset.intset.ConciseSet;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -11,8 +10,10 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -30,8 +31,9 @@ static ConciseSet toConcise(int[] dat) {
   public int AndRunContainer(BenchmarkState benchmarkState) {
     int answer = 0;
     for (int k = 1; k < benchmarkState.rc.size(); ++k)
-      answer += RoaringBitmap.and(benchmarkState.rc.get(k - 1), benchmarkState.rc.get(k))
-          .getCardinality();
+      answer +=
+          RoaringBitmap.and(benchmarkState.rc.get(k - 1), benchmarkState.rc.get(k))
+              .getCardinality();
     return answer;
   }
 
@@ -39,8 +41,9 @@ public int AndRunContainer(BenchmarkState benchmarkState) {
   public int AndBitmapContainer(BenchmarkState benchmarkState) {
     int answer = 0;
     for (int k = 1; k < benchmarkState.ac.size(); ++k)
-      answer += RoaringBitmap.and(benchmarkState.ac.get(k - 1), benchmarkState.ac.get(k))
-          .getCardinality();
+      answer +=
+          RoaringBitmap.and(benchmarkState.ac.get(k - 1), benchmarkState.ac.get(k))
+              .getCardinality();
     return answer;
   }
 
@@ -62,7 +65,6 @@ public static class BenchmarkState {
     Random rand = new Random();
     Container aggregate;
 
-
     public BenchmarkState() {
       int N = 30;
       Random rand = new Random(1234);
@@ -72,7 +74,7 @@ public BenchmarkState() {
 
         for (int z = 0; z < 50; ++z) {
           int end = start + rand.nextInt(10000);
-          rb.add((long)start, (long)end);
+          rb.add((long) start, (long) end);
           start = end + rand.nextInt(1000);
         }
         cc.add(toConcise(rb.toArray()));
@@ -95,9 +97,7 @@ public BenchmarkState() {
         rb = rb.clone();
         rb.runOptimize();
         rc.add(rb);
-
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndNotBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndNotBenchmark.java
index d6a78a932..b8b505fc4 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndNotBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayAndNotBenchmark.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.ArrayList;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RoaringBitmap;
 
 import io.druid.extendedset.intset.ConciseSet;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -11,8 +10,10 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -30,8 +31,9 @@ static ConciseSet toConcise(int[] dat) {
   public int AndNotRunContainer(BenchmarkState benchmarkState) {
     int answer = 0;
     for (int k = 1; k < benchmarkState.rc.size(); ++k)
-      answer += RoaringBitmap.andNot(benchmarkState.rc.get(k - 1), benchmarkState.rc.get(k))
-          .getCardinality();
+      answer +=
+          RoaringBitmap.andNot(benchmarkState.rc.get(k - 1), benchmarkState.rc.get(k))
+              .getCardinality();
     return answer;
   }
 
@@ -39,8 +41,9 @@ public int AndNotRunContainer(BenchmarkState benchmarkState) {
   public int AndNotBitmapContainer(BenchmarkState benchmarkState) {
     int answer = 0;
     for (int k = 1; k < benchmarkState.ac.size(); ++k)
-      answer += RoaringBitmap.andNot(benchmarkState.ac.get(k - 1), benchmarkState.ac.get(k))
-          .getCardinality();
+      answer +=
+          RoaringBitmap.andNot(benchmarkState.ac.get(k - 1), benchmarkState.ac.get(k))
+              .getCardinality();
     return answer;
   }
 
@@ -62,7 +65,6 @@ public static class BenchmarkState {
     Random rand = new Random();
     Container aggregate;
 
-
     public BenchmarkState() {
       int N = 30;
       Random rand = new Random(1234);
@@ -72,7 +74,7 @@ public BenchmarkState() {
 
         for (int z = 0; z < 50; ++z) {
           int end = start + rand.nextInt(10000);
-          rb.add((long)start, (long)end);
+          rb.add((long) start, (long) end);
           start = end + rand.nextInt(1000);
         }
         cc.add(toConcise(rb.toArray()));
@@ -95,9 +97,7 @@ public BenchmarkState() {
         rb = rb.clone();
         rb.runOptimize();
         rc.add(rb);
-
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayOrBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayOrBenchmark.java
index fe211fadc..9613a88c1 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayOrBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayOrBenchmark.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.ArrayList;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RoaringBitmap;
 
 import io.druid.extendedset.intset.ConciseSet;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -11,8 +10,10 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -62,7 +63,6 @@ public static class BenchmarkState {
     Random rand = new Random();
     Container aggregate;
 
-
     public BenchmarkState() {
       int N = 30;
       Random rand = new Random(1234);
@@ -72,7 +72,7 @@ public BenchmarkState() {
 
         for (int z = 0; z < 50; ++z) {
           int end = start + rand.nextInt(10000);
-          rb.add((long)start, (long)end);
+          rb.add((long) start, (long) end);
           start = end + rand.nextInt(1000);
         }
         cc.add(toConcise(rb.toArray()));
@@ -95,9 +95,7 @@ public BenchmarkState() {
         rb = rb.clone();
         rb.runOptimize();
         rc.add(rb);
-
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayXorBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayXorBenchmark.java
index d17f3512b..38f017a06 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayXorBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunArrayXorBenchmark.java
@@ -1,8 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-import java.util.ArrayList;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.Container;
+import org.roaringbitmap.RoaringBitmap;
 
 import io.druid.extendedset.intset.ConciseSet;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -11,8 +10,10 @@
 import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.Container;
-import org.roaringbitmap.RoaringBitmap;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -30,8 +31,9 @@ static ConciseSet toConcise(int[] dat) {
   public int XorRunContainer(BenchmarkState benchmarkState) {
     int answer = 0;
     for (int k = 1; k < benchmarkState.rc.size(); ++k)
-      answer += RoaringBitmap.xor(benchmarkState.rc.get(k - 1), benchmarkState.rc.get(k))
-          .getCardinality();
+      answer +=
+          RoaringBitmap.xor(benchmarkState.rc.get(k - 1), benchmarkState.rc.get(k))
+              .getCardinality();
     return answer;
   }
 
@@ -39,8 +41,9 @@ public int XorRunContainer(BenchmarkState benchmarkState) {
   public int XorBitmapContainer(BenchmarkState benchmarkState) {
     int answer = 0;
     for (int k = 1; k < benchmarkState.ac.size(); ++k)
-      answer += RoaringBitmap.xor(benchmarkState.ac.get(k - 1), benchmarkState.ac.get(k))
-          .getCardinality();
+      answer +=
+          RoaringBitmap.xor(benchmarkState.ac.get(k - 1), benchmarkState.ac.get(k))
+              .getCardinality();
     return answer;
   }
 
@@ -62,7 +65,6 @@ public static class BenchmarkState {
     Random rand = new Random();
     Container aggregate;
 
-
     public BenchmarkState() {
       int N = 30;
       Random rand = new Random(1234);
@@ -72,7 +74,7 @@ public BenchmarkState() {
 
         for (int z = 0; z < 50; ++z) {
           int end = start + rand.nextInt(10000);
-          rb.add((long)start, (long)end);
+          rb.add((long) start, (long) end);
           start = end + rand.nextInt(1000);
         }
         cc.add(toConcise(rb.toArray()));
@@ -95,9 +97,7 @@ public BenchmarkState() {
         rb = rb.clone();
         rb.runOptimize();
         rc.add(rb);
-
       }
     }
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunContainerRealDataBenchmarkRunOptimize.java b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunContainerRealDataBenchmarkRunOptimize.java
index 61708e0ec..effcbd591 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunContainerRealDataBenchmarkRunOptimize.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/runcontainer/RunContainerRealDataBenchmarkRunOptimize.java
@@ -1,11 +1,7 @@
 package org.roaringbitmap.runcontainer;
 
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.ZipRealDataRetriever;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -15,8 +11,12 @@
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.ZipRealDataRetriever;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -107,10 +107,20 @@ public int runOptimizeAndserializeToBAOSFromClone(BenchmarkState benchmarkState)
 
   @State(Scope.Benchmark)
   public static class BenchmarkState {
-    @Param({// putting the data sets in alpha. order
-        "census-income", "census1881", "dimension_008", "dimension_003", "dimension_033",
-        "uscensus2000", "weather_sept_85", "wikileaks-noquotes", "census-income_srt",
-        "census1881_srt", "weather_sept_85_srt", "wikileaks-noquotes_srt"})
+    @Param({ // putting the data sets in alpha. order
+      "census-income",
+      "census1881",
+      "dimension_008",
+      "dimension_003",
+      "dimension_033",
+      "uscensus2000",
+      "weather_sept_85",
+      "wikileaks-noquotes",
+      "census-income_srt",
+      "census1881_srt",
+      "weather_sept_85_srt",
+      "wikileaks-noquotes_srt"
+    })
     String dataset;
 
     ArrayList ac = new ArrayList();
@@ -132,7 +142,5 @@ public void setup() throws Exception {
         rc.add(opti);
       }
     }
-
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/serialization/Roaring64BmpSerializationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/serialization/Roaring64BmpSerializationBenchmark.java
index af7166c25..43b490d27 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/serialization/Roaring64BmpSerializationBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/serialization/Roaring64BmpSerializationBenchmark.java
@@ -1,5 +1,14 @@
 package org.roaringbitmap.serialization;
 
+import org.roaringbitmap.longlong.Roaring64Bitmap;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -8,13 +17,6 @@
 import java.util.LinkedHashSet;
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.longlong.Roaring64Bitmap;
 
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -24,8 +26,8 @@ public class Roaring64BmpSerializationBenchmark {
   @Benchmark
   public int testDeserialize(BenchmarkState benchmarkState) throws IOException {
     benchmarkState.presoutbb.rewind();
-    try (ByteBufferBackedInputStream in = new ByteBufferBackedInputStream(
-        benchmarkState.presoutbb)) {
+    try (ByteBufferBackedInputStream in =
+        new ByteBufferBackedInputStream(benchmarkState.presoutbb)) {
       benchmarkState.bitmap_b.deserialize(new DataInputStream(in));
     } catch (Exception e) {
       throw new RuntimeException(e);
@@ -37,8 +39,8 @@ public int testDeserialize(BenchmarkState benchmarkState) throws IOException {
   @Benchmark
   public int testSerialize(BenchmarkState benchmarkState) throws IOException {
     benchmarkState.outbb.rewind();
-    try (ByteBufferBackedOutputStream out = new ByteBufferBackedOutputStream(
-        benchmarkState.outbb)) {
+    try (ByteBufferBackedOutputStream out =
+        new ByteBufferBackedOutputStream(benchmarkState.outbb)) {
       benchmarkState.bitmap_a.serialize(new DataOutputStream(out));
     } catch (Exception e) {
       throw new RuntimeException(e);
@@ -57,7 +59,6 @@ public static class BenchmarkState {
 
     final ByteBuffer presoutbb;
 
-
     public BenchmarkState() {
 
       final long[] data = takeSortedAndDistinct(new Random(0xcb000a2b9b5bdfb6l), 100000);
@@ -107,5 +108,3 @@ private long[] toArray(LinkedHashSet longLinkedHashSet) {
     }
   }
 }
-
-
diff --git a/jmh/src/jmh/java/org/roaringbitmap/serialization/SerializationBenchmark.java b/jmh/src/jmh/java/org/roaringbitmap/serialization/SerializationBenchmark.java
index cb47ffaa9..2da848865 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/serialization/SerializationBenchmark.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/serialization/SerializationBenchmark.java
@@ -1,5 +1,15 @@
 package org.roaringbitmap.serialization;
 
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.buffer.MutableRoaringBitmap;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -11,26 +21,16 @@
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
 
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-import org.roaringbitmap.RoaringBitmap;
-import org.roaringbitmap.buffer.MutableRoaringBitmap;
-
-
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 public class SerializationBenchmark {
 
-
   @BenchmarkMode(Mode.AverageTime)
   @Benchmark
   public int testDeserialize(BenchmarkState benchmarkState) throws IOException {
     benchmarkState.presoutbb.rewind();
-    try(ByteBufferBackedInputStream in = new ByteBufferBackedInputStream(benchmarkState.presoutbb)) {
+    try (ByteBufferBackedInputStream in =
+        new ByteBufferBackedInputStream(benchmarkState.presoutbb)) {
       benchmarkState.bitmap_b.deserialize(new DataInputStream(in));
     }
     return benchmarkState.presoutbb.limit();
@@ -40,35 +40,35 @@ public int testDeserialize(BenchmarkState benchmarkState) throws IOException {
   @Benchmark
   public int testMutableDeserializeMutable(BenchmarkState benchmarkState) throws IOException {
     benchmarkState.presoutbb.rewind();
-    try(ByteBufferBackedInputStream in = new ByteBufferBackedInputStream(benchmarkState.presoutbb)) {
+    try (ByteBufferBackedInputStream in =
+        new ByteBufferBackedInputStream(benchmarkState.presoutbb)) {
       benchmarkState.bitmap_br.deserialize(new DataInputStream(in));
     }
     return benchmarkState.presoutbb.limit();
   }
 
-
   @BenchmarkMode(Mode.AverageTime)
   @Benchmark
   public int testSerialize(BenchmarkState benchmarkState) throws IOException {
     benchmarkState.outbb.rewind();
-    try(ByteBufferBackedOutputStream out = new ByteBufferBackedOutputStream(benchmarkState.outbb)) {
+    try (ByteBufferBackedOutputStream out =
+        new ByteBufferBackedOutputStream(benchmarkState.outbb)) {
       benchmarkState.bitmap_a.serialize(new DataOutputStream(out));
     }
     return benchmarkState.outbb.limit();
   }
 
-
   @BenchmarkMode(Mode.AverageTime)
   @Benchmark
   public int testMutableSerialize(BenchmarkState benchmarkState) throws IOException {
     benchmarkState.outbb.rewind();
-    try(ByteBufferBackedOutputStream out = new ByteBufferBackedOutputStream(benchmarkState.outbb)) {
+    try (ByteBufferBackedOutputStream out =
+        new ByteBufferBackedOutputStream(benchmarkState.outbb)) {
       benchmarkState.bitmap_ar.serialize(new DataOutputStream(out));
     }
     return benchmarkState.outbb.limit();
   }
 
-
   @State(Scope.Benchmark)
   public static class BenchmarkState {
 
@@ -84,7 +84,6 @@ public static class BenchmarkState {
 
     final ByteBuffer presoutbb;
 
-
     public BenchmarkState() {
 
       final int[] data = takeSortedAndDistinct(new Random(0xcb000a2b9b5bdfb6l), 100000);
@@ -130,10 +129,8 @@ private int[] toArray(LinkedHashSet integers) {
       return ints;
     }
   }
-
 }
 
-
 class ByteBufferBackedInputStream extends InputStream {
 
   ByteBuffer buf;
@@ -182,7 +179,6 @@ public int read(byte[] bytes, int off, int len) throws IOException {
   }
 }
 
-
 class ByteBufferBackedOutputStream extends OutputStream {
   ByteBuffer buf;
 
@@ -204,7 +200,4 @@ public synchronized void write(byte[] bytes) throws IOException {
   public synchronized void write(byte[] bytes, int off, int len) throws IOException {
     buf.put(bytes, off, len);
   }
-
 }
-
-
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkAnd.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkAnd.java
index d3ea92eb0..0ca08b564 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkAnd.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkAnd.java
@@ -1,12 +1,13 @@
 package org.roaringbitmap.spe150271.roaring;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.spe150271.roaring.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.spe150271.roaring.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -20,5 +21,4 @@ public int pairwiseAnd(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkOr.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkOr.java
index 76721c79a..e3e40221f 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkOr.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkOr.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.spe150271.roaring;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.wrapper.BitmapIterator;
+import org.roaringbitmap.spe150271.roaring.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.wrapper.BitmapIterator;
-import org.roaringbitmap.spe150271.roaring.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -33,5 +34,4 @@ public int pairwiseOr_NoCardinality(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkWideOrNaive.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkWideOrNaive.java
index c8e8a78a1..092fd926d 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkWideOrNaive.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/RealDataBenchmarkWideOrNaive.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.spe150271.roaring;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
+import org.roaringbitmap.spe150271.roaring.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
-import org.roaringbitmap.spe150271.roaring.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -18,5 +19,4 @@ public int wideOr_naive(RealDataBenchmarkState bs) {
     BitmapAggregator aggregator = bs.bitmaps.get(0).naiveOrAggregator();
     return aggregator.aggregate(bs.bitmaps).cardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/state/RealDataBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/state/RealDataBenchmarkState.java
index 2ddea6812..089379bc7 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/state/RealDataBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/roaring/state/RealDataBenchmarkState.java
@@ -11,22 +11,23 @@
 @State(Scope.Benchmark)
 public class RealDataBenchmarkState extends org.roaringbitmap.AbstractBenchmarkState {
 
-  @Param({// putting the data sets in alpha. order
-      CENSUS_INCOME})
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME
+  })
   public String dataset;
 
   @Param({ROARING})
   public String type;
 
-  @Param({"false",})
+  @Param({
+    "false",
+  })
   public boolean immutable;
 
-
   public RealDataBenchmarkState() {}
 
   @Setup
   public void setup() throws Exception {
     super.setup(dataset, type, immutable);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkAnd.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkAnd.java
index 9954142a7..d6f65697a 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkAnd.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkAnd.java
@@ -1,12 +1,13 @@
 package org.roaringbitmap.spe150271.runroaring;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.spe150271.runroaring.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.spe150271.runroaring.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -20,5 +21,4 @@ public int pairwiseAnd(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkOr.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkOr.java
index 854d9f10e..ae62ef34d 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkOr.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkOr.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.spe150271.runroaring;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.wrapper.BitmapIterator;
+import org.roaringbitmap.spe150271.runroaring.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.wrapper.BitmapIterator;
-import org.roaringbitmap.spe150271.runroaring.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -33,5 +34,4 @@ public int pairwiseOr_NoCardinality(RealDataBenchmarkState bs) {
     }
     return total;
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkWideOrNaive.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkWideOrNaive.java
index 9c425c3b3..05a5c4b22 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkWideOrNaive.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/RealDataBenchmarkWideOrNaive.java
@@ -1,13 +1,14 @@
 package org.roaringbitmap.spe150271.runroaring;
 
-import java.util.concurrent.TimeUnit;
+import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
+import org.roaringbitmap.spe150271.runroaring.state.RealDataBenchmarkState;
 
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.roaringbitmap.realdata.wrapper.BitmapAggregator;
-import org.roaringbitmap.spe150271.runroaring.state.RealDataBenchmarkState;
+
+import java.util.concurrent.TimeUnit;
 
 @BenchmarkMode(Mode.AverageTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
@@ -18,5 +19,4 @@ public int wideOr_naive(RealDataBenchmarkState bs) {
     BitmapAggregator aggregator = bs.bitmaps.get(0).naiveOrAggregator();
     return aggregator.aggregate(bs.bitmaps).cardinality();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/state/RealDataBenchmarkState.java b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/state/RealDataBenchmarkState.java
index 4389886af..5a7122f1b 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/state/RealDataBenchmarkState.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/spe150271/runroaring/state/RealDataBenchmarkState.java
@@ -11,22 +11,23 @@
 @State(Scope.Benchmark)
 public class RealDataBenchmarkState extends org.roaringbitmap.AbstractBenchmarkState {
 
-  @Param({// putting the data sets in alpha. order
-      CENSUS_INCOME})
+  @Param({ // putting the data sets in alpha. order
+    CENSUS_INCOME
+  })
   public String dataset;
 
   @Param({ROARING_WITH_RUN})
   public String type;
 
-  @Param({"false",})
+  @Param({
+    "false",
+  })
   public boolean immutable;
 
-
   public RealDataBenchmarkState() {}
 
   @Setup
   public void setup() throws Exception {
     super.setup(dataset, type, immutable);
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/writer/WriteSequential.java b/jmh/src/jmh/java/org/roaringbitmap/writer/WriteSequential.java
index 53930733b..5cfbdb5b7 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/writer/WriteSequential.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/writer/WriteSequential.java
@@ -1,8 +1,17 @@
 package org.roaringbitmap.writer;
 
+import org.roaringbitmap.RoaringBitmap;
+import org.roaringbitmap.RoaringBitmapWriter;
 
-import org.openjdk.jmh.annotations.*;
-import org.roaringbitmap.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
 
 import java.util.Arrays;
 import java.util.Random;
@@ -25,8 +34,8 @@ RoaringBitmapWriter newWriter() {
       RoaringBitmapWriter newWriter() {
         return RoaringBitmapWriter.writer().optimiseForArrays().get();
       }
-    }
-    ;
+    };
+
     abstract RoaringBitmapWriter newWriter();
   }
 
@@ -92,5 +101,4 @@ public RoaringBitmap incrementalUseOrderedWriter() {
     writer.flush();
     return writer.getUnderlying();
   }
-
 }
diff --git a/jmh/src/jmh/java/org/roaringbitmap/writer/WriteUnordered.java b/jmh/src/jmh/java/org/roaringbitmap/writer/WriteUnordered.java
index b3c087b93..0d18014a3 100644
--- a/jmh/src/jmh/java/org/roaringbitmap/writer/WriteUnordered.java
+++ b/jmh/src/jmh/java/org/roaringbitmap/writer/WriteUnordered.java
@@ -1,10 +1,23 @@
 package org.roaringbitmap.writer;
 
-import org.openjdk.jmh.annotations.*;
 import org.roaringbitmap.RoaringBitmap;
 import org.roaringbitmap.Util;
 
-import java.util.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
 import java.util.concurrent.TimeUnit;
 
 @State(Scope.Benchmark)
@@ -14,6 +27,7 @@ public class WriteUnordered {
 
   @Param({"10000", "100000", "1000000", "10000000"})
   int size;
+
   @Param({"0.1", "0.5", "0.9"})
   double randomness;
 
@@ -76,4 +90,3 @@ public RoaringBitmap partialSortThenBitmapOf() {
     return RoaringBitmap.bitmapOf(copy);
   }
 }
-
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNotTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNotTest.java
index 7d8fa6d88..8fa5c5599 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNotTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndNotTest.java
@@ -1,24 +1,43 @@
 package org.roaringbitmap.realdata;
 
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
-import static org.roaringbitmap.RealDataset.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
 
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
 
 public class RealDataBenchmarkAndNotTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 5666586).put(CENSUS1881, 1003836)
-          .put(DIMENSION_008, 2721459).put(DIMENSION_003, 3866831).put(DIMENSION_033, 3866842)
-          .put(USCENSUS2000, 5970).put(WEATHER_SEPT_85, 11960876).put(WIKILEAKS_NOQUOTES, 271605)
-          .put(CENSUS_INCOME_SRT, 5164671).put(CENSUS1881_SRT, 679375)
-          .put(WEATHER_SEPT_85_SRT, 14935706).put(WIKILEAKS_NOQUOTES_SRT, 286904).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 5666586)
+          .put(CENSUS1881, 1003836)
+          .put(DIMENSION_008, 2721459)
+          .put(DIMENSION_003, 3866831)
+          .put(DIMENSION_033, 3866842)
+          .put(USCENSUS2000, 5970)
+          .put(WEATHER_SEPT_85, 11960876)
+          .put(WIKILEAKS_NOQUOTES, 271605)
+          .put(CENSUS_INCOME_SRT, 5164671)
+          .put(CENSUS1881_SRT, 679375)
+          .put(WEATHER_SEPT_85_SRT, 14935706)
+          .put(WIKILEAKS_NOQUOTES_SRT, 286904)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndTest.java
index e0b8c33fb..85d3c8bb7 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkAndTest.java
@@ -1,21 +1,40 @@
 package org.roaringbitmap.realdata;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import com.google.common.collect.ImmutableMap;
 
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.roaringbitmap.RealDataset.*;
-
-
 public class RealDataBenchmarkAndTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 1245448).put(CENSUS1881, 23)
-          .put(DIMENSION_008, 112317).put(DIMENSION_003, 0).put(DIMENSION_033, 0)
-          .put(USCENSUS2000, 0).put(WEATHER_SEPT_85, 642019).put(WIKILEAKS_NOQUOTES, 3327)
-          .put(CENSUS_INCOME_SRT, 927715).put(CENSUS1881_SRT, 206).put(WEATHER_SEPT_85_SRT, 1062989)
-          .put(WIKILEAKS_NOQUOTES_SRT, 152).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 1245448)
+          .put(CENSUS1881, 23)
+          .put(DIMENSION_008, 112317)
+          .put(DIMENSION_003, 0)
+          .put(DIMENSION_033, 0)
+          .put(USCENSUS2000, 0)
+          .put(WEATHER_SEPT_85, 642019)
+          .put(WIKILEAKS_NOQUOTES, 3327)
+          .put(CENSUS_INCOME_SRT, 927715)
+          .put(CENSUS1881_SRT, 206)
+          .put(WEATHER_SEPT_85_SRT, 1062989)
+          .put(WIKILEAKS_NOQUOTES_SRT, 152)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkForEachTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkForEachTest.java
index 0ce9f6a5c..577fecb95 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkForEachTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkForEachTest.java
@@ -1,24 +1,45 @@
 package org.roaringbitmap.realdata;
 
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
-import static org.roaringbitmap.RealDataset.*;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH32;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
 
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
 
 public class RealDataBenchmarkForEachTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, -942184551)
-          .put(CENSUS1881, 246451066).put(DIMENSION_008, -423436314).put(DIMENSION_003, -1287135055)
-          .put(DIMENSION_033, -1287135055).put(USCENSUS2000, -1260727955)
-          .put(WEATHER_SEPT_85, 644036874).put(WIKILEAKS_NOQUOTES, 413846869)
-          .put(CENSUS_INCOME_SRT, -679313956).put(CENSUS1881_SRT, 445584405)
-          .put(WEATHER_SEPT_85_SRT, 1132748056).put(WIKILEAKS_NOQUOTES_SRT, 1921022163).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, -942184551)
+          .put(CENSUS1881, 246451066)
+          .put(DIMENSION_008, -423436314)
+          .put(DIMENSION_003, -1287135055)
+          .put(DIMENSION_033, -1287135055)
+          .put(USCENSUS2000, -1260727955)
+          .put(WEATHER_SEPT_85, 644036874)
+          .put(WIKILEAKS_NOQUOTES, 413846869)
+          .put(CENSUS_INCOME_SRT, -679313956)
+          .put(CENSUS1881_SRT, 445584405)
+          .put(WEATHER_SEPT_85_SRT, 1132748056)
+          .put(WIKILEAKS_NOQUOTES_SRT, 1921022163)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIOrTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIOrTest.java
index c8ebfa13f..2bba7e5a8 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIOrTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIOrTest.java
@@ -1,23 +1,47 @@
 package org.roaringbitmap.realdata;
 
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
-import static org.roaringbitmap.RealDataset.*;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH32;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING_WITH_RUN;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
 
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
 
 public class RealDataBenchmarkIOrTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 199523).put(CENSUS1881, 988653)
-          .put(DIMENSION_008, 148278).put(DIMENSION_003, 3866847).put(DIMENSION_033, 3866847)
-          .put(USCENSUS2000, 5985).put(WEATHER_SEPT_85, 1015367).put(WIKILEAKS_NOQUOTES, 242540)
-          .put(CENSUS_INCOME_SRT, 199523).put(CENSUS1881_SRT, 656346)
-          .put(WEATHER_SEPT_85_SRT, 1015367).put(WIKILEAKS_NOQUOTES_SRT, 236436).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 199523)
+          .put(CENSUS1881, 988653)
+          .put(DIMENSION_008, 148278)
+          .put(DIMENSION_003, 3866847)
+          .put(DIMENSION_033, 3866847)
+          .put(USCENSUS2000, 5985)
+          .put(WEATHER_SEPT_85, 1015367)
+          .put(WIKILEAKS_NOQUOTES, 242540)
+          .put(CENSUS_INCOME_SRT, 199523)
+          .put(CENSUS1881_SRT, 656346)
+          .put(WEATHER_SEPT_85_SRT, 1015367)
+          .put(WIKILEAKS_NOQUOTES_SRT, 236436)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
@@ -30,5 +54,4 @@ protected void doTest(String dataset, String type, boolean immutable) {
     RealDataBenchmarkIOr bench = new RealDataBenchmarkIOr();
     assertEquals(expected, bench.pairwiseIOr(bs));
   }
-
 }
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIterateTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIterateTest.java
index 55571fece..0677d43be 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIterateTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkIterateTest.java
@@ -1,22 +1,40 @@
 package org.roaringbitmap.realdata;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import com.google.common.collect.ImmutableMap;
 
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.roaringbitmap.RealDataset.*;
-
-
 public class RealDataBenchmarkIterateTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, -942184551)
-          .put(CENSUS1881, 246451066).put(DIMENSION_008, -423436314).put(DIMENSION_003, -1287135055)
-          .put(DIMENSION_033, -1287135055).put(USCENSUS2000, -1260727955)
-          .put(WEATHER_SEPT_85, 644036874).put(WIKILEAKS_NOQUOTES, 413846869)
-          .put(CENSUS_INCOME_SRT, -679313956).put(CENSUS1881_SRT, 445584405)
-          .put(WEATHER_SEPT_85_SRT, 1132748056).put(WIKILEAKS_NOQUOTES_SRT, 1921022163).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, -942184551)
+          .put(CENSUS1881, 246451066)
+          .put(DIMENSION_008, -423436314)
+          .put(DIMENSION_003, -1287135055)
+          .put(DIMENSION_033, -1287135055)
+          .put(USCENSUS2000, -1260727955)
+          .put(WEATHER_SEPT_85, 644036874)
+          .put(WIKILEAKS_NOQUOTES, 413846869)
+          .put(CENSUS_INCOME_SRT, -679313956)
+          .put(CENSUS1881_SRT, 445584405)
+          .put(WEATHER_SEPT_85_SRT, 1132748056)
+          .put(WIKILEAKS_NOQUOTES_SRT, 1921022163)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkOrTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkOrTest.java
index 44684daae..929ffbc81 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkOrTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkOrTest.java
@@ -1,33 +1,62 @@
 package org.roaringbitmap.realdata;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import com.google.common.collect.ImmutableMap;
 
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.roaringbitmap.RealDataset.*;
-
-
 public class RealDataBenchmarkOrTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 12487395).put(CENSUS1881, 2007691)
-          .put(DIMENSION_008, 5555233).put(DIMENSION_003, 7733676).put(DIMENSION_033, 7579526)
-          .put(USCENSUS2000, 11954).put(WEATHER_SEPT_85, 24729002).put(WIKILEAKS_NOQUOTES, 541893)
-          .put(CENSUS_INCOME_SRT, 11257282).put(CENSUS1881_SRT, 1360167)
-          .put(WEATHER_SEPT_85_SRT, 30863347).put(WIKILEAKS_NOQUOTES_SRT, 574463).build();
-
-  private static final Map EXPECTED_RESULTS_NO_CARDINALITY = ImmutableMap
-      .builder().put(CENSUS_INCOME, 20377).put(CENSUS1881, 192344014)
-      .put(DIMENSION_008, 60471647).put(DIMENSION_003, -2080279977).put(DIMENSION_033, 48993139)
-      .put(USCENSUS2000, 1085687199).put(WEATHER_SEPT_85, 164092).put(WIKILEAKS_NOQUOTES, 43309741)
-      .put(CENSUS_INCOME_SRT, 325103).put(CENSUS1881_SRT, 113309680)
-      .put(WEATHER_SEPT_85_SRT, 11922488).put(WIKILEAKS_NOQUOTES_SRT, 28702307).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 12487395)
+          .put(CENSUS1881, 2007691)
+          .put(DIMENSION_008, 5555233)
+          .put(DIMENSION_003, 7733676)
+          .put(DIMENSION_033, 7579526)
+          .put(USCENSUS2000, 11954)
+          .put(WEATHER_SEPT_85, 24729002)
+          .put(WIKILEAKS_NOQUOTES, 541893)
+          .put(CENSUS_INCOME_SRT, 11257282)
+          .put(CENSUS1881_SRT, 1360167)
+          .put(WEATHER_SEPT_85_SRT, 30863347)
+          .put(WIKILEAKS_NOQUOTES_SRT, 574463)
+          .build();
+
+  private static final Map EXPECTED_RESULTS_NO_CARDINALITY =
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 20377)
+          .put(CENSUS1881, 192344014)
+          .put(DIMENSION_008, 60471647)
+          .put(DIMENSION_003, -2080279977)
+          .put(DIMENSION_033, 48993139)
+          .put(USCENSUS2000, 1085687199)
+          .put(WEATHER_SEPT_85, 164092)
+          .put(WIKILEAKS_NOQUOTES, 43309741)
+          .put(CENSUS_INCOME_SRT, 325103)
+          .put(CENSUS1881_SRT, 113309680)
+          .put(WEATHER_SEPT_85_SRT, 11922488)
+          .put(WIKILEAKS_NOQUOTES_SRT, 28702307)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
     RealDataBenchmarkOr bench = new RealDataBenchmarkOr();
-    assertEquals((int)EXPECTED_RESULTS.get(dataset), bench.pairwiseOr(bs));
-    assertEquals((int)EXPECTED_RESULTS_NO_CARDINALITY.get(dataset), bench.pairwiseOr_NoCardinality(bs));
+    assertEquals((int) EXPECTED_RESULTS.get(dataset), bench.pairwiseOr(bs));
+    assertEquals(
+        (int) EXPECTED_RESULTS_NO_CARDINALITY.get(dataset), bench.pairwiseOr_NoCardinality(bs));
   }
 }
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterateTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterateTest.java
index 1cf2256ec..55cd6b438 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterateTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkReverseIterateTest.java
@@ -1,25 +1,43 @@
 package org.roaringbitmap.realdata;
 
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
-import static org.roaringbitmap.RealDataset.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
 
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
 
 public class RealDataBenchmarkReverseIterateTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, -942184551)
-          .put(CENSUS1881, 246451066).put(DIMENSION_008, -423436314).put(DIMENSION_003, -1287135055)
-          .put(DIMENSION_033, -1287135055).put(USCENSUS2000, -1260727955)
-          .put(WEATHER_SEPT_85, 644036874).put(WIKILEAKS_NOQUOTES, 413846869)
-          .put(CENSUS_INCOME_SRT, -679313956).put(CENSUS1881_SRT, 445584405)
-          .put(WEATHER_SEPT_85_SRT, 1132748056).put(WIKILEAKS_NOQUOTES_SRT, 1921022163).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, -942184551)
+          .put(CENSUS1881, 246451066)
+          .put(DIMENSION_008, -423436314)
+          .put(DIMENSION_003, -1287135055)
+          .put(DIMENSION_033, -1287135055)
+          .put(USCENSUS2000, -1260727955)
+          .put(WEATHER_SEPT_85, 644036874)
+          .put(WIKILEAKS_NOQUOTES, 413846869)
+          .put(CENSUS_INCOME_SRT, -679313956)
+          .put(CENSUS1881_SRT, 445584405)
+          .put(WEATHER_SEPT_85_SRT, 1132748056)
+          .put(WIKILEAKS_NOQUOTES_SRT, 1921022163)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
@@ -29,5 +47,4 @@ protected void doTest(String dataset, String type, boolean immutable) {
     RealDataBenchmarkReverseIterate bench = new RealDataBenchmarkReverseIterate();
     assertEquals(expected, bench.reverseIterate(bs));
   }
-
 }
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkSanityTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkSanityTest.java
index 8ee0037fc..a4ae1b1ba 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkSanityTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkSanityTest.java
@@ -1,5 +1,28 @@
 package org.roaringbitmap.realdata;
 
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.EWAH32;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING_ONLY;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.ROARING_WITH_RUN;
+import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
+
+import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
+import org.roaringbitmap.realdata.wrapper.BitmapFactory;
+
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.parallel.Execution;
@@ -7,21 +30,27 @@
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
-import org.roaringbitmap.realdata.state.RealDataBenchmarkState;
-import org.roaringbitmap.realdata.wrapper.BitmapFactory;
 
 import java.util.Arrays;
 import java.util.stream.Stream;
 
-import static org.roaringbitmap.RealDataset.*;
-import static org.roaringbitmap.realdata.wrapper.BitmapFactory.*;
-
 @Execution(ExecutionMode.CONCURRENT)
 public abstract class RealDataBenchmarkSanityTest {
 
-  public static final String[] REAL_DATA_SETS = {CENSUS_INCOME, CENSUS1881, DIMENSION_008,
-      DIMENSION_003, DIMENSION_033, USCENSUS2000, WEATHER_SEPT_85, WIKILEAKS_NOQUOTES,
-      CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT, WIKILEAKS_NOQUOTES_SRT};
+  public static final String[] REAL_DATA_SETS = {
+    CENSUS_INCOME,
+    CENSUS1881,
+    DIMENSION_008,
+    DIMENSION_003,
+    DIMENSION_033,
+    USCENSUS2000,
+    WEATHER_SEPT_85,
+    WIKILEAKS_NOQUOTES,
+    CENSUS_INCOME_SRT,
+    CENSUS1881_SRT,
+    WEATHER_SEPT_85_SRT,
+    WIKILEAKS_NOQUOTES_SRT
+  };
 
   public static final String[] BITMAP_TYPES =
       ROARING_ONLY.equals(System.getProperty(BitmapFactory.BITMAP_TYPES))
@@ -30,11 +59,11 @@ public abstract class RealDataBenchmarkSanityTest {
 
   public static final Boolean[] BITMAP_IMMUTABILITY = {false, true};
 
-
   // Ensure all tests related to the same dataset are run consecutively in order to take advantage
   // of any cache
   public static Stream params() {
-    Arguments[] product = new Arguments[REAL_DATA_SETS.length * BITMAP_TYPES.length * BITMAP_IMMUTABILITY.length];
+    Arguments[] product =
+        new Arguments[REAL_DATA_SETS.length * BITMAP_TYPES.length * BITMAP_IMMUTABILITY.length];
     int i = 0;
     for (String ds : REAL_DATA_SETS) {
       for (String type : BITMAP_TYPES) {
@@ -71,5 +100,4 @@ public void tearDown() {
   }
 
   protected abstract void doTest(String dataset, String type, boolean immutable);
-
 }
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaiveTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaiveTest.java
index 70b1f20bb..9594ee1f4 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaiveTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideAndNaiveTest.java
@@ -1,6 +1,5 @@
 package org.roaringbitmap.realdata;
 
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 public class RealDataBenchmarkWideAndNaiveTest extends RealDataBenchmarkSanityTest {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaiveTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaiveTest.java
index eac0ed8dc..c9af808e4 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaiveTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrNaiveTest.java
@@ -1,22 +1,40 @@
 package org.roaringbitmap.realdata;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import com.google.common.collect.ImmutableMap;
 
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.roaringbitmap.RealDataset.*;
-
-
 public class RealDataBenchmarkWideOrNaiveTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 199523).put(CENSUS1881, 988653)
-          .put(DIMENSION_008, 148278).put(DIMENSION_003, 3866847).put(DIMENSION_033, 3866847)
-          .put(USCENSUS2000, 5985).put(WEATHER_SEPT_85, 1015367).put(WIKILEAKS_NOQUOTES, 242540)
-          .put(CENSUS_INCOME_SRT, 199523).put(CENSUS1881_SRT, 656346)
-          .put(WEATHER_SEPT_85_SRT, 1015367).put(WIKILEAKS_NOQUOTES_SRT, 236436).build();
-
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 199523)
+          .put(CENSUS1881, 988653)
+          .put(DIMENSION_008, 148278)
+          .put(DIMENSION_003, 3866847)
+          .put(DIMENSION_033, 3866847)
+          .put(USCENSUS2000, 5985)
+          .put(WEATHER_SEPT_85, 1015367)
+          .put(WIKILEAKS_NOQUOTES, 242540)
+          .put(CENSUS_INCOME_SRT, 199523)
+          .put(CENSUS1881_SRT, 656346)
+          .put(WEATHER_SEPT_85_SRT, 1015367)
+          .put(WIKILEAKS_NOQUOTES_SRT, 236436)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPqTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPqTest.java
index 1c018a755..31283603e 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPqTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkWideOrPqTest.java
@@ -1,21 +1,40 @@
 package org.roaringbitmap.realdata;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
+
 import com.google.common.collect.ImmutableMap;
 
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.roaringbitmap.RealDataset.*;
-
-
 public class RealDataBenchmarkWideOrPqTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 199523).put(CENSUS1881, 988653)
-          .put(DIMENSION_008, 148278).put(DIMENSION_003, 3866847).put(DIMENSION_033, 3866847)
-          .put(USCENSUS2000, 5985).put(WEATHER_SEPT_85, 1015367).put(WIKILEAKS_NOQUOTES, 242540)
-          .put(CENSUS_INCOME_SRT, 199523).put(CENSUS1881_SRT, 656346)
-          .put(WEATHER_SEPT_85_SRT, 1015367).put(WIKILEAKS_NOQUOTES_SRT, 236436).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 199523)
+          .put(CENSUS1881, 988653)
+          .put(DIMENSION_008, 148278)
+          .put(DIMENSION_003, 3866847)
+          .put(DIMENSION_033, 3866847)
+          .put(USCENSUS2000, 5985)
+          .put(WEATHER_SEPT_85, 1015367)
+          .put(WIKILEAKS_NOQUOTES, 242540)
+          .put(CENSUS_INCOME_SRT, 199523)
+          .put(CENSUS1881_SRT, 656346)
+          .put(WEATHER_SEPT_85_SRT, 1015367)
+          .put(WIKILEAKS_NOQUOTES_SRT, 236436)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkXorTest.java b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkXorTest.java
index 7dec4b2b1..65cc47ea1 100644
--- a/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkXorTest.java
+++ b/jmh/src/test/java/org/roaringbitmap/realdata/RealDataBenchmarkXorTest.java
@@ -1,24 +1,43 @@
 package org.roaringbitmap.realdata;
 
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
-import static org.roaringbitmap.RealDataset.*;
+import static org.roaringbitmap.RealDataset.CENSUS1881;
+import static org.roaringbitmap.RealDataset.CENSUS1881_SRT;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME;
+import static org.roaringbitmap.RealDataset.CENSUS_INCOME_SRT;
+import static org.roaringbitmap.RealDataset.DIMENSION_003;
+import static org.roaringbitmap.RealDataset.DIMENSION_008;
+import static org.roaringbitmap.RealDataset.DIMENSION_033;
+import static org.roaringbitmap.RealDataset.USCENSUS2000;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85;
+import static org.roaringbitmap.RealDataset.WEATHER_SEPT_85_SRT;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES;
+import static org.roaringbitmap.RealDataset.WIKILEAKS_NOQUOTES_SRT;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.CONCISE;
 import static org.roaringbitmap.realdata.wrapper.BitmapFactory.WAH;
 
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
 
 public class RealDataBenchmarkXorTest extends RealDataBenchmarkSanityTest {
 
   private static final Map EXPECTED_RESULTS =
-      ImmutableMap.builder().put(CENSUS_INCOME, 11241947).put(CENSUS1881, 2007668)
-          .put(DIMENSION_008, 5442916).put(DIMENSION_003, 7733676).put(DIMENSION_033, 7579526)
-          .put(USCENSUS2000, 11954).put(WEATHER_SEPT_85, 24086983).put(WIKILEAKS_NOQUOTES, 538566)
-          .put(CENSUS_INCOME_SRT, 10329567).put(CENSUS1881_SRT, 1359961)
-          .put(WEATHER_SEPT_85_SRT, 29800358).put(WIKILEAKS_NOQUOTES_SRT, 574311).build();
+      ImmutableMap.builder()
+          .put(CENSUS_INCOME, 11241947)
+          .put(CENSUS1881, 2007668)
+          .put(DIMENSION_008, 5442916)
+          .put(DIMENSION_003, 7733676)
+          .put(DIMENSION_033, 7579526)
+          .put(USCENSUS2000, 11954)
+          .put(WEATHER_SEPT_85, 24086983)
+          .put(WIKILEAKS_NOQUOTES, 538566)
+          .put(CENSUS_INCOME_SRT, 10329567)
+          .put(CENSUS1881_SRT, 1359961)
+          .put(WEATHER_SEPT_85_SRT, 29800358)
+          .put(WIKILEAKS_NOQUOTES_SRT, 574311)
+          .build();
 
   @Override
   protected void doTest(String dataset, String type, boolean immutable) {
diff --git a/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java b/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java
index f380bdf7a..3f3620aac 100644
--- a/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java
+++ b/real-roaring-dataset/src/main/java/org/roaringbitmap/RealDataset.java
@@ -2,9 +2,7 @@
 
 public final class RealDataset {
 
-  private RealDataset() {
-
-  }
+  private RealDataset() {}
 
   public static final String CENSUS_INCOME = "census-income";
   public static final String CENSUS1881 = "census1881";
@@ -19,9 +17,10 @@ private RealDataset() {
   public static final String WEATHER_SEPT_85_SRT = "weather_sept_85_srt";
   public static final String WIKILEAKS_NOQUOTES_SRT = "wikileaks-noquotes_srt";
 
-  public static final String[] ALL = new String[]{
-      CENSUS_INCOME, CENSUS1881, DIMENSION_008, DIMENSION_003,
-      DIMENSION_033, USCENSUS2000, WEATHER_SEPT_85, WIKILEAKS_NOQUOTES,
-      CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT, WIKILEAKS_NOQUOTES_SRT
-  };
+  public static final String[] ALL =
+      new String[] {
+        CENSUS_INCOME, CENSUS1881, DIMENSION_008, DIMENSION_003,
+        DIMENSION_033, USCENSUS2000, WEATHER_SEPT_85, WIKILEAKS_NOQUOTES,
+        CENSUS_INCOME_SRT, CENSUS1881_SRT, WEATHER_SEPT_85_SRT, WIKILEAKS_NOQUOTES_SRT
+      };
 }
diff --git a/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java b/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java
index 053e0055f..a85c9f992 100644
--- a/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java
+++ b/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRangeRetriever.java
@@ -21,8 +21,8 @@ public class ZipRealDataRangeRetriever {
 
   private final String dataset;
 
-  public ZipRealDataRangeRetriever(String dataset, String folder) throws IOException,
-      URISyntaxException {
+  public ZipRealDataRangeRetriever(String dataset, String folder)
+      throws IOException, URISyntaxException {
     this.dataset = dataset;
     this.REAL_ROARING_DATASET = folder;
   }
@@ -86,7 +86,6 @@ private ZipEntry nextEntry() {
           }
         };
       }
-
     };
   }
 
@@ -101,5 +100,4 @@ private ZipInputStream getResourceAsStream() {
   private String resource() {
     return REAL_ROARING_DATASET + dataset + ZIP_EXTENSION;
   }
-
 }
diff --git a/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRetriever.java b/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRetriever.java
index 4ec120b48..b3bd76c72 100644
--- a/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRetriever.java
+++ b/real-roaring-dataset/src/main/java/org/roaringbitmap/ZipRealDataRetriever.java
@@ -5,9 +5,8 @@
 import java.io.InputStreamReader;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.util.List;
 import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -40,12 +39,8 @@ public String getName() {
   public List fetchBitPositions() throws IOException {
     List bitPositions = new ArrayList<>();
 
-
-    try (
-        final ZipInputStream zis = getResourceAsStream();
-        final BufferedReader buf = new BufferedReader(new InputStreamReader(zis));
-    ) {
-
+    try (final ZipInputStream zis = getResourceAsStream();
+        final BufferedReader buf = new BufferedReader(new InputStreamReader(zis)); ) {
 
       while (true) {
         ZipEntry nextEntry = zis.getNextEntry();
@@ -80,5 +75,4 @@ private ZipInputStream getResourceAsStream() {
   private String resource() {
     return REAL_ROARING_DATASET + dataset + ZIP_EXTENSION;
   }
-
 }
diff --git a/roaringbitmap/src/java11/java/org/roaringbitmap/ArraysShim.java b/roaringbitmap/src/java11/java/org/roaringbitmap/ArraysShim.java
index 152df11e7..6966833cc 100644
--- a/roaringbitmap/src/java11/java/org/roaringbitmap/ArraysShim.java
+++ b/roaringbitmap/src/java11/java/org/roaringbitmap/ArraysShim.java
@@ -34,8 +34,8 @@ public static boolean equals(char[] x, int xmin, int xmax, char[] y, int ymin, i
    * @param bToIndex exclusive
    * @return -1 if no mismatch found,othewise the mismatch offset
    */
-  public static int mismatch(byte[] a, int aFromIndex, int aToIndex,
-      byte[] b, int bFromIndex, int bToIndex) {
+  public static int mismatch(
+      byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
     if (bFromIndex > bToIndex) {
       return -1;
     }
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/AppendableStorage.java b/roaringbitmap/src/main/java/org/roaringbitmap/AppendableStorage.java
index 5d651c279..a3ae042ad 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/AppendableStorage.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/AppendableStorage.java
@@ -13,5 +13,4 @@ public interface AppendableStorage {
    * @param container the data to append
    */
   void append(char key, T container);
-
 }
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java
index 195022cf8..7f2686c2c 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/ArrayBatchIterator.java
@@ -1,6 +1,5 @@
 package org.roaringbitmap;
 
-
 import static org.roaringbitmap.Util.unsignedBinarySearch;
 
 public final class ArrayBatchIterator implements ContainerBatchIterator {
@@ -30,7 +29,7 @@ public boolean hasNext() {
   @Override
   public ContainerBatchIterator clone() {
     try {
-      return (ContainerBatchIterator)super.clone();
+      return (ContainerBatchIterator) super.clone();
     } catch (CloneNotSupportedException e) {
       // won't happen
       throw new IllegalStateException(e);
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
index 1c3b355ba..ebb2dd955 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
@@ -7,16 +7,17 @@
 import org.roaringbitmap.buffer.MappeableArrayContainer;
 import org.roaringbitmap.buffer.MappeableContainer;
 
-import java.io.*;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.CharBuffer;
 import java.util.Arrays;
 import java.util.Iterator;
 
-
-
-
 /**
  * Simple container made of an array of 16-bit integers
  */
@@ -24,8 +25,8 @@ public final class ArrayContainer extends Container implements Cloneable {
   private static final int DEFAULT_INIT_SIZE = 4;
   private static final int ARRAY_LAZY_LOWERBOUND = 1024;
 
-  static final int DEFAULT_MAX_SIZE = 4096;// containers with DEFAULT_MAX_SZE or less integers
-                                           // should be ArrayContainers
+  static final int DEFAULT_MAX_SIZE = 4096; // containers with DEFAULT_MAX_SZE or less integers
+  // should be ArrayContainers
 
   private static final long serialVersionUID = 1L;
 
@@ -37,7 +38,6 @@ protected static int serializedSizeInBytes(int cardinality) {
 
   char[] content;
 
-
   /**
    * Create an array container with default capacity
    */
@@ -48,6 +48,7 @@ public ArrayContainer() {
   public static ArrayContainer empty() {
     return new ArrayContainer();
   }
+
   /**
    * Create an array container with specified capacity
    *
@@ -101,7 +102,7 @@ public ArrayContainer(char[] newContent) {
 
   @Override
   public Container add(int begin, int end) {
-    if(end == begin) {
+    if (end == begin) {
       return clone();
     }
     if ((begin > end) || (end > (1 << 16))) {
@@ -125,8 +126,8 @@ public Container add(int begin, int end) {
       return a.iadd(begin, end);
     }
     ArrayContainer answer = new ArrayContainer(newcardinality, content);
-    System.arraycopy(content, indexend, answer.content, indexstart + rangelength,
-        cardinality - indexend);
+    System.arraycopy(
+        content, indexend, answer.content, indexstart + rangelength, cardinality - indexend);
     for (int k = 0; k < rangelength; ++k) {
       answer.content[k + indexstart] = (char) (begin + k);
     }
@@ -134,15 +135,12 @@ public Container add(int begin, int end) {
     return answer;
   }
 
-
-
   /**
    * running time is in O(n) time if insert is not in order.
    */
   @Override
   public Container add(final char x) {
-    if (cardinality == 0 || (cardinality > 0
-            && (x) > (content[cardinality - 1]))) {
+    if (cardinality == 0 || (cardinality > 0 && (x) > (content[cardinality - 1]))) {
       if (cardinality >= DEFAULT_MAX_SIZE) {
         return toBitmapContainer().add(x);
       }
@@ -185,8 +183,13 @@ public ArrayContainer and(final ArrayContainer value2) {
     ArrayContainer value1 = this;
     final int desiredCapacity = Math.min(value1.getCardinality(), value2.getCardinality());
     ArrayContainer answer = new ArrayContainer(desiredCapacity);
-    answer.cardinality = Util.unsignedIntersect2by2(value1.content, value1.getCardinality(),
-        value2.content, value2.getCardinality(), answer.content);
+    answer.cardinality =
+        Util.unsignedIntersect2by2(
+            value1.content,
+            value1.getCardinality(),
+            value2.content,
+            value2.getCardinality(),
+            answer.content);
     return answer;
   }
 
@@ -203,8 +206,8 @@ public Container and(RunContainer x) {
 
   @Override
   public int andCardinality(final ArrayContainer value2) {
-    return Util.unsignedLocalIntersect2by2Cardinality(content, cardinality, value2.content,
-        value2.getCardinality());
+    return Util.unsignedLocalIntersect2by2Cardinality(
+        content, cardinality, value2.content, value2.getCardinality());
   }
 
   @Override
@@ -223,8 +226,13 @@ public ArrayContainer andNot(final ArrayContainer value2) {
     ArrayContainer value1 = this;
     final int desiredCapacity = value1.getCardinality();
     ArrayContainer answer = new ArrayContainer(desiredCapacity);
-    answer.cardinality = Util.unsignedDifference(value1.content, value1.getCardinality(),
-        value2.content, value2.getCardinality(), answer.content);
+    answer.cardinality =
+        Util.unsignedDifference(
+            value1.content,
+            value1.getCardinality(),
+            value2.content,
+            value2.getCardinality(),
+            answer.content);
     return answer;
   }
 
@@ -298,16 +306,15 @@ public boolean contains(final char x) {
   @Override
   public boolean contains(int minimum, int supremum) {
     int maximum = supremum - 1;
-    int start = Util.advanceUntil(content, -1, cardinality, (char)minimum);
-    int end = Util.advanceUntil(content, start - 1, cardinality, (char)maximum);
+    int start = Util.advanceUntil(content, -1, cardinality, (char) minimum);
+    int end = Util.advanceUntil(content, start - 1, cardinality, (char) maximum);
     return start < cardinality
-            && end < cardinality
-            && end - start == maximum - minimum
-            && content[start] == (char)minimum
-            && content[end] == (char)maximum;
+        && end < cardinality
+        && end - start == maximum - minimum
+        && content[start] == (char) minimum
+        && content[end] == (char) maximum;
   }
 
-
   @Override
   protected boolean contains(RunContainer runContainer) {
     if (runContainer.getCardinality() > cardinality) {
@@ -330,11 +337,11 @@ protected boolean contains(ArrayContainer arrayContainer) {
       return false;
     }
     int i1 = 0, i2 = 0;
-    while(i1 < cardinality && i2 < arrayContainer.cardinality) {
-      if(content[i1] == arrayContainer.content[i2]) {
+    while (i1 < cardinality && i2 < arrayContainer.cardinality) {
+      if (content[i1] == arrayContainer.content[i2]) {
         ++i1;
         ++i2;
-      } else if(content[i1] < arrayContainer.content[i2]) {
+      } else if (content[i1] < arrayContainer.content[i2]) {
         ++i1;
       } else {
         return false;
@@ -367,7 +374,6 @@ private void emit(char val) {
     content[cardinality++] = val;
   }
 
-
   @Override
   public boolean equals(Object o) {
     if (o instanceof ArrayContainer) {
@@ -384,7 +390,6 @@ public void fillLeastSignificant16bits(int[] x, int i, int mask) {
     for (int k = 0; k < this.cardinality; ++k) {
       x[k + i] = (this.content[k]) | mask;
     }
-
   }
 
   @Override
@@ -445,7 +450,6 @@ public ContainerBatchIterator getBatchIterator() {
     return new ArrayBatchIterator(this);
   }
 
-
   @Override
   public int getSizeInBytes() {
     return this.cardinality * 2 + 4;
@@ -463,7 +467,7 @@ public int hashCode() {
   @Override
   public Container iadd(int begin, int end) {
     // TODO: may need to convert to a RunContainer
-    if(end == begin) {
+    if (end == begin) {
       return this;
     }
     if ((begin > end) || (end > (1 << 16))) {
@@ -519,12 +523,12 @@ public Container iadd(int begin, int end) {
        * so far cases - 1,2 and 6 are done Now, if e < cardinality, we copy from e to
        * cardinality.Otherwise do noting this covers remaining 3,4 and 5 cases
        */
-      System.arraycopy(content, indexend, destination, indexstart + rangelength, cardinality
-          - indexend);
+      System.arraycopy(
+          content, indexend, destination, indexstart + rangelength, cardinality - indexend);
       this.content = destination;
     } else {
-      System
-          .arraycopy(content, indexend, content, indexstart + rangelength, cardinality - indexend);
+      System.arraycopy(
+          content, indexend, content, indexstart + rangelength, cardinality - indexend);
       for (int k = 0; k < rangelength; ++k) {
         content[k + indexstart] = (char) (begin + k);
       }
@@ -533,12 +537,16 @@ public Container iadd(int begin, int end) {
     return this;
   }
 
-
   @Override
   public ArrayContainer iand(final ArrayContainer value2) {
     ArrayContainer value1 = this;
-    value1.cardinality = Util.unsignedIntersect2by2(value1.content, value1.getCardinality(),
-        value2.content, value2.getCardinality(), value1.content);
+    value1.cardinality =
+        Util.unsignedIntersect2by2(
+            value1.content,
+            value1.getCardinality(),
+            value2.content,
+            value2.getCardinality(),
+            value1.content);
     return this;
   }
 
@@ -548,7 +556,7 @@ public Container iand(BitmapContainer value2) {
     for (int k = 0; k < cardinality; ++k) {
       char v = this.content[k];
       this.content[pos] = v;
-      pos += (int)value2.bitValue(v);
+      pos += (int) value2.bitValue(v);
     }
     cardinality = pos;
     return this;
@@ -570,11 +578,15 @@ public Container iand(RunContainer x) {
     return this;
   }
 
-
   @Override
   public ArrayContainer iandNot(final ArrayContainer value2) {
-    this.cardinality = Util.unsignedDifference(this.content, this.getCardinality(), value2.content,
-        value2.getCardinality(), this.content);
+    this.cardinality =
+        Util.unsignedDifference(
+            this.content,
+            this.getCardinality(),
+            value2.content,
+            value2.getCardinality(),
+            this.content);
     return this;
   }
 
@@ -584,7 +596,7 @@ public ArrayContainer iandNot(BitmapContainer value2) {
     for (int k = 0; k < cardinality; ++k) {
       char v = this.content[k];
       this.content[pos] = v;
-      pos += 1 - (int)value2.bitValue(v);
+      pos += 1 - (int) value2.bitValue(v);
     }
     this.cardinality = pos;
     return this;
@@ -610,7 +622,6 @@ private void increaseCapacity() {
     increaseCapacity(false);
   }
 
-
   // temporarily allow an illegally large size, as long as the operation creating
   // the illegal container does not return it.
   private void increaseCapacity(boolean allowIllegalSize) {
@@ -626,12 +637,15 @@ private void increaseCapacity(boolean allowIllegalSize) {
     }
     this.content = Arrays.copyOf(this.content, newCapacity);
   }
+
   private int computeCapacity(int oldCapacity) {
-    return oldCapacity == 0 ? DEFAULT_INIT_SIZE
-        : oldCapacity < 64 ? oldCapacity * 2
-        : oldCapacity < 1024 ? oldCapacity * 3 / 2
-        : oldCapacity * 5 / 4;
+    return oldCapacity == 0
+        ? DEFAULT_INIT_SIZE
+        : oldCapacity < 64
+            ? oldCapacity * 2
+            : oldCapacity < 1024 ? oldCapacity * 3 / 2 : oldCapacity * 5 / 4;
   }
+
   private int calculateCapacity(int min) {
     int newCapacity = computeCapacity(this.content.length);
     if (newCapacity < min) {
@@ -656,8 +670,8 @@ public Container inot(final int firstOfRange, final int lastOfRange) {
     if (startIndex < 0) {
       startIndex = -startIndex - 1;
     }
-    int lastIndex = Util.unsignedBinarySearch(content, startIndex, cardinality,
-        (char) (lastOfRange - 1));
+    int lastIndex =
+        Util.unsignedBinarySearch(content, startIndex, cardinality, (char) (lastOfRange - 1));
     if (lastIndex < 0) {
       lastIndex = -lastIndex - 1 - 1;
     }
@@ -677,7 +691,11 @@ public Container inot(final int firstOfRange, final int lastOfRange) {
         content = Arrays.copyOf(content, newCardinality);
       }
       // slide right the contents after the range
-      System.arraycopy(content, lastIndex + 1, content, lastIndex + 1 + cardinalityChange,
+      System.arraycopy(
+          content,
+          lastIndex + 1,
+          content,
+          lastIndex + 1 + cardinalityChange,
           cardinality - 1 - lastIndex);
       negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange);
     } else { // no expansion needed
@@ -685,8 +703,12 @@ public Container inot(final int firstOfRange, final int lastOfRange) {
       if (cardinalityChange < 0) {
         // contraction, left sliding.
         // Leave array oversize
-        System.arraycopy(content, startIndex + newValuesInRange - cardinalityChange, content,
-            startIndex + newValuesInRange, newCardinality - (startIndex + newValuesInRange));
+        System.arraycopy(
+            content,
+            startIndex + newValuesInRange - cardinalityChange,
+            content,
+            startIndex + newValuesInRange,
+            newCardinality - (startIndex + newValuesInRange));
       }
     }
     cardinality = newCardinality;
@@ -696,11 +718,10 @@ public Container inot(final int firstOfRange, final int lastOfRange) {
   @Override
   public boolean intersects(ArrayContainer value2) {
     ArrayContainer value1 = this;
-    return Util.unsignedIntersects(value1.content, value1.getCardinality(), value2.content,
-        value2.getCardinality());
+    return Util.unsignedIntersects(
+        value1.content, value1.getCardinality(), value2.content, value2.getCardinality());
   }
 
-
   @Override
   public boolean intersects(BitmapContainer x) {
     return x.intersects(this);
@@ -713,15 +734,14 @@ public boolean intersects(RunContainer x) {
 
   @Override
   public boolean intersects(int minimum, int supremum) {
-    if((minimum < 0) || (supremum < minimum) || (supremum > (1<<16))) {
+    if ((minimum < 0) || (supremum < minimum) || (supremum > (1 << 16))) {
       throw new RuntimeException("This should never happen (bug).");
     }
-    int pos = Util.unsignedBinarySearch(content, 0, cardinality, (char)minimum);
+    int pos = Util.unsignedBinarySearch(content, 0, cardinality, (char) minimum);
     int index = pos >= 0 ? pos : -pos - 1;
     return index < cardinality && (content[index]) < supremum;
   }
 
-
   @Override
   public Container ior(final ArrayContainer value2) {
     int totalCardinality = this.getCardinality() + value2.getCardinality();
@@ -732,14 +752,20 @@ public Container ior(final ArrayContainer value2) {
       int newCapacity = calculateCapacity(totalCardinality);
       char[] destination = new char[newCapacity];
       cardinality =
-          Util.unsignedUnion2by2(content, 0, cardinality, value2.content, 0, value2.cardinality,
-              destination);
+          Util.unsignedUnion2by2(
+              content, 0, cardinality, value2.content, 0, value2.cardinality, destination);
       this.content = destination;
     } else {
       System.arraycopy(content, 0, content, value2.cardinality, cardinality);
       cardinality =
-          Util.unsignedUnion2by2(content, value2.cardinality, cardinality, value2.content, 0,
-              value2.cardinality, content);
+          Util.unsignedUnion2by2(
+              content,
+              value2.cardinality,
+              cardinality,
+              value2.content,
+              0,
+              value2.cardinality,
+              content);
     }
     return this;
   }
@@ -757,7 +783,7 @@ public Container ior(RunContainer x) {
 
   @Override
   public Container iremove(int begin, int end) {
-    if(end == begin) {
+    if (end == begin) {
       return this;
     }
     if ((begin > end) || (end > (1 << 16))) {
@@ -774,7 +800,11 @@ public Container iremove(int begin, int end) {
       indexend++;
     }
     int rangelength = indexend - indexstart;
-    System.arraycopy(content, indexstart + rangelength, content, indexstart,
+    System.arraycopy(
+        content,
+        indexstart + rangelength,
+        content,
+        indexstart,
         cardinality - indexstart - rangelength);
     cardinality -= rangelength;
     return this;
@@ -813,14 +843,12 @@ public Container ixor(BitmapContainer x) {
     return x.xor(this);
   }
 
-
   @Override
   public Container ixor(RunContainer x) {
     // possible performance issue, not taking advantage of possible inplace
     return x.xor(this);
   }
 
-
   @Override
   public Container limit(int maxcardinality) {
     if (maxcardinality < this.getCardinality()) {
@@ -836,8 +864,12 @@ void loadData(final BitmapContainer bitmapContainer) {
   }
 
   // for use in inot range known to be nonempty
-  private void negateRange(final char[] buffer, final int startIndex, final int lastIndex,
-      final int startRange, final int lastRange) {
+  private void negateRange(
+      final char[] buffer,
+      final int startIndex,
+      final int lastIndex,
+      final int startRange,
+      final int lastRange) {
     // compute the negation into buffer
 
     int outPos = 0;
@@ -884,8 +916,8 @@ public Container not(final int firstOfRange, final int lastOfRange) {
     if (startIndex < 0) {
       startIndex = -startIndex - 1;
     }
-    int lastIndex = Util.unsignedBinarySearch(content, startIndex, cardinality,
-        (char) (lastOfRange - 1));
+    int lastIndex =
+        Util.unsignedBinarySearch(content, startIndex, cardinality, (char) (lastOfRange - 1));
     if (lastIndex < 0) {
       lastIndex = -lastIndex - 2;
     }
@@ -954,11 +986,14 @@ public Container or(final ArrayContainer value2) {
     }
     ArrayContainer answer = new ArrayContainer(totalCardinality);
     answer.cardinality =
-            Util.unsignedUnion2by2(
-                    value1.content, 0, value1.getCardinality(),
-                    value2.content, 0, value2.getCardinality(),
-                    answer.content
-            );
+        Util.unsignedUnion2by2(
+            value1.content,
+            0,
+            value1.getCardinality(),
+            value2.content,
+            0,
+            value2.getCardinality(),
+            answer.content);
     return answer;
   }
 
@@ -1037,7 +1072,7 @@ public void readExternal(ObjectInput in) throws IOException {
 
   @Override
   public Container remove(int begin, int end) {
-    if(end == begin) {
+    if (end == begin) {
       return clone();
     }
     if ((begin > end) || (end > (1 << 16))) {
@@ -1055,7 +1090,11 @@ public Container remove(int begin, int end) {
     }
     int rangelength = indexend - indexstart;
     ArrayContainer answer = clone();
-    System.arraycopy(content, indexstart + rangelength, answer.content, indexstart,
+    System.arraycopy(
+        content,
+        indexstart + rangelength,
+        answer.content,
+        indexstart,
         cardinality - indexstart - rangelength);
     answer.cardinality = cardinality - rangelength;
     return answer;
@@ -1066,7 +1105,6 @@ void removeAtIndex(final int loc) {
     --cardinality;
   }
 
-
   @Override
   public Container remove(final char x) {
     final int loc = Util.unsignedBinarySearch(content, 0, cardinality, x);
@@ -1091,8 +1129,8 @@ public Container runOptimize() {
     int sizeAsRunContainer = RunContainer.serializedSizeInBytes(numRuns);
     if (getArraySizeInBytes() > sizeAsRunContainer) {
       return new RunContainer(this, numRuns); // this could be maybe
-                                              // faster if initial
-                                              // container is a bitmap
+      // faster if initial
+      // container is a bitmap
     } else {
       return this;
     }
@@ -1133,7 +1171,7 @@ public BitmapContainer toBitmapContainer() {
   public void copyBitmapTo(long[] dest, int position) {
     for (int k = 0; k < cardinality; ++k) {
       final char x = content[k];
-      dest[position + x/64] |= 1L << x;
+      dest[position + x / 64] |= 1L << x;
     }
   }
 
@@ -1268,10 +1306,10 @@ public String toString() {
     StringBuilder sb = new StringBuilder("{}".length() + "-123456789,".length() * cardinality);
     sb.append('{');
     for (int i = 0; i < this.cardinality - 1; i++) {
-      sb.append((int)(this.content[i]));
+      sb.append((int) (this.content[i]));
       sb.append(',');
     }
-    sb.append((int)(this.content[this.cardinality - 1]));
+    sb.append((int) (this.content[this.cardinality - 1]));
     sb.append('}');
     return sb.toString();
   }
@@ -1315,8 +1353,13 @@ public Container xor(final ArrayContainer value2) {
       return toBitmapContainer().ixor(value2);
     }
     ArrayContainer answer = new ArrayContainer(totalCardinality);
-    answer.cardinality = Util.unsignedExclusiveUnion2by2(value1.content, value1.getCardinality(),
-        value2.content, value2.getCardinality(), answer.content);
+    answer.cardinality =
+        Util.unsignedExclusiveUnion2by2(
+            value1.content,
+            value1.getCardinality(),
+            value2.content,
+            value2.getCardinality(),
+            answer.content);
     return answer;
   }
 
@@ -1330,7 +1373,6 @@ public Container xor(RunContainer x) {
     return x.xor(this);
   }
 
-
   protected Container xor(CharIterator it) {
     return or(it, true);
   }
@@ -1338,7 +1380,7 @@ protected Container xor(CharIterator it) {
   @Override
   public void forEach(char msb, IntConsumer ic) {
     int high = msb << 16;
-    for(int k = 0; k < cardinality; ++k) {
+    for (int k = 0; k < cardinality; ++k) {
       ic.accept(content[k] | high);
     }
   }
@@ -1346,7 +1388,7 @@ public void forEach(char msb, IntConsumer ic) {
   @Override
   public void forAll(int offset, final RelativeRangeConsumer rrc) {
     int next = 0;
-    for(int k = 0; k < cardinality; ++k) {
+    for (int k = 0; k < cardinality; ++k) {
       int value = content[k];
       if (next < value) {
         // fill in the missing values until value
@@ -1391,7 +1433,7 @@ public void forAllFrom(char startValue, final RelativeRangeConsumer rrc) {
   @Override
   public void forAllUntil(int offset, char endValue, final RelativeRangeConsumer rrc) {
     int next = 0;
-    for(int k = 0; k < cardinality; ++k) {
+    for (int k = 0; k < cardinality; ++k) {
       int value = content[k];
       if (endValue <= value) {
         // value is already beyond the end
@@ -1417,7 +1459,7 @@ public void forAllUntil(int offset, char endValue, final RelativeRangeConsumer r
   public void forAllInRange(char startValue, char endValue, final RelativeRangeConsumer rrc) {
     if (endValue <= startValue) {
       throw new IllegalArgumentException(
-              "startValue (" + startValue + ") must be less than endValue (" + endValue + ")");
+          "startValue (" + startValue + ") must be less than endValue (" + endValue + ")");
     }
     int startOffset = startValue;
     int loc = Util.unsignedBinarySearch(content, 0, cardinality, startValue);
@@ -1454,25 +1496,23 @@ protected Container lazyor(ArrayContainer value2) {
     }
     ArrayContainer answer = new ArrayContainer(totalCardinality);
     answer.cardinality =
-            Util.unsignedUnion2by2(
-                    value1.content, 0, value1.getCardinality(),
-                    value2.content, 0, value2.getCardinality(),
-                    answer.content
-            );
+        Util.unsignedUnion2by2(
+            value1.content,
+            0,
+            value1.getCardinality(),
+            value2.content,
+            0,
+            value2.getCardinality(),
+            answer.content);
     return answer;
-
   }
-
 }
 
-
 final class ArrayContainerCharIterator implements PeekableCharRankIterator {
   int pos;
   private ArrayContainer parent;
 
-  ArrayContainerCharIterator() {
-
-  }
+  ArrayContainerCharIterator() {}
 
   ArrayContainerCharIterator(ArrayContainer p) {
     wrap(p);
@@ -1493,7 +1533,7 @@ public PeekableCharRankIterator clone() {
     try {
       return (PeekableCharRankIterator) super.clone();
     } catch (CloneNotSupportedException e) {
-      return null;// will not happen
+      return null; // will not happen
     }
   }
 
@@ -1517,7 +1557,6 @@ public char peekNext() {
     return parent.content[pos];
   }
 
-
   @Override
   public void remove() {
     parent.removeAtIndex(pos - 1);
@@ -1528,17 +1567,13 @@ void wrap(ArrayContainer p) {
     parent = p;
     pos = 0;
   }
-
 }
 
-
 final class ReverseArrayContainerCharIterator implements PeekableCharIterator {
   int pos;
   private ArrayContainer parent;
 
-  ReverseArrayContainerCharIterator() {
-
-  }
+  ReverseArrayContainerCharIterator() {}
 
   ReverseArrayContainerCharIterator(ArrayContainer p) {
     wrap(p);
@@ -1554,7 +1589,7 @@ public PeekableCharIterator clone() {
     try {
       return (PeekableCharIterator) super.clone();
     } catch (CloneNotSupportedException e) {
-      return null;// will not happen
+      return null; // will not happen
     }
   }
 
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ArraysShim.java b/roaringbitmap/src/main/java/org/roaringbitmap/ArraysShim.java
index e4cdd7c03..aa189615a 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/ArraysShim.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/ArraysShim.java
@@ -43,8 +43,8 @@ public static boolean equals(char[] x, int xmin, int xmax, char[] y, int ymin, i
    * @param bToIndex exclusive
    * @return -1 if no mismatch found,otherwise the mismatch offset
    */
-  public static int mismatch(byte[] a, int aFromIndex, int aToIndex,
-      byte[] b, int bFromIndex, int bToIndex) {
+  public static int mismatch(
+      byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
     int aLength = aToIndex - aFromIndex;
     int bLength = bToIndex - bFromIndex;
     int length = Math.min(aLength, bLength);
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java
index e51ba5ea6..c40897a24 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/BatchIntIterator.java
@@ -45,7 +45,7 @@ public int next() {
   @Override
   public IntIterator clone() {
     try {
-      BatchIntIterator it = (BatchIntIterator)super.clone();
+      BatchIntIterator it = (BatchIntIterator) super.clone();
       it.delegate = delegate.clone();
       it.buffer = buffer.clone();
       return it;
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/BatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/BatchIterator.java
index 07fcf7314..bc2f55f40 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/BatchIterator.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/BatchIterator.java
@@ -69,6 +69,4 @@ default IntIterator asIntIterator(int[] buffer) {
    * @param target threshold
    */
   void advanceIfNeeded(int target);
-
-
 }
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/BitSetUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
index 1681a5ce4..f2ad81ffc 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/BitSetUtil.java
@@ -1,13 +1,11 @@
 package org.roaringbitmap;
 
+import static java.lang.Long.numberOfTrailingZeros;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.BitSet;
 
-import static java.lang.Long.numberOfTrailingZeros;
-
-
 /***
  *
  * This class provides convenience functions to manipulate BitSet and RoaringBitmap objects.
@@ -18,6 +16,7 @@ public class BitSetUtil {
   // a block consists has a maximum of 1024 words, each representing 64 bits,
   // thus representing at maximum 65536 bits
   public static final int BLOCK_LENGTH = BitmapContainer.MAX_CAPACITY / Long.SIZE; //
+
   // 64-bit
   // word
 
@@ -53,8 +52,8 @@ public static BitSet bitsetOfWithoutCopy(RoaringBitmap bitmap) {
    */
   public static byte[] toByteArray(RoaringBitmap bitmap) {
     long[] words = toLongArray(bitmap);
-    ByteBuffer buffer = ByteBuffer.allocate(words.length * Long.SIZE)
-            .order(ByteOrder.LITTLE_ENDIAN);
+    ByteBuffer buffer =
+        ByteBuffer.allocate(words.length * Long.SIZE).order(ByteOrder.LITTLE_ENDIAN);
     buffer.asLongBuffer().put(words);
     return buffer.array();
   }
@@ -89,7 +88,7 @@ public static long[] toLongArray(RoaringBitmap bitmap) {
         int remaining = wordsInUse - position;
         int length = Math.min(BLOCK_LENGTH, remaining);
         if (container instanceof BitmapContainer) {
-          ((BitmapContainer)container).copyBitmapTo(words, position, length);
+          ((BitmapContainer) container).copyBitmapTo(words, position, length);
         } else {
           container.copyBitmapTo(words, position);
         }
@@ -117,8 +116,8 @@ public static long[] toLongArray(RoaringBitmap bitmap) {
    * @param words       bitmap
    * @return array container's content char buffer
    */
-  public static char[] arrayContainerBufferOf(final int from, final int to, final int cardinality,
-                                              final long[] words) {
+  public static char[] arrayContainerBufferOf(
+      final int from, final int to, final int cardinality, final long[] words) {
     return arrayContainerBufferOf(from, to, new char[cardinality], words);
   }
 
@@ -132,8 +131,8 @@ public static char[] arrayContainerBufferOf(final int from, final int to, final
    * @param words       bitmap
    * @return array container's content char buffer - the same as {@code buffer}
    */
-  public static char[] arrayContainerBufferOf(final int from, final int to, final char[] buffer,
-                                              final long[] words) {
+  public static char[] arrayContainerBufferOf(
+      final int from, final int to, final char[] buffer, final long[] words) {
     // precondition: cardinality is max 4096
     int base = 0;
     int pos = 0;
@@ -147,12 +146,12 @@ public static char[] arrayContainerBufferOf(final int from, final int to, final
     }
     return buffer;
   }
-  private static ArrayContainer arrayContainerOf(final int from, final int to,
-                                                 final int cardinality, final long[] words) {
+
+  private static ArrayContainer arrayContainerOf(
+      final int from, final int to, final int cardinality, final long[] words) {
     return new ArrayContainer(arrayContainerBufferOf(from, to, cardinality, words));
   }
 
-
   /**
    * Generate a RoaringBitmap out of a BitSet
    *
@@ -180,7 +179,9 @@ public static RoaringBitmap bitmapOf(final long[] words) {
       final int to = Math.min(from + BLOCK_LENGTH, words.length);
       final int blockCardinality = cardinality(from, to, words);
       if (blockCardinality > 0) {
-        ans.highLowContainer.insertNewKeyValueAt(containerIndex++, Util.highbits(from * Long.SIZE),
+        ans.highLowContainer.insertNewKeyValueAt(
+            containerIndex++,
+            Util.highbits(from * Long.SIZE),
             BitSetUtil.containerOf(from, to, blockCardinality, words));
       }
     }
@@ -237,13 +238,15 @@ public static RoaringBitmap bitmapOf(ByteBuffer bb, boolean fastRank, long[] wor
       if (blockLength == BLOCK_LENGTH) {
         // Each block becomes a single container, if any bit is set
         if (blockCardinality > 0) {
-          ans.highLowContainer.insertNewKeyValueAt(containerIndex++, Util.highbits(offset),
+          ans.highLowContainer.insertNewKeyValueAt(
+              containerIndex++,
+              Util.highbits(offset),
               BitSetUtil.containerOf(0, blockLength, blockCardinality, wordsBuffer));
         }
         /*
-            Offset can overflow when bitsets size is more than Integer.MAX_VALUE - 64
-            It's harmless though, as it will happen after the last block is added
-         */
+           Offset can overflow when bitsets size is more than Integer.MAX_VALUE - 64
+           It's harmless though, as it will happen after the last block is added
+        */
         offset += (BLOCK_LENGTH * Long.SIZE);
         blockLength = blockCardinality = 0;
       }
@@ -266,7 +269,9 @@ public static RoaringBitmap bitmapOf(ByteBuffer bb, boolean fastRank, long[] wor
 
     // Add block to map, if any bit is set
     if (blockCardinality > 0) {
-      ans.highLowContainer.insertNewKeyValueAt(containerIndex, Util.highbits(offset),
+      ans.highLowContainer.insertNewKeyValueAt(
+          containerIndex,
+          Util.highbits(offset),
           BitSetUtil.containerOf(0, blockLength, blockCardinality, wordsBuffer));
     }
     return ans;
@@ -280,9 +285,8 @@ private static int cardinality(final int from, final int to, final long[] words)
     return sum;
   }
 
-
-  private static Container containerOf(final int from, final int to, final int blockCardinality,
-      final long[] words) {
+  private static Container containerOf(
+      final int from, final int to, final int blockCardinality, final long[] words) {
     // find the best container available
     if (blockCardinality <= ArrayContainer.DEFAULT_MAX_SIZE) {
       // containers with DEFAULT_MAX_SIZE or less integers should be
@@ -296,7 +300,6 @@ private static Container containerOf(final int from, final int to, final int blo
     }
   }
 
-
   /**
    * Compares a RoaringBitmap and a BitSet. They are equal if and only if they contain the same set
    * of integers.
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
index 59f6a3433..c9b754d13 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapBatchIterator.java
@@ -47,7 +47,7 @@ public boolean hasNext() {
   @Override
   public ContainerBatchIterator clone() {
     try {
-      return (ContainerBatchIterator)super.clone();
+      return (ContainerBatchIterator) super.clone();
     } catch (CloneNotSupportedException e) {
       // won't happen
       throw new IllegalStateException(e);
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
index 297504576..80298a303 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
@@ -4,20 +4,23 @@
 
 package org.roaringbitmap;
 
+import static java.lang.Long.bitCount;
+import static java.lang.Long.numberOfTrailingZeros;
+
 import org.roaringbitmap.buffer.MappeableBitmapContainer;
 import org.roaringbitmap.buffer.MappeableContainer;
 
-import java.io.*;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.LongBuffer;
 import java.util.Arrays;
 import java.util.Iterator;
 
-import static java.lang.Long.bitCount;
-import static java.lang.Long.numberOfTrailingZeros;
-
-
 /**
  * Simple bitset-like container.
  */
@@ -33,6 +36,7 @@ public final class BitmapContainer extends Container implements Cloneable {
   // bail out early when the number of runs is excessive, without
   // an exact count (just a decent lower bound)
   private static final int BLOCKSIZE = 128;
+
   // 64 words can have max 32 runs per word, max 2k runs
 
   /**
@@ -74,7 +78,6 @@ protected static int serializedSizeInBytes(int unusedCardinality) {
   // BitmapContainer.getArraySizeInBytes()
   private static final int MAXRUNS = (MAX_CAPACITY_BYTE - 2) / 4;
 
-
   /**
    * Create a bitmap container with all bits set to false
    */
@@ -83,8 +86,6 @@ public BitmapContainer() {
     this.bitmap = new long[MAX_CAPACITY_LONG];
   }
 
-
-
   /**
    * Create a bitmap container with a run of ones from firstOfRun to lastOfRun. Caller must ensure
    * that the range isn't so small that an ArrayContainer should have been created instead
@@ -114,8 +115,6 @@ public BitmapContainer(long[] newBitmap, int newCardinality) {
     this.bitmap = newBitmap;
   }
 
-
-
   /**
    * Creates a new non-mappeable container from a mappeable one. This copies the data.
    *
@@ -126,7 +125,6 @@ public BitmapContainer(MappeableBitmapContainer bc) {
     this.bitmap = bc.toLongArray();
   }
 
-
   @Override
   public Container add(int begin, int end) {
     // TODO: may need to convert to a RunContainer
@@ -143,15 +141,13 @@ public Container add(int begin, int end) {
     return answer;
   }
 
-
-
   @Override
   public Container add(final char i) {
     final long previous = bitmap[i >>> 6];
     long newval = previous | (1L << i);
     bitmap[i >>> 6] = newval;
     if (USE_BRANCHLESS) {
-      cardinality += (int)((previous ^ newval) >>> i);
+      cardinality += (int) ((previous ^ newval) >>> i);
     } else if (previous != newval) {
       ++cardinality;
     }
@@ -165,7 +161,7 @@ public ArrayContainer and(final ArrayContainer value2) {
     for (int k = 0; k < c; ++k) {
       char v = value2.content[k];
       answer.content[answer.cardinality] = v;
-      answer.cardinality += (int)this.bitValue(v);
+      answer.cardinality += (int) this.bitValue(v);
     }
     return answer;
   }
@@ -198,7 +194,7 @@ public int andCardinality(final ArrayContainer value2) {
     int c = value2.cardinality;
     for (int k = 0; k < c; ++k) {
       char v = value2.content[k];
-      answer += (int)this.bitValue(v);
+      answer += (int) this.bitValue(v);
     }
     return answer;
   }
@@ -345,13 +341,13 @@ public boolean contains(int minimum, int supremum) {
 
   @Override
   protected boolean contains(BitmapContainer bitmapContainer) {
-    if((cardinality != -1) && (bitmapContainer.cardinality != -1)) {
-      if(cardinality < bitmapContainer.cardinality) {
+    if ((cardinality != -1) && (bitmapContainer.cardinality != -1)) {
+      if (cardinality < bitmapContainer.cardinality) {
         return false;
       }
     }
-    for(int i = 0; i < bitmapContainer.bitmap.length; ++i ) {
-      if((this.bitmap[i] & bitmapContainer.bitmap[i]) != bitmapContainer.bitmap[i]) {
+    for (int i = 0; i < bitmapContainer.bitmap.length; ++i) {
+      if ((this.bitmap[i] & bitmapContainer.bitmap[i]) != bitmapContainer.bitmap[i]) {
         return false;
       }
     }
@@ -389,19 +385,17 @@ protected boolean contains(ArrayContainer arrayContainer) {
       }
     }
     for (int i = 0; i < arrayContainer.cardinality; ++i) {
-      if(!contains(arrayContainer.content[i])) {
+      if (!contains(arrayContainer.content[i])) {
         return false;
       }
     }
     return true;
   }
 
-
   int bitValue(final char i) {
-    return (int)(bitmap[i >>> 6] >>> i ) & 1;
+    return (int) (bitmap[i >>> 6] >>> i) & 1;
   }
 
-
   @Override
   public void deserialize(DataInput in) throws IOException {
     // little endian
@@ -427,7 +421,6 @@ public boolean equals(Object o) {
     return false;
   }
 
-
   /**
    * Fill the array with set bits
    *
@@ -451,13 +444,12 @@ public void fillLeastSignificant16bits(int[] x, int i, int mask) {
     }
   }
 
-
   @Override
   public Container flip(char i) {
     int index = i >>> 6;
     long bef = bitmap[index];
     long mask = 1L << i;
-    if (cardinality == ArrayContainer.DEFAULT_MAX_SIZE + 1) {// this is
+    if (cardinality == ArrayContainer.DEFAULT_MAX_SIZE + 1) { // this is
       // the
       // uncommon
       // path
@@ -468,7 +460,7 @@ public Container flip(char i) {
       }
     }
     // TODO: check whether a branchy version could be faster
-    cardinality += 1 - 2 * (int)((bef & mask) >>> i);
+    cardinality += 1 - 2 * (int) ((bef & mask) >>> i);
     bitmap[index] ^= mask;
     return this;
   }
@@ -576,7 +568,7 @@ public Container iand(RunContainer x) {
         int runEnd = runStart + (x.getLength(rlepos));
         for (int runValue = runStart; runValue <= runEnd; ++runValue) {
           answer.content[answer.cardinality] = (char) runValue;
-          answer.cardinality += (int)this.bitValue((char) runValue);
+          answer.cardinality += (int) this.bitValue((char) runValue);
         }
       }
       return answer;
@@ -655,7 +647,7 @@ public Container iandNot(RunContainer x) {
   }
 
   Container ilazyor(ArrayContainer value2) {
-    this.cardinality = -1;// invalid
+    this.cardinality = -1; // invalid
     int c = value2.cardinality;
     for (int k = 0; k < c; ++k) {
       char v = value2.content[k];
@@ -666,7 +658,7 @@ Container ilazyor(ArrayContainer value2) {
   }
 
   Container ilazyor(BitmapContainer x) {
-    this.cardinality = -1;// invalid
+    this.cardinality = -1; // invalid
     for (int k = 0; k < this.bitmap.length; k++) {
       this.bitmap[k] |= x.bitmap[k];
     }
@@ -723,7 +715,7 @@ public boolean intersects(RunContainer x) {
 
   @Override
   public boolean intersects(int minimum, int supremum) {
-    if((minimum < 0) || (supremum < minimum) || (supremum > (1<<16))) {
+    if ((minimum < 0) || (supremum < minimum) || (supremum > (1 << 16))) {
       throw new RuntimeException("This should never happen (bug).");
     }
     int start = minimum >>> 6;
@@ -755,7 +747,7 @@ public BitmapContainer ior(final ArrayContainer value2) {
       long aft = bef | (1L << value2.content[k]);
       this.bitmap[i] = aft;
       if (USE_BRANCHLESS) {
-        cardinality += (int)((bef - aft) >>> 63);
+        cardinality += (int) ((bef - aft) >>> 63);
       } else {
         if (bef != aft) {
           cardinality++;
@@ -842,7 +834,7 @@ public Container ixor(final ArrayContainer value2) {
       final int index = (vc) >>> 6;
       long ba = this.bitmap[index];
       // TODO: check whether a branchy version could be faster
-      this.cardinality += 1 - 2 * (int)((ba & mask) >>> vc);
+      this.cardinality += 1 - 2 * (int) ((ba & mask) >>> vc);
       this.bitmap[index] = ba ^ mask;
     }
     if (this.cardinality <= ArrayContainer.DEFAULT_MAX_SIZE) {
@@ -851,7 +843,6 @@ public Container ixor(final ArrayContainer value2) {
     return this;
   }
 
-
   @Override
   public Container ixor(BitmapContainer b2) {
     // do this first because we have to compute the xor no matter what, and this loop gets
@@ -886,7 +877,7 @@ public Container ixor(RunContainer x) {
 
   protected Container lazyor(ArrayContainer value2) {
     BitmapContainer answer = this.clone();
-    answer.cardinality = -1;// invalid
+    answer.cardinality = -1; // invalid
     int c = value2.cardinality;
     for (int k = 0; k < c; ++k) {
       char v = value2.content[k];
@@ -898,14 +889,13 @@ protected Container lazyor(ArrayContainer value2) {
 
   protected Container lazyor(BitmapContainer x) {
     BitmapContainer answer = new BitmapContainer();
-    answer.cardinality = -1;// invalid
+    answer.cardinality = -1; // invalid
     for (int k = 0; k < this.bitmap.length; k++) {
       answer.bitmap[k] = this.bitmap[k] | x.bitmap[k];
     }
     return answer;
   }
 
-
   protected Container lazyor(RunContainer x) {
     BitmapContainer bc = clone();
     bc.cardinality = -1; // invalid
@@ -998,7 +988,6 @@ private int nextClearBit(final int i) {
     return MAX_CAPACITY;
   }
 
-
   @Override
   public Container not(final int firstOfRange, final int lastOfRange) {
     BitmapContainer answer = clone();
@@ -1013,7 +1002,7 @@ int numberOfRuns() {
     for (int i = 0; i < bitmap.length - 1; i++) {
       long word = nextWord;
       nextWord = bitmap[i + 1];
-      numRuns += Long.bitCount((~word) & (word << 1)) + (int)((word >>> 63) & ~nextWord);
+      numRuns += Long.bitCount((~word) & (word << 1)) + (int) ((word >>> 63) & ~nextWord);
     }
 
     long word = nextWord;
@@ -1037,7 +1026,7 @@ public int numberOfRunsAdjustment() {
       final long word = nextWord;
 
       nextWord = bitmap[i + 1];
-      ans += (int)((word >>> 63) & ~nextWord);
+      ans += (int) ((word >>> 63) & ~nextWord);
     }
     final long word = nextWord;
 
@@ -1080,7 +1069,7 @@ public Container or(final ArrayContainer value2) {
       long aft = w | (1L << v);
       answer.bitmap[i] = aft;
       if (USE_BRANCHLESS) {
-        answer.cardinality += (int)((w - aft) >>> 63);
+        answer.cardinality += (int) ((w - aft) >>> 63);
       } else {
         if (w != aft) {
           answer.cardinality++;
@@ -1170,7 +1159,6 @@ public void readExternal(ObjectInput in) throws IOException {
     deserialize(in);
   }
 
-
   @Override
   public Container remove(int begin, int end) {
     if (end == begin) {
@@ -1194,7 +1182,7 @@ public Container remove(final char i) {
     int index = i >>> 6;
     long bef = bitmap[index];
     long mask = 1L << i;
-    if (cardinality == ArrayContainer.DEFAULT_MAX_SIZE + 1) {// this is
+    if (cardinality == ArrayContainer.DEFAULT_MAX_SIZE + 1) { // this is
       // the
       // uncommon
       // path
@@ -1214,7 +1202,7 @@ public Container remove(final char i) {
   public Container repairAfterLazy() {
     if (getCardinality() < 0) {
       computeCardinality();
-      if(getCardinality() <= ArrayContainer.DEFAULT_MAX_SIZE) {
+      if (getCardinality() <= ArrayContainer.DEFAULT_MAX_SIZE) {
         return this.toArrayContainer();
       } else if (isFull()) {
         return RunContainer.full();
@@ -1247,8 +1235,8 @@ public Container runOptimize() {
 
   @Override
   public char select(int j) {
-    if (//cardinality != -1 && // omitted as (-1>>>1) > j as j < (1<<16)
-        cardinality >>> 1 < j && j < cardinality) {
+    if ( // cardinality != -1 && // omitted as (-1>>>1) > j as j < (1<<16)
+    cardinality >>> 1 < j && j < cardinality) {
       int leftover = cardinality - j;
       for (int k = bitmap.length - 1; k >= 0; --k) {
         long w = bitmap[k];
@@ -1292,6 +1280,7 @@ public char selectOneSide(int j) {
     }
     throw new IllegalArgumentException("Insufficient cardinality.");
   }
+
   @Override
   public void serialize(DataOutput out) throws IOException {
     // little endian
@@ -1344,7 +1333,7 @@ public String toString() {
     final CharIterator i = this.getCharIterator();
     sb.append('{');
     while (i.hasNext()) {
-      sb.append((int)(i.next()));
+      sb.append((int) (i.next()));
       if (i.hasNext()) {
         sb.append(',');
       }
@@ -1354,9 +1343,7 @@ public String toString() {
   }
 
   @Override
-  public void trim() {
-
-  }
+  public void trim() {}
 
   @Override
   public void writeArray(DataOutput out) throws IOException {
@@ -1387,7 +1374,7 @@ public Container xor(final ArrayContainer value2) {
       final long mask = 1L << vc;
       final long val = answer.bitmap[index];
       // TODO: check whether a branchy version could be faster
-      answer.cardinality += (int)(1 - 2 * ((val & mask) >>> vc));
+      answer.cardinality += (int) (1 - 2 * ((val & mask) >>> vc));
       answer.bitmap[index] = val ^ mask;
     }
     if (answer.cardinality <= ArrayContainer.DEFAULT_MAX_SIZE) {
@@ -1636,19 +1623,13 @@ public void forAllInRange(char startValue, char endValue, final RelativeRangeCon
         return;
       } else {
         addWholeWordToRangeConsumer(
-            word,
-            wordStart - startValue,
-            wordEndExclusive - startValue,
-            rrc);
+            word, wordStart - startValue, wordEndExclusive - startValue, rrc);
       }
     }
   }
 
   private void addWholeWordToRangeConsumer(
-          long word,
-          int bufferWordStart,
-          int bufferWordEnd,
-          final RelativeRangeConsumer rrc) {
+      long word, int bufferWordStart, int bufferWordEnd, final RelativeRangeConsumer rrc) {
     // some special cases for efficiency
     if (word == 0) {
       rrc.acceptAllAbsent(bufferWordStart, bufferWordEnd);
@@ -1710,7 +1691,7 @@ public int previousAbsentValue(char fromValue) {
   public int first() {
     assertNonEmpty(cardinality == 0);
     int i = 0;
-    while(i < bitmap.length - 1 && bitmap[i] == 0) {
+    while (i < bitmap.length - 1 && bitmap[i] == 0) {
       ++i; // seek forward
     }
     // sizeof(long) * #empty words at start + number of bits preceding the first bit set
@@ -1721,7 +1702,7 @@ public int first() {
   public int last() {
     assertNonEmpty(cardinality == 0);
     int i = bitmap.length - 1;
-    while(i > 0 && bitmap[i] == 0) {
+    while (i > 0 && bitmap[i] == 0) {
       --i; // seek backward
     }
     // sizeof(long) * #words from start - number of bits after the last bit set
@@ -1729,7 +1710,6 @@ public int last() {
   }
 }
 
-
 class BitmapContainerCharIterator implements PeekableCharIterator {
 
   long w;
@@ -1737,9 +1717,7 @@ class BitmapContainerCharIterator implements PeekableCharIterator {
 
   long[] bitmap;
 
-  BitmapContainerCharIterator() {
-
-  }
+  BitmapContainerCharIterator() {}
 
   BitmapContainerCharIterator(long[] p) {
     wrap(p);
@@ -1750,7 +1728,7 @@ public PeekableCharIterator clone() {
     try {
       return (PeekableCharIterator) super.clone();
     } catch (CloneNotSupportedException e) {
-      return null;// will not happen
+      return null; // will not happen
     }
   }
 
@@ -1773,8 +1751,6 @@ public char next() {
     return answer;
   }
 
-
-
   @Override
   public int nextAsInt() {
     return (next());
@@ -1786,7 +1762,6 @@ public void remove() {
     throw new RuntimeException("unsupported operation: remove");
   }
 
-
   public void wrap(long[] b) {
     bitmap = b;
     for (x = 0; x < bitmap.length; ++x) {
@@ -1851,7 +1826,7 @@ public void advanceIfNeeded(char minval) {
       if (minval >= (x + 1) * 64) {
         int nextX = minval / 64;
         nextRank += bitCount(w);
-        for(x = x + 1; x < nextX; x++) {
+        for (x = x + 1; x < nextX; x++) {
           w = bitmap[x];
           nextRank += bitCount(w);
         }
@@ -1883,9 +1858,7 @@ final class ReverseBitmapContainerCharIterator implements PeekableCharIterator {
 
   long[] bitmap;
 
-  ReverseBitmapContainerCharIterator() {
-
-  }
+  ReverseBitmapContainerCharIterator() {}
 
   ReverseBitmapContainerCharIterator(long[] bitmap) {
     wrap(bitmap);
@@ -1908,7 +1881,7 @@ public boolean hasNext() {
   @Override
   public char next() {
     int shift = Long.numberOfLeadingZeros(word) + 1;
-    char answer = (char)((position + 1) * 64 - shift);
+    char answer = (char) ((position + 1) * 64 - shift);
     word &= (0xFFFFFFFFFFFFFFFEL >>> shift);
     while (word == 0) {
       --position;
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/CharIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/CharIterator.java
index 0dec02894..ed52cc7e8 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/CharIterator.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/CharIterator.java
@@ -20,7 +20,6 @@ public interface CharIterator extends Cloneable {
    */
   boolean hasNext();
 
-
   /**
    * @return next char value
    */
@@ -35,5 +34,4 @@ public interface CharIterator extends Cloneable {
    * If possible, remove the current value
    */
   void remove();
-
 }
diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java b/roaringbitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java
index a0e2ca1f0..98409dee7 100644
--- a/roaringbitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java
+++ b/roaringbitmap/src/main/java/org/roaringbitmap/ConstantMemoryContainerAppender.java
@@ -1,11 +1,12 @@
 package org.roaringbitmap;
 
+import static org.roaringbitmap.Util.highbits;
+import static org.roaringbitmap.Util.lowbits;
+import static org.roaringbitmap.Util.partialRadixSort;
+
 import java.util.Arrays;
 import java.util.function.Supplier;
 
-import static org.roaringbitmap.Util.*;
-
-
 /**
  * This class can be used to write quickly values to a bitmap.
  * The values are expected to be (increasing) sorted order.
@@ -31,8 +32,9 @@
  * }
  * 
*/ -public class ConstantMemoryContainerAppender> implements RoaringBitmapWriter { +public class ConstantMemoryContainerAppender< + T extends BitmapDataProvider & AppendableStorage> + implements RoaringBitmapWriter { private final boolean doPartialSort; private final boolean runCompress; @@ -50,9 +52,8 @@ public class ConstantMemoryContainerAppender newUnderlying) { + ConstantMemoryContainerAppender( + boolean doPartialSort, boolean runCompress, Supplier newUnderlying) { this.newUnderlying = newUnderlying; this.underlying = newUnderlying.get(); this.doPartialSort = doPartialSort; @@ -108,7 +109,7 @@ public void addMany(int... values) { public void add(long min, long max) { appendToUnderlying(); underlying.add(min, max); - int mark = (int)((max >>> 16) + 1); + int mark = (int) ((max >>> 16) + 1); if (currentKey < mark) { currentKey = mark; } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/Container.java b/roaringbitmap/src/main/java/org/roaringbitmap/Container.java index 648d3c552..788a3cd42 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/Container.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/Container.java @@ -16,8 +16,8 @@ /** * Base container class. */ -public abstract class Container implements Iterable, Cloneable, Externalizable, - WordStorage { +public abstract class Container + implements Iterable, Cloneable, Externalizable, WordStorage { /** * Create a container initialized with a range of consecutive values @@ -87,7 +87,6 @@ public Container and(Container x) { return and((RunContainer) x); } - /** * Computes the bitwise AND of this container with another (intersection). This container as well * as the provided container are left unaffected. @@ -135,7 +134,6 @@ public int xorCardinality(Container other) { return getCardinality() + other.getCardinality() - 2 * andCardinality(other); } - /** * Computes the bitwise ANDNOT of this container with another (difference). This container as well * as the provided container are left unaffected. @@ -170,7 +168,6 @@ public Container andNot(Container x) { return andNot((RunContainer) x); } - /** * Computes the bitwise ANDNOT of this container with another (difference). This container as well * as the provided container are left unaffected. @@ -231,24 +228,22 @@ public Container orNot(Container x, int endOfRange) { */ public abstract boolean contains(int minimum, int supremum); - /** * Checks whether the container is a subset of this container or not * @param subset the container to be tested * @return true if the parameter is a subset of this container */ public boolean contains(Container subset) { - if(subset instanceof RunContainer) { - return contains((RunContainer)subset); - } else if(subset instanceof ArrayContainer) { + if (subset instanceof RunContainer) { + return contains((RunContainer) subset); + } else if (subset instanceof ArrayContainer) { return contains((ArrayContainer) subset); - } else if(subset instanceof BitmapContainer){ - return contains((BitmapContainer)subset); + } else if (subset instanceof BitmapContainer) { + return contains((BitmapContainer) subset); } return false; } - protected abstract boolean contains(RunContainer runContainer); protected abstract boolean contains(ArrayContainer arrayContainer); @@ -263,7 +258,6 @@ public boolean contains(Container subset) { */ public abstract void deserialize(DataInput in) throws IOException; - /** * Fill the least significant 16 bits of the integer array, starting at index i, with the short * values from this container. The caller is responsible to allocate enough room. The most @@ -276,8 +270,6 @@ public boolean contains(Container subset) { */ public abstract void fillLeastSignificant16bits(int[] x, int i, int mask); - - /** * Add a short to the container if it is not present, otherwise remove it. May generate a new * container. @@ -320,8 +312,7 @@ public String getContainerName() { /** * Name of the various possible containers */ - public static final String[] ContainerNames = {"bitmap","array","run"}; - + public static final String[] ContainerNames = {"bitmap", "array", "run"}; /** * Iterate through the values of this container and pass them @@ -365,10 +356,7 @@ public String getContainerName() { * @param endValue First value greater than last value to consume. * @param rrc consumer */ - public abstract void forAllUntil( - int offset, - char endValue, - final RelativeRangeConsumer rrc); + public abstract void forAllUntil(int offset, char endValue, final RelativeRangeConsumer rrc); /** * Consumer presence information for all values in the @@ -379,9 +367,7 @@ public abstract void forAllUntil( * @param rrc consumer */ public abstract void forAllInRange( - char startValue, - char endValue, - final RelativeRangeConsumer rrc); + char startValue, char endValue, final RelativeRangeConsumer rrc); /** * Iterator to visit the char values in the container in descending order. @@ -437,7 +423,6 @@ public abstract void forAllInRange( */ public abstract Container iand(ArrayContainer x); - /** * Computes the in-place bitwise AND of this container with another (intersection). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate @@ -485,7 +470,6 @@ public Container iand(Container x) { */ public abstract Container iandNot(ArrayContainer x); - /** * Computes the in-place bitwise ANDNOT of this container with another (difference). The current * container is generally modified, whereas the provided container (x) is unaffected. May generate @@ -523,7 +507,6 @@ public Container iandNot(Container x) { */ public abstract Container iandNot(RunContainer x); - /** * Computes the in-place bitwise ORNOT of this container with another. The current * container is generally modified, whereas the provided container (x) is unaffected. May generate @@ -540,9 +523,6 @@ public Container iorNot(Container x, int endOfRange) { return ior(x.not(0, 0x10000)); } - - - /** * Computes the in-place bitwise NOT of this container (complement). Only those bits within the * range are affected. The current container is generally modified. May generate a new container. @@ -676,7 +656,6 @@ public Container ior(Container x) { */ public abstract Container ixor(BitmapContainer x); - /** * Computes the in-place bitwise OR of this container with another (union). The current container * is generally modified, whereas the provided container (x) is unaffected. May generate a new @@ -717,7 +696,7 @@ public Container ixor(Container x) { public Container lazyIOR(Container x) { if (this instanceof ArrayContainer) { if (x instanceof ArrayContainer) { - return ((ArrayContainer)this).lazyor((ArrayContainer) x); + return ((ArrayContainer) this).lazyor((ArrayContainer) x); } else if (x instanceof BitmapContainer) { return ior((BitmapContainer) x); } @@ -751,7 +730,7 @@ public Container lazyIOR(Container x) { public Container lazyOR(Container x) { if (this instanceof ArrayContainer) { if (x instanceof ArrayContainer) { - return ((ArrayContainer)this).lazyor((ArrayContainer) x); + return ((ArrayContainer) this).lazyor((ArrayContainer) x); } else if (x instanceof BitmapContainer) { return ((BitmapContainer) x).lazyor((ArrayContainer) this); } @@ -793,7 +772,6 @@ public Container lazyOR(Container x) { abstract int numberOfRuns(); // exact - /** * Computes the bitwise OR of this container with another (union). This container as well as the * provided container are left unaffected. @@ -837,7 +815,6 @@ public Container or(Container x) { */ public abstract Container or(RunContainer x); - /** * Rank returns the number of integers that are smaller or equal to x (Rank(infinity) would be * GetCardinality()). @@ -898,7 +875,6 @@ public Container or(Container x) { */ public abstract void serialize(DataOutput out) throws IOException; - /** * Report the number of bytes required to serialize this container. * @@ -913,7 +889,6 @@ public Container or(Container x) { */ public abstract MappeableContainer toMappeableContainer(); - /** * If possible, recover wasted memory. */ @@ -934,7 +909,6 @@ public Container or(Container x) { */ public abstract void writeArray(ByteBuffer buffer); - /** * Computes the bitwise XOR of this container with another (symmetric difference). This container * as well as the provided container are left unaffected. @@ -953,7 +927,6 @@ public Container or(Container x) { */ public abstract Container xor(BitmapContainer x); - /** * Computes the bitwise XOR of this container with another (symmetric difference). This container * as well as the provided container are left unaffected. @@ -1025,7 +998,6 @@ public Container xor(Container x) { */ public abstract int previousAbsentValue(char fromValue); - /** * Get the first integer held in the container * @return the first integer in the container @@ -1046,7 +1018,7 @@ public Container xor(Container x) { * @throws NoSuchElementException if empty */ protected void assertNonEmpty(boolean condition) { - if(condition) { + if (condition) { throw new NoSuchElementException("Empty " + getContainerName()); } } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ContainerAppender.java b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerAppender.java index 09bb3d91f..3dc5c72ec 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/ContainerAppender.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerAppender.java @@ -1,10 +1,11 @@ package org.roaringbitmap; +import static org.roaringbitmap.Util.highbits; +import static org.roaringbitmap.Util.lowbits; +import static org.roaringbitmap.Util.partialRadixSort; import java.util.function.Supplier; -import static org.roaringbitmap.Util.*; - /** * This class can be used to write quickly values to a bitmap. * The values are expected to be (increasing) sorted order. @@ -29,10 +30,9 @@ * } *
*/ -public class ContainerAppender, - T extends BitmapDataProvider & AppendableStorage> - implements RoaringBitmapWriter { - +public class ContainerAppender< + C extends WordStorage, T extends BitmapDataProvider & AppendableStorage> + implements RoaringBitmapWriter { private final boolean doPartialSort; private final boolean runCompress; @@ -46,10 +46,11 @@ public class ContainerAppender, * Initialize an ContainerAppender with a receiving bitmap * */ - ContainerAppender(boolean doPartialSort, - boolean runCompress, - Supplier newUnderlying, - Supplier newContainer) { + ContainerAppender( + boolean doPartialSort, + boolean runCompress, + Supplier newUnderlying, + Supplier newContainer) { this.doPartialSort = doPartialSort; this.runCompress = runCompress; this.newUnderlying = newUnderlying; @@ -96,7 +97,7 @@ public void add(int value) { public void add(long min, long max) { appendToUnderlying(); underlying.add(min, max); - int mark = (int)((max >>> 16) + 1); + int mark = (int) ((max >>> 16) + 1); if (currentKey < mark) { currentKey = mark; } @@ -130,11 +131,10 @@ public void reset() { private int appendToUnderlying() { if (!container.isEmpty()) { assert currentKey <= 0xFFFF; - underlying.append((char) currentKey, - runCompress ? container.runOptimize() : container); + underlying.append((char) currentKey, runCompress ? container.runOptimize() : container); container = newContainer.get(); return 1; } return 0; } -} \ No newline at end of file +} diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java index 69ac0d7ce..b28a34491 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerBatchIterator.java @@ -46,5 +46,4 @@ default int next(int key, int[] buffer) { * @param target the value to advance to. */ void advanceIfNeeded(char target); - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ContainerPointer.java b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerPointer.java index 7dd1198d0..174c4c165 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/ContainerPointer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/ContainerPointer.java @@ -9,13 +9,12 @@ * This interface allows you to iterate over the containers in a roaring bitmap. * */ -public interface ContainerPointer extends Comparable, Cloneable { +public interface ContainerPointer extends Comparable, Cloneable { /** * Move to the next container */ void advance(); - /** * Create a copy * diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/FastAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/FastAggregation.java index 6c89b97f1..2d8e5d38c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/FastAggregation.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/FastAggregation.java @@ -4,8 +4,13 @@ package org.roaringbitmap; -import java.util.*; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.PriorityQueue; /** * Fast algorithms to aggregate many bitmaps. @@ -14,7 +19,6 @@ */ public final class FastAggregation { - /** * Compute the AND aggregate. * @@ -50,7 +54,7 @@ public static RoaringBitmap and(RoaringBitmap... bitmaps) { */ public static RoaringBitmap and(long[] aggregationBuffer, RoaringBitmap... bitmaps) { if (bitmaps.length > 10) { - if(aggregationBuffer.length < 1024) { + if (aggregationBuffer.length < 1024) { throw new IllegalArgumentException("buffer should have at least 1024 elements."); } try { @@ -111,7 +115,6 @@ public static RoaringBitmap horizontal_or(Iterator bitm return naive_or(bitmaps); } - /** * Minimizes memory usage while computing the or aggregate on a moderate number of bitmaps. * @@ -230,7 +233,6 @@ public static RoaringBitmap horizontal_or(RoaringBitmap... bitmaps) { return answer; } - /** * Minimizes memory usage while computing the xor aggregate on a moderate number of bitmaps. * @@ -288,7 +290,6 @@ public static RoaringBitmap horizontal_xor(RoaringBitmap... bitmaps) { return answer; } - /** * Compute overall AND between bitmaps two-by-two. * @@ -312,7 +313,6 @@ public static RoaringBitmap naive_and(Iterator bitmaps) return answer; } - /** * Compute overall AND between bitmaps two-by-two. * @@ -372,8 +372,7 @@ public static RoaringBitmap workShyAnd(long[] buffer, RoaringBitmap... bitmaps) } } - RoaringArray array = - new RoaringArray(keys, new Container[numContainers], 0); + RoaringArray array = new RoaringArray(keys, new Container[numContainers], 0); for (int i = 0; i < numContainers; ++i) { Container[] slice = containers[i]; Arrays.fill(words, -1L); @@ -460,8 +459,6 @@ private static int horizontalOrCardinality(RoaringBitmap... bitmaps) { return cardinality; } - - /** * Computes the intersection by first intersecting the keys, avoids * materialising containers, limits memory usage. You must provide a long[] array @@ -475,7 +472,7 @@ private static int horizontalOrCardinality(RoaringBitmap... bitmaps) { * @return the intersection of the bitmaps */ public static RoaringBitmap workAndMemoryShyAnd(long[] buffer, RoaringBitmap... bitmaps) { - if(buffer.length < 1024) { + if (buffer.length < 1024) { throw new IllegalArgumentException("buffer should have at least 1024 elements."); } long[] words = buffer; @@ -485,15 +482,14 @@ public static RoaringBitmap workAndMemoryShyAnd(long[] buffer, RoaringBitmap... } int numContainers = keys.length; - RoaringArray array = - new RoaringArray(keys, new Container[numContainers], 0); + RoaringArray array = new RoaringArray(keys, new Container[numContainers], 0); for (int i = 0; i < numContainers; ++i) { char MatchingKey = keys[i]; Arrays.fill(words, -1L); Container tmp = new BitmapContainer(words, -1); - for(RoaringBitmap bitmap: bitmaps) { + for (RoaringBitmap bitmap : bitmaps) { int idx = bitmap.highLowContainer.getIndex(MatchingKey); - if(idx < 0) { + if (idx < 0) { continue; } Container container = bitmap.highLowContainer.getContainerAtIndex(idx); @@ -547,7 +543,6 @@ public static RoaringBitmap naive_or(RoaringBitmap... bitmaps) { return answer; } - /** * Compute overall XOR between bitmaps two-by-two. * @@ -564,7 +559,6 @@ public static RoaringBitmap naive_xor(Iterator bitmaps) return answer; } - /** * Compute overall XOR between bitmaps two-by-two. * @@ -626,12 +620,15 @@ public static RoaringBitmap priorityqueue_or(Iterator b for (int k = 0; k < sizes.length; ++k) { sizes[k] = buffer.get(k).getLongSizeInBytes(); } - PriorityQueue pq = new PriorityQueue<>(128, new Comparator() { - @Override - public int compare(Integer a, Integer b) { - return (int) (sizes[a] - sizes[b]); - } - }); + PriorityQueue pq = + new PriorityQueue<>( + 128, + new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return (int) (sizes[a] - sizes[b]); + } + }); for (int k = 0; k < sizes.length; ++k) { pq.add(k); } @@ -683,12 +680,15 @@ public static RoaringBitmap priorityqueue_or(RoaringBitmap... bitmaps) { for (int k = 0; k < sizes.length; ++k) { sizes[k] = buffer[k].getLongSizeInBytes(); } - PriorityQueue pq = new PriorityQueue<>(128, new Comparator() { - @Override - public int compare(Integer a, Integer b) { - return (int) (sizes[a] - sizes[b]); - } - }); + PriorityQueue pq = + new PriorityQueue<>( + 128, + new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return (int) (sizes[a] - sizes[b]); + } + }); for (int k = 0; k < sizes.length; ++k) { pq.add(k); } @@ -736,12 +736,14 @@ public static RoaringBitmap priorityqueue_xor(RoaringBitmap... bitmaps) { } PriorityQueue pq = - new PriorityQueue<>(bitmaps.length, new Comparator() { - @Override - public int compare(RoaringBitmap a, RoaringBitmap b) { - return (int)(a.getLongSizeInBytes() - b.getLongSizeInBytes()); - } - }); + new PriorityQueue<>( + bitmaps.length, + new Comparator() { + @Override + public int compare(RoaringBitmap a, RoaringBitmap b) { + return (int) (a.getLongSizeInBytes() - b.getLongSizeInBytes()); + } + }); Collections.addAll(pq, bitmaps); while (pq.size() > 1) { RoaringBitmap x1 = pq.poll(); @@ -776,8 +778,5 @@ public static RoaringBitmap xor(RoaringBitmap... bitmaps) { /** * Private constructor to prevent instantiation of utility class */ - private FastAggregation() { - - } - + private FastAggregation() {} } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java index 2da9fd63d..e7052ba01 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/FastRankRoaringBitmap.java @@ -168,8 +168,9 @@ private void preComputeCardinalities() { highToCumulatedCardinality[0] = highLowContainer.getContainerAtIndex(0).getCardinality(); for (int i = 1; i < highToCumulatedCardinality.length; i++) { - highToCumulatedCardinality[i] = highToCumulatedCardinality[i - 1] - + highLowContainer.getContainerAtIndex(i).getCardinality(); + highToCumulatedCardinality[i] = + highToCumulatedCardinality[i - 1] + + highLowContainer.getContainerAtIndex(i).getCardinality(); } } @@ -187,8 +188,9 @@ public long rankLong(int x) { char xhigh = Util.highbits(x); - int index = Util.hybridUnsignedBinarySearch(this.highLowContainer.keys, 0, - this.highLowContainer.size(), xhigh); + int index = + Util.hybridUnsignedBinarySearch( + this.highLowContainer.keys, 0, this.highLowContainer.size(), xhigh); boolean hasBitmapOnIdex; if (index < 0) { @@ -228,7 +230,7 @@ public int select(int j) { return this.last(); } else if (j > maxCardinality) { throw new IllegalArgumentException( - "select " + j + " when the cardinality is " + this.getCardinality()); + "select " + j + " when the cardinality is " + this.getCardinality()); } int index = Arrays.binarySearch(highToCumulatedCardinality, j); @@ -257,11 +259,9 @@ public int select(int j) { } int keycontrib = this.highLowContainer.getKeyAtIndex(fixedIndex) << 16; - int lowcontrib = ( - this.highLowContainer.getContainerAtIndex(fixedIndex).select((int) leftover)); + int lowcontrib = (this.highLowContainer.getContainerAtIndex(fixedIndex).select((int) leftover)); int value = lowcontrib + keycontrib; - return value; } @@ -309,14 +309,13 @@ public int peekNextRank() { @Override public PeekableIntRankIterator clone() { try { - FastRoaringIntRankIterator x = - (FastRoaringIntRankIterator) super.clone(); + FastRoaringIntRankIterator x = (FastRoaringIntRankIterator) super.clone(); if (this.iter != null) { x.iter = this.iter.clone(); } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -337,8 +336,11 @@ public int next() { private void nextContainer() { if (pos < FastRankRoaringBitmap.this.highLowContainer.size()) { - iter = FastRankRoaringBitmap.this.highLowContainer.getContainerAtIndex(pos) - .getCharRankIterator(); + iter = + FastRankRoaringBitmap.this + .highLowContainer + .getContainerAtIndex(pos) + .getCharRankIterator(); hs = FastRankRoaringBitmap.this.highLowContainer.getKeyAtIndex(pos) << 16; } } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java index 0dcc67168..369261834 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/ImmutableBitmapDataProvider.java @@ -87,10 +87,11 @@ public interface ImmutableBitmapDataProvider { * @return an Ordered, Distinct, Sorted and Sized IntStream in ascending order */ public default IntStream stream() { - int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED - | Spliterator.SIZED; - Spliterator.OfInt x = Spliterators.spliterator(new RoaringOfInt(getIntIterator()), - getCardinality(), characteristics); + int characteristics = + Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.SIZED; + Spliterator.OfInt x = + Spliterators.spliterator( + new RoaringOfInt(getIntIterator()), getCardinality(), characteristics); return StreamSupport.intStream(x, false); } @@ -99,8 +100,9 @@ public default IntStream stream() { */ public default IntStream reverseStream() { int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SIZED; - Spliterator.OfInt x = Spliterators.spliterator(new RoaringOfInt(getReverseIntIterator()), - getCardinality(), characteristics); + Spliterator.OfInt x = + Spliterators.spliterator( + new RoaringOfInt(getReverseIntIterator()), getCardinality(), characteristics); return StreamSupport.intStream(x, false); } @@ -170,15 +172,15 @@ public default IntStream reverseStream() { long rankLong(int x); /** - * Computes the number of values in the interval [start,end) where - * start is included and end excluded. - * rangeCardinality(0,0x100000000) provides the total cardinality (getLongCardinality). - * The answer is a 64-bit value between 1 and 0x100000000. - * - * @param start lower limit (included) - * @param end upper limit (excluded) - * @return the number of elements in [start,end), between 0 and 0x100000000. - */ + * Computes the number of values in the interval [start,end) where + * start is included and end excluded. + * rangeCardinality(0,0x100000000) provides the total cardinality (getLongCardinality). + * The answer is a 64-bit value between 1 and 0x100000000. + * + * @param start lower limit (included) + * @param end upper limit (excluded) + * @return the number of elements in [start,end), between 0 and 0x100000000. + */ long rangeCardinality(long start, long end); /** @@ -325,7 +327,6 @@ public default IntStream reverseStream() { */ int getContainerCount(); - /** * An internal class to help provide streams. * Sad but true the interface of IntIterator and PrimitiveIterator.OfInt diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/IntIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/IntIterator.java index 75f6d264f..efe49236a 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/IntIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/IntIterator.java @@ -27,5 +27,4 @@ public interface IntIterator extends Cloneable { * @return next integer value */ int next(); - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java index 0819177bd..8b06f704c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/IntIteratorFlyweight.java @@ -32,9 +32,7 @@ public class IntIteratorFlyweight implements PeekableIntIterator { * Creates an instance that is not ready for iteration. You must first call * {@link #wrap(RoaringBitmap)}. */ - public IntIteratorFlyweight() { - - } + public IntIteratorFlyweight() {} /** * Creates an instance that is ready for iteration. @@ -49,12 +47,12 @@ public IntIteratorFlyweight(RoaringBitmap r) { public PeekableIntIterator clone() { try { IntIteratorFlyweight x = (IntIteratorFlyweight) super.clone(); - if(this.iter != null) { + if (this.iter != null) { x.iter = this.iter.clone(); } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java b/roaringbitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java index 9a09e032c..0938773c3 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/InvalidRoaringFormat.java @@ -29,13 +29,10 @@ public InvalidRoaringFormat(String string) { private static final long serialVersionUID = 1L; /** - * Convert the exception to an IOException (convenience function) - * @return an IOException with a related error message. - */ + * Convert the exception to an IOException (convenience function) + * @return an IOException with a related error message. + */ public IOException toIOException() { return new IOException(toString()); } - - - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java index 3452a5c49..b732c881c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/ParallelAggregation.java @@ -1,6 +1,13 @@ package org.roaringbitmap; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.function.BiConsumer; @@ -38,9 +45,8 @@ */ public class ParallelAggregation { - private static final Collector>, - RoaringArray, RoaringBitmap> - XOR = new ContainerCollector(ParallelAggregation::xor); + private static final Collector>, RoaringArray, RoaringBitmap> + XOR = new ContainerCollector(ParallelAggregation::xor); private static final OrCollector OR = new OrCollector(); @@ -48,8 +54,8 @@ public class ParallelAggregation { * Collects containers grouped by their key into a RoaringBitmap, applying the * supplied aggregation function to each group. */ - public static class ContainerCollector implements - Collector>, RoaringArray, RoaringBitmap> { + public static class ContainerCollector + implements Collector>, RoaringArray, RoaringBitmap> { private final Function, Container> reducer; @@ -100,8 +106,7 @@ public Set characteristics() { /** * Collects a list of containers into a single container. */ - public static class OrCollector - implements Collector, Container, Container> { + public static class OrCollector implements Collector, Container, Container> { @Override public Supplier supplier() { @@ -152,7 +157,6 @@ public static SortedMap> groupByKey(RoaringBitmap... return new TreeMap<>(grouped); } - /** * Computes the bitwise union of the input bitmaps * @param bitmaps the input bitmaps @@ -169,8 +173,8 @@ public static RoaringBitmap or(RoaringBitmap... bitmaps) { slices.add(slice.getValue()); } IntStream.range(0, i) - .parallel() - .forEach(position -> values[position] = or(slices.get(position))); + .parallel() + .forEach(position -> values[position] = or(slices.get(position))); return new RoaringBitmap(new RoaringArray(keys, values, i)); } @@ -180,10 +184,7 @@ public static RoaringBitmap or(RoaringBitmap... bitmaps) { * @return the symmetric difference of the bitmaps */ public static RoaringBitmap xor(RoaringBitmap... bitmaps) { - return groupByKey(bitmaps) - .entrySet() - .parallelStream() - .collect(XOR); + return groupByKey(bitmaps).entrySet().parallelStream().collect(XOR); } private static Container xor(List containers) { @@ -216,16 +217,17 @@ private static Container or(List containers) { int mod = Math.floorMod(containers.size(), parallelism); // we have an enormous slice (probably skewed), parallelise it return IntStream.range(0, parallelism) - .parallel() - .mapToObj(i -> containers.subList(i * step + Math.min(i, mod), - (i + 1) * step + Math.min(i + 1, mod))) - .collect(OR); + .parallel() + .mapToObj( + i -> + containers.subList( + i * step + Math.min(i, mod), (i + 1) * step + Math.min(i + 1, mod))) + .collect(OR); } private static int availableParallelism() { return ForkJoinTask.inForkJoinPool() - ? ForkJoinTask.getPool().getParallelism() - : ForkJoinPool.getCommonPoolParallelism(); + ? ForkJoinTask.getPool().getParallelism() + : ForkJoinPool.getCommonPoolParallelism(); } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java index ec2b5cbae..5feb101f7 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableCharIterator.java @@ -3,8 +3,6 @@ */ package org.roaringbitmap; - - /** * Simple extension to the CharIterator interface * @@ -39,4 +37,3 @@ public interface PeekableCharIterator extends CharIterator { @Override PeekableCharIterator clone(); } - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java index e9143f5bf..f6e0e1e80 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntIterator.java @@ -1,6 +1,5 @@ package org.roaringbitmap; - /** * Simple extension to the IntIterator interface. * It allows you to "skip" values using the advanceIfNeeded @@ -86,5 +85,3 @@ public interface PeekableIntIterator extends IntIterator { @Override PeekableIntIterator clone(); } - - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java index c8b1561dd..2a56c8db0 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/PeekableIntRankIterator.java @@ -14,5 +14,3 @@ public interface PeekableIntRankIterator extends PeekableIntIterator { @Override PeekableIntRankIterator clone(); } - - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RangeBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/RangeBitmap.java index a47fe1c23..db0d178e9 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RangeBitmap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RangeBitmap.java @@ -1,5 +1,10 @@ package org.roaringbitmap; +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static org.roaringbitmap.Util.cardinalityInBitmapRange; +import static org.roaringbitmap.Util.resetBitmapRange; +import static org.roaringbitmap.Util.setBitmapRange; + import org.roaringbitmap.buffer.MappeableArrayContainer; import org.roaringbitmap.buffer.MappeableBitmapContainer; import org.roaringbitmap.buffer.MappeableContainer; @@ -12,11 +17,6 @@ import java.util.function.Consumer; import java.util.function.IntFunction; -import static java.nio.ByteOrder.LITTLE_ENDIAN; -import static org.roaringbitmap.Util.cardinalityInBitmapRange; -import static org.roaringbitmap.Util.resetBitmapRange; -import static org.roaringbitmap.Util.setBitmapRange; - /** * A 2D bitmap which associates values with a row index and can perform range queries. */ @@ -36,9 +36,8 @@ public final class RangeBitmap { * @param bufferSupplier provides ByteBuffers. * @return an appender. */ - public static Appender appender(long maxValue, - IntFunction bufferSupplier, - Consumer cleaner) { + public static Appender appender( + long maxValue, IntFunction bufferSupplier, Consumer cleaner) { return new Appender(maxValue, bufferSupplier, cleaner); } @@ -50,9 +49,8 @@ public static Appender appender(long maxValue, * @return an appender. */ public static Appender appender(long maxValue) { - return appender(maxValue, - capacity -> ByteBuffer.allocate(capacity).order(LITTLE_ENDIAN), b -> { - }); + return appender( + maxValue, capacity -> ByteBuffer.allocate(capacity).order(LITTLE_ENDIAN), b -> {}); } /** @@ -66,8 +64,8 @@ public static RangeBitmap map(ByteBuffer buffer) { ByteBuffer source = buffer.slice().order(LITTLE_ENDIAN); int cookie = source.getChar(); if (cookie != COOKIE) { - throw new InvalidRoaringFormat("invalid cookie for range bitmap (expected " - + COOKIE + " but got " + cookie + ")"); + throw new InvalidRoaringFormat( + "invalid cookie for range bitmap (expected " + COOKIE + " but got " + cookie + ")"); } int base = source.get() & 0xFF; if (base != 2) { @@ -80,8 +78,13 @@ public static RangeBitmap map(ByteBuffer buffer) { long maxRid = source.getInt() & 0xFFFFFFFFL; int masksOffset = source.position(); int containersOffset = masksOffset + maxKey * bytesPerMask; - return new RangeBitmap(mask, maxRid, (ByteBuffer) source.position(buffer.position()), - masksOffset, containersOffset, bytesPerMask); + return new RangeBitmap( + mask, + maxRid, + (ByteBuffer) source.position(buffer.position()), + masksOffset, + containersOffset, + bytesPerMask); } private final ByteBuffer buffer; @@ -91,8 +94,13 @@ public static RangeBitmap map(ByteBuffer buffer) { private final long max; private final byte bytesPerMask; - RangeBitmap(long mask, long max, ByteBuffer buffer, int masksOffset, int containersOffset, - byte bytesPerMask) { + RangeBitmap( + long mask, + long max, + ByteBuffer buffer, + int masksOffset, + int containersOffset, + byte bytesPerMask) { this.mask = mask; this.max = max; this.buffer = buffer; @@ -477,13 +485,14 @@ public RoaringBitmap computePoint(long value, boolean negate, RoaringBitmap cont empty = false; } if (!empty) { - Container toAppend = new BitmapContainer(bits, -1) + Container toAppend = + new BitmapContainer(bits, -1) .iand(contextArray.values[contextPos]) .repairAfterLazy() .runOptimize(); if (!toAppend.isEmpty()) { - output.append((char) prefix, - toAppend instanceof BitmapContainer ? toAppend.clone() : toAppend); + output.append( + (char) prefix, toAppend instanceof BitmapContainer ? toAppend.clone() : toAppend); } } contextPos++; @@ -600,13 +609,14 @@ private RoaringBitmap computeRange(long threshold, boolean upper, RoaringBitmap empty = false; } if (!empty) { - Container toAppend = new BitmapContainer(bits, -1) - .iand(contextArray.values[contextPos]) - .repairAfterLazy() - .runOptimize(); + Container toAppend = + new BitmapContainer(bits, -1) + .iand(contextArray.values[contextPos]) + .repairAfterLazy() + .runOptimize(); if (!toAppend.isEmpty()) { - output.append((char) prefix, - toAppend instanceof BitmapContainer ? toAppend.clone() : toAppend); + output.append( + (char) prefix, toAppend instanceof BitmapContainer ? toAppend.clone() : toAppend); } } contextPos++; @@ -656,9 +666,12 @@ private long countRange(long threshold, boolean upper, RoaringBitmap context) { } else { evaluateHorizontalSliceRange(remaining, threshold, containerMask); Container container = contextArray.values[contextPos]; - int cardinality = upper - ? container.andCardinality(new BitmapContainer(bits, -1)) - : container.andNot(new BitmapContainer(bits, -1).repairAfterLazy()).getCardinality(); + int cardinality = + upper + ? container.andCardinality(new BitmapContainer(bits, -1)) + : container + .andNot(new BitmapContainer(bits, -1).repairAfterLazy()) + .getCardinality(); count += cardinality; contextPos++; } @@ -775,35 +788,40 @@ private void andNextIntoBits() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - array.andInto(bits); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - bitmap.andInto(bits); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - run.andInto(bits); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + array.andInto(bits); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + bitmap.andInto(bits); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + run.andInto(bits); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -813,35 +831,40 @@ private void orNextIntoBits() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - array.orInto(bits); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - bitmap.orInto(bits); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - run.orInto(bits); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + array.orInto(bits); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + bitmap.orInto(bits); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + run.orInto(bits); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -851,35 +874,40 @@ private void removeNextFromBits() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - array.removeFrom(bits); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - bitmap.removeFrom(bits); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - run.removeFrom(bits); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + array.removeFrom(bits); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + bitmap.removeFrom(bits); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + run.removeFrom(bits); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -1013,8 +1041,8 @@ public long count(long lower, long upper, RoaringBitmap context) { return count; } - private void evaluateHorizontalSlice(long containerMask, long remaining, long lower, - long upper) { + private void evaluateHorizontalSlice( + long containerMask, long remaining, long lower, long upper) { // most significant absent bit in the threshold for which there is no container; // everything before this is wasted work, so we just skip over the containers int skipLow = 64 - Long.numberOfLeadingZeros((~(lower | containerMask) & mask)); @@ -1081,38 +1109,43 @@ private void orLowOrHigh() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - low.or(array); - high.or(array); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - low.or(bitmap); - high.or(bitmap); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - low.or(run); - high.or(run); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + low.or(array); + high.or(array); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + low.or(bitmap); + high.or(bitmap); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + low.or(run); + high.or(run); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -1122,38 +1155,43 @@ private void orLowAndHigh() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - low.or(array); - high.and(array); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - low.or(bitmap); - high.and(bitmap); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - low.or(run); - high.and(run); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + low.or(array); + high.and(array); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + low.or(bitmap); + high.and(bitmap); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + low.or(run); + high.and(run); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -1163,38 +1201,43 @@ private void andLowOrHigh() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - low.and(array); - high.or(array); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - low.and(bitmap); - high.or(bitmap); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - low.and(run); - high.or(run); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + low.and(array); + high.or(array); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + low.and(bitmap); + high.or(bitmap); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + low.and(run); + high.or(run); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -1204,38 +1247,43 @@ private void andLowAndHigh() { int size = buffer.getChar(position) & 0xFFFF; position += Character.BYTES; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableArrayContainer array = new MappeableArrayContainer(cb, size); - low.and(array); - high.and(array); - position += skip; - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer() - .limit(1024); - MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); - low.and(bitmap); - high.and(bitmap); - position += BITMAP_SIZE; - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position)).asCharBuffer() - .limit(skip >>> 1); - MappeableRunContainer run = new MappeableRunContainer(cb, size); - low.and(run); - high.and(run); - position += skip; - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableArrayContainer array = new MappeableArrayContainer(cb, size); + low.and(array); + high.and(array); + position += skip; + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) ((ByteBuffer) buffer.position(position)).asLongBuffer().limit(1024); + MappeableBitmapContainer bitmap = new MappeableBitmapContainer(lb, size); + low.and(bitmap); + high.and(bitmap); + position += BITMAP_SIZE; + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position)).asCharBuffer().limit(skip >>> 1); + MappeableRunContainer run = new MappeableRunContainer(cb, size); + low.and(run); + high.and(run); + position += skip; + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -1243,29 +1291,35 @@ private void orNextIntoBits(Bits bits) { int type = buffer.get(position); int size = buffer.getChar(position + 1) & 0xFFFF; switch (type) { - case ARRAY: { - int skip = size << 1; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position + 3)).asCharBuffer() - .limit(skip >>> 1); - bits.or(new MappeableArrayContainer(cb, size)); - } - break; - case BITMAP: { - LongBuffer lb = (LongBuffer) ((ByteBuffer) buffer.position(position + 3)).asLongBuffer() - .limit(1024); - bits.or(new MappeableBitmapContainer(lb, size)); - } - break; - case RUN: { - int skip = size << 2; - CharBuffer cb = (CharBuffer) ((ByteBuffer) buffer.position(position + 3)).asCharBuffer() - .limit(skip >>> 1); - bits.or(new MappeableRunContainer(cb, size)); - } - break; + case ARRAY: + { + int skip = size << 1; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position + 3)).asCharBuffer().limit(skip >>> 1); + bits.or(new MappeableArrayContainer(cb, size)); + } + break; + case BITMAP: + { + LongBuffer lb = + (LongBuffer) + ((ByteBuffer) buffer.position(position + 3)).asLongBuffer().limit(1024); + bits.or(new MappeableBitmapContainer(lb, size)); + } + break; + case RUN: + { + int skip = size << 2; + CharBuffer cb = + (CharBuffer) + ((ByteBuffer) buffer.position(position + 3)).asCharBuffer().limit(skip >>> 1); + bits.or(new MappeableRunContainer(cb, size)); + } + break; default: - throw new IllegalStateException("Unknown type " + type - + " (this is a bug, please report it.)"); + throw new IllegalStateException( + "Unknown type " + type + " (this is a bug, please report it.)"); } } @@ -1356,8 +1410,8 @@ private void makeNonFull() { } } - private static long getContainerMask(ByteBuffer buffer, int position, long mask, - int bytesPerMask) { + private static long getContainerMask( + ByteBuffer buffer, int position, long mask, int bytesPerMask) { switch (bytesPerMask) { case 0: case 1: @@ -1462,11 +1516,7 @@ public int serializedSizeInBytes() { int slicesSize = 1; int maxKeySize = 2; int maxRidSize = 4; - int headerSize = cookieSize - + baseSize - + slicesSize - + maxKeySize - + maxRidSize; + int headerSize = cookieSize + baseSize + slicesSize + maxKeySize + maxRidSize; int keysSize = key * bytesPerMask; return headerSize + keysSize + serializedContainerSize; } @@ -1485,19 +1535,17 @@ public void serialize(ByteBuffer buffer) { throw new IllegalStateException( "Attempted to serialize without calling serializedSizeInBytes first"); } - ByteBuffer target = buffer.order() == LITTLE_ENDIAN - ? buffer - : buffer.slice().order(LITTLE_ENDIAN); + ByteBuffer target = + buffer.order() == LITTLE_ENDIAN ? buffer : buffer.slice().order(LITTLE_ENDIAN); target.putChar((char) COOKIE); target.put((byte) 2); target.put((byte) Long.bitCount(rangeMask)); target.putChar((char) key); target.putInt(rid); int spaceForKeys = key * bytesPerMask; - target.put(((ByteBuffer) maskBuffer.slice() - .order(LITTLE_ENDIAN).limit(spaceForKeys))); - target.put(((ByteBuffer) containers.slice() - .order(LITTLE_ENDIAN).limit(serializedContainerSize))); + target.put(((ByteBuffer) maskBuffer.slice().order(LITTLE_ENDIAN).limit(spaceForKeys))); + target.put( + ((ByteBuffer) containers.slice().order(LITTLE_ENDIAN).limit(serializedContainerSize))); if (buffer != target) { buffer.position(target.position()); } @@ -1551,9 +1599,10 @@ private void append() { if (!container.isEmpty()) { Container toSerialize = container.runOptimize(); int serializedSize = toSerialize.serializedSizeInBytes(); - int type = (toSerialize instanceof BitmapContainer) - ? BITMAP - : (toSerialize instanceof RunContainer) ? RUN : ARRAY; + int type = + (toSerialize instanceof BitmapContainer) + ? BITMAP + : (toSerialize instanceof RunContainer) ? RUN : ARRAY; int required = serializedSize + (type == BITMAP ? 3 : 1); if (containers.capacity() - serializedContainerSize < required) { int growthFactor = 8192 * slice.length; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java index fcd83dd1c..a743db60e 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/ReverseIntIteratorFlyweight.java @@ -20,8 +20,7 @@ public class ReverseIntIteratorFlyweight implements IntIterator { private ReverseArrayContainerCharIterator arrIter = new ReverseArrayContainerCharIterator(); - private ReverseBitmapContainerCharIterator bitmapIter = - new ReverseBitmapContainerCharIterator(); + private ReverseBitmapContainerCharIterator bitmapIter = new ReverseBitmapContainerCharIterator(); private ReverseRunContainerCharIterator runIter = new ReverseRunContainerCharIterator(); @@ -29,14 +28,11 @@ public class ReverseIntIteratorFlyweight implements IntIterator { private RoaringBitmap roaringBitmap = null; - /** * Creates an instance that is not ready for iteration. You must first call * {@link #wrap(RoaringBitmap)}. */ - public ReverseIntIteratorFlyweight() { - - } + public ReverseIntIteratorFlyweight() {} /** * Creates an instance that is ready for iteration. @@ -51,12 +47,12 @@ public ReverseIntIteratorFlyweight(RoaringBitmap r) { public IntIterator clone() { try { ReverseIntIteratorFlyweight x = (ReverseIntIteratorFlyweight) super.clone(); - if(this.iter != null) { + if (this.iter != null) { x.iter = this.iter.clone(); } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -65,8 +61,6 @@ public boolean hasNext() { return pos >= 0; } - - @Override public int next() { final int x = iter.nextAsInt() | hs; @@ -79,8 +73,6 @@ public int next() { private void nextContainer() { - - if (pos >= 0) { Container container = this.roaringBitmap.highLowContainer.getContainerAtIndex(pos); @@ -109,5 +101,4 @@ public void wrap(RoaringBitmap r) { this.pos = (short) (this.roaringBitmap.highLowContainer.size() - 1); this.nextContainer(); } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringArray.java index 427e2a35a..dd04e2c51 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringArray.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringArray.java @@ -4,17 +4,20 @@ package org.roaringbitmap; +import static java.nio.ByteOrder.LITTLE_ENDIAN; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.LongBuffer; import java.util.Arrays; import java.util.NoSuchElementException; -import static java.nio.ByteOrder.LITTLE_ENDIAN; - - /** * Specialized array to store the containers used by a RoaringBitmap. This is not meant to be used * by end users. @@ -30,7 +33,6 @@ public final class RoaringArray implements Cloneable, Externalizable, Appendable static final int INITIAL_CAPACITY = 4; - char[] keys = null; Container[] values = null; @@ -45,7 +47,6 @@ protected RoaringArray() { this(new char[initialCapacity], new Container[initialCapacity], 0); } - RoaringArray(char[] keys, Container[] values, int size) { this.keys = keys; this.values = values; @@ -72,8 +73,7 @@ protected int advanceUntil(char x, int pos) { int spansize = 1; // could set larger // bootstrap an upper limit - while (lower + spansize < size - && (keys[lower + spansize]) < x) { + while (lower + spansize < size && (keys[lower + spansize]) < x) { spansize *= 2; // hoping for compiler will reduce to shift } int upper = (lower + spansize < size) ? lower + spansize : size - 1; @@ -84,8 +84,8 @@ protected int advanceUntil(char x, int pos) { return upper; } - if (keys[upper] < x) {// means array has no item key >= - // x + if (keys[upper] < x) { // means array has no item key >= + // x return size; } @@ -110,8 +110,7 @@ protected int advanceUntil(char x, int pos) { @Override public void append(char key, Container value) { if (size > 0 && key < keys[size - 1]) { - throw new IllegalArgumentException("append only: " - + (key) + " < " + (keys[size - 1])); + throw new IllegalArgumentException("append only: " + (key) + " < " + (keys[size - 1])); } extendArray(1); keys[size] = key; @@ -120,8 +119,7 @@ public void append(char key, Container value) { } void append(RoaringArray roaringArray) { - assert size == 0 || roaringArray.size == 0 - || keys[size - 1] < roaringArray.keys[0]; + assert size == 0 || roaringArray.size == 0 || keys[size - 1] < roaringArray.keys[0]; if (roaringArray.size != 0 && size != 0) { keys = Arrays.copyOf(keys, size + roaringArray.size); values = Arrays.copyOf(values, size + roaringArray.size); @@ -204,8 +202,6 @@ void appendCopy(RoaringArray sa, int startingIndex, int end) { } } - - /** * Append the values from another array, no copy is made (use with care) * @@ -222,7 +218,6 @@ protected void append(RoaringArray sa, int startingIndex, int end) { } } - private int binarySearch(int begin, int end, char key) { return Util.unsignedBinarySearch(keys, begin, end, key); } @@ -280,10 +275,12 @@ public void deserialize(DataInput in) throws IOException { if ((cookie & 0xFFFF) != SERIAL_COOKIE && cookie != SERIAL_COOKIE_NO_RUNCONTAINER) { throw new InvalidRoaringFormat("I failed to find a valid cookie."); } - this.size = ((cookie & 0xFFFF) == SERIAL_COOKIE) ? (cookie >>> 16) + 1 - : Integer.reverseBytes(in.readInt()); + this.size = + ((cookie & 0xFFFF) == SERIAL_COOKIE) + ? (cookie >>> 16) + 1 + : Integer.reverseBytes(in.readInt()); // logically we cannot have more than (1<<16) containers. - if(this.size > (1<<16)) { + if (this.size > (1 << 16)) { throw new InvalidRoaringFormat("Size too large"); } if ((this.keys == null) || (this.keys.length < this.size)) { @@ -291,7 +288,6 @@ public void deserialize(DataInput in) throws IOException { this.values = new Container[this.size]; } - byte[] bitmapOfRunContainers = null; boolean hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE; if (hasrun) { @@ -375,10 +371,12 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { if ((cookie & 0xFFFF) != SERIAL_COOKIE && cookie != SERIAL_COOKIE_NO_RUNCONTAINER) { throw new InvalidRoaringFormat("I failed to find a valid cookie."); } - this.size = ((cookie & 0xFFFF) == SERIAL_COOKIE) ? (cookie >>> 16) + 1 - : Integer.reverseBytes(in.readInt()); + this.size = + ((cookie & 0xFFFF) == SERIAL_COOKIE) + ? (cookie >>> 16) + 1 + : Integer.reverseBytes(in.readInt()); // logically we cannot have more than (1<<16) containers. - if(this.size > (1<<16)) { + if (this.size > (1 << 16)) { throw new InvalidRoaringFormat("Size too large"); } if ((this.keys == null) || (this.keys.length < this.size)) { @@ -386,7 +384,6 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { this.values = new Container[this.size]; } - byte[] bitmapOfRunContainers = null; boolean hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE; if (hasrun) { @@ -426,9 +423,9 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { if (buffer.length < (BitmapContainer.MAX_CAPACITY / 64) * 8) { // We have been provided a rather small buffer - for (int iBlock = 0 ; iBlock <= 8 * bitmapArray.length / buffer.length ; iBlock++) { + for (int iBlock = 0; iBlock <= 8 * bitmapArray.length / buffer.length; iBlock++) { int start = buffer.length * iBlock; - int end = Math.min(buffer.length * (iBlock +1 ), 8 * bitmapArray.length); + int end = Math.min(buffer.length * (iBlock + 1), 8 * bitmapArray.length); in.readFully(buffer, 0, end - start); @@ -472,9 +469,9 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { lengthsAndValues[j] = Character.reverseBytes(in.readChar()); } } else { - for (int iBlock = 0 ; iBlock <= 2 * lengthsAndValues.length / buffer.length ; iBlock++) { + for (int iBlock = 0; iBlock <= 2 * lengthsAndValues.length / buffer.length; iBlock++) { int start = buffer.length * iBlock; - int end = Math.min(buffer.length * (iBlock +1 ), 2 * lengthsAndValues.length); + int end = Math.min(buffer.length * (iBlock + 1), 2 * lengthsAndValues.length); in.readFully(buffer, 0, end - start); @@ -504,9 +501,9 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { charArray[j] = Character.reverseBytes(in.readChar()); } } else { - for (int iBlock = 0 ; iBlock <= 2 * charArray.length / buffer.length ; iBlock++) { + for (int iBlock = 0; iBlock <= 2 * charArray.length / buffer.length; iBlock++) { int start = buffer.length * iBlock; - int end = Math.min(buffer.length * (iBlock +1 ) , 2 * charArray.length); + int end = Math.min(buffer.length * (iBlock + 1), 2 * charArray.length); in.readFully(buffer, 0, end - start); @@ -561,7 +558,7 @@ public void deserialize(ByteBuffer bbf) { // buffer.limit(theLimit); // logically we cannot have more than (1<<16) containers. - if(this.size > (1<<16)) { + if (this.size > (1 << 16)) { throw new InvalidRoaringFormat("Size too large"); } if ((this.keys == null) || (this.keys.length < this.size)) { @@ -569,7 +566,6 @@ public void deserialize(ByteBuffer bbf) { this.values = new Container[this.size]; } - byte[] bitmapOfRunContainers = null; boolean hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE; if (hasrun) { @@ -617,7 +613,6 @@ public void deserialize(ByteBuffer bbf) { } else { final char[] charArray = new char[cardinalities[k]]; - buffer.asCharBuffer().get(charArray); buffer.position(buffer.position() + charArray.length * 2); @@ -628,7 +623,6 @@ public void deserialize(ByteBuffer bbf) { } } - @Override public boolean equals(Object o) { if (o instanceof RoaringArray) { @@ -681,10 +675,10 @@ public ContainerPointer getContainerPointer() { } /** - * Create a ContainerPointer for this RoaringArray - * @param startIndex starting index in the container list - * @return a ContainerPointer - */ + * Create a ContainerPointer for this RoaringArray + * @param startIndex starting index in the container list + * @return a ContainerPointer + */ public ContainerPointer getContainerPointer(final int startIndex) { return new ContainerPointer() { int k = startIndex; @@ -692,7 +686,6 @@ public ContainerPointer getContainerPointer(final int startIndex) { @Override public void advance() { ++k; - } @Override @@ -700,7 +693,7 @@ public ContainerPointer clone() { try { return (ContainerPointer) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -725,7 +718,6 @@ public Container getContainer() { return RoaringArray.this.values[k]; } - @Override public boolean isBitmapContainer() { return getContainer() instanceof BitmapContainer; @@ -736,11 +728,9 @@ public boolean isRunContainer() { return getContainer() instanceof RunContainer; } - @Override public char key() { return RoaringArray.this.keys[k]; - } }; } @@ -780,16 +770,15 @@ private boolean hasRunContainer() { private int headerSize() { if (hasRunContainer()) { - if (size < NO_OFFSET_THRESHOLD) {// for small bitmaps, we omit the offsets + if (size < NO_OFFSET_THRESHOLD) { // for small bitmaps, we omit the offsets return 4 + (size + 7) / 8 + 4 * size; } - return 4 + (size + 7) / 8 + 8 * size;// - 4 because we pack the size with the cookie + return 4 + (size + 7) / 8 + 8 * size; // - 4 because we pack the size with the cookie } else { return 4 + 4 + 8 * size; } } - // insert a new key, it is assumed that it does not exist void insertNewKeyValueAt(int i, char key, Container value) { extendArray(1); @@ -838,8 +827,6 @@ void resize(int newLength) { this.size = newLength; } - - /** * Serialize. * @@ -907,7 +894,7 @@ public void serialize(ByteBuffer buffer) { runMarker |= (1 << j); } } - buf.put((byte)runMarker); + buf.put((byte) runMarker); } int runMarkersLength = buf.position() - offset; if (this.size < NO_OFFSET_THRESHOLD) { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java index 602e460b4..759808d98 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBatchIterator.java @@ -35,7 +35,7 @@ public boolean hasNext() { @Override public BatchIterator clone() { try { - RoaringBatchIterator it = (RoaringBatchIterator)super.clone(); + RoaringBatchIterator it = (RoaringBatchIterator) super.clone(); if (null != iterator) { it.iterator = iterator.clone(); } @@ -74,11 +74,11 @@ private void nextIterator() { if (index < highLowContainer.size()) { Container container = highLowContainer.getContainerAtIndex(index); if (container instanceof ArrayContainer) { - nextIterator((ArrayContainer)container); + nextIterator((ArrayContainer) container); } else if (container instanceof BitmapContainer) { - nextIterator((BitmapContainer)container); - } else if (container instanceof RunContainer){ - nextIterator((RunContainer)container); + nextIterator((BitmapContainer) container); + } else if (container instanceof RunContainer) { + nextIterator((RunContainer) container); } key = highLowContainer.getKeyAtIndex(index) << 16; } else { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java index 23091f0a8..9f1587735 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitSet.java @@ -190,7 +190,6 @@ public Object clone() { return new RoaringBitSet(roaringBitmap.clone()); } - @Override public IntStream stream() { return roaringBitmap.stream(); diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java index e312b541a..7f21455ba 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java @@ -4,18 +4,24 @@ package org.roaringbitmap; +import static org.roaringbitmap.RoaringBitmapWriter.writer; +import static org.roaringbitmap.Util.lowbitsAsInteger; + import org.roaringbitmap.buffer.ImmutableRoaringBitmap; import org.roaringbitmap.buffer.MappeableContainerPointer; import org.roaringbitmap.buffer.MutableRoaringBitmap; +import org.roaringbitmap.longlong.LongUtils; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; import java.nio.ByteBuffer; import java.util.Iterator; -import static org.roaringbitmap.RoaringBitmapWriter.writer; -import static org.roaringbitmap.Util.lowbitsAsInteger; -import org.roaringbitmap.longlong.LongUtils; - /** * RoaringBitmap, a compressed alternative to the BitSet. * @@ -45,10 +51,14 @@ * * */ - - -public class RoaringBitmap implements Cloneable, Serializable, Iterable, Externalizable, - ImmutableBitmapDataProvider, BitmapDataProvider, AppendableStorage { +public class RoaringBitmap + implements Cloneable, + Serializable, + Iterable, + Externalizable, + ImmutableBitmapDataProvider, + BitmapDataProvider, + AppendableStorage { private class RoaringIntIterator implements PeekableIntIterator { private final char startingContainerIndex; @@ -76,7 +86,7 @@ public PeekableIntIterator clone() { } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -127,7 +137,6 @@ boolean shouldAdvanceContainer(final int hs, final int minval) { public int peekNext() { return (iter.peekNext()) | hs; } - } private final class RoaringSignedIntIterator extends RoaringIntIterator { @@ -146,7 +155,6 @@ char findStartingContainerIndex() { boolean shouldAdvanceContainer(final int hs, final int minval) { return (hs >> 16) < (minval >> 16); } - } private final class RoaringReverseIntIterator implements IntIterator { @@ -165,12 +173,12 @@ private RoaringReverseIntIterator() { public IntIterator clone() { try { RoaringReverseIntIterator clone = (RoaringReverseIntIterator) super.clone(); - if(this.iter != null) { + if (this.iter != null) { clone.iter = this.iter.clone(); } return clone; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -196,19 +204,18 @@ private void nextContainer() { hs = RoaringBitmap.this.highLowContainer.getKeyAtIndex(pos) << 16; } } - } private static final long serialVersionUID = 6L; private static void rangeSanityCheck(final long rangeStart, final long rangeEnd) { - if (rangeStart < 0 || rangeStart > (1L << 32)-1) { - throw new IllegalArgumentException("rangeStart="+ rangeStart - +" should be in [0, 0xffffffff]"); + if (rangeStart < 0 || rangeStart > (1L << 32) - 1) { + throw new IllegalArgumentException( + "rangeStart=" + rangeStart + " should be in [0, 0xffffffff]"); } if (rangeEnd > (1L << 32) || rangeEnd < 0) { - throw new IllegalArgumentException("rangeEnd="+ rangeEnd - +" should be in [0, 0xffffffff + 1]"); + throw new IllegalArgumentException( + "rangeEnd=" + rangeEnd + " should be in [0, 0xffffffff + 1]"); } } @@ -230,56 +237,52 @@ private static void rangeSanityCheck(final long rangeStart, final long rangeEnd) public static RoaringBitmap addOffset(final RoaringBitmap x, long offset) { // we need "offset" to be a long because we want to support values // between -0xFFFFFFFF up to +-0xFFFFFFFF - long container_offset_long = offset < 0 - ? (offset - (1<<16) + 1) / (1<<16) : offset / (1 << 16); - if((container_offset_long < -(1<<16) ) || (container_offset_long >= (1<<16) )) { + long container_offset_long = + offset < 0 ? (offset - (1 << 16) + 1) / (1 << 16) : offset / (1 << 16); + if ((container_offset_long < -(1 << 16)) || (container_offset_long >= (1 << 16))) { return new RoaringBitmap(); // it is necessarily going to be empty } // next cast is necessarily safe, the result is between -0xFFFF and 0xFFFF int container_offset = (int) container_offset_long; // next case is safe - int in_container_offset = (int)(offset - container_offset_long * (1L<<16)); - if(in_container_offset == 0) { + int in_container_offset = (int) (offset - container_offset_long * (1L << 16)); + if (in_container_offset == 0) { RoaringBitmap answer = new RoaringBitmap(); - for(int pos = 0; pos < x.highLowContainer.size(); pos++) { + for (int pos = 0; pos < x.highLowContainer.size(); pos++) { int key = (x.highLowContainer.getKeyAtIndex(pos)); key += container_offset; - answer.highLowContainer.append((char)key, - x.highLowContainer.getContainerAtIndex(pos).clone()); + answer.highLowContainer.append( + (char) key, x.highLowContainer.getContainerAtIndex(pos).clone()); } return answer; } else { RoaringBitmap answer = new RoaringBitmap(); - for(int pos = 0; pos < x.highLowContainer.size(); pos++) { + for (int pos = 0; pos < x.highLowContainer.size(); pos++) { int key = (x.highLowContainer.getKeyAtIndex(pos)); key += container_offset; if (key + 1 < 0 || key > 0xFFFF) { continue; } Container c = x.highLowContainer.getContainerAtIndex(pos); - Container[] offsetted = Util.addOffset(c, - (char)in_container_offset); + Container[] offsetted = Util.addOffset(c, (char) in_container_offset); boolean keyok = key >= 0; boolean keypok = key + 1 <= 0xFFFF; - if( !offsetted[0].isEmpty() && keyok) { + if (!offsetted[0].isEmpty() && keyok) { int current_size = answer.highLowContainer.size(); int lastkey = 0; - if(current_size > 0) { - lastkey = (answer.highLowContainer.getKeyAtIndex( - current_size - 1)); + if (current_size > 0) { + lastkey = (answer.highLowContainer.getKeyAtIndex(current_size - 1)); } - if((current_size > 0) && (lastkey == key)) { - Container prev = answer.highLowContainer - .getContainerAtIndex(current_size - 1); + if ((current_size > 0) && (lastkey == key)) { + Container prev = answer.highLowContainer.getContainerAtIndex(current_size - 1); Container orresult = prev.ior(offsetted[0]); - answer.highLowContainer.setContainerAtIndex(current_size - 1, - orresult); + answer.highLowContainer.setContainerAtIndex(current_size - 1, orresult); } else { - answer.highLowContainer.append((char)key, offsetted[0]); + answer.highLowContainer.append((char) key, offsetted[0]); } } - if( !offsetted[1].isEmpty() && keypok) { - answer.highLowContainer.append((char)(key + 1), offsetted[1]); + if (!offsetted[1].isEmpty() && keypok) { + answer.highLowContainer.append((char) (key + 1), offsetted[1]); } } answer.repairAfterLazy(); @@ -301,7 +304,6 @@ public static RoaringBitmap add(RoaringBitmap rb, final long rangeStart, final l return rb.clone(); // empty range } - final int hbStart = (Util.highbits(rangeStart)); final int lbStart = (Util.lowbits(rangeStart)); final int hbLast = (Util.highbits(rangeEnd - 1)); @@ -313,7 +315,8 @@ public static RoaringBitmap add(RoaringBitmap rb, final long rangeStart, final l if (hbStart == hbLast) { final int i = rb.highLowContainer.getIndex((char) hbStart); final Container c = - i >= 0 ? rb.highLowContainer.getContainerAtIndex(i).add(lbStart, lbLast + 1) + i >= 0 + ? rb.highLowContainer.getContainerAtIndex(i).add(lbStart, lbLast + 1) : Container.rangeOfOnes(lbStart, lbLast + 1); answer.highLowContainer.append((char) hbStart, c); answer.highLowContainer.appendCopiesAfter(rb.highLowContainer, (char) hbLast); @@ -323,10 +326,12 @@ public static RoaringBitmap add(RoaringBitmap rb, final long rangeStart, final l int ilast = rb.highLowContainer.getIndex((char) hbLast); { - final Container c = ifirst >= 0 - ? rb.highLowContainer.getContainerAtIndex(ifirst).add(lbStart, - Util.maxLowBitAsInteger() + 1) - : Container.rangeOfOnes(lbStart, Util.maxLowBitAsInteger() + 1); + final Container c = + ifirst >= 0 + ? rb.highLowContainer + .getContainerAtIndex(ifirst) + .add(lbStart, Util.maxLowBitAsInteger() + 1) + : Container.rangeOfOnes(lbStart, Util.maxLowBitAsInteger() + 1); answer.highLowContainer.append((char) hbStart, c); } for (int hb = hbStart + 1; hb < hbLast; ++hb) { @@ -335,7 +340,8 @@ public static RoaringBitmap add(RoaringBitmap rb, final long rangeStart, final l } { final Container c = - ilast >= 0 ? rb.highLowContainer.getContainerAtIndex(ilast).add(0, lbLast + 1) + ilast >= 0 + ? rb.highLowContainer.getContainerAtIndex(ilast).add(0, lbLast + 1) : Container.rangeOfOnes(0, lbLast + 1); answer.highLowContainer.append((char) hbLast, c); } @@ -400,7 +406,6 @@ public static RoaringBitmap and(final RoaringBitmap x1, final RoaringBitmap x2) return answer; } - /** * Cardinality of Bitwise AND (intersection) operation. The provided bitmaps are *not* modified. * This operation is thread-safe as long as the provided bitmaps remain unchanged. @@ -497,13 +502,13 @@ public void add(final int... dat) { */ public void addN(final int[] dat, final int offset, final int n) { // let us validate the values first. - if((n < 0) || (offset < 0)) { + if ((n < 0) || (offset < 0)) { throw new IllegalArgumentException("Negative values do not make sense."); } - if(n == 0) { + if (n == 0) { return; // nothing to do } - if(offset + n > dat.length) { + if (offset + n > dat.length) { throw new IllegalArgumentException("Data source is too small."); } Container currentcont = null; @@ -514,24 +519,24 @@ public void addN(final int[] dat, final int offset, final int n) { if (currentcontainerindex >= 0) { currentcont = highLowContainer.getContainerAtIndex(currentcontainerindex); Container newcont = currentcont.add(Util.lowbits(val)); - if(newcont != currentcont) { + if (newcont != currentcont) { highLowContainer.setContainerAtIndex(currentcontainerindex, newcont); currentcont = newcont; } } else { - currentcontainerindex = - currentcontainerindex - 1; + currentcontainerindex = -currentcontainerindex - 1; final ArrayContainer newac = new ArrayContainer(); currentcont = newac.add(Util.lowbits(val)); highLowContainer.insertNewKeyValueAt(currentcontainerindex, currenthb, currentcont); } j++; - for( ; j < n; ++j) { + for (; j < n; ++j) { val = dat[j + offset]; char newhb = Util.highbits(val); - if(currenthb == newhb) {// easy case + if (currenthb == newhb) { // easy case // this could be quite frequent Container newcont = currentcont.add(Util.lowbits(val)); - if(newcont != currentcont) { + if (newcont != currentcont) { highLowContainer.setContainerAtIndex(currentcontainerindex, newcont); currentcont = newcont; } @@ -541,12 +546,12 @@ public void addN(final int[] dat, final int offset, final int n) { if (currentcontainerindex >= 0) { currentcont = highLowContainer.getContainerAtIndex(currentcontainerindex); Container newcont = currentcont.add(Util.lowbits(val)); - if(newcont != currentcont) { + if (newcont != currentcont) { highLowContainer.setContainerAtIndex(currentcontainerindex, newcont); currentcont = newcont; } } else { - currentcontainerindex = - currentcontainerindex - 1; + currentcontainerindex = -currentcontainerindex - 1; final ArrayContainer newac = new ArrayContainer(); currentcont = newac.add(Util.lowbits(val)); highLowContainer.insertNewKeyValueAt(currentcontainerindex, currenthb, currentcont); @@ -575,8 +580,8 @@ public static RoaringBitmap bitmapOf(final int... dat) { * @return a new bitmap */ public static RoaringBitmap bitmapOfUnordered(final int... data) { - RoaringBitmapWriter writer = writer().constantMemory() - .doPartialRadixSort().get(); + RoaringBitmapWriter writer = + writer().constantMemory().doPartialRadixSort().get(); writer.addMany(data); writer.flush(); return writer.getUnderlying(); @@ -654,8 +659,8 @@ public static RoaringBitmap flip(RoaringBitmap bm, final long rangeStart, final } else { // *think* the range of ones must never be // empty. - answer.highLowContainer.insertNewKeyValueAt(-j - 1, (char) hb, - Container.rangeOfOnes(containerStart, containerLast + 1)); + answer.highLowContainer.insertNewKeyValueAt( + -j - 1, (char) hb, Container.rangeOfOnes(containerStart, containerLast + 1)); } } // copy the containers after the active area. @@ -683,10 +688,6 @@ public static RoaringBitmap flip(RoaringBitmap rb, final int rangeStart, final i return flip(rb, rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - - - - /** * Checks whether the two bitmaps intersect. This can be much faster than calling "and" and * checking the cardinality of the result. @@ -719,20 +720,23 @@ public static boolean intersects(final RoaringBitmap x1, final RoaringBitmap x2) return false; } - // important: inputs should not have been computed lazily protected static RoaringBitmap lazyor(final RoaringBitmap x1, final RoaringBitmap x2) { final RoaringBitmap answer = new RoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = x1.highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - answer.highLowContainer.append(s1, x1.highLowContainer.getContainerAtIndex(pos1) - .lazyOR(x2.highLowContainer.getContainerAtIndex(pos2))); + answer.highLowContainer.append( + s1, + x1.highLowContainer + .getContainerAtIndex(pos1) + .lazyOR(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -766,12 +770,13 @@ protected static RoaringBitmap lazyor(final RoaringBitmap x1, final RoaringBitma } // important: inputs should not be reused - protected static RoaringBitmap lazyorfromlazyinputs(final RoaringBitmap x1, - final RoaringBitmap x2) { + protected static RoaringBitmap lazyorfromlazyinputs( + final RoaringBitmap x1, final RoaringBitmap x2) { final RoaringBitmap answer = new RoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = x1.highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); @@ -802,7 +807,7 @@ protected static RoaringBitmap lazyorfromlazyinputs(final RoaringBitmap x1, s1 = x1.highLowContainer.getKeyAtIndex(pos1); } else { Container c2 = x2.highLowContainer.getContainerAtIndex(pos2); - answer.highLowContainer.append(s2,c2); + answer.highLowContainer.append(s2, c2); pos2++; if (pos2 == length2) { break main; @@ -819,7 +824,6 @@ protected static RoaringBitmap lazyorfromlazyinputs(final RoaringBitmap x1, return answer; } - /** * Compute overall OR between bitmaps. * @@ -861,14 +865,18 @@ public static RoaringBitmap or(final RoaringBitmap x1, final RoaringBitmap x2) { final RoaringBitmap answer = new RoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = x1.highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - answer.highLowContainer.append(s1, x1.highLowContainer.getContainerAtIndex(pos1) - .or(x2.highLowContainer.getContainerAtIndex(pos2))); + answer.highLowContainer.append( + s1, + x1.highLowContainer + .getContainerAtIndex(pos1) + .or(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -981,7 +989,7 @@ public static int andNotCardinality(final RoaringBitmap x1, final RoaringBitmap ++pos1; } } - return (int)cardinality; + return (int) cardinality; } /** @@ -998,7 +1006,6 @@ public static RoaringBitmap remove(RoaringBitmap rb, final long rangeStart, fina return rb.clone(); // empty range } - final int hbStart = (Util.highbits(rangeStart)); final int lbStart = (Util.lowbits(rangeStart)); final int hbLast = (Util.highbits(rangeEnd - 1)); @@ -1020,8 +1027,10 @@ public static RoaringBitmap remove(RoaringBitmap rb, final long rangeStart, fina int ifirst = rb.highLowContainer.getIndex((char) hbStart); int ilast = rb.highLowContainer.getIndex((char) hbLast); if ((ifirst >= 0) && (lbStart != 0)) { - final Container c = rb.highLowContainer.getContainerAtIndex(ifirst).remove(lbStart, - Util.maxLowBitAsInteger() + 1); + final Container c = + rb.highLowContainer + .getContainerAtIndex(ifirst) + .remove(lbStart, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { answer.highLowContainer.append((char) hbStart, c); } @@ -1055,7 +1064,6 @@ public static RoaringBitmap remove(RoaringBitmap rb, final int rangeStart, final return remove(rb, rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - /** * Bitwise XOR (symmetric difference) operation. The provided bitmaps are *not* modified. This * operation is thread-safe as long as the provided bitmaps remain unchanged. @@ -1073,14 +1081,17 @@ public static RoaringBitmap xor(final RoaringBitmap x1, final RoaringBitmap x2) int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = x1.highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - final Container c = x1.highLowContainer.getContainerAtIndex(pos1) - .xor(x2.highLowContainer.getContainerAtIndex(pos2)); + final Container c = + x1.highLowContainer + .getContainerAtIndex(pos1) + .xor(x2.highLowContainer.getContainerAtIndex(pos2)); if (!c.isEmpty()) { answer.highLowContainer.append(s1, c); } @@ -1126,7 +1137,6 @@ public RoaringBitmap() { highLowContainer = new RoaringArray(); } - /** * Wrap an existing high low container */ @@ -1163,15 +1173,14 @@ public void add(final int x) { final char hb = Util.highbits(x); final int i = highLowContainer.getIndex(hb); if (i >= 0) { - highLowContainer.setContainerAtIndex(i, - highLowContainer.getContainerAtIndex(i).add(Util.lowbits(x))); + highLowContainer.setContainerAtIndex( + i, highLowContainer.getContainerAtIndex(i).add(Util.lowbits(x))); } else { final ArrayContainer newac = new ArrayContainer(); highLowContainer.insertNewKeyValueAt(-i - 1, hb, newac.add(Util.lowbits(x))); } } - /** * Add to the current bitmap all integers in [rangeStart,rangeEnd). * @@ -1201,8 +1210,8 @@ public void add(final long rangeStart, final long rangeEnd) { highLowContainer.getContainerAtIndex(i).iadd(containerStart, containerLast + 1); highLowContainer.setContainerAtIndex(i, c); } else { - highLowContainer.insertNewKeyValueAt(-i - 1, (char) hb, - Container.rangeOfOnes(containerStart, containerLast + 1)); + highLowContainer.insertNewKeyValueAt( + -i - 1, (char) hb, Container.rangeOfOnes(containerStart, containerLast + 1)); } } } @@ -1224,7 +1233,6 @@ public void add(final int rangeStart, final int rangeEnd) { add(rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - /** * Checks if the range intersects with the bitmap. * @param minimum the inclusive unsigned lower bound of the range @@ -1236,12 +1244,12 @@ public boolean intersects(long minimum, long supremum) { if (supremum <= minimum) { return false; } - int minKey = (int)(minimum >>> 16); - int supKey = (int)(supremum >>> 16); + int minKey = (int) (minimum >>> 16); + int supKey = (int) (supremum >>> 16); int length = highLowContainer.size; char[] keys = highLowContainer.keys; int limit = lowbitsAsInteger(supremum); - int index = Util.unsignedBinarySearch(keys, 0, length, (char)minKey); + int index = Util.unsignedBinarySearch(keys, 0, length, (char) minKey); int pos = index >= 0 ? index : -index - 1; int offset = index >= 0 ? lowbitsAsInteger(minimum) : 0; if (pos < length && supKey == (keys[pos])) { @@ -1258,19 +1266,20 @@ public boolean intersects(long minimum, long supremum) { offset = 0; ++pos; } - return pos < length && supKey == keys[pos] - && highLowContainer.getContainerAtIndex(pos) - .intersects(offset, limit); + return pos < length + && supKey == keys[pos] + && highLowContainer.getContainerAtIndex(pos).intersects(offset, limit); } - /** * In-place bitwise AND (intersection) operation. The current bitmap is modified. * * @param x2 other bitmap */ public void and(final RoaringBitmap x2) { - if(x2 == this) { return; } + if (x2 == this) { + return; + } int pos1 = 0, pos2 = 0, intersectionSize = 0; final int length1 = highLowContainer.size(), length2 = x2.highLowContainer.size(); @@ -1295,7 +1304,6 @@ public void and(final RoaringBitmap x2) { highLowContainer.resize(intersectionSize); } - /** * Computes AND between input bitmaps in the given range, from rangeStart (inclusive) to rangeEnd * (exclusive) @@ -1305,8 +1313,8 @@ public void and(final RoaringBitmap x2) { * @param rangeEnd exclusive ending of range * @return new result bitmap */ - public static RoaringBitmap and(final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + public static RoaringBitmap and( + final Iterator bitmaps, final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); Iterator bitmapsIterator; @@ -1330,21 +1338,18 @@ public static RoaringBitmap and(final Iterator bitmaps, * @deprecated use the version where longs specify the range. Negative range end are illegal. */ @Deprecated - public static RoaringBitmap and(final Iterator bitmaps, - final int rangeStart, final int rangeEnd) { + public static RoaringBitmap and( + final Iterator bitmaps, final int rangeStart, final int rangeEnd) { return and(bitmaps, (long) rangeStart, (long) rangeEnd); } - - - /** * In-place bitwise ANDNOT (difference) operation. The current bitmap is modified. * * @param x2 other bitmap */ public void andNot(final RoaringBitmap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -1381,7 +1386,6 @@ public void andNot(final RoaringBitmap x2) { highLowContainer.resize(intersectionSize); } - /** * Bitwise ANDNOT (difference) operation for the given range, rangeStart (inclusive) and rangeEnd * (exclusive). The provided bitmaps are *not* modified. This operation is thread-safe as long as @@ -1393,8 +1397,8 @@ public void andNot(final RoaringBitmap x2) { * @param rangeEnd end point of the range (exclusive) * @return result of the operation */ - public static RoaringBitmap andNot(final RoaringBitmap x1, final RoaringBitmap x2, - long rangeStart, long rangeEnd) { + public static RoaringBitmap andNot( + final RoaringBitmap x1, final RoaringBitmap x2, long rangeStart, long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); RoaringBitmap rb1 = selectRangeWithoutCopy(x1, rangeStart, rangeEnd); @@ -1417,8 +1421,8 @@ public static RoaringBitmap andNot(final RoaringBitmap x1, final RoaringBitmap x * endpoints are not allowed. */ @Deprecated - public static RoaringBitmap andNot(final RoaringBitmap x1, final RoaringBitmap x2, - final int rangeStart, final int rangeEnd) { + public static RoaringBitmap andNot( + final RoaringBitmap x1, final RoaringBitmap x2, final int rangeStart, final int rangeEnd) { return andNot(x1, x2, (long) rangeStart, (long) rangeEnd); } @@ -1429,21 +1433,19 @@ public static RoaringBitmap andNot(final RoaringBitmap x1, final RoaringBitmap x * @param rangeEnd end point of the range (exclusive). */ public void orNot(final RoaringBitmap other, long rangeEnd) { - if(other == this) { + if (other == this) { throw new UnsupportedOperationException("orNot between a bitmap and itself?"); } rangeSanityCheck(0, rangeEnd); - int maxKey = (int)((rangeEnd - 1) >>> 16); - int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int)(rangeEnd & 0xFFFF); + int maxKey = (int) ((rangeEnd - 1) >>> 16); + int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int) (rangeEnd & 0xFFFF); int size = 0; int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(), length2 = other.highLowContainer.size(); int s1 = length1 > 0 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; int s2 = length2 > 0 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; int remainder = 0; - for (int i = highLowContainer.size - 1; - i >= 0 && highLowContainer.keys[i] > maxKey; - --i) { + for (int i = highLowContainer.size - 1; i >= 0 && highLowContainer.keys[i] > maxKey; --i) { ++remainder; } int correction = 0; @@ -1463,44 +1465,51 @@ public void orNot(final RoaringBitmap other, long rangeEnd) { Container[] newValues = new Container[maxSize]; for (int key = 0; key <= maxKey && size < maxSize; ++key) { if (key == s1 && key == s2) { // actually need to do an or not - newValues[size] = highLowContainer.getContainerAtIndex(pos1) - .iorNot(other.highLowContainer.getContainerAtIndex(pos2), - key == maxKey ? lastRun : 0x10000); + newValues[size] = + highLowContainer + .getContainerAtIndex(pos1) + .iorNot( + other.highLowContainer.getContainerAtIndex(pos2), + key == maxKey ? lastRun : 0x10000); ++pos1; ++pos2; s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = key == maxKey - ? highLowContainer.getContainerAtIndex(pos1).ior( - RunContainer.rangeOfOnes(0, lastRun)) - : RunContainer.full(); + newValues[size] = + key == maxKey + ? highLowContainer + .getContainerAtIndex(pos1) + .ior(RunContainer.rangeOfOnes(0, lastRun)) + : RunContainer.full(); ++pos1; s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement - newValues[size] = other.highLowContainer.getContainerAtIndex(pos2) + newValues[size] = + other + .highLowContainer + .getContainerAtIndex(pos2) .not(0, key == maxKey ? lastRun : 0x10000); ++pos2; s2 = pos2 < length2 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else { // key missing from both - newValues[size] = key == maxKey - ? RunContainer.rangeOfOnes(0, lastRun) - : RunContainer.full(); + newValues[size] = + key == maxKey ? RunContainer.rangeOfOnes(0, lastRun) : RunContainer.full(); } // might have appended an empty container (rare case) if (newValues[size].isEmpty()) { newValues[size] = null; } else { - newKeys[size] = (char)key; + newKeys[size] = (char) key; ++size; } } // copy over everything which will remain without being complemented if (remainder > 0) { - System.arraycopy(highLowContainer.keys, highLowContainer.size - remainder, - newKeys, size, remainder); - System.arraycopy(highLowContainer.values, highLowContainer.size - remainder, - newValues, size, remainder); + System.arraycopy( + highLowContainer.keys, highLowContainer.size - remainder, newKeys, size, remainder); + System.arraycopy( + highLowContainer.values, highLowContainer.size - remainder, newValues, size, remainder); } highLowContainer.keys = newKeys; highLowContainer.values = newValues; @@ -1518,11 +1527,10 @@ public void orNot(final RoaringBitmap other, long rangeEnd) { * @param rangeEnd end point of the range (exclusive) * @return result of the operation */ - public static RoaringBitmap orNot( - final RoaringBitmap x1, final RoaringBitmap x2, long rangeEnd) { + public static RoaringBitmap orNot(final RoaringBitmap x1, final RoaringBitmap x2, long rangeEnd) { rangeSanityCheck(0, rangeEnd); - int maxKey = (int)((rangeEnd - 1) >>> 16); - int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int)(rangeEnd & 0xFFFF); + int maxKey = (int) ((rangeEnd - 1) >>> 16); + int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int) (rangeEnd & 0xFFFF); int size = 0; int pos1 = 0, pos2 = 0; int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); @@ -1530,8 +1538,8 @@ public static RoaringBitmap orNot( int s2 = length2 > 0 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; int remainder = 0; for (int i = x1.highLowContainer.size - 1; - i >= 0 && x1.highLowContainer.keys[i] > maxKey; - --i) { + i >= 0 && x1.highLowContainer.keys[i] > maxKey; + --i) { ++remainder; } int correction = 0; @@ -1551,43 +1559,51 @@ public static RoaringBitmap orNot( Container[] newValues = new Container[maxSize]; for (int key = 0; key <= maxKey && size < maxSize; ++key) { if (key == s1 && key == s2) { // actually need to do an or not - newValues[size] = x1.highLowContainer.getContainerAtIndex(pos1) - .orNot(x2.highLowContainer.getContainerAtIndex(pos2), - key == maxKey ? lastRun : 0x10000); + newValues[size] = + x1.highLowContainer + .getContainerAtIndex(pos1) + .orNot( + x2.highLowContainer.getContainerAtIndex(pos2), + key == maxKey ? lastRun : 0x10000); ++pos1; ++pos2; s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = key == maxKey - ? x1.highLowContainer.getContainerAtIndex(pos1).ior( - RunContainer.rangeOfOnes(0, lastRun)) - : RunContainer.full(); + newValues[size] = + key == maxKey + ? x1.highLowContainer + .getContainerAtIndex(pos1) + .ior(RunContainer.rangeOfOnes(0, lastRun)) + : RunContainer.full(); ++pos1; s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement - newValues[size] = x2.highLowContainer.getContainerAtIndex(pos2) - .not(0, key == maxKey ? lastRun : 0x10000); + newValues[size] = + x2.highLowContainer.getContainerAtIndex(pos2).not(0, key == maxKey ? lastRun : 0x10000); ++pos2; s2 = pos2 < length2 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else { // key missing from both - newValues[size] = key == maxKey - ? RunContainer.rangeOfOnes(0, lastRun) - : RunContainer.full(); + newValues[size] = + key == maxKey ? RunContainer.rangeOfOnes(0, lastRun) : RunContainer.full(); } // might have appended an empty container (rare case) if (newValues[size].isEmpty()) { newValues[size] = null; } else { - newKeys[size++] = (char)key; + newKeys[size++] = (char) key; } } // copy over everything which will remain without being complemented if (remainder > 0) { - System.arraycopy(x1.highLowContainer.keys, x1.highLowContainer.size - remainder, - newKeys, size, remainder); - System.arraycopy(x1.highLowContainer.values, x1.highLowContainer.size - remainder, - newValues, size, remainder); + System.arraycopy( + x1.highLowContainer.keys, x1.highLowContainer.size - remainder, newKeys, size, remainder); + System.arraycopy( + x1.highLowContainer.values, + x1.highLowContainer.size - remainder, + newValues, + size, + remainder); for (int i = size; i < size + remainder; ++i) { newValues[i] = newValues[i].clone(); } @@ -1599,8 +1615,6 @@ public static RoaringBitmap orNot( return result; } - - /** * Add the value to the container (set the value to "true"), whether it already appears or not. * @@ -1720,21 +1734,21 @@ public boolean contains(long minimum, long supremum) { } int begin = highLowContainer.getIndex(firstKey); int end = highLowContainer.getIndex(lastKey); - end = end < 0 ? -end -1 : end; + end = end < 0 ? -end - 1 : end; if (begin < 0 || end - begin != span) { return false; } - int min = (char)minimum; - int sup = (char)supremum; + int min = (char) minimum; + int sup = (char) supremum; if (firstKey == lastKey) { - return highLowContainer.getContainerAtIndex(begin) - .contains(min, (supremum & 0xFFFF) == 0 ? 0x10000 : sup); + return highLowContainer + .getContainerAtIndex(begin) + .contains(min, (supremum & 0xFFFF) == 0 ? 0x10000 : sup); } if (!highLowContainer.getContainerAtIndex(begin).contains(min, 1 << 16)) { return false; } - if (sup != 0 && end < len && !highLowContainer.getContainerAtIndex(end) - .contains(0, sup)) { + if (sup != 0 && end < len && !highLowContainer.getContainerAtIndex(end).contains(0, sup)) { return false; } for (int i = begin + 1; i < end; ++i) { @@ -1745,7 +1759,6 @@ public boolean contains(long minimum, long supremum) { return true; } - /** * Deserialize (retrieve) this bitmap. See format specification at * https://github.com/RoaringBitmap/RoaringFormatSpec @@ -1762,8 +1775,8 @@ public boolean contains(long minimum, long supremum) { public void deserialize(DataInput in, byte[] buffer) throws IOException { try { this.highLowContainer.deserialize(in, buffer); - } catch(InvalidRoaringFormat cookie) { - throw cookie.toIOException();// we convert it to an IOException + } catch (InvalidRoaringFormat cookie) { + throw cookie.toIOException(); // we convert it to an IOException } } @@ -1779,8 +1792,8 @@ public void deserialize(DataInput in, byte[] buffer) throws IOException { public void deserialize(DataInput in) throws IOException { try { this.highLowContainer.deserialize(in); - } catch(InvalidRoaringFormat cookie) { - throw cookie.toIOException();// we convert it to an IOException + } catch (InvalidRoaringFormat cookie) { + throw cookie.toIOException(); // we convert it to an IOException } } @@ -1805,8 +1818,8 @@ public void deserialize(DataInput in) throws IOException { public void deserialize(ByteBuffer bbf) throws IOException { try { this.highLowContainer.deserialize(bbf); - } catch(InvalidRoaringFormat cookie) { - throw cookie.toIOException();// we convert it to an IOException + } catch (InvalidRoaringFormat cookie) { + throw cookie.toIOException(); // we convert it to an IOException } } @@ -1834,16 +1847,16 @@ public boolean isHammingSimilar(RoaringBitmap other, int tolerance) { int pos1 = 0; int pos2 = 0; int budget = tolerance; - while(budget >= 0 && pos1 < size1 && pos2 < size2) { + while (budget >= 0 && pos1 < size1 && pos2 < size2) { final char key1 = this.highLowContainer.getKeyAtIndex(pos1); final char key2 = other.highLowContainer.getKeyAtIndex(pos2); Container left = highLowContainer.getContainerAtIndex(pos1); Container right = other.highLowContainer.getContainerAtIndex(pos2); - if(key1 == key2) { + if (key1 == key2) { budget -= left.xorCardinality(right); ++pos1; ++pos2; - } else if(key1 < key2) { + } else if (key1 < key2) { budget -= left.getCardinality(); ++pos1; } else { @@ -1851,11 +1864,11 @@ public boolean isHammingSimilar(RoaringBitmap other, int tolerance) { ++pos2; } } - while(budget >= 0 && pos1 < size1) { + while (budget >= 0 && pos1 < size1) { Container container = highLowContainer.getContainerAtIndex(pos1++); budget -= container.getCardinality(); } - while(budget >= 0 && pos2 < size2) { + while (budget >= 0 && pos2 < size2) { Container container = other.highLowContainer.getContainerAtIndex(pos2++); budget -= container.getCardinality(); } @@ -1918,14 +1931,13 @@ public void flip(final long rangeStart, final long rangeEnd) { highLowContainer.removeAtIndex(i); } } else { - highLowContainer.insertNewKeyValueAt(-i - 1, (char) hb, - Container.rangeOfOnes(containerStart, containerLast + 1)); + highLowContainer.insertNewKeyValueAt( + -i - 1, (char) hb, Container.rangeOfOnes(containerStart, containerLast + 1)); } } } - - /** + /** * Modifies the current bitmap by complementing the bits in the given range, from rangeStart * (inclusive) rangeEnd (exclusive). * @@ -1944,10 +1956,6 @@ public void flip(final int rangeStart, final int rangeEnd) { } } - - - - /** * Returns the number of distinct integers added to the bitmap (e.g., number of bits set). * @@ -2009,18 +2017,21 @@ public void forAllInRange(int uStart, int length, final RelativeRangeConsumer rr final long endInclusiveL = startL + (long) (length - 1); if (endInclusiveL > LongUtils.MAX_UNSIGNED_INT) { final long remainingLength = LongUtils.MAX_UNSIGNED_INT - startL + 1L; - throw new IllegalArgumentException("Cannot read past the end of the unsigned integer range. " - + remainingLength + " values remaining; requested " + length); + throw new IllegalArgumentException( + "Cannot read past the end of the unsigned integer range. " + + remainingLength + + " values remaining; requested " + + length); } final int uEndInclusive = (int) endInclusiveL; - final char endHigh = Util.highbits(uEndInclusive); + final char endHigh = Util.highbits(uEndInclusive); int startIndex = highLowContainer.getContainerIndex(startHigh); startIndex = startIndex < 0 ? -startIndex - 1 : startIndex; int uFilledUntil = uStart; for (int containerIndex = startIndex; - containerIndex < highLowContainer.size(); - containerIndex++) { + containerIndex < highLowContainer.size(); + containerIndex++) { if (Integer.compareUnsigned(uEndInclusive, uFilledUntil) < 0) { // We are done, no need to look at the next container. return; @@ -2034,7 +2045,7 @@ public void forAllInRange(int uStart, int length, final RelativeRangeConsumer rr final int fillFromRelative = uFilledUntil - uStart; // This should always result in a non-negative number, since unsigned // `uFilledUntil >= uStart`. - assert(fillFromRelative >= 0); + assert (fillFromRelative >= 0); rrc.acceptAllAbsent(fillFromRelative, length); } return; @@ -2045,8 +2056,8 @@ public void forAllInRange(int uStart, int length, final RelativeRangeConsumer rr final int fillToRelative = uContainerStart - uStart; // These should always result in a non-negative number, since unsigned // `uFilledUntil >= uStart`. - assert(fillFromRelative >= 0); - assert(fillToRelative >= 0); + assert (fillFromRelative >= 0); + assert (fillToRelative >= 0); rrc.acceptAllAbsent(fillFromRelative, fillToRelative); uFilledUntil = uContainerStart; } @@ -2055,7 +2066,7 @@ public void forAllInRange(int uStart, int length, final RelativeRangeConsumer rr final int containerRangeStartOffset = uFilledUntil - uStart; // These should always result in a non-negative number, since unsigned // `uFilledUntil >= uStart`. - assert(containerRangeStartOffset >= 0); + assert (containerRangeStartOffset >= 0); final boolean startInContainer = Integer.compareUnsigned(uContainerStart, uStart) < 0; final boolean endInContainer = @@ -2066,31 +2077,28 @@ public void forAllInRange(int uStart, int length, final RelativeRangeConsumer rr final char containerRangeStart = LongUtils.lowPart(uStart); final int uEndExclusive = uEndInclusive + 1; // This block should only be entered when this addition is legal. - assert(Integer.compareUnsigned(uEndInclusive, uEndExclusive) < 0); + assert (Integer.compareUnsigned(uEndInclusive, uEndExclusive) < 0); final char containerRangeEnd = LongUtils.lowPart(uEndExclusive); - container.forAllInRange( - containerRangeStart, - containerRangeEnd, - rrc); + container.forAllInRange(containerRangeStart, containerRangeEnd, rrc); return; - } else if (startInContainer) {// && !endInContainer + } else if (startInContainer) { // && !endInContainer // Range begins within the container. final char containerRangeStart = LongUtils.lowPart(uStart); container.forAllFrom(containerRangeStart, rrc); final int numValuesAdded = BitmapContainer.MAX_CAPACITY - (int) containerRangeStart; // Must be non-negative, since both are basically char-sized values. - assert(numValuesAdded >= 0); + assert (numValuesAdded >= 0); final int uOldFilledUntil = uFilledUntil; uFilledUntil += numValuesAdded; if (Integer.compareUnsigned(uFilledUntil, uOldFilledUntil) < 0) { // Wrapped the fill counter, so we must have completed the filling. return; } - } else if (endInContainer) {// && !startInContainer + } else if (endInContainer) { // && !startInContainer // Range ends within the container. final int uEndExclusive = uEndInclusive + 1; // This block should only be entered when this addition is legal. - assert(Integer.compareUnsigned(uEndInclusive, uEndExclusive) < 0); + assert (Integer.compareUnsigned(uEndInclusive, uEndExclusive) < 0); final char containerRangeEnd = LongUtils.lowPart(uEndExclusive); container.forAllUntil(containerRangeStartOffset, containerRangeEnd, rrc); return; @@ -2111,7 +2119,7 @@ public void forAllInRange(int uStart, int length, final RelativeRangeConsumer rr final int fillToRelative = length; // These should always result in a non-negative number, since unsigned // `uFilledUntil >= uStart`. - assert(fillFromRelative >= 0); + assert (fillFromRelative >= 0); rrc.acceptAllAbsent(fillFromRelative, fillToRelative); } } @@ -2127,7 +2135,6 @@ public void forEachInRange(int start, int length, final IntConsumer ic) { forAllInRange(start, length, new IntConsumerRelativeRangeAdapter(start, ic)); } - /** * Return a low-level container pointer that can be used to access the underlying data structure. * @@ -2137,7 +2144,6 @@ public ContainerPointer getContainerPointer() { return this.highLowContainer.getContainerPointer(); } - /** * * For better performance, consider using the {@link #forEach forEach} method. @@ -2167,7 +2173,6 @@ public IntIterator getReverseIntIterator() { return new RoaringReverseIntIterator(); } - @Override public RoaringBatchIterator getBatchIterator() { return new RoaringBatchIterator(highLowContainer); @@ -2255,7 +2260,7 @@ public long getLongSizeInBytes() { */ @Override public int getSizeInBytes() { - return (int) getLongSizeInBytes() ; + return (int) getLongSizeInBytes(); } /** @@ -2276,7 +2281,6 @@ public int hashCode() { return highLowContainer.hashCode(); } - /** * Check whether this bitmap has had its runs compressed. * @@ -2302,7 +2306,6 @@ public boolean isEmpty() { return highLowContainer.size() == 0; } - /** * iterate over the positions of the true values. * @@ -2347,26 +2350,30 @@ public void remove() { // todo: implement throw new UnsupportedOperationException(); } - }.init(); } - // don't forget to call repairAfterLazy() afterward // important: x2 should not have been computed lazily protected void lazyor(final RoaringBitmap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - this.highLowContainer.setContainerAtIndex(pos1, highLowContainer.getContainerAtIndex(pos1) - .lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); + this.highLowContainer.setContainerAtIndex( + pos1, + highLowContainer + .getContainerAtIndex(pos1) + .lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -2381,8 +2388,8 @@ protected void lazyor(final RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { - highLowContainer.insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + highLowContainer.insertNewKeyValueAt( + pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -2402,20 +2409,23 @@ protected void lazyor(final RoaringBitmap x2) { // important: x2 should not have been computed lazily // this method is like lazyor except that it will convert // the current container to a bitset - protected void naivelazyor(RoaringBitmap x2) { - if(this == x2) { return; } + protected void naivelazyor(RoaringBitmap x2) { + if (this == x2) { + return; + } int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { BitmapContainer c1 = highLowContainer.getContainerAtIndex(pos1).toBitmapContainer(); - this.highLowContainer.setContainerAtIndex(pos1, - c1.lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); + this.highLowContainer.setContainerAtIndex( + pos1, c1.lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -2430,8 +2440,8 @@ protected void naivelazyor(RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { - highLowContainer.insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + highLowContainer.insertNewKeyValueAt( + pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -2457,8 +2467,9 @@ protected void naivelazyor(RoaringBitmap x2) { public RoaringBitmap limit(int maxcardinality) { RoaringBitmap answer = new RoaringBitmap(); int currentcardinality = 0; - for (int i = 0; (currentcardinality < maxcardinality) - && (i < this.highLowContainer.size()); i++) { + for (int i = 0; + (currentcardinality < maxcardinality) && (i < this.highLowContainer.size()); + i++) { Container c = this.highLowContainer.getContainerAtIndex(i); if (c.getCardinality() + currentcardinality <= maxcardinality) { answer.highLowContainer.appendCopy(this.highLowContainer, i); @@ -2479,18 +2490,24 @@ public RoaringBitmap limit(int maxcardinality) { * @param x2 other bitmap */ public void or(final RoaringBitmap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - this.highLowContainer.setContainerAtIndex(pos1, highLowContainer.getContainerAtIndex(pos1) - .ior(x2.highLowContainer.getContainerAtIndex(pos2))); + this.highLowContainer.setContainerAtIndex( + pos1, + highLowContainer + .getContainerAtIndex(pos1) + .ior(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -2505,8 +2522,8 @@ public void or(final RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { - highLowContainer.insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + highLowContainer.insertNewKeyValueAt( + pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -2522,8 +2539,6 @@ public void or(final RoaringBitmap x2) { } } - - /** * Computes OR between input bitmaps in the given range, from rangeStart (inclusive) to rangeEnd * (exclusive) @@ -2533,8 +2548,8 @@ public void or(final RoaringBitmap x2) { * @param rangeEnd exclusive ending of range * @return new result bitmap */ - public static RoaringBitmap or(final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + public static RoaringBitmap or( + final Iterator bitmaps, final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); Iterator bitmapsIterator; @@ -2542,7 +2557,6 @@ public static RoaringBitmap or(final Iterator bitmaps, return or(bitmapsIterator); } - /** * Computes OR between input bitmaps in the given range, from rangeStart (inclusive) to rangeEnd * (exclusive) @@ -2554,12 +2568,11 @@ public static RoaringBitmap or(final Iterator bitmaps, * Negative range points are forbidden. */ @Deprecated - public static RoaringBitmap or(final Iterator bitmaps, - final int rangeStart, final int rangeEnd) { + public static RoaringBitmap or( + final Iterator bitmaps, final int rangeStart, final int rangeEnd) { return or(bitmaps, (long) rangeStart, (long) rangeEnd); } - /** * Rank returns the number of integers that are smaller or equal to x (Rank(infinity) would be * GetCardinality()). If you provide the smallest value as a parameter, this function will @@ -2588,19 +2601,20 @@ public long rankLong(int x) { @Override public long rangeCardinality(long start, long end) { - if(Long.compareUnsigned(start, end) >= 0) { + if (Long.compareUnsigned(start, end) >= 0) { return 0; } long size = 0; int startIndex = this.highLowContainer.getIndex(Util.highbits(start)); - if(startIndex < 0) { + if (startIndex < 0) { startIndex = -startIndex - 1; } else { int inContainerStart = (Util.lowbits(start)); - if(inContainerStart != 0) { - size -= this.highLowContainer - .getContainerAtIndex(startIndex) - .rank((char)(inContainerStart - 1)); + if (inContainerStart != 0) { + size -= + this.highLowContainer + .getContainerAtIndex(startIndex) + .rank((char) (inContainerStart - 1)); } } char xhigh = Util.highbits(end - 1); @@ -2609,15 +2623,13 @@ public long rangeCardinality(long start, long end) { if (key < xhigh) { size += this.highLowContainer.getContainerAtIndex(i).getCardinality(); } else if (key == xhigh) { - return size + this.highLowContainer - .getContainerAtIndex(i).rank(Util.lowbits((int)(end - 1))); + return size + + this.highLowContainer.getContainerAtIndex(i).rank(Util.lowbits((int) (end - 1))); } } return size; } - - @Override public int rank(int x) { return (int) rankLong(x); @@ -2640,8 +2652,8 @@ public void remove(final int x) { if (i < 0) { return; } - highLowContainer.setContainerAtIndex(i, - highLowContainer.getContainerAtIndex(i).remove(Util.lowbits(x))); + highLowContainer.setContainerAtIndex( + i, highLowContainer.getContainerAtIndex(i).remove(Util.lowbits(x))); if (highLowContainer.getContainerAtIndex(i).isEmpty()) { highLowContainer.removeAtIndex(i); } @@ -2661,7 +2673,6 @@ public void remove(final long rangeStart, final long rangeEnd) { return; // empty range } - final int hbStart = (Util.highbits(rangeStart)); final int lbStart = (Util.lowbits(rangeStart)); final int hbLast = (Util.highbits(rangeEnd - 1)); @@ -2683,8 +2694,10 @@ public void remove(final long rangeStart, final long rangeEnd) { int ilast = highLowContainer.getIndex((char) hbLast); if (ifirst >= 0) { if (lbStart != 0) { - final Container c = highLowContainer.getContainerAtIndex(ifirst).iremove(lbStart, - Util.maxLowBitAsInteger() + 1); + final Container c = + highLowContainer + .getContainerAtIndex(ifirst) + .iremove(lbStart, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { highLowContainer.setContainerAtIndex(ifirst, c); ifirst++; @@ -2710,8 +2723,6 @@ public void remove(final long rangeStart, final long rangeEnd) { highLowContainer.removeIndexRange(ifirst, ilast); } - - /** * Remove from the current bitmap all integers in [rangeStart,rangeEnd). * @@ -2729,7 +2740,6 @@ public void remove(final int rangeStart, final int rangeEnd) { remove(rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - /** * Remove run-length encoding even when it is more space efficient * @@ -2788,7 +2798,7 @@ public boolean contains(RoaringBitmap subset) { if (s1 == s2) { Container c1 = this.highLowContainer.getContainerAtIndex(pos1); Container c2 = subset.highLowContainer.getContainerAtIndex(pos2); - if(!c1.contains(c2)) { + if (!c1.contains(c2)) { return false; } ++pos1; @@ -2802,7 +2812,6 @@ public boolean contains(RoaringBitmap subset) { return pos2 == length2; } - /** * Return the jth value stored in this bitmap. The provided value * needs to be smaller than the cardinality otherwise an @@ -2824,14 +2833,17 @@ public int select(int j) { int thiscard = c.getCardinality(); if (thiscard > leftover) { int keycontrib = this.highLowContainer.getKeyAtIndex(i) << 16; - int lowcontrib = (c.select((int)leftover)); + int lowcontrib = (c.select((int) leftover)); return lowcontrib + keycontrib; } leftover -= thiscard; } - throw new IllegalArgumentException("You are trying to select the " - + j + "th value when the cardinality is " - + this.getCardinality() + "."); + throw new IllegalArgumentException( + "You are trying to select the " + + j + + "th value when the cardinality is " + + this.getCardinality() + + "."); } @Override @@ -2842,7 +2854,8 @@ public long nextValue(int fromValue) { while (containerIndex < highLowContainer.size() && nextSetBit == -1L) { char containerKey = highLowContainer.getKeyAtIndex(containerIndex); Container container = highLowContainer.getContainerAtIndex(containerIndex); - int bit = (containerKey - key > 0 + int bit = + (containerKey - key > 0 ? container.first() : container.nextValue(Util.lowbits(fromValue))); nextSetBit = bit == -1 ? -1L : Util.toUnsignedLong((containerKey << 16) | bit); @@ -2871,7 +2884,8 @@ public long previousValue(int fromValue) { while (containerIndex != -1 && prevSetBit == -1L) { char containerKey = highLowContainer.getKeyAtIndex(containerIndex); Container container = highLowContainer.getContainerAtIndex(containerIndex); - int bit = (containerKey < key + int bit = + (containerKey < key ? container.last() : container.previousValue(Util.lowbits(fromValue))); prevSetBit = bit == -1 ? -1L : Util.toUnsignedLong((containerKey << 16) | bit); @@ -2885,7 +2899,7 @@ public long previousValue(int fromValue) { @Override public long nextAbsentValue(int fromValue) { long nextAbsentBit = computeNextAbsentValue(fromValue); - if(nextAbsentBit == 0x100000000L) { + if (nextAbsentBit == 0x100000000L) { return -1L; } return nextAbsentBit; @@ -3018,7 +3032,6 @@ public void serialize(ByteBuffer buffer) { highLowContainer.serialize(buffer); } - /** * Assume that one wants to store "cardinality" integers in [0, universe_size), this function * returns an upper bound on the serialized size in bytes. @@ -3060,27 +3073,27 @@ public int serializedSizeInBytes() { * @param rangeEnd exclusive * @return new iterator of bitmaps */ - private static Iterator selectRangeWithoutCopy(final - Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + private static Iterator selectRangeWithoutCopy( + final Iterator bitmaps, final long rangeStart, final long rangeEnd) { Iterator bitmapsIterator; - bitmapsIterator = new Iterator() { - @Override - public boolean hasNext() { - return bitmaps.hasNext(); - } + bitmapsIterator = + new Iterator() { + @Override + public boolean hasNext() { + return bitmaps.hasNext(); + } - @Override - public RoaringBitmap next() { - RoaringBitmap next = bitmaps.next(); - return selectRangeWithoutCopy(next, rangeStart, rangeEnd); - } + @Override + public RoaringBitmap next() { + RoaringBitmap next = bitmaps.next(); + return selectRangeWithoutCopy(next, rangeStart, rangeEnd); + } - @Override - public void remove() { - throw new UnsupportedOperationException("Remove not supported"); - } - }; + @Override + public void remove() { + throw new UnsupportedOperationException("Remove not supported"); + } + }; return bitmapsIterator; } @@ -3099,7 +3112,7 @@ public RoaringBitmap selectRange(final long rangeStart, final long rangeEnd) { final int lbLast = (Util.lowbits(rangeEnd - 1)); RoaringBitmap answer = new RoaringBitmap(); - assert(rangeStart >= 0 && rangeEnd >= 0); + assert (rangeStart >= 0 && rangeEnd >= 0); if (rangeEnd <= rangeStart) { return answer; @@ -3108,8 +3121,11 @@ public RoaringBitmap selectRange(final long rangeStart, final long rangeEnd) { if (hbStart == hbLast) { final int i = this.highLowContainer.getIndex((char) hbStart); if (i >= 0) { - final Container c = this.highLowContainer.getContainerAtIndex(i).remove(0, lbStart) - .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); + final Container c = + this.highLowContainer + .getContainerAtIndex(i) + .remove(0, lbStart) + .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { answer.highLowContainer.append((char) hbStart, c); } @@ -3127,19 +3143,21 @@ public RoaringBitmap selectRange(final long rangeStart, final long rangeEnd) { // revised to loop on ints for (int hb = hbStart + 1; hb <= hbLast - 1; ++hb) { - final int i = this.highLowContainer.getIndex((char)hb); + final int i = this.highLowContainer.getIndex((char) hb); final int j = answer.highLowContainer.getIndex((char) hb); assert j < 0; if (i >= 0) { final Container c = this.highLowContainer.getContainerAtIndex(i); - answer.highLowContainer.insertNewKeyValueAt(-j - 1, (char)hb, c.clone()); + answer.highLowContainer.insertNewKeyValueAt(-j - 1, (char) hb, c.clone()); } } if (ilast >= 0) { - final Container c = this.highLowContainer.getContainerAtIndex(ilast).remove(lbLast + 1, - Util.maxLowBitAsInteger() + 1); + final Container c = + this.highLowContainer + .getContainerAtIndex(ilast) + .remove(lbLast + 1, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { answer.highLowContainer.append((char) hbLast, c); } @@ -3157,15 +3175,15 @@ public RoaringBitmap selectRange(final long rangeStart, final long rangeEnd) { * @param rangeEnd exclusive * @return new bitmap */ - private static RoaringBitmap selectRangeWithoutCopy(RoaringBitmap rb, final long rangeStart, - final long rangeEnd) { + private static RoaringBitmap selectRangeWithoutCopy( + RoaringBitmap rb, final long rangeStart, final long rangeEnd) { final int hbStart = (Util.highbits(rangeStart)); final int lbStart = (Util.lowbits(rangeStart)); final int hbLast = (Util.highbits(rangeEnd - 1)); final int lbLast = (Util.lowbits(rangeEnd - 1)); RoaringBitmap answer = new RoaringBitmap(); - assert(rangeStart >= 0 && rangeEnd >= 0); + assert (rangeStart >= 0 && rangeEnd >= 0); if (rangeEnd <= rangeStart) { return answer; @@ -3174,8 +3192,11 @@ private static RoaringBitmap selectRangeWithoutCopy(RoaringBitmap rb, final long if (hbStart == hbLast) { final int i = rb.highLowContainer.getIndex((char) hbStart); if (i >= 0) { - final Container c = rb.highLowContainer.getContainerAtIndex(i).remove(0, lbStart) - .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); + final Container c = + rb.highLowContainer + .getContainerAtIndex(i) + .remove(0, lbStart) + .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { answer.highLowContainer.append((char) hbStart, c); } @@ -3193,19 +3214,21 @@ private static RoaringBitmap selectRangeWithoutCopy(RoaringBitmap rb, final long // revised to loop on ints for (int hb = hbStart + 1; hb <= hbLast - 1; ++hb) { - final int i = rb.highLowContainer.getIndex((char)hb); + final int i = rb.highLowContainer.getIndex((char) hb); final int j = answer.highLowContainer.getIndex((char) hb); assert j < 0; if (i >= 0) { final Container c = rb.highLowContainer.getContainerAtIndex(i); - answer.highLowContainer.insertNewKeyValueAt(-j - 1, (char)hb, c); + answer.highLowContainer.insertNewKeyValueAt(-j - 1, (char) hb, c); } } if (ilast >= 0) { - final Container c = rb.highLowContainer.getContainerAtIndex(ilast).remove(lbLast + 1, - Util.maxLowBitAsInteger() + 1); + final Container c = + rb.highLowContainer + .getContainerAtIndex(ilast) + .remove(lbLast + 1, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { answer.highLowContainer.append((char) hbLast, c); } @@ -3213,7 +3236,6 @@ private static RoaringBitmap selectRangeWithoutCopy(RoaringBitmap rb, final long return answer; } - /** * Return the set values as an array, if the cardinality is smaller than 2147483648. * The integer values are in sorted order. @@ -3264,7 +3286,7 @@ public String toString() { while (i.hasNext()) { answer.append(','); // to avoid using too much memory, we limit the size - if(answer.length() > 0x80000) { + if (answer.length() > 0x80000) { answer.append('.').append('.').append('.'); break; } @@ -3282,7 +3304,6 @@ public void trim() { this.highLowContainer.trim(); } - @Override public void writeExternal(ObjectOutput out) throws IOException { this.highLowContainer.writeExternal(out); @@ -3294,7 +3315,7 @@ public void writeExternal(ObjectOutput out) throws IOException { * @param x2 other bitmap */ public void xor(final RoaringBitmap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -3302,14 +3323,17 @@ public void xor(final RoaringBitmap x2) { int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - final Container c = highLowContainer.getContainerAtIndex(pos1) - .ixor(x2.highLowContainer.getContainerAtIndex(pos2)); + final Container c = + highLowContainer + .getContainerAtIndex(pos1) + .ixor(x2.highLowContainer.getContainerAtIndex(pos2)); if (!c.isEmpty()) { this.highLowContainer.setContainerAtIndex(pos1, c); pos1++; @@ -3330,8 +3354,8 @@ public void xor(final RoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { - highLowContainer.insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + highLowContainer.insertNewKeyValueAt( + pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -3356,8 +3380,8 @@ public void xor(final RoaringBitmap x2) { * @param rangeEnd exclusive ending of range * @return new result bitmap */ - public static RoaringBitmap xor(final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + public static RoaringBitmap xor( + final Iterator bitmaps, final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); Iterator bitmapsIterator; bitmapsIterator = selectRangeWithoutCopy(bitmaps, rangeStart, rangeEnd); @@ -3376,8 +3400,8 @@ public static RoaringBitmap xor(final Iterator bitmaps, * Negative values not allowed for rangeStart and rangeEnd */ @Deprecated - public static RoaringBitmap xor(final Iterator bitmaps, - final int rangeStart, final int rangeEnd) { + public static RoaringBitmap xor( + final Iterator bitmaps, final int rangeStart, final int rangeEnd) { return xor(bitmaps, (long) rangeStart, (long) rangeEnd); } @@ -3390,5 +3414,4 @@ public static RoaringBitmap xor(final Iterator bitmaps, public int getContainerCount() { return highLowContainer.size(); } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java index abe48673a..d1cac33a1 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapSupplier.java @@ -16,5 +16,4 @@ public class RoaringBitmapSupplier implements BitmapDataProviderSupplier { public BitmapDataProvider newEmpty() { return new RoaringBitmap(); } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java index f06ecc207..a04f290cc 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RoaringBitmapWriter.java @@ -1,6 +1,10 @@ package org.roaringbitmap; -import org.roaringbitmap.buffer.*; +import org.roaringbitmap.buffer.MappeableArrayContainer; +import org.roaringbitmap.buffer.MappeableContainer; +import org.roaringbitmap.buffer.MappeableRunContainer; +import org.roaringbitmap.buffer.MutableRoaringArray; +import org.roaringbitmap.buffer.MutableRoaringBitmap; import java.util.function.Supplier; @@ -14,9 +18,9 @@ static Wizard bufferWriter() { return new BufferWizard(); } - abstract class Wizard, - T extends BitmapDataProvider & AppendableStorage> - implements Supplier> { + abstract class Wizard< + C extends WordStorage, T extends BitmapDataProvider & AppendableStorage> + implements Supplier> { protected int initialCapacity = RoaringArray.INITIAL_CAPACITY; protected boolean constantMemory; @@ -152,8 +156,8 @@ public Wizard doPartialRadixSort() { @Override public RoaringBitmapWriter get() { int capacity = initialCapacity; - return new ContainerAppender<>(partiallySortValues, runCompress, - () -> createUnderlying(capacity), containerSupplier); + return new ContainerAppender<>( + partiallySortValues, runCompress, () -> createUnderlying(capacity), containerSupplier); } private static void sanityCheck(int count) { @@ -208,7 +212,7 @@ public RoaringBitmapWriter get() { if (constantMemory) { int capacity = initialCapacity; return new ConstantMemoryContainerAppender<>( - partiallySortValues, runCompress, () -> createUnderlying(capacity)); + partiallySortValues, runCompress, () -> createUnderlying(capacity)); } return super.get(); } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java index 47509fd48..64ee24404 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RunBatchIterator.java @@ -1,7 +1,5 @@ package org.roaringbitmap; - - public final class RunBatchIterator implements ContainerBatchIterator { private RunContainer runs; @@ -44,7 +42,7 @@ public boolean hasNext() { @Override public ContainerBatchIterator clone() { try { - return (ContainerBatchIterator)super.clone(); + return (ContainerBatchIterator) super.clone(); } catch (CloneNotSupportedException e) { // won't happen throw new IllegalStateException(e); diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java index 6c4eca896..9634c7d1e 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java @@ -6,14 +6,17 @@ import org.roaringbitmap.buffer.MappeableContainer; import org.roaringbitmap.buffer.MappeableRunContainer; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.CharBuffer; import java.util.Arrays; import java.util.Iterator; - /** * This container takes the form of runs of consecutive values (effectively, run-length encoding). * @@ -26,8 +29,8 @@ public final class RunContainer extends Container implements Cloneable { private static final long serialVersionUID = 1L; - private static int branchyUnsignedInterleavedBinarySearch(final char[] array, final int begin, - final int end, final char k) { + private static int branchyUnsignedInterleavedBinarySearch( + final char[] array, final int begin, final int end, final char k) { int low = begin; int high = end - 1; while (low <= high) { @@ -45,8 +48,8 @@ private static int branchyUnsignedInterleavedBinarySearch(final char[] array, fi } // starts with binary search and finishes with a sequential search - private static int hybridUnsignedInterleavedBinarySearch(final char[] array, final int begin, - final int end, final char k) { + private static int hybridUnsignedInterleavedBinarySearch( + final char[] array, final int begin, final int end, final char k) { int low = begin; int high = end - 1; // 16 in the next line matches the size of a cache line @@ -79,25 +82,23 @@ protected static int serializedSizeInBytes(int numberOfRuns) { return 2 + 2 * 2 * numberOfRuns; // each run requires 2 2-byte entries. } - private static int unsignedInterleavedBinarySearch(final char[] array, final int begin, - final int end, final char k) { + private static int unsignedInterleavedBinarySearch( + final char[] array, final int begin, final int end, final char k) { if (Util.USE_HYBRID_BINSEARCH) { return hybridUnsignedInterleavedBinarySearch(array, begin, end, k); } else { return branchyUnsignedInterleavedBinarySearch(array, begin, end, k); } - } - private char[] valueslength;// we interleave values and lengths, so + private char[] valueslength; // we interleave values and lengths, so // that if you have the values 11,12,13,14,15, you store that as 11,4 where 4 means that beyond 11 // itself, there are // 4 contiguous values that follows. // Other example: e.g., 1, 10, 20,0, 31,2 would be a concise representation of 1, 2, ..., 11, 20, // 31, 32, 33 - int nbrruns = 0;// how many runs, this number should fit in 16 bits. - + int nbrruns = 0; // how many runs, this number should fit in 16 bits. /** * Create a container with default capacity @@ -106,7 +107,6 @@ public RunContainer() { this(DEFAULT_INIT_SIZE); } - protected RunContainer(ArrayContainer arr, int nbrRuns) { this.nbrruns = nbrRuns; valueslength = new char[2 * nbrRuns]; @@ -143,7 +143,7 @@ protected RunContainer(ArrayContainer arr, int nbrRuns) { */ public RunContainer(final int firstOfRun, final int lastOfRun) { this.nbrruns = 1; - this.valueslength = new char[]{(char) firstOfRun, (char) (lastOfRun - 1 - firstOfRun)}; + this.valueslength = new char[] {(char) firstOfRun, (char) (lastOfRun - 1 - firstOfRun)}; } // convert a bitmap container to a run container somewhat efficiently. @@ -205,13 +205,11 @@ public RunContainer(final int capacity) { valueslength = new char[2 * capacity]; } - private RunContainer(int nbrruns, char[] valueslength) { this.nbrruns = nbrruns; this.valueslength = Arrays.copyOf(valueslength, valueslength.length); } - /** * Creates a new non-mappeable container from a mappeable one. This copies the data. * @@ -252,10 +250,10 @@ public Container add(char k) { // runOptimize int index = unsignedInterleavedBinarySearch(valueslength, 0, nbrruns, k); if (index >= 0) { - return this;// already there + return this; // already there } - index = -index - 2;// points to preceding value, possibly -1 - if (index >= 0) {// possible match + index = -index - 2; // points to preceding value, possibly -1 + if (index >= 0) { // possible match int offset = (k) - (getValue(index)); int le = (getLength(index)); if (offset <= le) { @@ -266,8 +264,7 @@ public Container add(char k) { if (index + 1 < nbrruns) { if ((getValue(index + 1)) == (k) + 1) { // indeed fusion is needed - setLength(index, - (char) (getValue(index + 1) + getLength(index + 1) - getValue(index))); + setLength(index, (char) (getValue(index + 1) + getLength(index + 1) - getValue(index))); recoverRoomAtIndex(index + 1); return this; } @@ -314,16 +311,16 @@ public Container and(ArrayContainer x) { int rlelength = (this.getLength(rlepos)); while (arraypos < x.cardinality) { int arrayval = (x.content[arraypos]); - while (rleval + rlelength < arrayval) {// this will frequently be false + while (rleval + rlelength < arrayval) { // this will frequently be false ++rlepos; if (rlepos == this.nbrruns) { - return ac;// we are done + return ac; // we are done } rleval = (this.getValue(rlepos)); rlelength = (this.getLength(rlepos)); } if (rleval > arrayval) { - arraypos = Util.advanceUntil(x.content, arraypos, x.cardinality, (char)rleval); + arraypos = Util.advanceUntil(x.content, arraypos, x.cardinality, (char) rleval); } else { ac.content[ac.cardinality] = (char) arrayval; ac.cardinality++; @@ -333,7 +330,6 @@ public Container and(ArrayContainer x) { return ac; } - @Override public Container and(BitmapContainer x) { // could be implemented as return toBitmapOrArrayContainer().iand(x); @@ -349,8 +345,8 @@ public Container and(BitmapContainer x) { int runStart = (this.getValue(rlepos)); int runEnd = runStart + (this.getLength(rlepos)); for (int runValue = runStart; runValue <= runEnd; ++runValue) { - if (x.contains((char) runValue)) {// it looks like contains() should be cheap enough if - // accessed sequentially + if (x.contains((char) runValue)) { // it looks like contains() should be cheap enough if + // accessed sequentially answer.content[answer.cardinality++] = (char) runValue; } } @@ -394,7 +390,7 @@ public Container and(RunContainer x) { if (end <= xstart) { if (ENABLE_GALLOPING_AND) { rlepos = skipAhead(this, rlepos, xstart); // skip over runs until we have end > xstart (or - // rlepos is advanced beyond end) + // rlepos is advanced beyond end) } else { ++rlepos; } @@ -415,10 +411,10 @@ public Container and(RunContainer x) { xstart = x.getValue(xrlepos); xend = xstart + x.getLength(xrlepos) + 1; } - } else {// they overlap + } else { // they overlap final int lateststart = Math.max(start, xstart); int earliestend; - if (end == xend) {// improbable + if (end == xend) { // improbable earliestend = end; rlepos++; xrlepos++; @@ -438,7 +434,7 @@ public Container and(RunContainer x) { end = start + this.getLength(rlepos) + 1; } - } else {// end > xend + } else { // end > xend earliestend = xend; xrlepos++; if (xrlepos < x.nbrruns) { @@ -452,7 +448,7 @@ public Container and(RunContainer x) { } } return answer.toEfficientContainer(); // subsequent trim() may be required to avoid wasted - // space. + // space. } @Override @@ -467,10 +463,10 @@ public int andCardinality(ArrayContainer x) { int rlelength = (this.getLength(rlepos)); while (arraypos < x.cardinality) { int arrayval = (x.content[arraypos]); - while (rleval + rlelength < arrayval) {// this will frequently be false + while (rleval + rlelength < arrayval) { // this will frequently be false ++rlepos; if (rlepos == this.nbrruns) { - return andCardinality;// we are done + return andCardinality; // we are done } rleval = (this.getValue(rlepos)); rlelength = (this.getLength(rlepos)); @@ -485,7 +481,6 @@ public int andCardinality(ArrayContainer x) { return andCardinality; } - @Override public int andCardinality(BitmapContainer x) { // could be implemented as return toBitmapOrArrayContainer().iand(x); @@ -511,7 +506,7 @@ public int andCardinality(RunContainer x) { if (end <= xstart) { if (ENABLE_GALLOPING_AND) { rlepos = skipAhead(this, rlepos, xstart); // skip over runs until we have end > xstart (or - // rlepos is advanced beyond end) + // rlepos is advanced beyond end) } else { ++rlepos; } @@ -532,10 +527,10 @@ public int andCardinality(RunContainer x) { xstart = (x.getValue(xrlepos)); xend = xstart + (x.getLength(xrlepos)) + 1; } - } else {// they overlap + } else { // they overlap final int lateststart = Math.max(start, xstart); int earliestend; - if (end == xend) {// improbable + if (end == xend) { // improbable earliestend = end; rlepos++; xrlepos++; @@ -555,7 +550,7 @@ public int andCardinality(RunContainer x) { end = start + (this.getLength(rlepos)) + 1; } - } else {// end > xend + } else { // end > xend earliestend = xend; xrlepos++; if (xrlepos < x.nbrruns) { @@ -602,8 +597,8 @@ public Container andNot(BitmapContainer x) { int runStart = (this.getValue(rlepos)); int runEnd = runStart + (this.getLength(rlepos)); for (int runValue = runStart; runValue <= runEnd; ++runValue) { - if (!x.contains((char) runValue)) {// it looks like contains() should be cheap enough if - // accessed sequentially + if (!x.contains((char) runValue)) { // it looks like contains() should be cheap enough if + // accessed sequentially answer.content[answer.cardinality++] = (char) runValue; } } @@ -683,7 +678,11 @@ public Container andNot(RunContainer x) { answer.nbrruns++; rlepos++; if (rlepos < this.nbrruns) { - System.arraycopy(this.valueslength, 2 * rlepos, answer.valueslength, 2 * answer.nbrruns, + System.arraycopy( + this.valueslength, + 2 * rlepos, + answer.valueslength, + 2 * answer.nbrruns, 2 * (this.nbrruns - rlepos)); answer.nbrruns = answer.nbrruns + this.nbrruns - rlepos; } @@ -738,7 +737,7 @@ public boolean contains(char x) { return true; } index = -index - 2; // points to preceding value, possibly -1 - if (index != -1) {// possible match + if (index != -1) { // possible match int offset = x - getValue(index); int le = getLength(index); return offset <= le; @@ -765,17 +764,17 @@ public boolean contains(int minimum, int supremum) { @Override protected boolean contains(RunContainer runContainer) { int i1 = 0, i2 = 0; - while(i1 < numberOfRuns() && i2 < runContainer.numberOfRuns()) { + while (i1 < numberOfRuns() && i2 < runContainer.numberOfRuns()) { int start1 = (getValue(i1)); int stop1 = start1 + (getLength(i1)); int start2 = (runContainer.getValue(i2)); int stop2 = start2 + (runContainer.getLength(i2)); - if(start1 > start2) { + if (start1 > start2) { return false; } else { - if(stop1 > stop2) { + if (stop1 > stop2) { i2++; - } else if(stop1 == stop2) { + } else if (stop1 == stop2) { i1++; i2++; } else { @@ -794,11 +793,11 @@ protected boolean contains(ArrayContainer arrayContainer) { return false; } int ia = 0, ir = 0; - while(ia < arrayContainer.getCardinality() && ir < runCount) { + while (ia < arrayContainer.getCardinality() && ir < runCount) { int start = (this.getValue(ir)); int stop = start + (getLength(ir)); int ac = (arrayContainer.content[ia]); - if(ac < start) { + if (ac < start) { return false; } else if (ac > stop) { ++ir; @@ -855,7 +854,6 @@ protected boolean contains(BitmapContainer bitmapContainer) { return true; } - // a very cheap check... if you have more than 4096, then you should use a bitmap container. // this function avoids computing the cardinality private Container convertToLazyBitmapIfNeeded() { @@ -874,8 +872,6 @@ private Container convertToLazyBitmapIfNeeded() { return this; } - - // Push all values length to the end of the array (resize array if needed) private void copyToOffset(int offset) { if (!ensureCapacity(offset, 2 * (offset + nbrruns))) { @@ -889,11 +885,9 @@ private void copyValuesLength(char[] src, int srcIndex, char[] dst, int dstIndex } private void decrementLength(int index) { - valueslength[2 * index + 1]--;// caller is responsible to ensure that value is non-zero + valueslength[2 * index + 1]--; // caller is responsible to ensure that value is non-zero } - - private void decrementValue(int index) { valueslength[2 * index]--; } @@ -914,7 +908,7 @@ boolean ensureCapacity(int offset, int minNbRuns) { final int minCapacity = 2 * minNbRuns; if (valueslength.length < minCapacity) { int newCapacity = valueslength.length; - while(newCapacity < minCapacity) { + while (newCapacity < minCapacity) { newCapacity = computeCapacity(newCapacity); } char[] nv = new char[newCapacity]; @@ -949,8 +943,7 @@ public boolean equals(Object o) { } private boolean equals(RunContainer rc) { - return ArraysShim.equals(valueslength, 0, 2 * nbrruns, - rc.valueslength, 0, 2 * rc.nbrruns); + return ArraysShim.equals(valueslength, 0, 2 * nbrruns, rc.valueslength, 0, 2 * rc.nbrruns); } private boolean equals(ArrayContainer arrayContainer) { @@ -964,7 +957,7 @@ private boolean equals(ArrayContainer arrayContainer) { if (arrayContainer.content[pos] != runStart) { return false; } - if (arrayContainer.content[pos + length] != (char)((runStart) + length)) { + if (arrayContainer.content[pos + length] != (char) ((runStart) + length)) { return false; } pos += length + 1; @@ -998,10 +991,9 @@ public int getArraySizeInBytes() { return 2 + 4 * this.nbrruns; // "array" includes its size } - @Override public int getCardinality() { - int sum = nbrruns;// lengths are returned -1 + int sum = nbrruns; // lengths are returned -1 for (int k = 1; k < nbrruns * 2; k += 2) { sum += valueslength[k]; } @@ -1068,7 +1060,7 @@ public int hashCode() { public Container iadd(int begin, int end) { // TODO: it might be better and simpler to do return // toBitmapOrArrayContainer(getCardinality()).iadd(begin,end) - if(end == begin) { + if (end == begin) { return this; } if ((begin > end) || (end > (1 << 16))) { @@ -1081,8 +1073,9 @@ public Container iadd(int begin, int end) { } int bIndex = unsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = unsignedInterleavedBinarySearch(this.valueslength, - bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); + int eIndex = + unsignedInterleavedBinarySearch( + this.valueslength, bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); if (bIndex >= 0 && eIndex >= 0) { mergeValuesLength(bIndex, eIndex); @@ -1172,14 +1165,11 @@ public Container iand(BitmapContainer x) { return and(x); } - - @Override public Container iand(RunContainer x) { return and(x); } - @Override public Container iandNot(ArrayContainer x) { return andNot(x); @@ -1240,17 +1230,17 @@ private Container ilazyorToRun(ArrayContainer x) { } private int computeCapacity(int oldCapacity) { - return oldCapacity == 0 ? DEFAULT_INIT_SIZE - : oldCapacity < 64 ? oldCapacity * 2 - : oldCapacity < 1024 ? oldCapacity * 3 / 2 - : oldCapacity * 5 / 4; + return oldCapacity == 0 + ? DEFAULT_INIT_SIZE + : oldCapacity < 64 + ? oldCapacity * 2 + : oldCapacity < 1024 ? oldCapacity * 3 / 2 : oldCapacity * 5 / 4; } private void incrementLength(int index) { valueslength[2 * index + 1]++; } - private void incrementValue(int index) { valueslength[2 * index]++; } @@ -1336,7 +1326,7 @@ public Container inot(int rangeStart, int rangeEnd) { // use local variables so we are always reading 1 location ahead. char bufferedValue = 0, bufferedLength = 0; // 65535 start and 65535 length would be illegal, - // could use as sentinel + // could use as sentinel char nextValue = 0, nextLength = 0; if (k < myNbrRuns) { // prime the readahead variables bufferedValue = getValue(k); @@ -1374,7 +1364,7 @@ public boolean intersects(ArrayContainer x) { int rlelength = this.getLength(rlepos); while (arraypos < x.cardinality) { int arrayval = (x.content[arraypos]); - while (rleval + rlelength < arrayval) {// this will frequently be false + while (rleval + rlelength < arrayval) { // this will frequently be false ++rlepos; if (rlepos == this.nbrruns) { return false; @@ -1415,7 +1405,7 @@ public boolean intersects(RunContainer x) { if (end <= xstart) { if (ENABLE_GALLOPING_AND) { rlepos = skipAhead(this, rlepos, xstart); // skip over runs until we have end > xstart (or - // rlepos is advanced beyond end) + // rlepos is advanced beyond end) } else { ++rlepos; } @@ -1436,7 +1426,7 @@ public boolean intersects(RunContainer x) { xstart = (x.getValue(xrlepos)); xend = xstart + (x.getLength(xrlepos)) + 1; } - } else {// they overlap + } else { // they overlap return true; } } @@ -1445,7 +1435,7 @@ public boolean intersects(RunContainer x) { @Override public boolean intersects(int minimum, int supremum) { - if((minimum < 0) || (supremum < minimum) || (supremum > (1<<16))) { + if ((minimum < 0) || (supremum < minimum) || (supremum > (1 << 16))) { throw new RuntimeException("This should never happen (bug)."); } for (int i = 0; i < numberOfRuns(); ++i) { @@ -1553,7 +1543,7 @@ public Container ior(RunContainer x) { public Container iremove(int begin, int end) { // TODO: it might be better and simpler to do return // toBitmapOrArrayContainer(getCardinality()).iremove(begin,end) - if(end == begin) { + if (end == begin) { return this; } if ((begin > end) || (end > (1 << 16))) { @@ -1565,8 +1555,9 @@ public Container iremove(int begin, int end) { } int bIndex = unsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = unsignedInterleavedBinarySearch(this.valueslength, - bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); + int eIndex = + unsignedInterleavedBinarySearch( + this.valueslength, bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); // note, eIndex is looking for (end-1) @@ -1597,7 +1588,7 @@ public Container iremove(int begin, int end) { } // last run is one shorter - if (getLength(eIndex) == 0) {// special case where we remove last run + if (getLength(eIndex) == 0) { // special case where we remove last run recoverRoomsInRange(eIndex - 1, eIndex); } else { incrementValue(eIndex); @@ -1612,7 +1603,7 @@ public Container iremove(int begin, int end) { if (eIndex >= 0) { // end-1 is not before first run. if (bIndex >= 0) { // nor is begin if (bIndex == eIndex) { // all removal nested properly between - // one run start and the next + // one run start and the next if (valueLengthContains(begin, bIndex)) { if (valueLengthContains(end, eIndex)) { // proper nesting within a run, generates 2 sub-runs @@ -1633,7 +1624,7 @@ public Container iremove(int begin, int end) { // there is additional stuff in the eIndex run initValueLength(end, eIndex); eIndex--; - } // run ends at or before the range being removed, can delete it + } // run ends at or before the range being removed, can delete it recoverRoomsInRange(bIndex, eIndex); } @@ -1647,10 +1638,7 @@ public Container iremove(int begin, int end) { recoverRoomsInRange(bIndex, eIndex); } } - } // eIndex == -1: whole range is before first run, nothing to delete... - - } return this; } @@ -1684,7 +1672,6 @@ public void remove() { i.remove(); } }; - } @Override @@ -1697,8 +1684,6 @@ public Container ixor(BitmapContainer x) { return xor(x); } - - @Override public Container ixor(RunContainer x) { return xor(x); @@ -1754,7 +1739,11 @@ private RunContainer lazyandNot(ArrayContainer x) { answer.nbrruns++; rlepos++; if (rlepos < this.nbrruns) { - System.arraycopy(this.valueslength, 2 * rlepos, answer.valueslength, 2 * answer.nbrruns, + System.arraycopy( + this.valueslength, + 2 * rlepos, + answer.valueslength, + 2 * answer.nbrruns, 2 * (this.nbrruns - rlepos)); answer.nbrruns = answer.nbrruns + this.nbrruns - rlepos; } @@ -1851,7 +1840,6 @@ private Container lazyxor(ArrayContainer x) { return answer; } - @Override public Container limit(int maxcardinality) { if (maxcardinality >= getCardinality()) { @@ -1867,9 +1855,8 @@ public Container limit(int maxcardinality) { } } - RunContainer rc = new RunContainer(Arrays.copyOf(valueslength, 2 * (r+1)), r+1); - rc.setLength(r , - (char) ((rc.getLength(r)) - cardinality + maxcardinality)); + RunContainer rc = new RunContainer(Arrays.copyOf(valueslength, 2 * (r + 1)), r + 1); + rc.setLength(r, (char) ((rc.getLength(r)) - cardinality + maxcardinality)); return rc; } @@ -2022,8 +2009,8 @@ private void recoverRoomAtIndex(int index) { // To recover rooms between begin(exclusive) and end(inclusive) private void recoverRoomsInRange(int begin, int end) { if (end + 1 < this.nbrruns) { - copyValuesLength(this.valueslength, end + 1, this.valueslength, begin + 1, - this.nbrruns - 1 - end); + copyValuesLength( + this.valueslength, end + 1, this.valueslength, begin + 1, this.nbrruns - 1 - end); } this.nbrruns -= end - begin; } @@ -2044,10 +2031,10 @@ public Container remove(char x) { incrementValue(index); decrementLength(index); } - return this;// already there + return this; // already there } - index = -index - 2;// points to preceding value, possibly -1 - if (index >= 0) {// possible match + index = -index - 2; // points to preceding value, possibly -1 + if (index >= 0) { // possible match int offset = (x) - (getValue(index)); int le = (getLength(index)); if (offset < le) { @@ -2078,7 +2065,6 @@ public Container repairAfterLazy() { * Convert to Array or Bitmap container if the serialized form would be shorter. Exactly the same * functionality as toEfficientContainer. */ - @Override public Container runOptimize() { return toEfficientContainer(); @@ -2103,7 +2089,6 @@ public void serialize(DataOutput out) throws IOException { writeArray(out); } - @Override public int serializedSizeInBytes() { return serializedSizeInBytes(nbrruns); @@ -2113,8 +2098,6 @@ private void setLength(int index, char v) { setLength(valueslength, index, v); } - - private void setLength(char[] valueslength, int index, char v) { valueslength[2 * index + 1] = v; } @@ -2127,8 +2110,6 @@ private void setValue(char[] valueslength, int index, char v) { valueslength[2 * index] = v; } - - // bootstrapping (aka "galloping") binary search. Always skips at least one. // On our "real data" benchmarks, enabling galloping is a minor loss // .."ifdef ENABLE_GALLOPING_AND" :) @@ -2144,14 +2125,12 @@ private int skipAhead(RunContainer skippingOn, int pos, int targetToExceed) { // expect it might be quite common to find the container cannot be advanced as far as // requested. Optimize for it. probePos = skippingOn.nbrruns - 1; - end = (skippingOn.getValue(probePos)) - + (skippingOn.getLength(probePos)) + 1; + end = (skippingOn.getValue(probePos)) + (skippingOn.getLength(probePos)) + 1; if (end <= targetToExceed) { return skippingOn.nbrruns; } } - end = (skippingOn.getValue(probePos)) - + (skippingOn.getLength(probePos)) + 1; + end = (skippingOn.getValue(probePos)) + (skippingOn.getLength(probePos)) + 1; span *= 2; } while (end <= targetToExceed); int right = probePos; @@ -2161,8 +2140,7 @@ private int skipAhead(RunContainer skippingOn, int pos, int targetToExceed) { // invariant is maintained. while (right - left > 1) { int mid = (right + left) / 2; - int midVal = (skippingOn.getValue(mid)) - + (skippingOn.getLength(mid)) + 1; + int midVal = (skippingOn.getValue(mid)) + (skippingOn.getLength(mid)) + 1; if (midVal > targetToExceed) { right = mid; } else { @@ -2175,8 +2153,9 @@ private int skipAhead(RunContainer skippingOn, int pos, int targetToExceed) { private void smartAppend(char val) { int oldend; if ((nbrruns == 0) - || (val > (oldend = (valueslength[2 * (nbrruns - 1)]) - + (valueslength[2 * (nbrruns - 1) + 1])) + 1)) { // we add a new one + || (val + > (oldend = (valueslength[2 * (nbrruns - 1)]) + (valueslength[2 * (nbrruns - 1) + 1])) + + 1)) { // we add a new one valueslength[2 * nbrruns] = val; valueslength[2 * nbrruns + 1] = 0; nbrruns++; @@ -2189,9 +2168,10 @@ private void smartAppend(char val) { void smartAppend(char start, char length) { int oldend; - if ((nbrruns == 0) || ((start) > (oldend = - (getValue(nbrruns - 1)) + (getLength(nbrruns - 1))) - + 1)) { // we add a new one + if ((nbrruns == 0) + || ((start) + > (oldend = (getValue(nbrruns - 1)) + (getLength(nbrruns - 1))) + + 1)) { // we add a new one ensureCapacity(0, nbrruns + 1); valueslength[2 * nbrruns] = start; valueslength[2 * nbrruns + 1] = length; @@ -2207,8 +2187,8 @@ void smartAppend(char start, char length) { private void smartAppendExclusive(char val) { int oldend; if ((nbrruns == 0) - || (val > (oldend = getValue(nbrruns - 1) - + getLength(nbrruns - 1) + 1))) { // we add a new one + || (val + > (oldend = getValue(nbrruns - 1) + getLength(nbrruns - 1) + 1))) { // we add a new one valueslength[2 * nbrruns] = val; valueslength[2 * nbrruns + 1] = 0; nbrruns++; @@ -2243,14 +2223,14 @@ private void smartAppendExclusive(char val) { setLength(nbrruns, (char) (oldend - newend - 1)); nbrruns++; } // otherwise newend == oldend - } private void smartAppendExclusive(char start, char length) { int oldend; if ((nbrruns == 0) - || (start > (oldend = (getValue(nbrruns - 1)) - + (getLength(nbrruns - 1)) + 1))) { // we add a new one + || (start + > (oldend = + (getValue(nbrruns - 1)) + (getLength(nbrruns - 1)) + 1))) { // we add a new one valueslength[2 * nbrruns] = start; valueslength[2 * nbrruns + 1] = length; nbrruns++; @@ -2356,7 +2336,7 @@ public String toString() { StringBuilder sb = new StringBuilder("[]".length() + "-123456789,".length() * nbrruns); for (int k = 0; k < this.nbrruns; ++k) { sb.append('['); - sb.append((int)(this.getValue(k))); + sb.append((int) (this.getValue(k))); sb.append(','); sb.append((this.getValue(k)) + (this.getLength(k))); sb.append(']'); @@ -2364,7 +2344,6 @@ public String toString() { return sb.toString(); } - @Override public void trim() { if (valueslength.length == 2 * nbrruns) { @@ -2373,7 +2352,6 @@ public void trim() { valueslength = Arrays.copyOf(valueslength, 2 * nbrruns); } - // To check if a value length contains a given value private boolean valueLengthContains(int value, int index) { int initialValue = (getValue(index)); @@ -2394,7 +2372,7 @@ public void writeArray(DataOutput out) throws IOException { public void writeArray(ByteBuffer buffer) { assert buffer.order() == ByteOrder.LITTLE_ENDIAN; CharBuffer buf = buffer.asCharBuffer(); - buf.put((char)nbrruns); + buf.put((char) nbrruns); buf.put(valueslength, 0, nbrruns * 2); int bytesWritten = (nbrruns * 2 + 1) * 2; buffer.position(buffer.position() + bytesWritten); @@ -2403,7 +2381,6 @@ public void writeArray(ByteBuffer buffer) { @Override public void writeExternal(ObjectOutput out) throws IOException { serialize(out); - } @Override @@ -2484,10 +2461,10 @@ public Container xor(RunContainer x) { @Override public void forEach(char msb, IntConsumer ic) { int high = msb << 16; - for(int k = 0; k < this.nbrruns; ++k) { + for (int k = 0; k < this.nbrruns; ++k) { int base = this.getValue(k) | high; int le = this.getLength(k); - for(int l = base; l - le <= base; ++l) { + for (int l = base; l - le <= base; ++l) { ic.accept(l); } } @@ -2583,7 +2560,7 @@ public void forAllUntil(int offset, char endValue, final RelativeRangeConsumer r public void forAllInRange(char startValue, char endValue, final RelativeRangeConsumer rrc) { if (endValue <= startValue) { throw new IllegalArgumentException( - "startValue (" + startValue + ") must be less than endValue (" + endValue + ")"); + "startValue (" + startValue + ") must be less than endValue (" + endValue + ")"); } int startOffset = startValue; int next = startValue; @@ -2730,10 +2707,8 @@ public int last() { int length = (getLength(index)); return start + length; } - } - class RunContainerCharIterator implements PeekableCharIterator { int pos; int le = 0; @@ -2742,9 +2717,7 @@ class RunContainerCharIterator implements PeekableCharIterator { RunContainer parent; - RunContainerCharIterator() { - - } + RunContainerCharIterator() {} RunContainerCharIterator(RunContainer p) { wrap(p); @@ -2755,7 +2728,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -2796,7 +2769,7 @@ public int nextAsInt() { @Override public void remove() { - throw new RuntimeException("Not implemented");// TODO + throw new RuntimeException("Not implemented"); // TODO } void wrap(RunContainer p) { @@ -2827,13 +2800,10 @@ public void advanceIfNeeded(char minval) { le = (minval) - base; } - - @Override public char peekNext() { return (char) (base + le); } - } class RunContainerCharRankIterator extends RunContainerCharIterator @@ -2892,7 +2862,6 @@ public RunContainerCharRankIterator clone() { } } - final class ReverseRunContainerCharIterator implements PeekableCharIterator { int pos; private int le; @@ -2900,10 +2869,7 @@ final class ReverseRunContainerCharIterator implements PeekableCharIterator { private int maxlength; private int base; - - ReverseRunContainerCharIterator() { - - } + ReverseRunContainerCharIterator() {} ReverseRunContainerCharIterator(RunContainer p) { wrap(p); @@ -2914,7 +2880,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -2971,7 +2937,6 @@ public void advanceIfNeeded(char maxval) { le = maxlength + base - (maxval); } - @Override public char peekNext() { return (char) (base + maxlength - le); @@ -2979,7 +2944,7 @@ public char peekNext() { @Override public void remove() { - throw new RuntimeException("Not implemented");// TODO + throw new RuntimeException("Not implemented"); // TODO } void wrap(RunContainer p) { @@ -2991,5 +2956,4 @@ void wrap(RunContainer p) { base = (parent.getValue(pos)); } } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/Util.java b/roaringbitmap/src/main/java/org/roaringbitmap/Util.java index b2b656276..5a5f39b5a 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/Util.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/Util.java @@ -4,10 +4,10 @@ package org.roaringbitmap; -import java.util.Arrays; - import static java.lang.Long.numberOfTrailingZeros; +import java.util.Arrays; + /** * Various useful methods for roaring bitmaps. */ @@ -19,7 +19,6 @@ public final class Util { */ public static final boolean USE_HYBRID_BINSEARCH = true; - /** * Add value "offset" to all values in the container, producing * two new containers. The existing container remains unchanged. @@ -29,8 +28,8 @@ public final class Util { * @param offsets value to add to each value in the container * @return return an array made of two containers */ - public static Container[] addOffset(Container source, char offsets) { - if(source instanceof ArrayContainer) { + public static Container[] addOffset(Container source, char offsets) { + if (source instanceof ArrayContainer) { return addOffsetArray((ArrayContainer) source, offsets); } else if (source instanceof BitmapContainer) { return addOffsetBitmap((BitmapContainer) source, offsets); @@ -47,19 +46,19 @@ private static Container[] addOffsetArray(ArrayContainer source, char offsets) { } else if (source.last() + offsets < 0xFFFF) { splitIndex = source.cardinality; } else { - splitIndex = Util.unsignedBinarySearch(source.content, 0, source.cardinality, - (char) (0x10000 - offsets)); + splitIndex = + Util.unsignedBinarySearch( + source.content, 0, source.cardinality, (char) (0x10000 - offsets)); if (splitIndex < 0) { splitIndex = -splitIndex - 1; } } - ArrayContainer low = splitIndex == 0 - ? new ArrayContainer() - : new ArrayContainer(splitIndex); - ArrayContainer high = source.cardinality - splitIndex == 0 - ? new ArrayContainer() - : new ArrayContainer(source.cardinality - splitIndex); + ArrayContainer low = splitIndex == 0 ? new ArrayContainer() : new ArrayContainer(splitIndex); + ArrayContainer high = + source.cardinality - splitIndex == 0 + ? new ArrayContainer() + : new ArrayContainer(source.cardinality - splitIndex); int lowCardinality = 0; for (int k = 0; k < splitIndex; k++) { @@ -75,7 +74,7 @@ private static Container[] addOffsetArray(ArrayContainer source, char offsets) { } high.cardinality = highCardinality; - return new Container[]{low, high}; + return new Container[] {low, high}; } private static Container[] addOffsetBitmap(BitmapContainer source, char offsets) { @@ -86,18 +85,16 @@ private static Container[] addOffsetBitmap(BitmapContainer source, char offsets) high.cardinality = -1; final int b = (int) offsets >>> 6; final int i = (int) offsets % 64; - if(i == 0) { + if (i == 0) { System.arraycopy(c.bitmap, 0, low.bitmap, b, 1024 - b); System.arraycopy(c.bitmap, 1024 - b, high.bitmap, 0, b); } else { low.bitmap[b] = c.bitmap[0] << i; - for(int k = 1; k < 1024 - b; k++) { + for (int k = 1; k < 1024 - b; k++) { low.bitmap[b + k] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64 - i)); } - for(int k = 1024 - b; k < 1024 ; k++) { - high.bitmap[k - (1024 - b)] = - (c.bitmap[k] << i) - | (c.bitmap[k - 1] >>> (64 - i)); + for (int k = 1024 - b; k < 1024; k++) { + high.bitmap[k - (1024 - b)] = (c.bitmap[k] << i) | (c.bitmap[k - 1] >>> (64 - i)); } high.bitmap[b] = c.bitmap[1024 - 1] >>> (64 - i); } @@ -108,11 +105,11 @@ private static Container[] addOffsetRun(RunContainer source, char offsets) { RunContainer input = source; RunContainer low = new RunContainer(); RunContainer high = new RunContainer(); - for(int k = 0 ; k < input.nbrruns; k++) { - int val = input.getValue(k) + offsets; + for (int k = 0; k < input.nbrruns; k++) { + int val = input.getValue(k) + offsets; int finalval = val + input.getLength(k); - if(val <= 0xFFFF) { - if(finalval <= 0xFFFF) { + if (val <= 0xFFFF) { + if (finalval <= 0xFFFF) { low.smartAppend((char) val, input.getLength(k)); } else { low.smartAppend((char) val, (char) (0xFFFF - val)); @@ -122,7 +119,7 @@ private static Container[] addOffsetRun(RunContainer source, char offsets) { high.smartAppend((char) val, input.getLength(k)); } } - return new Container[]{low, high}; + return new Container[] {low, high}; } /** @@ -147,8 +144,7 @@ public static int advanceUntil(char[] array, int pos, int length, char min) { int spansize = 1; // could set larger // bootstrap an upper limit - while (lower + spansize < length - && (array[lower + spansize]) < (int) (min)) { + while (lower + spansize < length && (array[lower + spansize]) < (int) (min)) { spansize *= 2; // hoping for compiler will reduce to } // shift @@ -183,10 +179,8 @@ public static int advanceUntil(char[] array, int pos, int length, char min) { } } return upper; - } - /** * Find the largest integer smaller than pos such that array[pos]<= max. If none can be found, * return length. Based on code by O. Kaser. @@ -209,8 +203,7 @@ public static int reverseUntil(char[] array, int pos, int length, char max) { int spansize = 1; // could set larger // bootstrap an upper limit - while (lower - spansize > 0 - && (array[lower - spansize]) > (int) (max)) { + while (lower - spansize > 0 && (array[lower - spansize]) > (int) (max)) { spansize *= 2; // hoping for compiler will reduce to } // shift @@ -245,7 +238,6 @@ public static int reverseUntil(char[] array, int pos, int length, char max) { } } return upper; - } /** @@ -266,8 +258,8 @@ public static int iterateUntil(char[] array, int pos, int length, int min) { return pos; } - protected static int branchyUnsignedBinarySearch(final char[] array, final int begin, - final int end, final char k) { + protected static int branchyUnsignedBinarySearch( + final char[] array, final int begin, final int end, final char k) { // next line accelerates the possibly common case where the value would // be inserted at the end if ((end > 0) && ((array[end - 1]) < (int) (k))) { @@ -297,8 +289,8 @@ protected static int branchyUnsignedBinarySearch(final char[] array, final int b * @param bitmap1 first bitmap * @param bitmap2 second bitmap */ - public static void fillArrayAND(final char[] container, final long[] bitmap1, - final long[] bitmap2) { + public static void fillArrayAND( + final char[] container, final long[] bitmap1, final long[] bitmap2) { int pos = 0; if (bitmap1.length != bitmap2.length) { throw new IllegalArgumentException("not supported"); @@ -319,8 +311,8 @@ public static void fillArrayAND(final char[] container, final long[] bitmap1, * @param bitmap1 first bitmap * @param bitmap2 second bitmap */ - public static void fillArrayANDNOT(final char[] container, final long[] bitmap1, - final long[] bitmap2) { + public static void fillArrayANDNOT( + final char[] container, final long[] bitmap1, final long[] bitmap2) { int pos = 0; if (bitmap1.length != bitmap2.length) { throw new IllegalArgumentException("not supported"); @@ -341,8 +333,8 @@ public static void fillArrayANDNOT(final char[] container, final long[] bitmap1, * @param bitmap1 first bitmap * @param bitmap2 second bitmap */ - public static void fillArrayXOR(final char[] container, final long[] bitmap1, - final long[] bitmap2) { + public static void fillArrayXOR( + final char[] container, final long[] bitmap1, final long[] bitmap2) { int pos = 0; if (bitmap1.length != bitmap2.length) { throw new IllegalArgumentException("not supported"); @@ -376,7 +368,6 @@ public static void flipBitmapRange(long[] bitmap, int start, int end) { bitmap[endword] ^= ~0L >>> -end; } - /** * Hamming weight of the 64-bit words involved in the range * start, start+1,..., end-1, that is, it will compute the @@ -402,7 +393,6 @@ public static int cardinalityInBitmapWordRange(long[] bitmap, int start, int end return answer; } - /** * Hamming weight of the bitset in the range * start, start+1,..., end-1 @@ -419,7 +409,7 @@ public static int cardinalityInBitmapRange(long[] bitmap, int start, int end) { int firstword = start / 64; int endword = (end - 1) / 64; if (firstword == endword) { - return Long.bitCount(bitmap[firstword] & ( (~0L << start) & (~0L >>> -end) )); + return Long.bitCount(bitmap[firstword] & ((~0L << start) & (~0L >>> -end))); } int answer = Long.bitCount(bitmap[firstword] & (~0L << start)); for (int i = firstword + 1; i < endword; i++) { @@ -438,8 +428,8 @@ protected static char highbits(long x) { } // starts with binary search and finishes with a sequential search - protected static int hybridUnsignedBinarySearch(final char[] array, final int begin, - final int end, final char k) { + protected static int hybridUnsignedBinarySearch( + final char[] array, final int begin, final int end, final char k) { // next line accelerates the possibly common case where the value would // be inserted at the end if ((end > 0) && ((array[end - 1]) < (int) k)) { @@ -482,13 +472,12 @@ protected static char lowbits(long x) { return (char) x; } - protected static int lowbitsAsInteger(int x) { return x & 0xFFFF; } protected static int lowbitsAsInteger(long x) { - return (int)(x & 0xFFFF); + return (int) (x & 0xFFFF); } public static int maxLowBitAsInteger() { @@ -518,7 +507,6 @@ public static void resetBitmapRange(long[] bitmap, int start, int end) { bitmap[i] = 0; } bitmap[endword] &= ~(~0L >>> -end); - } /** @@ -642,12 +630,11 @@ public static void setBitmapRange(long[] bitmap, int start, int end) { @Deprecated public static int setBitmapRangeAndCardinalityChange(long[] bitmap, int start, int end) { int cardbefore = cardinalityInBitmapWordRange(bitmap, start, end); - setBitmapRange(bitmap, start,end); + setBitmapRange(bitmap, start, end); int cardafter = cardinalityInBitmapWordRange(bitmap, start, end); return cardafter - cardbefore; } - /** * flip bits at start, start+1,..., end-1 and report the * cardinality change @@ -660,12 +647,11 @@ public static int setBitmapRangeAndCardinalityChange(long[] bitmap, int start, i @Deprecated public static int flipBitmapRangeAndCardinalityChange(long[] bitmap, int start, int end) { int cardbefore = cardinalityInBitmapWordRange(bitmap, start, end); - flipBitmapRange(bitmap, start,end); + flipBitmapRange(bitmap, start, end); int cardafter = cardinalityInBitmapWordRange(bitmap, start, end); return cardafter - cardbefore; } - /** * reset bits at start, start+1,..., end-1 and report the * cardinality change @@ -678,7 +664,7 @@ public static int flipBitmapRangeAndCardinalityChange(long[] bitmap, int start, @Deprecated public static int resetBitmapRangeAndCardinalityChange(long[] bitmap, int start, int end) { int cardbefore = cardinalityInBitmapWordRange(bitmap, start, end); - resetBitmapRange(bitmap, start,end); + resetBitmapRange(bitmap, start, end); int cardafter = cardinalityInBitmapWordRange(bitmap, start, end); return cardafter - cardbefore; } @@ -694,8 +680,8 @@ public static int resetBitmapRangeAndCardinalityChange(long[] bitmap, int start, * @param k value we search for * @return count */ - public static int unsignedBinarySearch(final char[] array, final int begin, final int end, - final char k) { + public static int unsignedBinarySearch( + final char[] array, final int begin, final int end, final char k) { if (USE_HYBRID_BINSEARCH) { return hybridUnsignedBinarySearch(array, begin, end, k); } else { @@ -714,8 +700,12 @@ public static int unsignedBinarySearch(final char[] array, final int begin, fina * @param buffer output array * @return cardinality of the difference */ - public static int unsignedDifference(final char[] set1, final int length1, final char[] set2, - final int length2, final char[] buffer) { + public static int unsignedDifference( + final char[] set1, + final int length1, + final char[] set2, + final int length2, + final char[] buffer) { int pos = 0; int k1 = 0, k2 = 0; if (0 == length2) { @@ -747,7 +737,7 @@ public static int unsignedDifference(final char[] set1, final int length1, final } s1 = set1[k1]; s2 = set2[k2]; - } else {// if (val1>val2) + } else { // if (val1>val2) ++k2; if (k2 >= length2) { System.arraycopy(set1, k1, buffer, pos, length1 - k1); @@ -768,8 +758,7 @@ public static int unsignedDifference(final char[] set1, final int length1, final * @param buffer output array * @return cardinality of the difference */ - public static int unsignedDifference(CharIterator set1, CharIterator set2, - final char[] buffer) { + public static int unsignedDifference(CharIterator set1, CharIterator set2, final char[] buffer) { int pos = 0; if (!set2.hasNext()) { while (set1.hasNext()) { @@ -801,7 +790,7 @@ public static int unsignedDifference(CharIterator set1, CharIterator set2, } v1 = set1.next(); v2 = set2.next(); - } else {// if (val1>val2) + } else { // if (val1>val2) if (!set2.hasNext()) { buffer[pos++] = v1; while (set1.hasNext()) { @@ -826,8 +815,12 @@ public static int unsignedDifference(CharIterator set1, CharIterator set2, * @param buffer output array * @return cardinality of the exclusive union */ - public static int unsignedExclusiveUnion2by2(final char[] set1, final int length1, - final char[] set2, final int length2, final char[] buffer) { + public static int unsignedExclusiveUnion2by2( + final char[] set1, + final int length1, + final char[] set2, + final int length2, + final char[] buffer) { int pos = 0; int k1 = 0, k2 = 0; if (0 == length2) { @@ -862,7 +855,7 @@ public static int unsignedExclusiveUnion2by2(final char[] set1, final int length } s1 = set1[k1]; s2 = set2[k2]; - } else {// if (val1>val2) + } else { // if (val1>val2) buffer[pos++] = s2; ++k2; if (k2 >= length2) { @@ -875,8 +868,6 @@ public static int unsignedExclusiveUnion2by2(final char[] set1, final int length // return pos; } - - /** * Intersect two sorted lists and write the result to the provided output array * @@ -887,8 +878,12 @@ public static int unsignedExclusiveUnion2by2(final char[] set1, final int length * @param buffer output array * @return cardinality of the intersection */ - public static int unsignedIntersect2by2(final char[] set1, final int length1, final char[] set2, - final int length2, final char[] buffer) { + public static int unsignedIntersect2by2( + final char[] set1, + final int length1, + final char[] set2, + final int length2, + final char[] buffer) { final int THRESHOLD = 25; if (set1.length * THRESHOLD < set2.length) { return unsignedOneSidedGallopingIntersect2by2(set1, length1, set2, length2, buffer); @@ -899,8 +894,6 @@ public static int unsignedIntersect2by2(final char[] set1, final int length1, fi } } - - /** * Checks if two arrays intersect * @@ -919,7 +912,8 @@ public static boolean unsignedIntersects(char[] set1, int length1, char[] set2, int k2 = 0; char s1 = set1[k1]; char s2 = set2[k2]; - mainwhile: while (true) { + mainwhile: + while (true) { if (s2 < s1) { do { ++k2; @@ -944,9 +938,12 @@ public static boolean unsignedIntersects(char[] set1, int length1, char[] set2, return false; } - - protected static int unsignedLocalIntersect2by2(final char[] set1, final int length1, - final char[] set2, final int length2, final char[] buffer) { + protected static int unsignedLocalIntersect2by2( + final char[] set1, + final int length1, + final char[] set2, + final int length2, + final char[] buffer) { if ((0 == length1) || (0 == length2)) { return 0; } @@ -956,7 +953,8 @@ protected static int unsignedLocalIntersect2by2(final char[] set1, final int len char s1 = set1[k1]; char s2 = set2[k2]; - mainwhile: while (true) { + mainwhile: + while (true) { int v1 = (s1); int v2 = s2; if (v2 < v1) { @@ -996,7 +994,6 @@ protected static int unsignedLocalIntersect2by2(final char[] set1, final int len return pos; } - /** * Compute the cardinality of the intersection * @param set1 first set @@ -1005,8 +1002,8 @@ protected static int unsignedLocalIntersect2by2(final char[] set1, final int len * @param length2 how many values to consider in the second set * @return cardinality of the intersection */ - public static int unsignedLocalIntersect2by2Cardinality(final char[] set1, final int length1, - final char[] set2, final int length2) { + public static int unsignedLocalIntersect2by2Cardinality( + final char[] set1, final int length1, final char[] set2, final int length2) { if ((0 == length1) || (0 == length2)) { return 0; } @@ -1016,7 +1013,8 @@ public static int unsignedLocalIntersect2by2Cardinality(final char[] set1, final char s1 = set1[k1]; char s2 = set2[k2]; - mainwhile: while (true) { + mainwhile: + while (true) { int v1 = s1; int v2 = s2; if (v2 < v1) { @@ -1056,9 +1054,12 @@ public static int unsignedLocalIntersect2by2Cardinality(final char[] set1, final return pos; } - - protected static int unsignedOneSidedGallopingIntersect2by2(final char[] smallSet, - final int smallLength, final char[] largeSet, final int largeLength, final char[] buffer) { + protected static int unsignedOneSidedGallopingIntersect2by2( + final char[] smallSet, + final int smallLength, + final char[] largeSet, + final int largeLength, + final char[] buffer) { if (0 == smallLength) { return 0; } @@ -1095,10 +1096,8 @@ protected static int unsignedOneSidedGallopingIntersect2by2(final char[] smallSe } s1 = largeSet[k1]; } - } return pos; - } /** @@ -1114,9 +1113,13 @@ protected static int unsignedOneSidedGallopingIntersect2by2(final char[] smallSe * @return cardinality of the union */ public static int unsignedUnion2by2( - final char[] set1, final int offset1, final int length1, - final char[] set2, final int offset2, final int length2, - final char[] buffer) { + final char[] set1, + final int offset1, + final int length1, + final char[] set2, + final int offset2, + final int length2, + final char[] buffer) { if (0 == length2) { System.arraycopy(set1, offset1, buffer, 0, length1); return length1; @@ -1154,7 +1157,7 @@ public static int unsignedUnion2by2( } s1 = set1[k1]; s2 = set2[k2]; - } else {// if (set1[k1]>set2[k2]) + } else { // if (set1[k1]>set2[k2]) buffer[pos++] = s2; ++k2; if (k2 >= length2 + offset2) { @@ -1167,7 +1170,6 @@ public static int unsignedUnion2by2( // return pos; } - /** * Converts the argument to a {@code long} by an unsigned conversion. In an unsigned conversion to * a {@code long}, the high-order 32 bits of the {@code long} are zero and the low-order 32 bits @@ -1185,6 +1187,7 @@ public static int unsignedUnion2by2( public static long toUnsignedLong(int x) { return ((long) x) & 0xffffffffL; } + /** * Sorts the data by the 16 bit prefix using Radix sort. * The resulting data will be partially sorted if you just @@ -1249,8 +1252,9 @@ static char[] intersectKeys(long[] words, RoaringBitmap[] bitmaps) { } int numContainers = first.highLowContainer.size; for (int i = 1; i < bitmaps.length && numContainers > 0; ++i) { - numContainers = Util.intersectArrayIntoBitmap(words, - bitmaps[i].highLowContainer.keys, bitmaps[i].highLowContainer.size); + numContainers = + Util.intersectArrayIntoBitmap( + words, bitmaps[i].highLowContainer.keys, bitmaps[i].highLowContainer.size); } if (numContainers == 0) { return new char[0]; @@ -1261,9 +1265,7 @@ static char[] intersectKeys(long[] words, RoaringBitmap[] bitmaps) { /** * Private constructor to prevent instantiation of utility class */ - private Util() { - - } + private Util() {} /** * Fill the array with set bits diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/WordStorage.java b/roaringbitmap/src/main/java/org/roaringbitmap/WordStorage.java index 12cf74b95..755792490 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/WordStorage.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/WordStorage.java @@ -7,5 +7,4 @@ public interface WordStorage { boolean isEmpty(); T runOptimize(); - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java index 7dd79b12e..c76935181 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/AbstractShuttle.java @@ -10,7 +10,7 @@ public abstract class AbstractShuttle implements Shuttle { protected static final int MAX_DEPTH = 7; protected NodeEntry[] stack = new NodeEntry[MAX_DEPTH]; - //started from 0 + // started from 0 protected int depth = -1; protected boolean hasRun = false; protected Art art; @@ -57,22 +57,22 @@ public boolean moveToNextLeaf() { return false; } } - //skip the top leaf node + // skip the top leaf node Node node = stack[depth].node; if (node.nodeType == NodeType.LEAF_NODE) { depth--; } - //visit parent node + // visit parent node while (depth >= 0) { NodeEntry currentNodeEntry = stack[depth]; if (currentNodeEntry.node.nodeType == NodeType.LEAF_NODE) { - //found current leaf node's next sibling node to benefit the removing operation + // found current leaf node's next sibling node to benefit the removing operation if (depth - 1 >= 0) { findNextSiblingKeyOfLeafNode(); } return true; } - //visit the next child node + // visit the next child node int pos; int nextPos; if (!currentNodeEntry.visited) { @@ -83,19 +83,19 @@ public boolean moveToNextLeaf() { } else if (currentNodeEntry.startFromNextSiblingPosition) { nextPos = currentNodeEntry.position; currentNodeEntry.startFromNextSiblingPosition = false; - } else { + } else { pos = currentNodeEntry.position; nextPos = visitedNodeNextPosition(currentNodeEntry.node, pos); } if (nextPos != Node.ILLEGAL_IDX) { stack[depth].position = nextPos; depth++; - //add a fresh entry on the top of the visiting stack + // add a fresh entry on the top of the visiting stack NodeEntry freshEntry = new NodeEntry(); freshEntry.node = currentNodeEntry.node.getChild(nextPos); stack[depth] = freshEntry; } else { - //current internal node doesn't have anymore unvisited child,move to a top node + // current internal node doesn't have anymore unvisited child,move to a top node depth--; } } @@ -122,13 +122,13 @@ public void remove() { } Node node = toolkit.freshMatchedParentNode; if (depth - 1 >= 0) { - //update the parent node to a fresh node as the parent node may changed by the - //art adaptive removing logic + // update the parent node to a fresh node as the parent node may changed by the + // art adaptive removing logic NodeEntry oldEntry = stack[depth - 1]; oldEntry.visited = oldEntry.node == node; oldEntry.node = node; oldEntry.startFromNextSiblingPosition = true; - if (node.nodeType != NodeType.LEAF_NODE) { + if (node.nodeType != NodeType.LEAF_NODE) { oldEntry.position = node.getChildPos(oldEntry.leafNodeNextSiblingKey); } } @@ -145,7 +145,7 @@ private void visitToLeaf(Node node, boolean inRunDirection) { stack[depth] = nodeEntry; } if (node.nodeType == NodeType.LEAF_NODE) { - //leaf node's corresponding NodeEntry will not have the position member set. + // leaf node's corresponding NodeEntry will not have the position member set. if (depth - 1 >= 0) { findNextSiblingKeyOfLeafNode(); } @@ -154,7 +154,7 @@ private void visitToLeaf(Node node, boolean inRunDirection) { if (depth == MAX_DEPTH) { return; } - //find next min child + // find next min child int pos = boundaryNodePosition(node, inRunDirection); stack[depth].position = pos; stack[depth].visited = true; @@ -177,7 +177,7 @@ private void visitToLeafFrom(byte[] high, int keyDepth, Node node) { stack[depth] = nodeEntry; } if (node.nodeType == NodeType.LEAF_NODE) { - //leaf node's corresponding NodeEntry will not have the position member set. + // leaf node's corresponding NodeEntry will not have the position member set. if (depth - 1 >= 0) { findNextSiblingKeyOfLeafNode(); } @@ -188,13 +188,8 @@ private void visitToLeafFrom(byte[] high, int keyDepth, Node node) { } if (node.prefixLength > 0) { - int commonLength = Art.commonPrefixLength( - high, - keyDepth, - high.length, - node.prefix, - 0, - node.prefixLength); + int commonLength = + Art.commonPrefixLength(high, keyDepth, high.length, node.prefix, 0, node.prefixLength); if (commonLength != node.prefixLength) { byte nodeValue = node.prefix[commonLength]; byte highValue = high[keyDepth + commonLength]; @@ -203,10 +198,10 @@ private void visitToLeafFrom(byte[] high, int keyDepth, Node node) { visitToLeaf(node, visitDirection); return; } - //common prefix is the same ,then increase the depth + // common prefix is the same ,then increase the depth keyDepth += node.prefixLength; } - //find next child + // find next child SearchResult result = node.getNearestChildPos(high[keyDepth]); int pos; boolean continueAtBoundary = false; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Art.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Art.java index 3f0984ab8..1cf10553e 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Art.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Art.java @@ -1,10 +1,11 @@ package org.roaringbitmap.art; +import org.roaringbitmap.ArraysShim; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; -import org.roaringbitmap.ArraysShim; /** * See: https://db.in.tum.de/~leis/papers/ART.pdf a cpu cache friendly main memory data structure. @@ -61,21 +62,26 @@ private Node findByKey(Node node, byte[] key, int depth) { if (depth == LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES) { return leafNode; } - int mismatchIndex = ArraysShim - .mismatch(leafNodeKeyBytes, depth, LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES, - key, depth, LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES); + int mismatchIndex = + ArraysShim.mismatch( + leafNodeKeyBytes, + depth, + LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES, + key, + depth, + LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES); if (mismatchIndex != -1) { return null; } return leafNode; } if (node.prefixLength > 0) { - int commonLength = commonPrefixLength(key, depth, key.length, node.prefix, 0, - node.prefixLength); + int commonLength = + commonPrefixLength(key, depth, key.length, node.prefix, 0, node.prefixLength); if (commonLength != node.prefixLength) { return null; } - //common prefix is the same ,then increase the depth + // common prefix is the same ,then increase the depth depth += node.prefixLength; } int pos = node.getChildPos(key[depth]); @@ -115,10 +121,10 @@ protected Toolkit removeSpecifyKey(Node node, byte[] key, int dep) { return null; } if (node.nodeType == NodeType.LEAF_NODE) { - //root is null + // root is null LeafNode leafNode = (LeafNode) node; if (leafMatch(leafNode, key, dep)) { - //remove this node + // remove this node if (node == this.root) { this.root = null; } @@ -129,10 +135,8 @@ protected Toolkit removeSpecifyKey(Node node, byte[] key, int dep) { } } if (node.prefixLength > 0) { - int commonLength = commonPrefixLength( - key, dep, key.length, - node.prefix, 0, node.prefixLength - ); + int commonLength = + commonPrefixLength(key, dep, key.length, node.prefix, 0, node.prefixLength); if (commonLength != node.prefixLength) { return null; } @@ -142,7 +146,7 @@ protected Toolkit removeSpecifyKey(Node node, byte[] key, int dep) { if (pos != Node.ILLEGAL_IDX) { Node child = node.getChild(pos); if (child.nodeType == NodeType.LEAF_NODE && leafMatch((LeafNode) child, key, dep)) { - //found matched leaf node from the current node. + // found matched leaf node from the current node. Node freshNode = node.remove(pos); keySize--; if (node == this.root && freshNode != node) { @@ -154,10 +158,11 @@ protected Toolkit removeSpecifyKey(Node node, byte[] key, int dep) { return toolkit; } else { Toolkit toolkit = removeSpecifyKey(child, key, dep + 1); - if (toolkit != null && toolkit.needToVerifyReplacing - && toolkit.freshMatchedParentNode != null && toolkit.freshMatchedParentNode - != toolkit.originalMatchedParentNode) { - //meaning find the matched key and the shrinking happened + if (toolkit != null + && toolkit.needToVerifyReplacing + && toolkit.freshMatchedParentNode != null + && toolkit.freshMatchedParentNode != toolkit.originalMatchedParentNode) { + // meaning find the matched key and the shrinking happened node.replaceNode(pos, toolkit.freshMatchedParentNode); toolkit.needToVerifyReplacing = false; return toolkit; @@ -172,11 +177,13 @@ protected Toolkit removeSpecifyKey(Node node, byte[] key, int dep) { class Toolkit { - Node freshMatchedParentNode;//indicating a fresh parent node while the original + Node freshMatchedParentNode; // indicating a fresh parent node while the original // parent node shrunk and changed - long matchedContainerId; //holding the matched key's corresponding container index id - Node originalMatchedParentNode; //holding the matched key's leaf node's original old parent node - boolean needToVerifyReplacing = false; //indicate whether the shrinking node's parent + long matchedContainerId; // holding the matched key's corresponding container index id + Node + originalMatchedParentNode; // holding the matched key's leaf node's original old parent node + boolean needToVerifyReplacing = false; // indicate whether the shrinking node's parent + // node has replaced its corresponding child node Toolkit(Node freshMatchedParentNode, long matchedContainerId, Node originalMatchedParentNode) { @@ -188,9 +195,14 @@ class Toolkit { private boolean leafMatch(LeafNode leafNode, byte[] key, int dep) { byte[] leafNodeKeyBytes = leafNode.getKeyBytes(); - int mismatchIndex = ArraysShim - .mismatch(leafNodeKeyBytes, dep, LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES, - key, dep, LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES); + int mismatchIndex = + ArraysShim.mismatch( + leafNodeKeyBytes, + dep, + LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES, + key, + dep, + LeafNode.LEAF_NODE_KEY_LENGTH_IN_BYTES); if (mismatchIndex == -1) { return true; } else { @@ -207,41 +219,41 @@ private Node insert(Node node, byte[] key, int depth, long containerIdx) { LeafNode leafNode = (LeafNode) node; byte[] prefix = leafNode.getKeyBytes(); int commonPrefix = commonPrefixLength(prefix, depth, prefix.length, key, depth, key.length); - //The leaf node maybe was shrunk from some other node type before and + // The leaf node maybe was shrunk from some other node type before and // contained an old prefixLength,so we reset it to 0 here. leafNode.prefixLength = 0; leafNode.prefix = EMPTY_BYTES; Node4 node4 = new Node4(commonPrefix); - //copy common prefix + // copy common prefix node4.prefixLength = (byte) commonPrefix; System.arraycopy(key, depth, node4.prefix, 0, commonPrefix); - //generate two leaf nodes as the children of the fresh node4 + // generate two leaf nodes as the children of the fresh node4 Node4.insert(node4, leafNode, prefix[depth + commonPrefix]); LeafNode anotherLeaf = new LeafNode(key, containerIdx); Node4.insert(node4, anotherLeaf, key[depth + commonPrefix]); - //replace the current node with this internal node4 + // replace the current node with this internal node4 return node4; } - //to a inner node case + // to a inner node case if (node.prefixLength > 0) { - //find the mismatch position - int mismatchPos = ArraysShim.mismatch(node.prefix, 0, node.prefixLength, - key, depth, key.length); + // find the mismatch position + int mismatchPos = + ArraysShim.mismatch(node.prefix, 0, node.prefixLength, key, depth, key.length); if (mismatchPos != node.prefixLength) { Node4 node4 = new Node4(mismatchPos); - //copy prefix + // copy prefix node4.prefixLength = (byte) mismatchPos; System.arraycopy(node.prefix, 0, node4.prefix, 0, mismatchPos); - //split the current internal node, spawn a fresh node4 and let the - //current internal node as its children. + // split the current internal node, spawn a fresh node4 and let the + // current internal node as its children. Node4.insert(node4, node, node.prefix[mismatchPos]); int nodeOriginalPrefixLength = node.prefixLength; node.prefixLength = (byte) (nodeOriginalPrefixLength - (mismatchPos + (byte) 1)); - //move the remained common prefix of the initial internal node + // move the remained common prefix of the initial internal node if (node.prefixLength > 0) { System.arraycopy(node.prefix, mismatchPos + 1, node.prefix, 0, node.prefixLength); } else { - //TODO:to reduce the 0 prefix memory space,we could mark the prefix as null + // TODO:to reduce the 0 prefix memory space,we could mark the prefix as null node.prefix = new byte[0]; } LeafNode leafNode = new LeafNode(key, containerIdx); @@ -252,7 +264,7 @@ private Node insert(Node node, byte[] key, int depth, long containerIdx) { } int pos = node.getChildPos(key[depth]); if (pos != Node.ILLEGAL_IDX) { - //insert the key as current internal node's children's child node. + // insert the key as current internal node's children's child node. Node child = node.getChild(pos); Node freshOne = insert(child, key, depth + 1, containerIdx); if (freshOne != child) { @@ -260,15 +272,15 @@ private Node insert(Node node, byte[] key, int depth, long containerIdx) { } return node; } - //insert the key as a child leaf node of the current internal node + // insert the key as a child leaf node of the current internal node LeafNode leafNode = new LeafNode(key, containerIdx); Node freshOne = Node.insertLeaf(node, leafNode, key[depth]); return freshOne; } - //find common prefix length - static int commonPrefixLength(byte[] key1, int aFromIndex, int aToIndex, - byte[] key2, int bFromIndex, int bToIndex) { + // find common prefix length + static int commonPrefixLength( + byte[] key1, int aFromIndex, int aToIndex, byte[] key2, int bFromIndex, int bToIndex) { int aLength = aToIndex - aFromIndex; int bLength = bToIndex - bFromIndex; int minLength = Math.min(aLength, bLength); @@ -284,10 +296,9 @@ public Node getRoot() { return root; } - private LeafNode getExtremeLeaf(boolean reverse) { Node parent = getRoot(); - for (int depth = 0 ; depth < AbstractShuttle.MAX_DEPTH ; depth++) { + for (int depth = 0; depth < AbstractShuttle.MAX_DEPTH; depth++) { if (parent.nodeType == NodeType.LEAF_NODE) { break; } @@ -336,36 +347,36 @@ public LeafNodeIterator leafNodeIteratorFrom(long bound, boolean reverse, Contai private void serialize(Node node, DataOutput dataOutput) throws IOException { if (node.nodeType != NodeType.LEAF_NODE) { - //serialize the internal node itself first + // serialize the internal node itself first node.serialize(dataOutput); - //then all the internal node's children + // then all the internal node's children int nexPos = node.getNextLargerPos(Node.ILLEGAL_IDX); while (nexPos != Node.ILLEGAL_IDX) { - //serialize all the not null child node + // serialize all the not null child node Node child = node.getChild(nexPos); serialize(child, dataOutput); nexPos = node.getNextLargerPos(nexPos); } } else { - //serialize the leaf node + // serialize the leaf node node.serialize(dataOutput); } } private void serialize(Node node, ByteBuffer byteBuffer) throws IOException { if (node.nodeType != NodeType.LEAF_NODE) { - //serialize the internal node itself first + // serialize the internal node itself first node.serialize(byteBuffer); - //then all the internal node's children + // then all the internal node's children int nexPos = node.getNextLargerPos(Node.ILLEGAL_IDX); while (nexPos != Node.ILLEGAL_IDX) { - //serialize all the not null child node + // serialize all the not null child node Node child = node.getChild(nexPos); serialize(child, byteBuffer); nexPos = node.getNextLargerPos(nexPos); } } else { - //serialize the leaf node + // serialize the leaf node node.serialize(byteBuffer); } } @@ -378,9 +389,9 @@ private Node deserialize(DataInput dataInput) throws IOException { if (oneNode.nodeType == NodeType.LEAF_NODE) { return oneNode; } else { - //internal node + // internal node int count = oneNode.count; - //all the not null child nodes + // all the not null child nodes Node[] children = new Node[count]; for (int i = 0; i < count; i++) { Node child = deserialize(dataInput); @@ -399,9 +410,9 @@ private Node deserialize(ByteBuffer byteBuffer) throws IOException { if (oneNode.nodeType == NodeType.LEAF_NODE) { return oneNode; } else { - //internal node + // internal node int count = oneNode.count; - //all the not null child nodes + // all the not null child nodes Node[] children = new Node[count]; for (int i = 0; i < count; i++) { Node child = deserialize(byteBuffer); @@ -422,13 +433,13 @@ public long getKeySize() { private long serializeSizeInBytes(Node node) { if (node.nodeType != NodeType.LEAF_NODE) { - //serialize the internal node itself first + // serialize the internal node itself first int currentNodeSize = node.serializeSizeInBytes(); - //then all the internal node's children + // then all the internal node's children long childrenTotalSize = 0L; int nexPos = node.getNextLargerPos(Node.ILLEGAL_IDX); while (nexPos != Node.ILLEGAL_IDX) { - //serialize all the not null child node + // serialize all the not null child node Node child = node.getChild(nexPos); long childSize = serializeSizeInBytes(child); nexPos = node.getNextLargerPos(nexPos); @@ -436,7 +447,7 @@ private long serializeSizeInBytes(Node node) { } return currentNodeSize + childrenTotalSize; } else { - //serialize the leaf node + // serialize the leaf node int nodeSize = node.serializeSizeInBytes(); return nodeSize; } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java index d12edee8e..36eeb6a21 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/ContainerIterator.java @@ -1,8 +1,9 @@ package org.roaringbitmap.art; -import java.util.Iterator; import org.roaringbitmap.Container; +import java.util.Iterator; + public class ContainerIterator implements Iterator { private Containers containers; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Containers.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Containers.java index 7665d0e6d..f9213b3b6 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Containers.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Containers.java @@ -1,5 +1,10 @@ package org.roaringbitmap.art; +import org.roaringbitmap.ArrayContainer; +import org.roaringbitmap.BitmapContainer; +import org.roaringbitmap.Container; +import org.roaringbitmap.RunContainer; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; @@ -7,11 +12,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.roaringbitmap.ArrayContainer; -import org.roaringbitmap.BitmapContainer; -import org.roaringbitmap.Container; -import org.roaringbitmap.RoaringBitmap; -import org.roaringbitmap.RunContainer; /** * To support the largest 2^48 different keys,we almost need 2^18 Container arrays which holds 2^31 @@ -62,7 +62,7 @@ public void remove(long containerIdx) { * @return the corresponding Container */ public Container getContainer(long idx) { - //split the idx into two part + // split the idx into two part int firstDimIdx = (int) (idx >>> 32); int secondDimIdx = (int) idx; Container[] containers = containerArrays.get(firstDimIdx); @@ -214,7 +214,7 @@ public void serialize(DataOutput dataOutput) throws IOException { Container[] containers = containerArrays.get(i); int secondLevelSize = containers.length; dataOutput.writeByte(NOT_TRIMMED_MARK); - //TODO:serialize the trimmed related data + // TODO:serialize the trimmed related data dataOutput.writeInt(Integer.reverseBytes(secondLevelSize)); for (int j = 0; j < containers.length; j++) { Container container = containers[j]; @@ -247,7 +247,7 @@ public void serialize(ByteBuffer byteBuffer) throws IOException { Container[] containers = containerArrays.get(i); int secondLevelSize = containers.length; byteBuffer.put(NOT_TRIMMED_MARK); - //TODO:serialize the trimmed related data + // TODO:serialize the trimmed related data byteBuffer.putInt(secondLevelSize); for (int j = 0; j < containers.length; j++) { Container container = containers[j]; @@ -277,7 +277,7 @@ public void deserialize(DataInput dataInput) throws IOException { int firstLevelSize = Integer.reverseBytes(dataInput.readInt()); ArrayList containersArray = new ArrayList<>(firstLevelSize); for (int i = 0; i < firstLevelSize; i++) { - //TODO:deserialize the trimmed related data + // TODO:deserialize the trimmed related data byte trimTag = dataInput.readByte(); int secondLevelSize = Integer.reverseBytes(dataInput.readInt()); Container[] containers = new Container[secondLevelSize]; @@ -312,7 +312,7 @@ public void deserialize(ByteBuffer byteBuffer) throws IOException { int firstLevelSize = byteBuffer.getInt(); ArrayList containersArray = new ArrayList<>(firstLevelSize); for (int i = 0; i < firstLevelSize; i++) { - //TODO:deserialize the trimmed related data + // TODO:deserialize the trimmed related data byte trimTag = byteBuffer.get(); int secondLevelSize = byteBuffer.getInt(); Container[] containers = new Container[secondLevelSize]; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNode.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNode.java index ce344215d..a8e805322 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNode.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNode.java @@ -1,15 +1,16 @@ package org.roaringbitmap.art; +import org.roaringbitmap.longlong.LongUtils; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; -import org.roaringbitmap.longlong.LongUtils; public class LeafNode extends Node { - //key are saved as the lazy expanding logic,here we only care about the - //high 48 bit data,so only the high 48 bit is valuable + // key are saved as the lazy expanding logic,here we only care about the + // high 48 bit data,so only the high 48 bit is valuable private long key; long containerIdx; public static final int LEAF_NODE_KEY_LENGTH_IN_BYTES = 6; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java index 07e5dad0b..014a31cad 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/LeafNodeIterator.java @@ -61,7 +61,6 @@ public LeafNodeIterator(Art art, boolean reverse, Containers containers, long fr calledHasNext = false; } - private boolean advance() { boolean hasLeafNode = shuttle.moveToNextLeaf(); if (hasLeafNode) { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node.java index dbcaa31ea..37e505516 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node.java @@ -7,14 +7,14 @@ public abstract class Node { - //node type + // node type protected NodeType nodeType; - //length of compressed path(prefix) + // length of compressed path(prefix) protected byte prefixLength; - //the compressed path path (prefix) + // the compressed path path (prefix) protected byte[] prefix; - //number of non-null children, the largest value will not beyond 255 - //to benefit calculation,we keep the value as a short type + // number of non-null children, the largest value will not beyond 255 + // to benefit calculation,we keep the value as a short type protected short count; public static final int ILLEGAL_IDX = -1; @@ -34,7 +34,8 @@ public Node(NodeType nodeType, int compressedPrefixSize) { /** * sort the small arrays through the insertion sort alg. */ - protected static byte[] sortSmallByteArray(byte[] key, Node[] children, int left, int right) {//x + protected static byte[] sortSmallByteArray( + byte[] key, Node[] children, int left, int right) { // x for (int i = left, j = i; i < right; j = ++i) { byte ai = key[i + 1]; Node child = children[i + 1]; @@ -274,8 +275,7 @@ public static void copyPrefix(Node src, Node dst) { * @param k the target key byte value * @return the array offset of the target input key 'k' or -1 to not found */ - public static int binarySearch(byte[] key, int fromIndex, int toIndex, - byte k) { + public static int binarySearch(byte[] key, int fromIndex, int toIndex, byte k) { int inputUnsignedByte = Byte.toUnsignedInt(k); int low = fromIndex; int high = toIndex - 1; @@ -296,8 +296,7 @@ public static int binarySearch(byte[] key, int fromIndex, int toIndex, return ILLEGAL_IDX; } - static SearchResult binarySearchWithResult(byte[] key, int fromIndex, int toIndex, - byte k) { + static SearchResult binarySearchWithResult(byte[] key, int fromIndex, int toIndex, byte k) { int inputUnsignedByte = Byte.toUnsignedInt(k); int low = fromIndex; int high = toIndex - 1; @@ -324,9 +323,9 @@ static SearchResult binarySearchWithResult(byte[] key, int fromIndex, int toInde } private void serializeHeader(DataOutput dataOutput) throws IOException { - //first byte: node type + // first byte: node type dataOutput.writeByte((byte) this.nodeType.ordinal()); - //non null object count + // non null object count dataOutput.writeShort(Short.reverseBytes(this.count)); dataOutput.writeByte(this.prefixLength); if (prefixLength > 0) { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node16.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node16.java index 46d40913b..189168dcb 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node16.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node16.java @@ -1,11 +1,12 @@ package org.roaringbitmap.art; +import org.roaringbitmap.longlong.LongUtils; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import org.roaringbitmap.longlong.LongUtils; public class Node16 extends Node { @@ -44,36 +45,37 @@ public SearchResult getNearestChildPos(byte k) { if (count <= 8) { return Node.binarySearchWithResult(firstBytes, 0, count, k); } else { - SearchResult firstResult = Node.binarySearchWithResult( - firstBytes, 0, 8, k); + SearchResult firstResult = Node.binarySearchWithResult(firstBytes, 0, 8, k); // given the values are "in order" if we found a match or a value larger than // the target we are done. - if (firstResult.outcome == SearchResult.Outcome.FOUND - || firstResult.hasNextLargerPos()) { + if (firstResult.outcome == SearchResult.Outcome.FOUND || firstResult.hasNextLargerPos()) { return firstResult; } else { byte[] secondBytes = LongUtils.toBDBytes(secondV); - SearchResult secondResult = Node.binarySearchWithResult( - secondBytes, 0, (count - 8), k); + SearchResult secondResult = Node.binarySearchWithResult(secondBytes, 0, (count - 8), k); - switch(secondResult.outcome) { + switch (secondResult.outcome) { case FOUND: return SearchResult.found(8 + secondResult.getKeyPos()); case NOT_FOUND: int lowPos = secondResult.getNextSmallerPos(); int highPos = secondResult.getNextLargerPos(); // don't map -1 into the legal range by adding 8! - if (lowPos>=0){ lowPos += 8;} - if (highPos>=0){ highPos += 8;} + if (lowPos >= 0) { + lowPos += 8; + } + if (highPos >= 0) { + highPos += 8; + } - if(firstResult.hasNextLargerPos() == false && secondResult.hasNextSmallerPos() == false) - { + if (firstResult.hasNextLargerPos() == false + && secondResult.hasNextSmallerPos() == false) { // this happens when the result is in the gap of the two ranges, the correct // "smaller value" is that of first result. lowPos = firstResult.getNextSmallerPos(); } - return SearchResult.notFound( lowPos, highPos); + return SearchResult.notFound(lowPos, highPos); default: throw new IllegalStateException("There only two possible search outcomes"); @@ -145,7 +147,7 @@ public int getNextSmallerPos(int pos) { public static Node insert(Node node, Node child, byte key) { Node16 currentNode16 = (Node16) node; if (currentNode16.count < 8) { - //first + // first byte[] bytes = LongUtils.toBDBytes(currentNode16.firstV); bytes[currentNode16.count] = key; currentNode16.children[currentNode16.count] = child; @@ -154,7 +156,7 @@ public static Node insert(Node node, Node child, byte key) { currentNode16.firstV = LongUtils.fromBDBytes(bytes); return currentNode16; } else if (currentNode16.count < 16) { - //second + // second ByteBuffer byteBuffer = ByteBuffer.allocate(16).order(ByteOrder.BIG_ENDIAN); byteBuffer.putLong(currentNode16.firstV); byteBuffer.putLong(currentNode16.secondV); @@ -169,7 +171,7 @@ public static Node insert(Node node, Node child, byte key) { Node48 node48 = new Node48(currentNode16.prefixLength); for (int i = 0; i < 8; i++) { int unsignedIdx = Byte.toUnsignedInt((byte) (currentNode16.firstV >>> ((7 - i) << 3))); - //i won't be beyond 48 + // i won't be beyond 48 Node48.setOneByte(unsignedIdx, (byte) i, node48.childIndex); node48.children[i] = currentNode16.children[i]; } @@ -177,7 +179,7 @@ public static Node insert(Node node, Node child, byte key) { for (int i = 8; i < currentNode16.count; i++) { byte v = secondBytes[i - 8]; int unsignedIdx = Byte.toUnsignedInt(v); - //i won't be beyond 48 + // i won't be beyond 48 Node48.setOneByte(unsignedIdx, (byte) i, node48.childIndex); node48.children[i] = currentNode16.children[i]; } @@ -199,9 +201,9 @@ public Node remove(int pos) { secondV = byteBuffer.getLong(8); count--; if (count <= 3) { - //shrink to node4 + // shrink to node4 Node4 node4 = new Node4(prefixLength); - //copy the keys + // copy the keys node4.key = (int) (firstV >> 32); System.arraycopy(children, 0, node4.children, 0, count); node4.count = count; @@ -213,7 +215,7 @@ public Node remove(int pos) { @Override public void serializeNodeBody(DataOutput dataOutput) throws IOException { - //little endian + // little endian dataOutput.writeLong(Long.reverseBytes(firstV)); dataOutput.writeLong(Long.reverseBytes(secondV)); } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node256.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node256.java index 0f41c4cb4..c23757b5c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node256.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node256.java @@ -11,11 +11,10 @@ public class Node256 extends Node { Node[] children = new Node[256]; - //a helper utility field + // a helper utility field long[] bitmapMask = new long[4]; private static final long LONG_MASK = 0xffffffffffffffffL; - public Node256(int compressedPrefixSize) { super(NodeType.NODE256, compressedPrefixSize); } @@ -175,7 +174,7 @@ public Node remove(int pos) { @Override public void replaceChildren(Node[] children) { if (children.length == this.children.length) { - //short circuit path + // short circuit path this.children = children; return; } @@ -194,7 +193,6 @@ public void replaceChildren(Node[] children) { } } - @Override public void serializeNodeBody(DataOutput dataOutput) throws IOException { for (long longv : bitmapMask) { @@ -229,4 +227,3 @@ public int serializeNodeBodySizeInBytes() { return 4 * 8; } } - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node4.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node4.java index 205c238db..048faa7bc 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node4.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node4.java @@ -1,11 +1,12 @@ package org.roaringbitmap.art; +import org.roaringbitmap.longlong.IntegerUtil; +import org.roaringbitmap.longlong.LongUtils; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; -import org.roaringbitmap.longlong.IntegerUtil; -import org.roaringbitmap.longlong.LongUtils; public class Node4 extends Node { @@ -90,14 +91,14 @@ public int getNextSmallerPos(int pos) { public static Node insert(Node node, Node childNode, byte key) { Node4 current = (Node4) node; if (current.count < 4) { - //insert leaf into current node + // insert leaf into current node current.key = IntegerUtil.setByte(current.key, key, current.count); current.children[current.count] = childNode; current.count++; insertionSort(current); return current; } else { - //grow to Node16 + // grow to Node16 Node16 node16 = new Node16(current.prefixLength); node16.count = 4; node16.firstV = LongUtils.initWithFirst4Byte(current.key); @@ -118,7 +119,7 @@ public Node remove(int pos) { children[pos] = children[pos + 1]; } if (count == 1) { - //shrink to the child node + // shrink to the child node Node child = children[0]; byte newLength = (byte) (child.prefixLength + this.prefixLength + 1); byte[] newPrefix = new byte[newLength]; @@ -164,7 +165,6 @@ public int serializeNodeBodySizeInBytes() { return 4; } - @Override public void replaceChildren(Node[] children) { System.arraycopy(children, 0, this.children, 0, count); diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node48.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node48.java index e255fbbe3..5a9616419 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/Node48.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/Node48.java @@ -7,11 +7,10 @@ import java.nio.ByteOrder; import java.nio.LongBuffer; import java.util.Arrays; -import org.roaringbitmap.longlong.LongUtils; public class Node48 extends Node { - //the actual byte value of childIndex content won't be beyond 48 + // the actual byte value of childIndex content won't be beyond 48 // 256 bytes packed into longs static final int BYTES_PER_LONG = 8; static final int LONGS_USED = 256 / BYTES_PER_LONG; @@ -19,7 +18,7 @@ public class Node48 extends Node { static final int POS_MASK = 0x7; // the mask to access the pos in the long for the byte long[] childIndex = new long[LONGS_USED]; Node[] children = new Node[48]; - static final byte EMPTY_VALUE = (byte)0xFF; + static final byte EMPTY_VALUE = (byte) 0xFF; static final long INIT_LONG_VALUE = 0xFFffFFffFFffFFffL; public Node48(int compressedPrefixSize) { @@ -71,7 +70,7 @@ public int getMinPos() { for (int i = 0; i < LONGS_USED; i++) { long longv = childIndex[i]; if (longv == INIT_LONG_VALUE) { - //skip over empty bytes + // skip over empty bytes pos += BYTES_PER_LONG; continue; } else { @@ -97,7 +96,7 @@ public int getNextLargerPos(int pos) { for (; i < LONGS_USED; i++) { long longv = childIndex[i]; if (longv == INIT_LONG_VALUE) { - //skip over empty bytes + // skip over empty bytes pos = (pos + BYTES_PER_LONG) & 0xF8; continue; } @@ -148,8 +147,8 @@ public int getNextSmallerPos(int pos) { for (; i >= 0 && i < LONGS_USED; i--) { long longv = childIndex[i]; if (longv == INIT_LONG_VALUE) { - //skip over empty bytes - pos -= Math.min(BYTES_PER_LONG,(pos & POS_MASK) + 1); + // skip over empty bytes + pos -= Math.min(BYTES_PER_LONG, (pos & POS_MASK) + 1); continue; } // because we are starting potentially at non aligned location, we need to start at 7 @@ -177,7 +176,7 @@ public int getNextSmallerPos(int pos) { public static Node insert(Node currentNode, Node child, byte key) { Node48 node48 = (Node48) currentNode; if (node48.count < 48) { - //insert leaf node into current node + // insert leaf node into current node int pos = node48.count; if (node48.children[pos] != null) { pos = 0; @@ -187,11 +186,11 @@ public static Node insert(Node currentNode, Node child, byte key) { } node48.children[pos] = child; int unsignedByte = Byte.toUnsignedInt(key); - setOneByte(unsignedByte, (byte)pos, node48.childIndex); + setOneByte(unsignedByte, (byte) pos, node48.childIndex); node48.count++; return node48; } else { - //grow to Node256 + // grow to Node256 Node256 node256 = new Node256(node48.prefixLength); int currentPos = ILLEGAL_IDX; while ((currentPos = node48.getNextLargerPos(currentPos)) != ILLEGAL_IDX) { @@ -213,7 +212,7 @@ public Node remove(int pos) { children[idx] = null; count--; if (count <= 12) { - //shrink to node16 + // shrink to node16 Node16 node16 = new Node16(this.prefixLength); int j = 0; ByteBuffer byteBuffer = ByteBuffer.allocate(16).order(ByteOrder.BIG_ENDIAN); diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/art/NodeType.java b/roaringbitmap/src/main/java/org/roaringbitmap/art/NodeType.java index ab7bacbc6..1a73dd2c2 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/art/NodeType.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/art/NodeType.java @@ -1,5 +1,10 @@ package org.roaringbitmap.art; public enum NodeType { - NODE4, NODE16, NODE48, NODE256, LEAF_NODE, DUMMY_ROOT; + NODE4, + NODE16, + NODE48, + NODE256, + LEAF_NODE, + DUMMY_ROOT; } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java index f0664e95b..075e1633c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ArrayBatchIterator.java @@ -1,12 +1,11 @@ package org.roaringbitmap.buffer; +import static org.roaringbitmap.buffer.BufferUtil.unsignedBinarySearch; + import org.roaringbitmap.ContainerBatchIterator; import java.nio.CharBuffer; -import static org.roaringbitmap.buffer.BufferUtil.unsignedBinarySearch; - - public final class ArrayBatchIterator implements ContainerBatchIterator { private int index = 0; @@ -34,7 +33,7 @@ public boolean hasNext() { @Override public ContainerBatchIterator clone() { try { - return (ContainerBatchIterator)super.clone(); + return (ContainerBatchIterator) super.clone(); } catch (CloneNotSupportedException e) { // won't happen throw new IllegalStateException(e); diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java index d8e26681f..28475871f 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BitmapBatchIterator.java @@ -1,9 +1,9 @@ package org.roaringbitmap.buffer; -import org.roaringbitmap.ContainerBatchIterator; - import static java.lang.Long.numberOfTrailingZeros; +import org.roaringbitmap.ContainerBatchIterator; + public final class BitmapBatchIterator implements ContainerBatchIterator { private int wordIndex = 0; @@ -49,7 +49,7 @@ public boolean hasNext() { @Override public ContainerBatchIterator clone() { try { - return (ContainerBatchIterator)super.clone(); + return (ContainerBatchIterator) super.clone(); } catch (CloneNotSupportedException e) { // won't happen throw new IllegalStateException(e); @@ -73,5 +73,4 @@ void wrap(MappeableBitmapContainer bitmap) { this.word = bitmap.bitmap.get(0); this.wordIndex = 0; } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java index 88917b901..b95370b69 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferBitSetUtil.java @@ -1,6 +1,5 @@ package org.roaringbitmap.buffer; - import org.roaringbitmap.BitSetUtil; import org.roaringbitmap.IntIterator; @@ -10,7 +9,6 @@ import java.nio.LongBuffer; import java.util.BitSet; - /*** * * This class provides convenience functions to manipulate BitSet and MutableRoaringBitmap objects. @@ -21,17 +19,17 @@ public class BufferBitSetUtil { // a block consists has a maximum of 1024 words, each representing 64 bits, // thus representing at maximum 65536 bits - static final private int BLOCK_LENGTH = MappeableBitmapContainer.MAX_CAPACITY / Long.SIZE; // + private static final int BLOCK_LENGTH = MappeableBitmapContainer.MAX_CAPACITY / Long.SIZE; // + // 64-bit // word - private static MappeableArrayContainer arrayContainerOf(final int from, final int to, - final int cardinality, final long[] words) { + private static MappeableArrayContainer arrayContainerOf( + final int from, final int to, final int cardinality, final long[] words) { char[] content = BitSetUtil.arrayContainerBufferOf(from, to, cardinality, words); return new MappeableArrayContainer(CharBuffer.wrap(content), cardinality); } - /** * Generate a MutableRoaringBitmap out of a BitSet * @@ -59,9 +57,11 @@ public static MutableRoaringBitmap bitmapOf(final long[] words) { final int to = Math.min(from + BLOCK_LENGTH, words.length); final int blockCardinality = cardinality(from, to, words); if (blockCardinality > 0) { - ((MutableRoaringArray) ans.highLowContainer).insertNewKeyValueAt(containerIndex++, - BufferUtil.highbits(from * Long.SIZE), - BufferBitSetUtil.containerOf(from, to, blockCardinality, words)); + ((MutableRoaringArray) ans.highLowContainer) + .insertNewKeyValueAt( + containerIndex++, + BufferUtil.highbits(from * Long.SIZE), + BufferBitSetUtil.containerOf(from, to, blockCardinality, words)); } } return ans; @@ -113,14 +113,16 @@ public static MutableRoaringBitmap bitmapOf(ByteBuffer bb, long[] wordsBuffer) { if (blockLength == BLOCK_LENGTH) { // Each block becomes a single container, if any bit is set if (blockCardinality > 0) { - ((MutableRoaringArray) ans.highLowContainer).insertNewKeyValueAt(containerIndex++, - BufferUtil.highbits(offset), BufferBitSetUtil.containerOf(0, blockLength, - blockCardinality, wordsBuffer)); + ((MutableRoaringArray) ans.highLowContainer) + .insertNewKeyValueAt( + containerIndex++, + BufferUtil.highbits(offset), + BufferBitSetUtil.containerOf(0, blockLength, blockCardinality, wordsBuffer)); } /* - Offset can overflow when bitsets size is more than Integer.MAX_VALUE - 64 - It's harmless though, as it will happen after the last block is added - */ + Offset can overflow when bitsets size is more than Integer.MAX_VALUE - 64 + It's harmless though, as it will happen after the last block is added + */ offset += (BLOCK_LENGTH * Long.SIZE); blockLength = blockCardinality = 0; } @@ -143,9 +145,11 @@ public static MutableRoaringBitmap bitmapOf(ByteBuffer bb, long[] wordsBuffer) { // Add block to map, if any bit is set if (blockCardinality > 0) { - ((MutableRoaringArray) ans.highLowContainer).insertNewKeyValueAt(containerIndex, - BufferUtil.highbits(offset), - BufferBitSetUtil.containerOf(0, blockLength, blockCardinality, wordsBuffer)); + ((MutableRoaringArray) ans.highLowContainer) + .insertNewKeyValueAt( + containerIndex, + BufferUtil.highbits(offset), + BufferBitSetUtil.containerOf(0, blockLength, blockCardinality, wordsBuffer)); } return ans; } @@ -158,9 +162,8 @@ private static int cardinality(final int from, final int to, final long[] words) return sum; } - - private static MappeableContainer containerOf(final int from, final int to, - final int blockCardinality, final long[] words) { + private static MappeableContainer containerOf( + final int from, final int to, final int blockCardinality, final long[] words) { // find the best container available if (blockCardinality <= MappeableArrayContainer.DEFAULT_MAX_SIZE) { // containers with DEFAULT_MAX_SIZE or less integers should be @@ -174,7 +177,6 @@ private static MappeableContainer containerOf(final int from, final int to, } } - /** * Compares a RoaringBitmap and a BitSet. They are equal if and only if they contain the same set * of integers. diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java index cef3ec1b4..616969943 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferFastAggregation.java @@ -9,8 +9,13 @@ import java.nio.CharBuffer; import java.nio.LongBuffer; -import java.util.*; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.PriorityQueue; /** * Fast algorithms to aggregate many bitmaps. @@ -19,7 +24,6 @@ */ public final class BufferFastAggregation { - /** * Compute the AND aggregate. * @@ -41,10 +45,10 @@ public static MutableRoaringBitmap and(ImmutableRoaringBitmap... bitmaps) { * @param bitmaps input bitmaps * @return aggregated bitmap */ - public static MutableRoaringBitmap and(long[] aggregationBuffer, - ImmutableRoaringBitmap... bitmaps) { + public static MutableRoaringBitmap and( + long[] aggregationBuffer, ImmutableRoaringBitmap... bitmaps) { if (bitmaps.length > 10) { - if(aggregationBuffer.length < 1024) { + if (aggregationBuffer.length < 1024) { throw new IllegalArgumentException("buffer should have at least 1024 elements."); } try { @@ -77,8 +81,8 @@ public static MutableRoaringBitmap and(Iterator bitmaps) { + public static MutableRoaringBitmap and( + long[] aggregationBuffer, Iterator bitmaps) { if (bitmaps.hasNext()) { try { return workShyAnd(aggregationBuffer, bitmaps); @@ -89,7 +93,6 @@ public static MutableRoaringBitmap and(long[] aggregationBuffer, return new MutableRoaringBitmap(); } - /** * Compute the AND aggregate. * @@ -161,12 +164,8 @@ public ImmutableRoaringBitmap next() { } @Override - public void remove() { - - } - + public void remove() {} }; - } private static ImmutableRoaringBitmap[] convertToImmutable(MutableRoaringBitmap[] array) { @@ -175,7 +174,6 @@ private static ImmutableRoaringBitmap[] convertToImmutable(MutableRoaringBitmap[ return answer; } - /** * Minimizes memory usage while computing the or aggregate on a moderate number of bitmaps. * @@ -235,7 +233,6 @@ public static MutableRoaringBitmap horizontal_or(ImmutableRoaringBitmap... bitma return answer; } - /** * Calls naive_or. * @@ -260,7 +257,6 @@ public static MutableRoaringBitmap horizontal_or(MutableRoaringBitmap... bitmaps return horizontal_or(convertToImmutable(bitmaps)); } - /** * Minimizes memory usage while computing the xor aggregate on a moderate number of bitmaps. * @@ -332,7 +328,6 @@ public static MutableRoaringBitmap horizontal_xor(MutableRoaringBitmap... bitmap return horizontal_xor(convertToImmutable(bitmaps)); } - /** * Compute overall AND between bitmaps two-by-two. * @@ -424,8 +419,8 @@ public static MutableRoaringBitmap naive_and(MutableRoaringBitmap... bitmaps) { * @param bitmaps the inputs * @return the intersection of the bitmaps */ - static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, - ImmutableRoaringBitmap... bitmaps) { + static MutableRoaringBitmap workShyAnd( + long[] aggregationBuffer, ImmutableRoaringBitmap... bitmaps) { long[] words = aggregationBuffer; char[] keys = BufferUtil.intersectKeys(words, bitmaps); if (keys.length == 0) { @@ -446,7 +441,7 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, } MutableRoaringArray array = - new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0); + new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0); for (int i = 0; i < numContainers; ++i) { MappeableContainer[] slice = containers[i]; Arrays.fill(words, -1L); @@ -476,8 +471,8 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, * @param bitmaps the inputs * @return the intersection of the bitmaps */ - static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, - Iterator bitmaps) { + static MutableRoaringBitmap workShyAnd( + long[] aggregationBuffer, Iterator bitmaps) { long[] words = aggregationBuffer; List collected = new ArrayList<>(); ImmutableRoaringBitmap first = bitmaps.next(); @@ -501,9 +496,9 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, keys[j] = bitmap.highLowContainer.getKeyAtIndex(j); } } - numContainers = BufferUtil.intersectArrayIntoBitmap(words, - CharBuffer.wrap(keys), - bitmap.highLowContainer.size()); + numContainers = + BufferUtil.intersectArrayIntoBitmap( + words, CharBuffer.wrap(keys), bitmap.highLowContainer.size()); } if (numContainers == 0) { return new MutableRoaringBitmap(); @@ -523,7 +518,7 @@ static MutableRoaringBitmap workShyAnd(long[] aggregationBuffer, } MutableRoaringArray array = - new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0); + new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0); for (int i = 0; i < numContainers; ++i) { MappeableContainer[] slice = containers[i]; Arrays.fill(words, -1L); @@ -624,9 +619,9 @@ private static int horizontalOrCardinality(ImmutableRoaringBitmap... bitmaps) { * @param bitmaps the inputs * @return the intersection of the bitmaps */ - public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer, - ImmutableRoaringBitmap... bitmaps) { - if(buffer.length < 1024) { + public static MutableRoaringBitmap workAndMemoryShyAnd( + long[] buffer, ImmutableRoaringBitmap... bitmaps) { + if (buffer.length < 1024) { throw new IllegalArgumentException("buffer should have at least 1024 elements."); } long[] words = buffer; @@ -637,14 +632,14 @@ public static MutableRoaringBitmap workAndMemoryShyAnd(long[] buffer, int numContainers = keys.length; MutableRoaringArray array = - new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0); + new MutableRoaringArray(keys, new MappeableContainer[numContainers], 0); for (int i = 0; i < numContainers; ++i) { char MatchingKey = keys[i]; Arrays.fill(words, -1L); MappeableContainer tmp = new MappeableBitmapContainer(LongBuffer.wrap(words), -1); - for(ImmutableRoaringBitmap bitmap: bitmaps) { + for (ImmutableRoaringBitmap bitmap : bitmaps) { int idx = bitmap.highLowContainer.getIndex(MatchingKey); - if(idx < 0) { + if (idx < 0) { continue; } MappeableContainer container = bitmap.highLowContainer.getContainerAtIndex(idx); @@ -698,8 +693,6 @@ public static MutableRoaringBitmap naive_or(@SuppressWarnings("rawtypes") Iterat return answer; } - - /** * Compute overall OR between bitmaps two-by-two. * @@ -749,7 +742,6 @@ public static MutableRoaringBitmap naive_xor(@SuppressWarnings("rawtypes") Itera return answer; } - /** * Compute overall XOR between bitmaps two-by-two. * @@ -766,7 +758,6 @@ public static MutableRoaringBitmap naive_xor(MutableRoaringBitmap... bitmaps) { return answer; } - /** * Compute overall OR between bitmaps. * @@ -777,7 +768,6 @@ public static MutableRoaringBitmap or(ImmutableRoaringBitmap... bitmaps) { return naive_or(bitmaps); } - /** * Compute overall OR between bitmaps. * @@ -820,12 +810,15 @@ public static MutableRoaringBitmap priorityqueue_or(ImmutableRoaringBitmap... bi for (int k = 0; k < sizes.length; ++k) { sizes[k] = buffer[k].serializedSizeInBytes(); } - PriorityQueue pq = new PriorityQueue<>(128, new Comparator() { - @Override - public int compare(Integer a, Integer b) { - return sizes[a] - sizes[b]; - } - }); + PriorityQueue pq = + new PriorityQueue<>( + 128, + new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return sizes[a] - sizes[b]; + } + }); for (int k = 0; k < sizes.length; ++k) { pq.add(k); } @@ -833,8 +826,9 @@ public int compare(Integer a, Integer b) { Integer x1 = pq.poll(); Integer x2 = pq.poll(); if (istmp[x1] && istmp[x2]) { - buffer[x1] = MutableRoaringBitmap.lazyorfromlazyinputs((MutableRoaringBitmap) buffer[x1], - (MutableRoaringBitmap) buffer[x2]); + buffer[x1] = + MutableRoaringBitmap.lazyorfromlazyinputs( + (MutableRoaringBitmap) buffer[x1], (MutableRoaringBitmap) buffer[x2]); sizes[x1] = buffer[x1].serializedSizeInBytes(); pq.add(x1); } else if (istmp[x2]) { @@ -881,12 +875,15 @@ public static MutableRoaringBitmap priorityqueue_or( for (int k = 0; k < sizes.length; ++k) { sizes[k] = buffer.get(k).getLongSizeInBytes(); } - PriorityQueue pq = new PriorityQueue<>(128, new Comparator() { - @Override - public int compare(Integer a, Integer b) { - return (int)(sizes[a] - sizes[b]); - } - }); + PriorityQueue pq = + new PriorityQueue<>( + 128, + new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return (int) (sizes[a] - sizes[b]); + } + }); for (int k = 0; k < sizes.length; ++k) { pq.add(k); } @@ -897,8 +894,10 @@ public int compare(Integer a, Integer b) { Integer x1 = pq.poll(); Integer x2 = pq.poll(); if (istmp[x1] && istmp[x2]) { - buffer.set(x1, MutableRoaringBitmap.lazyorfromlazyinputs( - (MutableRoaringBitmap) buffer.get(x1), (MutableRoaringBitmap) buffer.get(x2))); + buffer.set( + x1, + MutableRoaringBitmap.lazyorfromlazyinputs( + (MutableRoaringBitmap) buffer.get(x1), (MutableRoaringBitmap) buffer.get(x2))); sizes[x1] = buffer.get(x1).getLongSizeInBytes(); pq.add(x1); } else if (istmp[x2]) { @@ -936,12 +935,14 @@ public static MutableRoaringBitmap priorityqueue_xor(ImmutableRoaringBitmap... b throw new IllegalArgumentException("Expecting at least 2 bitmaps"); } final PriorityQueue pq = - new PriorityQueue<>(bitmaps.length, new Comparator() { - @Override - public int compare(ImmutableRoaringBitmap a, ImmutableRoaringBitmap b) { - return (int)(a.getLongSizeInBytes() - b.getLongSizeInBytes()); - } - }); + new PriorityQueue<>( + bitmaps.length, + new Comparator() { + @Override + public int compare(ImmutableRoaringBitmap a, ImmutableRoaringBitmap b) { + return (int) (a.getLongSizeInBytes() - b.getLongSizeInBytes()); + } + }); Collections.addAll(pq, bitmaps); while (pq.size() > 1) { final ImmutableRoaringBitmap x1 = pq.poll(); @@ -951,7 +952,6 @@ public int compare(ImmutableRoaringBitmap a, ImmutableRoaringBitmap b) { return (MutableRoaringBitmap) pq.poll(); } - /** * Compute overall XOR between bitmaps. * @@ -963,7 +963,6 @@ public static MutableRoaringBitmap xor(ImmutableRoaringBitmap... bitmaps) { return naive_xor(bitmaps); } - /** * Compute overall XOR between bitmaps. * @@ -974,7 +973,6 @@ public static MutableRoaringBitmap xor(@SuppressWarnings("rawtypes") Iterator bi return naive_xor(bitmaps); } - /** * Compute overall XOR between bitmaps. * @@ -989,8 +987,5 @@ public static MutableRoaringBitmap xor(MutableRoaringBitmap... bitmaps) { /** * Private constructor to prevent instantiation of utility class */ - private BufferFastAggregation() { - - } - + private BufferFastAggregation() {} } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java index 0f8a4b319..cf2604c48 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferIntIteratorFlyweight.java @@ -28,7 +28,6 @@ public class BufferIntIteratorFlyweight implements PeekableIntIterator { private MappeableRunContainerCharIterator runIter = new MappeableRunContainerCharIterator(); - private int pos; private ImmutableRoaringBitmap roaringBitmap = null; @@ -37,9 +36,7 @@ public class BufferIntIteratorFlyweight implements PeekableIntIterator { * Creates an instance that is not ready for iteration. You must first call * {@link #wrap(ImmutableRoaringBitmap)}. */ - public BufferIntIteratorFlyweight() { - - } + public BufferIntIteratorFlyweight() {} /** * Creates an instance that is ready for iteration. @@ -54,12 +51,12 @@ public BufferIntIteratorFlyweight(ImmutableRoaringBitmap r) { public PeekableIntIterator clone() { try { BufferIntIteratorFlyweight x = (BufferIntIteratorFlyweight) super.clone(); - if(this.iter != null) { + if (this.iter != null) { x.iter = this.iter.clone(); } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -129,6 +126,4 @@ public void advanceIfNeeded(int minval) { public int peekNext() { return (iter.peekNext()) | hs; } - - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java index a04d3b699..0e6ea1b5d 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferParallelAggregation.java @@ -1,7 +1,14 @@ package org.roaringbitmap.buffer; import java.nio.LongBuffer; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.function.BiConsumer; @@ -40,9 +47,9 @@ */ public class BufferParallelAggregation { - private static final Collector>, - MutableRoaringArray, MutableRoaringBitmap> - XOR = new ContainerCollector(BufferParallelAggregation::xor); + private static final Collector< + Map.Entry>, MutableRoaringArray, MutableRoaringBitmap> + XOR = new ContainerCollector(BufferParallelAggregation::xor); private static final OrCollector OR = new OrCollector(); @@ -50,9 +57,11 @@ public class BufferParallelAggregation { * Collects containers grouped by their key into a RoaringBitmap, applying the * supplied aggregation function to each group. */ - public static class ContainerCollector implements - Collector>, - MutableRoaringArray, MutableRoaringBitmap> { + public static class ContainerCollector + implements Collector< + Map.Entry>, + MutableRoaringArray, + MutableRoaringBitmap> { private final Function, MappeableContainer> reducer; @@ -70,8 +79,8 @@ public Supplier supplier() { } @Override - public BiConsumer< - MutableRoaringArray, Map.Entry>> accumulator() { + public BiConsumer>> + accumulator() { return (l, r) -> { assert l.size == 0 || l.keys[l.size - 1] < r.getKey(); MappeableContainer container = reducer.apply(r.getValue()); @@ -105,7 +114,7 @@ public Set characteristics() { * Collects a list of containers into a single container. */ public static class OrCollector - implements Collector, MappeableContainer, MappeableContainer> { + implements Collector, MappeableContainer, MappeableContainer> { @Override public Supplier supplier() { @@ -139,7 +148,7 @@ public Set characteristics() { * @return The containers from the bitmaps grouped by key */ public static SortedMap> groupByKey( - ImmutableRoaringBitmap... bitmaps) { + ImmutableRoaringBitmap... bitmaps) { Map> grouped = new HashMap<>(); for (ImmutableRoaringBitmap bitmap : bitmaps) { MappeableContainerPointer it = bitmap.highLowContainer.getContainerPointer(); @@ -174,8 +183,8 @@ public static MutableRoaringBitmap or(ImmutableRoaringBitmap... bitmaps) { slices.add(slice.getValue()); } IntStream.range(0, i) - .parallel() - .forEach(position -> values[position] = or(slices.get(position))); + .parallel() + .forEach(position -> values[position] = or(slices.get(position))); return new MutableRoaringBitmap(new MutableRoaringArray(keys, values, i)); } @@ -185,14 +194,9 @@ public static MutableRoaringBitmap or(ImmutableRoaringBitmap... bitmaps) { * @return the symmetric difference of the bitmaps */ public static MutableRoaringBitmap xor(ImmutableRoaringBitmap... bitmaps) { - return groupByKey(bitmaps) - .entrySet() - .parallelStream() - .collect(XOR); + return groupByKey(bitmaps).entrySet().parallelStream().collect(XOR); } - - private static MappeableContainer xor(List containers) { MappeableContainer result = containers.get(0).clone(); for (int i = 1; i < containers.size(); ++i) { @@ -223,17 +227,17 @@ private static MappeableContainer or(List containers) { int step = Math.floorDiv(containers.size(), parallelism); int mod = Math.floorMod(containers.size(), parallelism); return IntStream.range(0, parallelism) - .parallel() - .mapToObj(i -> containers.subList(i * step + Math.min(i, mod), - (i + 1) * step + Math.min(i + 1, mod))) - .collect(OR); + .parallel() + .mapToObj( + i -> + containers.subList( + i * step + Math.min(i, mod), (i + 1) * step + Math.min(i + 1, mod))) + .collect(OR); } private static int availableParallelism() { return ForkJoinTask.inForkJoinPool() - ? ForkJoinTask.getPool().getParallelism() - : ForkJoinPool.getCommonPoolParallelism(); + ? ForkJoinTask.getPool().getParallelism() + : ForkJoinPool.getCommonPoolParallelism(); } - } - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java index 95662fdbf..fed549b63 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferReverseIntIteratorFlyweight.java @@ -34,14 +34,11 @@ public class BufferReverseIntIteratorFlyweight implements IntIterator { private ImmutableRoaringBitmap roaringBitmap = null; - /** * Creates an instance that is not ready for iteration. You must first call * {@link #wrap(ImmutableRoaringBitmap)}. */ - public BufferReverseIntIteratorFlyweight() { - - } + public BufferReverseIntIteratorFlyweight() {} /** * Creates an instance that is ready for iteration. @@ -56,12 +53,12 @@ public BufferReverseIntIteratorFlyweight(ImmutableRoaringBitmap r) { public IntIterator clone() { try { BufferReverseIntIteratorFlyweight x = (BufferReverseIntIteratorFlyweight) super.clone(); - if(this.iter != null) { + if (this.iter != null) { x.iter = this.iter.clone(); } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -70,8 +67,6 @@ public boolean hasNext() { return pos >= 0; } - - @Override public int next() { final int x = iter.nextAsInt() | hs; @@ -114,5 +109,4 @@ public void wrap(ImmutableRoaringBitmap r) { this.pos = (short) (this.roaringBitmap.highLowContainer.size() - 1); this.nextContainer(); } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java index 50bbd14cf..22f3ea15e 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/BufferUtil.java @@ -4,6 +4,8 @@ package org.roaringbitmap.buffer; +import static java.lang.Long.numberOfTrailingZeros; + import org.roaringbitmap.BitSetUtil; import org.roaringbitmap.Util; @@ -13,8 +15,6 @@ import java.nio.LongBuffer; import java.util.Arrays; -import static java.lang.Long.numberOfTrailingZeros; - /** * Various useful methods for roaring bitmaps. * @@ -31,8 +31,8 @@ public final class BufferUtil { * @param offsets value to add to each value in the container * @return return an array made of two containers */ - public static MappeableContainer[] addOffset(MappeableContainer source, char offsets) { - if(source instanceof MappeableArrayContainer) { + public static MappeableContainer[] addOffset(MappeableContainer source, char offsets) { + if (source instanceof MappeableArrayContainer) { return addOffsetArray((MappeableArrayContainer) source, offsets); } else if (source instanceof MappeableBitmapContainer) { return addOffsetBitmap((MappeableBitmapContainer) source, offsets); @@ -42,26 +42,26 @@ public static MappeableContainer[] addOffset(MappeableContainer source, char of throw new RuntimeException("unknown container type"); // never happens } - private static MappeableContainer[] addOffsetArray(MappeableArrayContainer source, - char offsets) { + private static MappeableContainer[] addOffsetArray(MappeableArrayContainer source, char offsets) { int splitIndex; if (source.first() + offsets > 0xFFFF) { splitIndex = 0; } else if (source.last() + offsets < 0xFFFF) { splitIndex = source.cardinality; } else { - splitIndex = BufferUtil.unsignedBinarySearch(source.content, 0, source.cardinality, - (char) (0x10000 - offsets)); + splitIndex = + BufferUtil.unsignedBinarySearch( + source.content, 0, source.cardinality, (char) (0x10000 - offsets)); if (splitIndex < 0) { splitIndex = -splitIndex - 1; } } - MappeableArrayContainer low = splitIndex == 0 - ? new MappeableArrayContainer() - : new MappeableArrayContainer(splitIndex); - MappeableArrayContainer high = source.cardinality - splitIndex == 0 - ? new MappeableArrayContainer() - : new MappeableArrayContainer(source.cardinality - splitIndex); + MappeableArrayContainer low = + splitIndex == 0 ? new MappeableArrayContainer() : new MappeableArrayContainer(splitIndex); + MappeableArrayContainer high = + source.cardinality - splitIndex == 0 + ? new MappeableArrayContainer() + : new MappeableArrayContainer(source.cardinality - splitIndex); int lowCardinality = 0; for (int k = 0; k < splitIndex; k++) { @@ -77,11 +77,11 @@ private static MappeableContainer[] addOffsetArray(MappeableArrayContainer sourc } high.cardinality = highCardinality; - return new MappeableContainer[]{low, high}; + return new MappeableContainer[] {low, high}; } - private static MappeableContainer[] addOffsetBitmap(MappeableBitmapContainer source, - char offsets) { + private static MappeableContainer[] addOffsetBitmap( + MappeableBitmapContainer source, char offsets) { MappeableBitmapContainer c = source; MappeableBitmapContainer low = new MappeableBitmapContainer(); MappeableBitmapContainer high = new MappeableBitmapContainer(); @@ -100,17 +100,15 @@ private static MappeableContainer[] addOffsetBitmap(MappeableBitmapContainer sou //noinspection PointlessArithmeticExpression low.bitmap.put(b + 0, c.bitmap.get(0) << i); for (int k = 1; k < 1024 - b; k++) { - low.bitmap.put(b + k, (c.bitmap.get(k) << i) - | (c.bitmap.get(k - 1) >>> (64 - i))); + low.bitmap.put(b + k, (c.bitmap.get(k) << i) | (c.bitmap.get(k - 1) >>> (64 - i))); } for (int k = 1024 - b; k < 1024; k++) { - high.bitmap.put(k - (1024 - b), - (c.bitmap.get(k) << i) - | (c.bitmap.get(k - 1) >>> (64 - i))); + high.bitmap.put( + k - (1024 - b), (c.bitmap.get(k) << i) | (c.bitmap.get(k - 1) >>> (64 - i))); } high.bitmap.put(b, (c.bitmap.get(1024 - 1) >>> (64 - i))); } - return new MappeableContainer[]{low.repairAfterLazy(), high.repairAfterLazy()}; + return new MappeableContainer[] {low.repairAfterLazy(), high.repairAfterLazy()}; } private static MappeableContainer[] addOffsetRun(MappeableRunContainer source, char offsets) { @@ -132,8 +130,9 @@ private static MappeableContainer[] addOffsetRun(MappeableRunContainer source, c high.smartAppend((char) val, c.getLength(k)); } } - return new MappeableContainer[]{low, high}; + return new MappeableContainer[] {low, high}; } + /** * Find the smallest integer larger than pos such that array[pos]>= min. If none can be found, * return length. Based on code by O. Kaser. @@ -156,8 +155,7 @@ protected static int advanceUntil(CharBuffer array, int pos, int length, char mi int spansize = 1; // could set larger // bootstrap an upper limit - while (lower + spansize < length - && (array.get(lower + spansize)) < (min)) { + while (lower + spansize < length && (array.get(lower + spansize)) < (min)) { spansize *= 2; // hoping for compiler will reduce to } // shift @@ -170,7 +168,7 @@ protected static int advanceUntil(CharBuffer array, int pos, int length, char mi return upper; } - if ((array.get(upper)) < (min)) {// means + if ((array.get(upper)) < (min)) { // means // array // has no // item @@ -196,7 +194,6 @@ protected static int advanceUntil(CharBuffer array, int pos, int length, char mi } } return upper; - } /** @@ -217,9 +214,8 @@ public static int iterateUntil(CharBuffer array, int pos, int length, int min) { return pos; } - - protected static void arraycopy(CharBuffer src, int srcPos, CharBuffer dest, int destPos, - int length) { + protected static void arraycopy( + CharBuffer src, int srcPos, CharBuffer dest, int destPos, int length) { if (BufferUtil.isBackedBySimpleArray(src) && BufferUtil.isBackedBySimpleArray(dest)) { System.arraycopy(src.array(), srcPos, dest.array(), destPos, length); } else { @@ -235,8 +231,8 @@ protected static void arraycopy(CharBuffer src, int srcPos, CharBuffer dest, int } } - protected static int branchyUnsignedBinarySearch(final CharBuffer array, final int begin, - final int end, final char k) { + protected static int branchyUnsignedBinarySearch( + final CharBuffer array, final int begin, final int end, final char k) { // next line accelerates the possibly common case where the value would be inserted at the end if ((end > 0) && ((array.get(end - 1)) < (int) (k))) { return -end - 1; @@ -258,18 +254,17 @@ protected static int branchyUnsignedBinarySearch(final CharBuffer array, final i return -(low + 1); } - - protected static int branchyUnsignedBinarySearch(final ByteBuffer array, int position, - final int begin, final int end, final char k) { + protected static int branchyUnsignedBinarySearch( + final ByteBuffer array, int position, final int begin, final int end, final char k) { // next line accelerates the possibly common case where the value would be inserted at the end - if ((end > 0) && ((array.getChar(position + (end - 1)*2)) < (int) (k))) { + if ((end > 0) && ((array.getChar(position + (end - 1) * 2)) < (int) (k))) { return -end - 1; } int low = begin; int high = end - 1; while (low <= high) { final int middleIndex = (low + high) >>> 1; - final int middleValue = (array.getChar(position + 2* middleIndex)); + final int middleValue = (array.getChar(position + 2 * middleIndex)); if (middleValue < (int) (k)) { low = middleIndex + 1; @@ -344,7 +339,7 @@ protected static void fillArrayXOR(char[] container, LongBuffer bitmap1, LongBuf throw new IllegalArgumentException("not supported"); } if (BufferUtil.isBackedBySimpleArray(bitmap1) && BufferUtil.isBackedBySimpleArray(bitmap2)) { - org.roaringbitmap.Util.fillArrayXOR(container, bitmap1.array(), bitmap2.array()); + org.roaringbitmap.Util.fillArrayXOR(container, bitmap1.array(), bitmap2.array()); } else { int len = bitmap1.limit(); for (int k = 0; k < len; ++k) { @@ -357,7 +352,6 @@ protected static void fillArrayXOR(char[] container, LongBuffer bitmap1, LongBuf } } - /** * flip bits at start, start+1,..., end-1 * @@ -382,7 +376,6 @@ public static void flipBitmapRange(LongBuffer bitmap, int start, int end) { bitmap.put(endword, bitmap.get(endword) ^ (~0L >>> -end)); } - /** * Hamming weight of the 64-bit words involved in the range start, start+1,..., end-1 * that is, it will compute the cardinality of the bitset from index @@ -439,7 +432,6 @@ public static int cardinalityInBitmapRange(LongBuffer bitmap, int start, int end return answer; } - /** * set bits at start, start+1,..., end-1 and report the cardinality change * @@ -459,7 +451,6 @@ public static int setBitmapRangeAndCardinalityChange(LongBuffer bitmap, int star return cardafter - cardbefore; } - /** * flip bits at start, start+1,..., end-1 and report the cardinality change * @@ -479,7 +470,6 @@ public static int flipBitmapRangeAndCardinalityChange(LongBuffer bitmap, int sta return cardafter - cardbefore; } - /** * reset bits at start, start+1,..., end-1 and report the cardinality change * @@ -509,8 +499,8 @@ public static int resetBitmapRangeAndCardinalityChange(LongBuffer bitmap, int st * * @return the size in bytes */ - protected static int getSizeInBytesFromCardinalityEtc(int card, int numRuns, - boolean isRunEncoded) { + protected static int getSizeInBytesFromCardinalityEtc( + int card, int numRuns, boolean isRunEncoded) { if (isRunEncoded) { return 2 + numRuns * 2 * 2; // each run uses 2 chars, plus the initial char giving num runs } @@ -520,14 +510,12 @@ protected static int getSizeInBytesFromCardinalityEtc(int card, int numRuns, } else { return card * 2; } - } protected static char highbits(int x) { return (char) (x >>> 16); } - protected static char highbits(long x) { return (char) (x >>> 16); } @@ -554,7 +542,7 @@ protected static char lowbits(long x) { } protected static int lowbitsAsInteger(long x) { - return (int)(x & 0xFFFF); + return (int) (x & 0xFFFF); } protected static char maxLowBit() { @@ -593,7 +581,6 @@ public static void resetBitmapRange(LongBuffer bitmap, int start, int end) { bitmap.put(endword, bitmap.get(endword) & (~(~0L >>> -end))); } - /** * set bits at start, start+1,..., end-1 * @@ -634,10 +621,11 @@ public static void setBitmapRange(LongBuffer bitmap, int start, int end) { * @param k value we search for * @return count */ - public static int unsignedBinarySearch(final CharBuffer array, final int begin, final int end, - final char k) { + public static int unsignedBinarySearch( + final CharBuffer array, final int begin, final int end, final char k) { return branchyUnsignedBinarySearch(array, begin, end, k); } + /** * Look for value k in buffer in the range [begin,end). If the value is found, return its index. * If not, return -(i+1) where i is the index where the value would be inserted. The buffer is @@ -650,13 +638,17 @@ public static int unsignedBinarySearch(final CharBuffer array, final int begin, * @param k value we search for * @return count */ - public static int unsignedBinarySearch(final ByteBuffer array, int position, - final int begin, final int end, final char k) { + public static int unsignedBinarySearch( + final ByteBuffer array, int position, final int begin, final int end, final char k) { return branchyUnsignedBinarySearch(array, position, begin, end, k); } - protected static int unsignedDifference(final CharBuffer set1, final int length1, - final CharBuffer set2, final int length2, final char[] buffer) { + protected static int unsignedDifference( + final CharBuffer set1, + final int length1, + final CharBuffer set2, + final int length2, + final char[] buffer) { int pos = 0; int k1 = 0, k2 = 0; if (0 == length2) { @@ -689,7 +681,7 @@ protected static int unsignedDifference(final CharBuffer set1, final int length1 } s1 = set1.get(k1); s2 = set2.get(k2); - } else {// if (val1>val2) + } else { // if (val1>val2) ++k2; if (k2 >= length2) { set1.position(k1); @@ -702,7 +694,6 @@ protected static int unsignedDifference(final CharBuffer set1, final int length1 return pos; } - /** * Intersects the bitmap with the array, returning the cardinality of the result * @param bitmap the bitmap, modified @@ -780,8 +771,12 @@ public static int intersectArrayIntoBitmap(LongBuffer bitmap, CharBuffer array, return cardinality; } - protected static int unsignedExclusiveUnion2by2(final CharBuffer set1, final int length1, - final CharBuffer set2, final int length2, final char[] buffer) { + protected static int unsignedExclusiveUnion2by2( + final CharBuffer set1, + final int length1, + final CharBuffer set2, + final int length2, + final char[] buffer) { int pos = 0; int k1 = 0, k2 = 0; if (0 == length2) { @@ -819,7 +814,7 @@ protected static int unsignedExclusiveUnion2by2(final CharBuffer set1, final int } s1 = set1.get(k1); s2 = set2.get(k2); - } else {// if (val1>val2) + } else { // if (val1>val2) buffer[pos++] = s2; ++k2; if (k2 >= length2) { @@ -833,9 +828,12 @@ protected static int unsignedExclusiveUnion2by2(final CharBuffer set1, final int // return pos; } - - protected static int unsignedIntersect2by2(final CharBuffer set1, final int length1, - final CharBuffer set2, final int length2, final char[] buffer) { + protected static int unsignedIntersect2by2( + final CharBuffer set1, + final int length1, + final CharBuffer set2, + final int length2, + final char[] buffer) { final int THRESHOLD = 34; if (length1 * THRESHOLD < length2) { return unsignedOneSidedGallopingIntersect2by2(set1, length1, set2, length2, buffer); @@ -855,8 +853,8 @@ protected static int unsignedIntersect2by2(final CharBuffer set1, final int leng * @param length2 length of second array * @return true if they intersect */ - public static boolean unsignedIntersects(CharBuffer set1, int length1, CharBuffer set2, - int length2) { + public static boolean unsignedIntersects( + CharBuffer set1, int length1, CharBuffer set2, int length2) { if ((0 == length1) || (0 == length2)) { return false; } @@ -867,7 +865,8 @@ public static boolean unsignedIntersects(CharBuffer set1, int length1, CharBuffe char s1 = set1.get(k1); char s2 = set2.get(k2); - mainwhile: while (true) { + mainwhile: + while (true) { if (s2 < s1) { do { ++k2; @@ -892,8 +891,12 @@ public static boolean unsignedIntersects(CharBuffer set1, int length1, CharBuffe return false; } - protected static int unsignedLocalIntersect2by2(final CharBuffer set1, final int length1, - final CharBuffer set2, final int length2, final char[] buffer) { + protected static int unsignedLocalIntersect2by2( + final CharBuffer set1, + final int length1, + final CharBuffer set2, + final int length2, + final char[] buffer) { if ((0 == length1) || (0 == length2)) { return 0; } @@ -903,7 +906,8 @@ protected static int unsignedLocalIntersect2by2(final CharBuffer set1, final int char s1 = set1.get(k1); char s2 = set2.get(k2); - mainwhile: while (true) { + mainwhile: + while (true) { if (s2 < s1) { do { ++k2; @@ -936,14 +940,13 @@ protected static int unsignedLocalIntersect2by2(final CharBuffer set1, final int break; } s2 = set2.get(k2); - } } return pos; } - protected static int unsignedLocalIntersect2by2Cardinality(final CharBuffer set1, - final int length1, final CharBuffer set2, final int length2) { + protected static int unsignedLocalIntersect2by2Cardinality( + final CharBuffer set1, final int length1, final CharBuffer set2, final int length2) { if ((0 == length1) || (0 == length2)) { return 0; } @@ -953,7 +956,8 @@ protected static int unsignedLocalIntersect2by2Cardinality(final CharBuffer set1 char s1 = set1.get(k1); char s2 = set2.get(k2); - mainwhile: while (true) { + mainwhile: + while (true) { if (s2 < s1) { do { ++k2; @@ -985,15 +989,16 @@ protected static int unsignedLocalIntersect2by2Cardinality(final CharBuffer set1 break; } s2 = set2.get(k2); - } } return pos; } - - protected static int unsignedOneSidedGallopingIntersect2by2(final CharBuffer smallSet, - final int smallLength, final CharBuffer largeSet, final int largeLength, + protected static int unsignedOneSidedGallopingIntersect2by2( + final CharBuffer smallSet, + final int smallLength, + final CharBuffer largeSet, + final int largeLength, final char[] buffer) { if (0 == smallLength) { return 0; @@ -1032,16 +1037,18 @@ protected static int unsignedOneSidedGallopingIntersect2by2(final CharBuffer sma } s1 = largeSet.get(k1); } - } return pos; - } protected static int unsignedUnion2by2( - final CharBuffer set1, final int offset1, final int length1, - final CharBuffer set2, final int offset2, final int length2, - final char[] buffer) { + final CharBuffer set1, + final int offset1, + final int length1, + final CharBuffer set2, + final int offset2, + final int length2, + final char[] buffer) { if (0 == length2) { set1.position(offset1); set1.get(buffer, 0, length1); @@ -1084,7 +1091,7 @@ protected static int unsignedUnion2by2( } s1 = set1.get(k1); s2 = set2.get(k2); - } else {// if (set1.get(k1)>set2.get(k2)) + } else { // if (set1.get(k1)>set2.get(k2)) buffer[pos++] = s2; ++k2; if (k2 >= length2 + offset2) { @@ -1122,9 +1129,9 @@ static char[] intersectKeys(long[] words, ImmutableRoaringBitmap[] bitmaps) { keys[j] = bitmaps[i].highLowContainer.getKeyAtIndex(j); } } - numContainers = BufferUtil.intersectArrayIntoBitmap(words, - CharBuffer.wrap(keys), - bitmaps[i].highLowContainer.size()); + numContainers = + BufferUtil.intersectArrayIntoBitmap( + words, CharBuffer.wrap(keys), bitmaps[i].highLowContainer.size()); } if (numContainers == 0) { return new char[0]; @@ -1135,7 +1142,5 @@ static char[] intersectKeys(long[] words, ImmutableRoaringBitmap[] bitmaps) { /** * Private constructor to prevent instantiation of utility class */ - private BufferUtil() { - - } + private BufferUtil() {} } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java index cbd173771..8c795b60a 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringArray.java @@ -17,7 +17,6 @@ import java.nio.channels.WritableByteChannel; import java.util.NoSuchElementException; - /** * This is the underlying data structure for an ImmutableRoaringBitmap. This class is not meant for * end-users. @@ -28,7 +27,7 @@ public final class ImmutableRoaringArray implements PointableRoaringArray { protected static final short SERIAL_COOKIE = MutableRoaringArray.SERIAL_COOKIE; protected static final short SERIAL_COOKIE_NO_RUNCONTAINER = MutableRoaringArray.SERIAL_COOKIE_NO_RUNCONTAINER; - private final static int startofrunbitmap = 4; // if there is a runcontainer bitmap + private static final int startofrunbitmap = 4; // if there is a runcontainer bitmap ByteBuffer buffer; int size; @@ -75,7 +74,7 @@ public int advanceUntil(char x, int pos) { return upper; } - if (getKey(upper) < (x)) {// means array has no item key >= x + if (getKey(upper) < (x)) { // means array has no item key >= x return size; } @@ -115,20 +114,17 @@ private int branchyUnsignedBinarySearch(final char k) { return -(low + 1); } - - @Override public ImmutableRoaringArray clone() { ImmutableRoaringArray sa; try { sa = (ImmutableRoaringArray) super.clone(); } catch (CloneNotSupportedException e) { - return null;// should never happen + return null; // should never happen } return sa; } - private int computeSerializedSizeInBytes(boolean hasRunContainers) { if (this.size == 0) { return headerSize(hasRunContainers); @@ -155,8 +151,6 @@ public int getCardinality(int k) { return buffer.getChar(this.getStartOfKeys() + 4 * k + 2) + 1; } - - @Override public int getContainerIndex(char x) { return unsignedBinarySearch(x); @@ -165,8 +159,8 @@ public int getContainerIndex(char x) { @Override public MappeableContainer getContainerAtIndex(int i) { boolean hasrun = hasRunCompression(); - ByteBuffer tmp = buffer.duplicate();// sad but ByteBuffer is not thread-safe so it is either a - // duplicate or a lock + ByteBuffer tmp = buffer.duplicate(); // sad but ByteBuffer is not thread-safe so it is either a + // duplicate or a lock // note that tmp will indeed be garbage-collected some time after the end of this function tmp.order(buffer.order()); tmp.position(getOffsetContainer(i, hasrun)); @@ -179,7 +173,7 @@ public MappeableContainer getContainerAtIndex(int i) { } int cardinality = getCardinality(i); final boolean isBitmap = cardinality > MappeableArrayContainer.DEFAULT_MAX_SIZE; // if not a - // runcontainer + // runcontainer if (isBitmap) { final LongBuffer bitmapArray = tmp.asLongBuffer(); bitmapArray.limit(MappeableBitmapContainer.MAX_CAPACITY / 64); @@ -202,7 +196,7 @@ public boolean containsForContainerAtIndex(int i, char x) { } int cardinality = getCardinality(i); final boolean isBitmap = cardinality > MappeableArrayContainer.DEFAULT_MAX_SIZE; // if not a - // runcontainer + // runcontainer if (isBitmap) { return MappeableBitmapContainer.contains(buffer, containerpos, x); } else { @@ -210,8 +204,6 @@ public boolean containsForContainerAtIndex(int i, char x) { } } - - @Override public MappeableContainerPointer getContainerPointer() { return getContainerPointer(0); @@ -228,13 +220,12 @@ public void advance() { ++k; } - @Override public MappeableContainerPointer clone() { try { return (MappeableContainerPointer) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -259,7 +250,6 @@ public MappeableContainer getContainer() { return ImmutableRoaringArray.this.getContainerAtIndex(k); } - @Override public int getSizeInBytes() { // might be a tad expensive @@ -294,10 +284,8 @@ public boolean isRunContainer() { @Override public char key() { return ImmutableRoaringArray.this.getKeyAtIndex(k); - } - @Override public void previous() { --k; @@ -336,7 +324,6 @@ private int getOffsetContainer(int k, boolean hasRunCompression) { } } - private int getOffsetContainerSlow(int k, boolean hasRunCompression) { int pos = this.headerSize(hasRunCompression); for (int z = 0; z < k; ++z) { @@ -362,21 +349,20 @@ private int getStartOfKeys() { } } - @Override public boolean equals(Object o) { if (o instanceof ImmutableRoaringArray) { - ImmutableRoaringArray srb = (ImmutableRoaringArray)o; + ImmutableRoaringArray srb = (ImmutableRoaringArray) o; if (srb.size() != this.size()) { return false; } MappeableContainerPointer cp = this.getContainerPointer(); MappeableContainerPointer cpo = srb.getContainerPointer(); - while(cp.hasContainer() && cpo.hasContainer()) { - if(cp.key() != cpo.key()) { + while (cp.hasContainer() && cpo.hasContainer()) { + if (cp.key() != cpo.key()) { return false; } - if(!cp.getContainer().equals(cpo.getContainer())) { + if (!cp.getContainer().equals(cpo.getContainer())) { return false; } } @@ -404,16 +390,16 @@ public boolean hasRunCompression() { // hasrun should be equal to hasRunCompression() protected int headerSize(boolean hasrun) { if (hasrun) { - if (size < MutableRoaringArray.NO_OFFSET_THRESHOLD) {// for small bitmaps, we omit the offsets + if (size + < MutableRoaringArray.NO_OFFSET_THRESHOLD) { // for small bitmaps, we omit the offsets return 4 + (size + 7) / 8 + 4 * size; } - return 4 + (size + 7) / 8 + 8 * size;// - 4 because we pack the size with the cookie + return 4 + (size + 7) / 8 + 8 * size; // - 4 because we pack the size with the cookie } else { return 4 + 4 + 8 * size; } } - /** * Returns true if this bitmap is empty. * diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java index 763fdbbdf..9c9448afb 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/ImmutableRoaringBitmap.java @@ -4,17 +4,26 @@ package org.roaringbitmap.buffer; -import org.roaringbitmap.*; +import static org.roaringbitmap.Util.toUnsignedLong; +import static org.roaringbitmap.buffer.BufferUtil.highbits; +import static org.roaringbitmap.buffer.BufferUtil.lowbits; +import static org.roaringbitmap.buffer.BufferUtil.lowbitsAsInteger; +import static org.roaringbitmap.buffer.MutableRoaringBitmap.rangeSanityCheck; + +import org.roaringbitmap.BatchIterator; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.ImmutableBitmapDataProvider; +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.PeekableCharIterator; +import org.roaringbitmap.PeekableIntIterator; +import org.roaringbitmap.RoaringBitmap; +import org.roaringbitmap.Util; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Iterator; -import java.util.NoSuchElementException; - -import static org.roaringbitmap.Util.toUnsignedLong; -import static org.roaringbitmap.buffer.BufferUtil.*; -import static org.roaringbitmap.buffer.MutableRoaringBitmap.rangeSanityCheck; /** * ImmutableRoaringBitmap provides a compressed immutable (cannot be modified) bitmap. It is meant @@ -109,7 +118,7 @@ public PeekableIntIterator clone() { x.iterations = this.iterations; return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -170,7 +179,6 @@ boolean shouldAdvanceContainer(final int hs, final int minval) { public int peekNext() { return (iter.peekNext()) | hs; } - } private class ImmutableRoaringSignedIntIterator extends ImmutableRoaringIntIterator { @@ -178,8 +186,8 @@ private class ImmutableRoaringSignedIntIterator extends ImmutableRoaringIntItera @Override char findStartingContainerIndex() { // skip to starting at negative signed integers - char index = (char) - ImmutableRoaringBitmap.this.highLowContainer.advanceUntil((char) (1 << 15), -1); + char index = + (char) ImmutableRoaringBitmap.this.highLowContainer.advanceUntil((char) (1 << 15), -1); if (index == ImmutableRoaringBitmap.this.highLowContainer.size()) { index = 0; } @@ -193,8 +201,9 @@ boolean shouldAdvanceContainer(final int hs, final int minval) { } private final class ImmutableRoaringReverseIntIterator implements IntIterator { - private MappeableContainerPointer cp = ImmutableRoaringBitmap.this.highLowContainer - .getContainerPointer(ImmutableRoaringBitmap.this.highLowContainer.size() - 1); + private MappeableContainerPointer cp = + ImmutableRoaringBitmap.this.highLowContainer.getContainerPointer( + ImmutableRoaringBitmap.this.highLowContainer.size() - 1); private int hs = 0; @@ -210,15 +219,15 @@ public ImmutableRoaringReverseIntIterator() { public IntIterator clone() { try { ImmutableRoaringReverseIntIterator x = (ImmutableRoaringReverseIntIterator) super.clone(); - if(this.iter != null) { + if (this.iter != null) { x.iter = this.iter.clone(); } - if(this.cp != null) { + if (this.cp != null) { x.cp = this.cp.clone(); } return x; } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -237,7 +246,6 @@ public int next() { return x; } - private void nextContainer() { ok = cp.hasContainer(); if (ok) { @@ -245,8 +253,6 @@ private void nextContainer() { hs = (cp.key()) << 16; } } - - } /** @@ -258,9 +264,11 @@ private void nextContainer() { * @param rangeEnd exclusive ending of range * @return new result bitmap */ - public static MutableRoaringBitmap and(final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { - rangeSanityCheck(rangeStart,rangeEnd); + public static MutableRoaringBitmap and( + final Iterator bitmaps, + final long rangeStart, + final long rangeEnd) { + rangeSanityCheck(rangeStart, rangeEnd); Iterator bitmapsIterator; bitmapsIterator = selectRangeWithoutCopy(bitmaps, rangeStart, rangeEnd); return BufferFastAggregation.and(bitmapsIterator); @@ -278,13 +286,13 @@ public static MutableRoaringBitmap and(final Iterator bitmaps, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap and( + final Iterator bitmaps, + final int rangeStart, + final int rangeEnd) { return and(bitmaps, (long) rangeStart, (long) rangeEnd); } - - /** * Bitwise AND (intersection) operation. The provided bitmaps are *not* modified. This operation * is thread-safe as long as the provided bitmaps remain unchanged. @@ -296,8 +304,8 @@ public static MutableRoaringBitmap and(final Iterator>> 16); - int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int)(rangeEnd & 0xFFFF); + int maxKey = (int) ((rangeEnd - 1) >>> 16); + int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int) (rangeEnd & 0xFFFF); int size = 0; int pos1 = 0, pos2 = 0; int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); @@ -493,8 +501,8 @@ public static MutableRoaringBitmap orNot( int s2 = length2 > 0 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; int remainder = 0; for (int i = x1.highLowContainer.size() - 1; - i >= 0 && x1.highLowContainer.getKeyAtIndex(i) > maxKey; - --i) { + i >= 0 && x1.highLowContainer.getKeyAtIndex(i) > maxKey; + --i) { ++remainder; } int correction = 0; @@ -506,8 +514,8 @@ public static MutableRoaringBitmap orNot( } // it's almost certain that the bitmap will grow, so make a conservative overestimate, // this avoids temporary allocation, and can trim afterwards - int maxSize = Math.min(maxKey + 1 + remainder - correction - + x1.highLowContainer.size(), 0x10000); + int maxSize = + Math.min(maxKey + 1 + remainder - correction + x1.highLowContainer.size(), 0x10000); if (maxSize == 0) { return new MutableRoaringBitmap(); } @@ -515,27 +523,33 @@ public static MutableRoaringBitmap orNot( MappeableContainer[] newValues = new MappeableContainer[maxSize]; for (int key = 0; key <= maxKey && size < maxSize; ++key) { if (key == s1 && key == s2) { // actually need to do an or not - newValues[size] = x1.highLowContainer.getContainerAtIndex(pos1) - .orNot(x2.highLowContainer.getContainerAtIndex(pos2), - key == maxKey ? lastRun : 0x10000); + newValues[size] = + x1.highLowContainer + .getContainerAtIndex(pos1) + .orNot( + x2.highLowContainer.getContainerAtIndex(pos2), + key == maxKey ? lastRun : 0x10000); ++pos1; ++pos2; s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = key == maxKey - ? x1.highLowContainer.getContainerAtIndex(pos1).ior( - MappeableRunContainer.rangeOfOnes(0, lastRun)) - : MappeableRunContainer.full(); + newValues[size] = + key == maxKey + ? x1.highLowContainer + .getContainerAtIndex(pos1) + .ior(MappeableRunContainer.rangeOfOnes(0, lastRun)) + : MappeableRunContainer.full(); ++pos1; s1 = pos1 < length1 ? x1.highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement - newValues[size] = x2.highLowContainer.getContainerAtIndex(pos2) - .not(0, key == maxKey ? lastRun : 0x10000); + newValues[size] = + x2.highLowContainer.getContainerAtIndex(pos2).not(0, key == maxKey ? lastRun : 0x10000); ++pos2; s2 = pos2 < length2 ? x2.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else { // key missing from both - newValues[size] = key == maxKey + newValues[size] = + key == maxKey ? MappeableRunContainer.rangeOfOnes(0, lastRun) : MappeableRunContainer.full(); } @@ -543,7 +557,7 @@ public static MutableRoaringBitmap orNot( if (newValues[size].isEmpty()) { newValues[size] = null; } else { - newKeys[size++] = (char)key; + newKeys[size++] = (char) key; } } // copy over everything which will remain without being complemented @@ -578,8 +592,6 @@ public static ImmutableRoaringBitmap bitmapOf(final int... data) { return MutableRoaringBitmap.bitmapOf(data); } - - /** * Complements the bits in the given range, from rangeStart (inclusive) rangeEnd (exclusive). The * given bitmap is unchanged. @@ -589,8 +601,8 @@ public static ImmutableRoaringBitmap bitmapOf(final int... data) { * @param rangeEnd exclusive ending of range * @return a new Bitmap */ - public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, final long rangeStart, - final long rangeEnd) { + public static MutableRoaringBitmap flip( + ImmutableRoaringBitmap bm, final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); if (rangeStart >= rangeEnd) { throw new RuntimeException("Invalid range " + rangeStart + " -- " + rangeEnd); @@ -623,8 +635,10 @@ public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, final long ra } else { // *think* the range of ones must never be // empty. - answer.getMappeableRoaringArray().insertNewKeyValueAt(-j - 1, hb, - MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); + answer + .getMappeableRoaringArray() + .insertNewKeyValueAt( + -j - 1, hb, MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); } } // copy the containers after the active area. @@ -633,9 +647,7 @@ public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, final long ra return answer; } - - - /** + /** * Complements the bits in the given range, from rangeStart (inclusive) rangeEnd (exclusive). The * given bitmap is unchanged. * @@ -646,8 +658,8 @@ public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, final long ra * @deprecated use the version where longs specify the range */ @Deprecated - public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap flip( + ImmutableRoaringBitmap bm, final int rangeStart, final int rangeEnd) { if (rangeStart >= 0) { return flip(bm, (long) rangeStart, (long) rangeEnd); } @@ -656,8 +668,6 @@ public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, return flip(bm, rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - - /** * Return new iterator with only values from rangeStart (inclusive) to rangeEnd (exclusive) * @@ -668,25 +678,27 @@ public static MutableRoaringBitmap flip(ImmutableRoaringBitmap bm, */ private static Iterator selectRangeWithoutCopy( final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + final long rangeStart, + final long rangeEnd) { Iterator bitmapsIterator; - bitmapsIterator = new Iterator() { - @Override - public boolean hasNext() { - return bitmaps.hasNext(); - } + bitmapsIterator = + new Iterator() { + @Override + public boolean hasNext() { + return bitmaps.hasNext(); + } - @Override - public ImmutableRoaringBitmap next() { - ImmutableRoaringBitmap next = bitmaps.next(); - return selectRangeWithoutCopy(next, rangeStart, rangeEnd); - } + @Override + public ImmutableRoaringBitmap next() { + ImmutableRoaringBitmap next = bitmaps.next(); + return selectRangeWithoutCopy(next, rangeStart, rangeEnd); + } - @Override - public void remove() { - throw new UnsupportedOperationException("Remove not supported"); - } - }; + @Override + public void remove() { + throw new UnsupportedOperationException("Remove not supported"); + } + }; return bitmapsIterator; } @@ -705,7 +717,7 @@ public MutableRoaringBitmap selectRange(final long rangeStart, final long rangeE final int lbLast = (BufferUtil.lowbits(rangeEnd - 1)); MutableRoaringBitmap answer = new MutableRoaringBitmap(); - assert(rangeStart >= 0 && rangeEnd >= 0); + assert (rangeStart >= 0 && rangeEnd >= 0); if (rangeEnd <= rangeStart) { return answer; @@ -714,8 +726,11 @@ public MutableRoaringBitmap selectRange(final long rangeStart, final long rangeE if (hbStart == hbLast) { final int i = this.highLowContainer.getIndex((char) hbStart); if (i >= 0) { - final MappeableContainer c = this.highLowContainer.getContainerAtIndex(i).remove(0, lbStart) - .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); + final MappeableContainer c = + this.highLowContainer + .getContainerAtIndex(i) + .remove(0, lbStart) + .iremove(lbLast + 1, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); } @@ -733,20 +748,22 @@ public MutableRoaringBitmap selectRange(final long rangeStart, final long rangeE // revised to loop on ints for (int hb = hbStart + 1; hb <= hbLast - 1; ++hb) { - final int i = this.highLowContainer.getIndex((char)hb); + final int i = this.highLowContainer.getIndex((char) hb); final int j = answer.highLowContainer.getIndex((char) hb); assert j < 0; if (i >= 0) { final MappeableContainer c = this.highLowContainer.getContainerAtIndex(i); - ((MutableRoaringArray) answer.highLowContainer).insertNewKeyValueAt(-j - 1, - (char)hb, c.clone()); + ((MutableRoaringArray) answer.highLowContainer) + .insertNewKeyValueAt(-j - 1, (char) hb, c.clone()); } } if (ilast >= 0) { - MappeableContainer c = this.highLowContainer.getContainerAtIndex(ilast).remove(lbLast + 1, - Util.maxLowBitAsInteger() + 1); + MappeableContainer c = + this.highLowContainer + .getContainerAtIndex(ilast) + .remove(lbLast + 1, Util.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { ((MutableRoaringArray) answer.highLowContainer).append((char) hbLast, c); } @@ -764,9 +781,8 @@ public MutableRoaringBitmap selectRange(final long rangeStart, final long rangeE * @param rangeEnd exclusive * @return new bitmap */ - - private static MutableRoaringBitmap selectRangeWithoutCopy(ImmutableRoaringBitmap rb, - final long rangeStart, final long rangeEnd) { + private static MutableRoaringBitmap selectRangeWithoutCopy( + ImmutableRoaringBitmap rb, final long rangeStart, final long rangeEnd) { final int hbStart = (highbits(rangeStart)); final int lbStart = (lowbits(rangeStart)); final int hbLast = (highbits(rangeEnd - 1)); @@ -780,8 +796,11 @@ private static MutableRoaringBitmap selectRangeWithoutCopy(ImmutableRoaringBitma if (hbStart == hbLast) { final int i = rb.highLowContainer.getIndex((char) hbStart); if (i >= 0) { - final MappeableContainer c = rb.highLowContainer.getContainerAtIndex(i).remove(0, lbStart) - .iremove(lbLast + 1, BufferUtil.maxLowBitAsInteger() + 1); + final MappeableContainer c = + rb.highLowContainer + .getContainerAtIndex(i) + .remove(0, lbStart) + .iremove(lbLast + 1, BufferUtil.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); } @@ -810,14 +829,15 @@ private static MutableRoaringBitmap selectRangeWithoutCopy(ImmutableRoaringBitma } if (ilast >= 0) { - final MappeableContainer c = rb.highLowContainer.getContainerAtIndex(ilast).remove(lbLast + 1, - BufferUtil.maxLowBitAsInteger() + 1); + final MappeableContainer c = + rb.highLowContainer + .getContainerAtIndex(ilast) + .remove(lbLast + 1, BufferUtil.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { ((MutableRoaringArray) answer.highLowContainer).append((char) hbLast, c); } } return answer; - } /** @@ -828,8 +848,8 @@ private static MutableRoaringBitmap selectRangeWithoutCopy(ImmutableRoaringBitma * @param x2 other bitmap * @return true if they intersect */ - public static boolean intersects(final ImmutableRoaringBitmap x1, - final ImmutableRoaringBitmap x2) { + public static boolean intersects( + final ImmutableRoaringBitmap x1, final ImmutableRoaringBitmap x2) { int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); @@ -855,16 +875,18 @@ public static boolean intersects(final ImmutableRoaringBitmap x1, } // important: inputs should not be reused - protected static MutableRoaringBitmap lazyor(final ImmutableRoaringBitmap x1, - final ImmutableRoaringBitmap x2) { + protected static MutableRoaringBitmap lazyor( + final ImmutableRoaringBitmap x1, final ImmutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); MappeableContainerPointer i1 = x1.highLowContainer.getContainerPointer(); MappeableContainerPointer i2 = x2.highLowContainer.getContainerPointer(); - main: if (i1.hasContainer() && i2.hasContainer()) { + main: + if (i1.hasContainer() && i2.hasContainer()) { while (true) { if (i1.key() == i2.key()) { - answer.getMappeableRoaringArray().append(i1.key(), - i1.getContainer().lazyOR(i2.getContainer())); + answer + .getMappeableRoaringArray() + .append(i1.key(), i1.getContainer().lazyOR(i2.getContainer())); i1.advance(); i2.advance(); if (!i1.hasContainer() || !i2.hasContainer()) { @@ -924,16 +946,18 @@ public static MutableRoaringBitmap or(ImmutableRoaringBitmap... bitmaps) { * @see BufferFastAggregation#or(ImmutableRoaringBitmap...) * @see BufferFastAggregation#horizontal_or(ImmutableRoaringBitmap...) */ - public static MutableRoaringBitmap or(final ImmutableRoaringBitmap x1, - final ImmutableRoaringBitmap x2) { + public static MutableRoaringBitmap or( + final ImmutableRoaringBitmap x1, final ImmutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); MappeableContainerPointer i1 = x1.highLowContainer.getContainerPointer(); MappeableContainerPointer i2 = x2.highLowContainer.getContainerPointer(); - main: if (i1.hasContainer() && i2.hasContainer()) { + main: + if (i1.hasContainer() && i2.hasContainer()) { while (true) { if (i1.key() == i2.key()) { - answer.getMappeableRoaringArray().append(i1.key(), - i1.getContainer().or(i2.getContainer())); + answer + .getMappeableRoaringArray() + .append(i1.key(), i1.getContainer().or(i2.getContainer())); i1.advance(); i2.advance(); if (!i1.hasContainer() || !i2.hasContainer()) { @@ -989,8 +1013,10 @@ public static MutableRoaringBitmap or(Iterator * @param rangeEnd exclusive ending of range * @return new result bitmap */ - public static MutableRoaringBitmap or(final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + public static MutableRoaringBitmap or( + final Iterator bitmaps, + final long rangeStart, + final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); Iterator bitmapsIterator; bitmapsIterator = selectRangeWithoutCopy(bitmaps, rangeStart, rangeEnd); @@ -1009,14 +1035,13 @@ public static MutableRoaringBitmap or(final Iterator bitmaps, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap or( + final Iterator bitmaps, + final int rangeStart, + final int rangeEnd) { return or(bitmaps, (long) rangeStart, (long) rangeEnd); } - - - /** * Cardinality of the bitwise OR (union) operation. The provided bitmaps are *not* modified. This * operation is thread-safe as long as the provided bitmaps remain unchanged. @@ -1029,8 +1054,8 @@ public static MutableRoaringBitmap or(final Iterator bitmaps, - final long rangeStart, final long rangeEnd) { + public static MutableRoaringBitmap xor( + final Iterator bitmaps, + final long rangeStart, + final long rangeEnd) { Iterator bitmapsIterator; bitmapsIterator = selectRangeWithoutCopy(bitmaps, rangeStart, rangeEnd); return BufferFastAggregation.xor(bitmapsIterator); } - /** * Computes XOR between input bitmaps in the given range, from rangeStart (inclusive) to rangeEnd * (exclusive) @@ -1065,13 +1091,13 @@ public static MutableRoaringBitmap xor(final Iterator bitmaps, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap xor( + final Iterator bitmaps, + final int rangeStart, + final int rangeEnd) { return xor(bitmaps, (long) rangeStart, (long) rangeEnd); } - - /** * Bitwise XOR (symmetric difference) operation. The provided bitmaps are *not* modified. This * operation is thread-safe as long as the provided bitmaps remain unchanged. @@ -1084,12 +1110,13 @@ public static MutableRoaringBitmap xor(final Iterator= 0 - && highLowContainer.containsForContainerAtIndex(index, lowbits(x)); + return index >= 0 && highLowContainer.containsForContainerAtIndex(index, lowbits(x)); } /** @@ -1208,22 +1231,22 @@ public boolean contains(long minimum, long supremum) { } int begin = highLowContainer.getIndex(firstKey); int end = highLowContainer.getIndex(lastKey); - end = end < 0 ? -end -1 : end; + end = end < 0 ? -end - 1 : end; if (begin < 0 || end - begin != span) { return false; } - int min = (char)minimum; - int sup = (char)supremum; + int min = (char) minimum; + int sup = (char) supremum; if (firstKey == lastKey) { - return highLowContainer.getContainerAtIndex(begin) - .contains(min, (supremum & 0xFFFF) == 0 ? 0x10000 : sup); + return highLowContainer + .getContainerAtIndex(begin) + .contains(min, (supremum & 0xFFFF) == 0 ? 0x10000 : sup); } if (!highLowContainer.getContainerAtIndex(begin).contains(min, 1 << 16)) { return false; } - if (sup != 0 && end < len && !highLowContainer.getContainerAtIndex(end) - .contains(0, sup)) { + if (sup != 0 && end < len && !highLowContainer.getContainerAtIndex(end).contains(0, sup)) { return false; } for (int i = begin + 1; i < end; ++i) { @@ -1249,7 +1272,7 @@ public boolean contains(ImmutableRoaringBitmap subset) { if (s1 == s2) { MappeableContainer c1 = this.highLowContainer.getContainerAtIndex(pos1); MappeableContainer c2 = subset.highLowContainer.getContainerAtIndex(pos2); - if(!c1.contains(c2)) { + if (!c1.contains(c2)) { return false; } ++pos1; @@ -1263,7 +1286,6 @@ public boolean contains(ImmutableRoaringBitmap subset) { return pos2 == length2; } - @Override public boolean equals(Object o) { if (o instanceof ImmutableRoaringBitmap) { @@ -1306,16 +1328,16 @@ public boolean isHammingSimilar(ImmutableRoaringBitmap other, int tolerance) { int pos1 = 0; int pos2 = 0; int budget = tolerance; - while(budget >= 0 && pos1 < size1 && pos2 < size2) { + while (budget >= 0 && pos1 < size1 && pos2 < size2) { final char key1 = highLowContainer.getKeyAtIndex(pos1); final char key2 = other.highLowContainer.getKeyAtIndex(pos2); MappeableContainer left = highLowContainer.getContainerAtIndex(pos1); MappeableContainer right = other.highLowContainer.getContainerAtIndex(pos2); - if(key1 == key2) { + if (key1 == key2) { budget -= left.xorCardinality(right); ++pos1; ++pos2; - } else if(key1 < key2) { + } else if (key1 < key2) { budget -= left.getCardinality(); ++pos1; } else { @@ -1323,18 +1345,17 @@ public boolean isHammingSimilar(ImmutableRoaringBitmap other, int tolerance) { ++pos2; } } - while(budget >= 0 && pos1 < size1) { + while (budget >= 0 && pos1 < size1) { MappeableContainer container = highLowContainer.getContainerAtIndex(pos1++); budget -= container.getCardinality(); } - while(budget >= 0 && pos2 < size2) { + while (budget >= 0 && pos2 < size2) { MappeableContainer container = other.highLowContainer.getContainerAtIndex(pos2++); budget -= container.getCardinality(); } return budget >= 0; } - /** * Checks if the range intersects with the bitmap. * @param minimum the inclusive unsigned lower bound of the range @@ -1346,8 +1367,8 @@ public boolean intersects(long minimum, long supremum) { if (supremum <= minimum) { return false; } - int minKey = (int)(minimum >>> 16); - int supKey = (int)(supremum >>> 16); + int minKey = (int) (minimum >>> 16); + int supKey = (int) (supremum >>> 16); int length = highLowContainer.size(); // seek to start int pos = 0; @@ -1355,7 +1376,7 @@ public boolean intersects(long minimum, long supremum) { ++pos; } // it is possible for pos == length to be true - if(pos == length) { + if (pos == length) { return false; } // we have that pos < length. @@ -1375,9 +1396,9 @@ public boolean intersects(long minimum, long supremum) { offset = 0; ++pos; } - return pos < length && supKey == highLowContainer.getKeyAtIndex(pos) - && highLowContainer.getContainerAtIndex(pos) - .intersects(offset, limit); + return pos < length + && supKey == highLowContainer.getKeyAtIndex(pos) + && highLowContainer.getContainerAtIndex(pos).intersects(offset, limit); } /** @@ -1422,8 +1443,6 @@ public void forEach(IntConsumer ic) { } } - - /** * Return a low-level container pointer that can be used to access the underlying data structure. * @@ -1466,7 +1485,6 @@ public BatchIterator getBatchIterator() { return new RoaringBatchIterator(null == highLowContainer ? null : getContainerPointer()); } - /** * Estimate of the memory usage of this data structure. This can be expected to be within 1% of * the true memory usage in common usage scenarios. @@ -1513,8 +1531,10 @@ public long getLongSizeInBytes() { (MappeableRunContainer) this.highLowContainer.getContainerAtIndex(i); size += 4 + BufferUtil.getSizeInBytesFromCardinalityEtc(0, thisRunContainer.nbrruns, true); } else { - size += 4 + BufferUtil - .getSizeInBytesFromCardinalityEtc(this.highLowContainer.getCardinality(i), 0, false); + size += + 4 + + BufferUtil.getSizeInBytesFromCardinalityEtc( + this.highLowContainer.getCardinality(i), 0, false); } } return size; @@ -1559,7 +1579,7 @@ public long getLongSizeInBytes() { */ @Override public int getSizeInBytes() { - return (int) getLongSizeInBytes() ; + return (int) getLongSizeInBytes(); } /** @@ -1580,7 +1600,6 @@ public int hashCode() { return highLowContainer.hashCode(); } - /** * Check whether this bitmap has had its runs compressed. * @@ -1623,8 +1642,11 @@ public boolean hasNext() { public Iterator init() { if (pos < ImmutableRoaringBitmap.this.highLowContainer.size()) { - iter = ImmutableRoaringBitmap.this.highLowContainer.getContainerAtIndex(pos) - .getCharIterator(); + iter = + ImmutableRoaringBitmap.this + .highLowContainer + .getContainerAtIndex(pos) + .getCharIterator(); hs = (ImmutableRoaringBitmap.this.highLowContainer.getKeyAtIndex(pos)) << 16; } return this; @@ -1644,7 +1666,6 @@ public Integer next() { public void remove() { throw new RuntimeException("Cannot modify."); } - }.init(); } @@ -1658,8 +1679,9 @@ public void remove() { public MutableRoaringBitmap limit(int maxcardinality) { MutableRoaringBitmap answer = new MutableRoaringBitmap(); int currentcardinality = 0; - for (int i = 0; (currentcardinality < maxcardinality) - && (i < this.highLowContainer.size()); i++) { + for (int i = 0; + (currentcardinality < maxcardinality) && (i < this.highLowContainer.size()); + i++) { MappeableContainer c = this.highLowContainer.getContainerAtIndex(i); if (c.getCardinality() + currentcardinality <= maxcardinality) { ((MutableRoaringArray) answer.highLowContainer) @@ -1694,41 +1716,38 @@ public long rankLong(int x) { char key = this.highLowContainer.getKeyAtIndex(i); if (key < xhigh) { size += this.highLowContainer.getCardinality(i); - } else if(key == xhigh) { + } else if (key == xhigh) { return size + this.highLowContainer.getContainerAtIndex(i).rank(lowbits(x)); } } return size; } - @Override public long rangeCardinality(long start, long end) { - if(Long.compareUnsigned(start, end) >= 0) { + if (Long.compareUnsigned(start, end) >= 0) { return 0; } long size = 0; int startIndex = this.highLowContainer.getIndex(highbits(start)); - if(startIndex < 0) { + if (startIndex < 0) { startIndex = -startIndex - 1; } else { int inContainerStart = (lowbits(start)); - if(inContainerStart != 0) { - size -= this.highLowContainer - .getContainerAtIndex(startIndex) - .rank((char)(inContainerStart - 1)); + if (inContainerStart != 0) { + size -= + this.highLowContainer + .getContainerAtIndex(startIndex) + .rank((char) (inContainerStart - 1)); } } char xhigh = highbits(end - 1); for (int i = startIndex; i < this.highLowContainer.size(); i++) { char key = this.highLowContainer.getKeyAtIndex(i); if (key < xhigh) { - size += this.highLowContainer - .getContainerAtIndex(i).getCardinality(); + size += this.highLowContainer.getContainerAtIndex(i).getCardinality(); } else if (key == xhigh) { - return size + this.highLowContainer - .getContainerAtIndex(i) - .rank(lowbits((int)(end - 1))); + return size + this.highLowContainer.getContainerAtIndex(i).rank(lowbits((int) (end - 1))); } } return size; @@ -1760,14 +1779,17 @@ public int select(int j) { if (thiscard > leftover) { int keycontrib = this.highLowContainer.getKeyAtIndex(i) << 16; MappeableContainer c = this.highLowContainer.getContainerAtIndex(i); - int lowcontrib = (c.select((int)leftover)); + int lowcontrib = (c.select((int) leftover)); return lowcontrib + keycontrib; } leftover -= thiscard; } - throw new IllegalArgumentException("You are trying to select the " - + j + "th value when the cardinality is " - + this.getCardinality() + "."); + throw new IllegalArgumentException( + "You are trying to select the " + + j + + "th value when the cardinality is " + + this.getCardinality() + + "."); } @Override @@ -1798,7 +1820,8 @@ public long nextValue(int fromValue) { while (containerIndex < highLowContainer.size() && nextSetBit == -1L) { char containerKey = highLowContainer.getKeyAtIndex(containerIndex); MappeableContainer container = highLowContainer.getContainerAtIndex(containerIndex); - int bit = ((containerKey) - (key) > 0 + int bit = + ((containerKey) - (key) > 0 ? container.first() : container.nextValue(lowbits(fromValue))); nextSetBit = bit == -1 ? -1L : toUnsignedLong((containerKey << 16) | bit); @@ -1827,9 +1850,8 @@ public long previousValue(int fromValue) { while (containerIndex != -1 && prevSetBit == -1L) { char containerKey = highLowContainer.getKeyAtIndex(containerIndex); MappeableContainer container = highLowContainer.getContainerAtIndex(containerIndex); - int bit = (containerKey < key - ? container.last() - : container.previousValue(lowbits(fromValue))); + int bit = + (containerKey < key ? container.last() : container.previousValue(lowbits(fromValue))); prevSetBit = bit == -1 ? -1L : toUnsignedLong((containerKey << 16) | bit); --containerIndex; } @@ -1841,7 +1863,7 @@ public long previousValue(int fromValue) { @Override public long nextAbsentValue(int fromValue) { long nextAbsentBit = computeNextAbsentValue(fromValue); - if(nextAbsentBit == 0x100000000L) { + if (nextAbsentBit == 0x100000000L) { return -1L; } return nextAbsentBit; @@ -1967,7 +1989,6 @@ public int serializedSizeInBytes() { return this.highLowContainer.serializedSizeInBytes(); } - /** * Return the set values as an array if the cardinality is less * than 2147483648. The integer values are in sorted order. @@ -2002,7 +2023,6 @@ public MutableRoaringBitmap toMutableRoaringBitmap() { return c; } - /** * Copies this bitmap to a mutable RoaringBitmap. * @@ -2012,7 +2032,6 @@ public RoaringBitmap toRoaringBitmap() { return new RoaringBitmap(this); } - /** * A string describing the bitmap. * @@ -2029,7 +2048,7 @@ public String toString() { while (i.hasNext()) { answer.append(','); // to avoid using too much memory, we limit the size - if(answer.length() > 0x80000) { + if (answer.length() > 0x80000) { answer.append('.').append('.').append('.'); break; } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java index 9069d216f..4285e450d 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableArrayContainer.java @@ -4,7 +4,15 @@ package org.roaringbitmap.buffer; -import org.roaringbitmap.*; +import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; + +import org.roaringbitmap.ArrayContainer; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.Container; +import org.roaringbitmap.ContainerBatchIterator; +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.PeekableCharIterator; +import org.roaringbitmap.Util; import java.io.DataOutput; import java.io.IOException; @@ -16,9 +24,6 @@ import java.util.Arrays; import java.util.Iterator; -import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; - - /** * Simple container made of an array of 16-bit integers. Unlike org.roaringbitmap.ArrayContainer, * this class uses a CharBuffer to store data. @@ -27,7 +32,7 @@ public final class MappeableArrayContainer extends MappeableContainer implements private static final int DEFAULT_INIT_SIZE = 4; private static final int ARRAY_LAZY_LOWERBOUND = 1024; protected static final int DEFAULT_MAX_SIZE = 4096; // containers with DEFAULT_MAX_SZE or less - // integers should be ArrayContainers + // integers should be ArrayContainers private static final long serialVersionUID = 1L; @@ -41,11 +46,8 @@ protected static int serializedSizeInBytes(int cardinality) { protected int cardinality = 0; - protected CharBuffer content; - - /** * Create an array container with default capacity */ @@ -67,7 +69,6 @@ public MappeableArrayContainer(ArrayContainer bc) { this.content = bc.toCharBuffer(); } - /** * Create an array container with specified capacity * @@ -96,7 +97,7 @@ public MappeableArrayContainer(final int firstOfRun, final int lastOfRun) { private MappeableArrayContainer(int newCard, CharBuffer newContent) { this.cardinality = newCard; - CharBuffer tmp = newContent.duplicate();// for thread-safety + CharBuffer tmp = newContent.duplicate(); // for thread-safety this.content = CharBuffer.allocate(Math.max(newCard, tmp.limit())); tmp.rewind(); this.content.put(tmp); @@ -130,8 +131,8 @@ public MappeableContainer add(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, - (char) (end - 1)); + int indexend = + BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -147,8 +148,8 @@ public MappeableContainer add(int begin, int end) { if (!BufferUtil.isBackedBySimpleArray(answer.content)) { throw new RuntimeException("Should not happen. Internal bug."); } - BufferUtil.arraycopy(content, indexend, answer.content, indexstart + rangelength, - cardinality - indexend); + BufferUtil.arraycopy( + content, indexend, answer.content, indexstart + rangelength, cardinality - indexend); char[] answerarray = answer.content.array(); for (int k = 0; k < rangelength; ++k) { answerarray[k + indexstart] = (char) (begin + k); @@ -166,8 +167,7 @@ public MappeableContainer add(final char x) { if (BufferUtil.isBackedBySimpleArray(this.content)) { char[] sarray = content.array(); - if (cardinality == 0 || (cardinality > 0 - && (x) > (sarray[cardinality - 1]))) { + if (cardinality == 0 || (cardinality > 0 && (x) > (sarray[cardinality - 1]))) { if (cardinality >= DEFAULT_MAX_SIZE) { return toBitmapContainer().add(x); } @@ -199,8 +199,7 @@ public MappeableContainer add(final char x) { } } } else { - if (cardinality == 0 || (cardinality > 0 - && (x) > (content.get(cardinality - 1)))) { + if (cardinality == 0 || (cardinality > 0 && (x) > (content.get(cardinality - 1)))) { if (cardinality >= DEFAULT_MAX_SIZE) { return toBitmapContainer().add(x); } @@ -282,7 +281,6 @@ private int advance(CharIterator it) { } } - @Override public MappeableArrayContainer and(final MappeableArrayContainer value2) { @@ -291,12 +289,21 @@ public MappeableArrayContainer and(final MappeableArrayContainer value2) { MappeableArrayContainer answer = new MappeableArrayContainer(desiredCapacity); if (BufferUtil.isBackedBySimpleArray(this.content) && BufferUtil.isBackedBySimpleArray(value2.content)) { - answer.cardinality = org.roaringbitmap.Util.unsignedIntersect2by2(value1.content.array(), - value1.getCardinality(), value2.content.array(), value2.getCardinality(), - answer.content.array()); + answer.cardinality = + org.roaringbitmap.Util.unsignedIntersect2by2( + value1.content.array(), + value1.getCardinality(), + value2.content.array(), + value2.getCardinality(), + answer.content.array()); } else { - answer.cardinality = BufferUtil.unsignedIntersect2by2(value1.content, value1.getCardinality(), - value2.content, value2.getCardinality(), answer.content.array()); + answer.cardinality = + BufferUtil.unsignedIntersect2by2( + value1.content, + value1.getCardinality(), + value2.content, + value2.getCardinality(), + answer.content.array()); } return answer; } @@ -311,7 +318,6 @@ public MappeableContainer and(final MappeableRunContainer value2) { return value2.and(this); } - @Override public MappeableArrayContainer andNot(final MappeableArrayContainer value2) { final MappeableArrayContainer value1 = this; @@ -320,11 +326,20 @@ public MappeableArrayContainer andNot(final MappeableArrayContainer value2) { if (BufferUtil.isBackedBySimpleArray(value1.content) && BufferUtil.isBackedBySimpleArray(value2.content)) { answer.cardinality = - org.roaringbitmap.Util.unsignedDifference(value1.content.array(), value1.getCardinality(), - value2.content.array(), value2.getCardinality(), answer.content.array()); + org.roaringbitmap.Util.unsignedDifference( + value1.content.array(), + value1.getCardinality(), + value2.content.array(), + value2.getCardinality(), + answer.content.array()); } else { - answer.cardinality = BufferUtil.unsignedDifference(value1.content, value1.getCardinality(), - value2.content, value2.getCardinality(), answer.content.array()); + answer.cardinality = + BufferUtil.unsignedDifference( + value1.content, + value1.getCardinality(), + value2.content, + value2.getCardinality(), + answer.content.array()); } return answer; } @@ -340,13 +355,13 @@ public MappeableArrayContainer andNot(MappeableBitmapContainer value2) { for (int k = 0; k < cardinality; ++k) { char v = c[k]; sarray[pos] = v; - pos += 1 - (int)value2.bitValue(v); + pos += 1 - (int) value2.bitValue(v); } } else { for (int k = 0; k < cardinality; ++k) { char v = this.content.get(k); sarray[pos] = v; - pos += 1 - (int)value2.bitValue(v); + pos += 1 - (int) value2.bitValue(v); } } answer.cardinality = pos; @@ -380,7 +395,6 @@ public MappeableContainer andNot(final MappeableRunContainer x) { write += cardinality - read; answer.cardinality = write; return answer; - } @Override @@ -411,7 +425,6 @@ public static boolean contains(ByteBuffer buf, int position, final char x, int c return BufferUtil.unsignedBinarySearch(buf, position, 0, cardinality, x) >= 0; } - // in order // not thread-safe private void emit(char val) { @@ -453,7 +466,6 @@ public boolean equals(Object o) { return false; } - @Override public void fillLeastSignificant16bits(int[] x, int i, int mask) { if (BufferUtil.isBackedBySimpleArray(this.content)) { @@ -589,8 +601,8 @@ public MappeableContainer iadd(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, - (char) (end - 1)); + int indexend = + BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -637,12 +649,12 @@ public MappeableContainer iadd(int begin, int end) { destination.put(k + indexstart, (char) (begin + k)); } } - BufferUtil.arraycopy(content, indexend, destination, indexstart + rangelength, cardinality - - indexend); + BufferUtil.arraycopy( + content, indexend, destination, indexstart + rangelength, cardinality - indexend); this.content = destination; } else { - BufferUtil.arraycopy(content, indexend, content, indexstart + rangelength, cardinality - - indexend); + BufferUtil.arraycopy( + content, indexend, content, indexstart + rangelength, cardinality - indexend); if (BufferUtil.isBackedBySimpleArray(content)) { char[] contentarray = content.array(); for (int k = 0; k < rangelength; ++k) { @@ -664,25 +676,28 @@ public MappeableArrayContainer iand(final MappeableArrayContainer value2) { if (!BufferUtil.isBackedBySimpleArray(value1.content)) { throw new RuntimeException("Should not happen. Internal bug."); } - value1.cardinality = BufferUtil.unsignedIntersect2by2(value1.content, value1.getCardinality(), - value2.content, value2.getCardinality(), value1.content.array()); + value1.cardinality = + BufferUtil.unsignedIntersect2by2( + value1.content, + value1.getCardinality(), + value2.content, + value2.getCardinality(), + value1.content.array()); return this; } - @Override public MappeableContainer iand(MappeableBitmapContainer value2) { int pos = 0; for (int k = 0; k < cardinality; ++k) { char v = this.content.get(k); this.content.put(pos, v); - pos += (int)value2.bitValue(v); + pos += (int) value2.bitValue(v); } cardinality = pos; return this; } - @Override public MappeableContainer iand(final MappeableRunContainer value2) { PeekableCharIterator it = value2.getCharIterator(); @@ -706,11 +721,20 @@ public MappeableArrayContainer iandNot(final MappeableArrayContainer value2) { } if (BufferUtil.isBackedBySimpleArray(value2.content)) { this.cardinality = - org.roaringbitmap.Util.unsignedDifference(this.content.array(), this.getCardinality(), - value2.content.array(), value2.getCardinality(), this.content.array()); + org.roaringbitmap.Util.unsignedDifference( + this.content.array(), + this.getCardinality(), + value2.content.array(), + value2.getCardinality(), + this.content.array()); } else { - this.cardinality = BufferUtil.unsignedDifference(this.content, this.getCardinality(), - value2.content, value2.getCardinality(), this.content.array()); + this.cardinality = + BufferUtil.unsignedDifference( + this.content, + this.getCardinality(), + value2.content, + value2.getCardinality(), + this.content.array()); } return this; @@ -726,7 +750,7 @@ public MappeableArrayContainer iandNot(MappeableBitmapContainer value2) { for (int k = 0; k < cardinality; ++k) { char v = c[k]; c[pos] = v; - pos += 1 - (int)value2.bitValue(v); + pos += 1 - (int) value2.bitValue(v); } this.cardinality = pos; return this; @@ -762,8 +786,10 @@ private void increaseCapacity(boolean allowIllegalSize) { newCapacity = MappeableArrayContainer.DEFAULT_MAX_SIZE; } // if we are within 1/16th of the max., go to max right away to avoid further reallocations - if (newCapacity > MappeableArrayContainer.DEFAULT_MAX_SIZE - - MappeableArrayContainer.DEFAULT_MAX_SIZE / 16 && !allowIllegalSize) { + if (newCapacity + > MappeableArrayContainer.DEFAULT_MAX_SIZE + - MappeableArrayContainer.DEFAULT_MAX_SIZE / 16 + && !allowIllegalSize) { newCapacity = MappeableArrayContainer.DEFAULT_MAX_SIZE; } final CharBuffer newContent = CharBuffer.allocate(newCapacity); @@ -774,12 +800,14 @@ private void increaseCapacity(boolean allowIllegalSize) { private int calculateCapacity() { int len = this.content.limit(); - int newCapacity = (len == 0) ? DEFAULT_INIT_SIZE - : len < 64 ? len * 2 : len < 1067 ? len * 3 / 2 : len * 5 / 4; + int newCapacity = + (len == 0) + ? DEFAULT_INIT_SIZE + : len < 64 ? len * 2 : len < 1067 ? len * 3 / 2 : len * 5 / 4; return newCapacity; } - private int calculateCapacity(int min){ + private int calculateCapacity(int min) { int newCapacity = calculateCapacity(); if (newCapacity < min) { newCapacity = min; @@ -787,8 +815,9 @@ private int calculateCapacity(int min){ if (newCapacity > MappeableArrayContainer.DEFAULT_MAX_SIZE) { newCapacity = MappeableArrayContainer.DEFAULT_MAX_SIZE; } - if (newCapacity > MappeableArrayContainer.DEFAULT_MAX_SIZE - - MappeableArrayContainer.DEFAULT_MAX_SIZE / 16) { + if (newCapacity + > MappeableArrayContainer.DEFAULT_MAX_SIZE + - MappeableArrayContainer.DEFAULT_MAX_SIZE / 16) { newCapacity = MappeableArrayContainer.DEFAULT_MAX_SIZE; } return newCapacity; @@ -848,8 +877,8 @@ public MappeableContainer inot(final int firstOfRange, final int lastOfRange) { @Override public boolean intersects(MappeableArrayContainer value2) { MappeableArrayContainer value1 = this; - return BufferUtil.unsignedIntersects(value1.content, value1.getCardinality(), value2.content, - value2.getCardinality()); + return BufferUtil.unsignedIntersects( + value1.content, value1.getCardinality(), value2.content, value2.getCardinality()); } @Override @@ -875,12 +904,24 @@ public MappeableContainer ior(final MappeableArrayContainer value2) { if (BufferUtil.isBackedBySimpleArray(content) && BufferUtil.isBackedBySimpleArray(value2.content)) { cardinality = - Util.unsignedUnion2by2(content.array(), 0, cardinality, value2.content.array(), 0, - value2.cardinality, destination.array()); + Util.unsignedUnion2by2( + content.array(), + 0, + cardinality, + value2.content.array(), + 0, + value2.cardinality, + destination.array()); } else { cardinality = - BufferUtil.unsignedUnion2by2(content, 0, cardinality, value2.content, 0, - value2.cardinality, destination.array()); + BufferUtil.unsignedUnion2by2( + content, + 0, + cardinality, + value2.content, + 0, + value2.cardinality, + destination.array()); } this.content = destination; } else { @@ -889,12 +930,24 @@ public MappeableContainer ior(final MappeableArrayContainer value2) { if (BufferUtil.isBackedBySimpleArray(content) && BufferUtil.isBackedBySimpleArray(value2.content)) { cardinality = - Util.unsignedUnion2by2(content.array(), value2.cardinality, cardinality, - value2.content.array(), 0, value2.cardinality, content.array()); + Util.unsignedUnion2by2( + content.array(), + value2.cardinality, + cardinality, + value2.content.array(), + 0, + value2.cardinality, + content.array()); } else { cardinality = - BufferUtil.unsignedUnion2by2(content, value2.cardinality, cardinality, value2.content, - 0, value2.cardinality, content.array()); + BufferUtil.unsignedUnion2by2( + content, + value2.cardinality, + cardinality, + value2.content, + 0, + value2.cardinality, + content.array()); } } return this; @@ -923,15 +976,19 @@ public MappeableContainer iremove(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, - (char) (end - 1)); + int indexend = + BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { indexend++; } int rangelength = indexend - indexstart; - BufferUtil.arraycopy(content, indexstart + rangelength, content, indexstart, + BufferUtil.arraycopy( + content, + indexstart + rangelength, + content, + indexstart, cardinality - indexstart - rangelength); cardinality -= rangelength; return this; @@ -942,7 +999,6 @@ protected boolean isArrayBacked() { return BufferUtil.isBackedBySimpleArray(this.content); } - @Override public Iterator iterator() { @@ -972,7 +1028,6 @@ public MappeableContainer ixor(final MappeableArrayContainer value2) { return this.xor(value2); } - @Override public MappeableContainer ixor(MappeableBitmapContainer x) { return x.xor(this); @@ -992,7 +1047,6 @@ public MappeableContainer limit(int maxcardinality) { } } - void loadData(final MappeableBitmapContainer bitmapContainer) { this.cardinality = bitmapContainer.cardinality; if (!BufferUtil.isBackedBySimpleArray(this.content)) { @@ -1002,8 +1056,12 @@ void loadData(final MappeableBitmapContainer bitmapContainer) { } // for use in inot range known to be nonempty - private void negateRange(final CharBuffer buffer, final int startIndex, final int lastIndex, - final int startRange, final int lastRange) { + private void negateRange( + final CharBuffer buffer, + final int startIndex, + final int lastIndex, + final int startRange, + final int lastRange) { // compute the negation into buffer int outPos = 0; @@ -1136,7 +1194,6 @@ int numberOfRuns() { } } - @Override public MappeableContainer or(final MappeableArrayContainer value2) { final MappeableArrayContainer value1 = this; @@ -1149,17 +1206,23 @@ public MappeableContainer or(final MappeableArrayContainer value2) { && BufferUtil.isBackedBySimpleArray(value2.content)) { answer.cardinality = Util.unsignedUnion2by2( - value1.content.array(), 0, value1.getCardinality(), - value2.content.array(), 0, value2.getCardinality(), - answer.content.array() - ); + value1.content.array(), + 0, + value1.getCardinality(), + value2.content.array(), + 0, + value2.getCardinality(), + answer.content.array()); } else { answer.cardinality = - BufferUtil.unsignedUnion2by2( - value1.content, 0, value1.getCardinality(), - value2.content, 0, value2.getCardinality(), - answer.content.array() - ); + BufferUtil.unsignedUnion2by2( + value1.content, + 0, + value1.getCardinality(), + value2.content, + 0, + value2.getCardinality(), + answer.content.array()); } return answer; } @@ -1174,23 +1237,28 @@ protected MappeableContainer lazyor(final MappeableArrayContainer value2) { if (BufferUtil.isBackedBySimpleArray(value1.content) && BufferUtil.isBackedBySimpleArray(value2.content)) { answer.cardinality = - Util.unsignedUnion2by2( - value1.content.array(), 0, value1.getCardinality(), - value2.content.array(), 0, value2.getCardinality(), - answer.content.array() - ); + Util.unsignedUnion2by2( + value1.content.array(), + 0, + value1.getCardinality(), + value2.content.array(), + 0, + value2.getCardinality(), + answer.content.array()); } else { answer.cardinality = - BufferUtil.unsignedUnion2by2( - value1.content, 0, value1.getCardinality(), - value2.content, 0, value2.getCardinality(), - answer.content.array() - ); + BufferUtil.unsignedUnion2by2( + value1.content, + 0, + value1.getCardinality(), + value2.content, + 0, + value2.getCardinality(), + answer.content.array()); } return answer; } - @Override public MappeableContainer or(MappeableBitmapContainer x) { return x.or(this); @@ -1283,8 +1351,8 @@ public MappeableContainer remove(int begin, int end) { if (indexstart < 0) { indexstart = -indexstart - 1; } - int indexend = BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, - (char) (end - 1)); + int indexend = + BufferUtil.unsignedBinarySearch(content, indexstart, cardinality, (char) (end - 1)); if (indexend < 0) { indexend = -indexend - 1; } else { @@ -1292,7 +1360,11 @@ public MappeableContainer remove(int begin, int end) { } int rangelength = indexend - indexstart; MappeableArrayContainer answer = clone(); - BufferUtil.arraycopy(content, indexstart + rangelength, answer.content, indexstart, + BufferUtil.arraycopy( + content, + indexstart + rangelength, + answer.content, + indexstart, cardinality - indexstart - rangelength); answer.cardinality = cardinality - rangelength; return answer; @@ -1303,7 +1375,6 @@ void removeAtIndex(final int loc) { --cardinality; } - @Override public MappeableContainer remove(final char x) { if (BufferUtil.isBackedBySimpleArray(this.content)) { @@ -1322,7 +1393,6 @@ public MappeableContainer remove(final char x) { --cardinality; } return this; - } } @@ -1331,17 +1401,16 @@ public MappeableContainer repairAfterLazy() { return this; } - @Override public MappeableContainer runOptimize() { int numRuns = numberOfRuns(); int sizeAsRunContainer = MappeableRunContainer.getArraySizeInBytes(numRuns); if (getArraySizeInBytes() > sizeAsRunContainer) { return new MappeableRunContainer(this, numRuns); // this could be - // maybe faster if - // initial - // container is a - // bitmap + // maybe faster if + // initial + // container is a + // bitmap } else { return this; } @@ -1497,14 +1566,14 @@ public String toString() { if (this.cardinality == 0) { return "{}"; } - final StringBuilder sb = new StringBuilder("{}".length() + "-123456789,".length() - * cardinality); + final StringBuilder sb = + new StringBuilder("{}".length() + "-123456789,".length() * cardinality); sb.append('{'); for (int i = 0; i < this.cardinality - 1; i++) { - sb.append((int)(this.content.get(i))); + sb.append((int) (this.content.get(i))); sb.append(','); } - sb.append((int)(this.content.get(this.cardinality - 1))); + sb.append((int) (this.content.get(this.cardinality - 1))); sb.append('}'); return sb.toString(); } @@ -1580,12 +1649,21 @@ public MappeableContainer xor(final MappeableArrayContainer value2) { final MappeableArrayContainer answer = new MappeableArrayContainer(totalCardinality); if (BufferUtil.isBackedBySimpleArray(value1.content) && BufferUtil.isBackedBySimpleArray(value2.content)) { - answer.cardinality = org.roaringbitmap.Util.unsignedExclusiveUnion2by2(value1.content.array(), - value1.getCardinality(), value2.content.array(), value2.getCardinality(), - answer.content.array()); + answer.cardinality = + org.roaringbitmap.Util.unsignedExclusiveUnion2by2( + value1.content.array(), + value1.getCardinality(), + value2.content.array(), + value2.getCardinality(), + answer.content.array()); } else { - answer.cardinality = BufferUtil.unsignedExclusiveUnion2by2(value1.content, - value1.getCardinality(), value2.content, value2.getCardinality(), answer.content.array()); + answer.cardinality = + BufferUtil.unsignedExclusiveUnion2by2( + value1.content, + value1.getCardinality(), + value2.content, + value2.getCardinality(), + answer.content.array()); } return answer; } @@ -1600,7 +1678,6 @@ public MappeableContainer xor(final MappeableRunContainer value2) { return value2.xor(this); } - protected MappeableContainer xor(CharIterator it) { return or(it, true); } @@ -1624,11 +1701,11 @@ public void forEach(char msb, IntConsumer ic) { public int andCardinality(MappeableArrayContainer value2) { if (BufferUtil.isBackedBySimpleArray(content) && BufferUtil.isBackedBySimpleArray(value2.content)) { - return Util.unsignedLocalIntersect2by2Cardinality(content.array(), cardinality, - value2.content.array(), value2.getCardinality()); + return Util.unsignedLocalIntersect2by2Cardinality( + content.array(), cardinality, value2.content.array(), value2.getCardinality()); } - return BufferUtil.unsignedLocalIntersect2by2Cardinality(content, cardinality, - value2.content, value2.getCardinality()); + return BufferUtil.unsignedLocalIntersect2by2Cardinality( + content, cardinality, value2.content, value2.getCardinality()); } @Override @@ -1664,7 +1741,7 @@ protected boolean contains(MappeableArrayContainer arrayContainer) { return false; } int i1 = 0, i2 = 0; - while(i1 < cardinality && i2 < arrayContainer.cardinality) { + while (i1 < cardinality && i2 < arrayContainer.cardinality) { if (content.get(i1) == arrayContainer.content.get(i2)) { ++i1; ++i2; @@ -1684,10 +1761,10 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) { @Override public boolean intersects(int minimum, int supremum) { - if((minimum < 0) || (supremum < minimum) || (supremum > (1<<16))) { + if ((minimum < 0) || (supremum < minimum) || (supremum > (1 << 16))) { throw new RuntimeException("This should never happen (bug)."); } - int pos = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char)minimum); + int pos = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (char) minimum); int index = pos >= 0 ? pos : -pos - 1; return index < cardinality && (content.get(index)) < supremum; } @@ -1695,26 +1772,21 @@ public boolean intersects(int minimum, int supremum) { @Override public boolean contains(int minimum, int supremum) { int maximum = supremum - 1; - int start = BufferUtil.advanceUntil(content, -1, cardinality, (char)minimum); - int end = BufferUtil.advanceUntil(content, start - 1, cardinality, (char)maximum); + int start = BufferUtil.advanceUntil(content, -1, cardinality, (char) minimum); + int end = BufferUtil.advanceUntil(content, start - 1, cardinality, (char) maximum); return start < cardinality - && end < cardinality - && end - start == maximum - minimum - && content.get(start) == (char)minimum - && content.get(end) == (char)maximum; + && end < cardinality + && end - start == maximum - minimum + && content.get(start) == (char) minimum + && content.get(end) == (char) maximum; } - } - final class MappeableArrayContainerCharIterator implements PeekableCharIterator { int pos; private MappeableArrayContainer parent; - MappeableArrayContainerCharIterator() { - - } - + MappeableArrayContainerCharIterator() {} MappeableArrayContainerCharIterator(MappeableArrayContainer p) { wrap(p); @@ -1730,7 +1802,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -1744,7 +1816,6 @@ public char next() { return parent.content.get(pos++); } - @Override public int nextAsInt() { return (parent.content.get(pos++)); @@ -1755,7 +1826,6 @@ public char peekNext() { return parent.content.get(pos); } - @Override public void remove() { parent.removeAtIndex(pos - 1); @@ -1766,18 +1836,13 @@ void wrap(MappeableArrayContainer p) { parent = p; pos = 0; } - - - } - final class RawArrayContainerCharIterator implements PeekableCharIterator { int pos; private MappeableArrayContainer parent; char[] content; - RawArrayContainerCharIterator(MappeableArrayContainer p) { parent = p; if (!p.isArrayBacked()) { @@ -1787,7 +1852,6 @@ final class RawArrayContainerCharIterator implements PeekableCharIterator { pos = 0; } - @Override public void advanceIfNeeded(char minval) { pos = Util.advanceUntil(content, pos - 1, parent.cardinality, minval); @@ -1798,7 +1862,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -1827,16 +1891,13 @@ public void remove() { parent.removeAtIndex(pos - 1); pos--; } - } - final class RawReverseArrayContainerCharIterator implements CharIterator { int pos; private MappeableArrayContainer parent; char[] content; - RawReverseArrayContainerCharIterator(MappeableArrayContainer p) { parent = p; if (!p.isArrayBacked()) { @@ -1851,7 +1912,7 @@ public CharIterator clone() { try { return (CharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -1860,7 +1921,6 @@ public boolean hasNext() { return pos >= 0; } - @Override public char next() { return content[pos--]; @@ -1876,20 +1936,15 @@ public void remove() { parent.removeAtIndex(pos + 1); pos++; } - } - final class ReverseMappeableArrayContainerCharIterator implements CharIterator { int pos; private MappeableArrayContainer parent; - ReverseMappeableArrayContainerCharIterator() { - - } - + ReverseMappeableArrayContainerCharIterator() {} ReverseMappeableArrayContainerCharIterator(MappeableArrayContainer p) { wrap(p); @@ -1900,7 +1955,7 @@ public CharIterator clone() { try { return (CharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -1914,7 +1969,6 @@ public char next() { return parent.content.get(pos--); } - @Override public int nextAsInt() { return (parent.content.get(pos--)); @@ -1930,5 +1984,4 @@ void wrap(MappeableArrayContainer p) { parent = p; pos = parent.cardinality - 1; } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java index 104484b18..cb0814752 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableBitmapContainer.java @@ -4,7 +4,18 @@ package org.roaringbitmap.buffer; -import org.roaringbitmap.*; +import static java.lang.Long.numberOfLeadingZeros; +import static java.lang.Long.numberOfTrailingZeros; +import static java.nio.ByteOrder.LITTLE_ENDIAN; + +import org.roaringbitmap.BitSetUtil; +import org.roaringbitmap.BitmapContainer; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.Container; +import org.roaringbitmap.ContainerBatchIterator; +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.PeekableCharIterator; +import org.roaringbitmap.Util; import java.io.DataOutput; import java.io.IOException; @@ -14,11 +25,6 @@ import java.nio.LongBuffer; import java.util.Iterator; -import static java.lang.Long.numberOfLeadingZeros; -import static java.lang.Long.numberOfTrailingZeros; -import static java.nio.ByteOrder.LITTLE_ENDIAN; - - /** * Simple bitset-like container. Unlike org.roaringbitmap.BitmapContainer, this class uses a * LongBuffer to store data. @@ -35,6 +41,7 @@ public final class MappeableBitmapContainer extends MappeableContainer implement // bail out early when the number of runs is excessive, without // an exact count (just a decent lower bound) private static final int BLOCKSIZE = 128; + // 64 words can have max 32 runs per word, max 2k runs /** @@ -43,7 +50,6 @@ public final class MappeableBitmapContainer extends MappeableContainer implement */ private static final boolean USE_BRANCHLESS = true; - // the parameter is for overloading and symmetry with ArrayContainer protected static int serializedSizeInBytes(int unusedCardinality) { return MAX_CAPACITY / 8; @@ -89,8 +95,6 @@ public MappeableBitmapContainer(final int firstOfRun, final int lastOfRun) { Util.setBitmapRange(bitmap.array(), firstOfRun, lastOfRun); } - - MappeableBitmapContainer(int newCardinality, LongBuffer newBitmap) { this.cardinality = newCardinality; LongBuffer tmp = newBitmap.duplicate(); // for thread safety @@ -107,8 +111,11 @@ public MappeableBitmapContainer(final int firstOfRun, final int lastOfRun) { */ public MappeableBitmapContainer(final LongBuffer array, final int initCardinality) { if (array.limit() != MAX_CAPACITY / 64) { - throw new RuntimeException("Mismatch between buffer and storage requirements: " - + array.limit() + " vs. " + MAX_CAPACITY / 64); + throw new RuntimeException( + "Mismatch between buffer and storage requirements: " + + array.limit() + + " vs. " + + MAX_CAPACITY / 64); } this.cardinality = initCardinality; this.bitmap = array; @@ -130,14 +137,13 @@ public MappeableContainer add(int begin, int end) { return answer; } - @Override public MappeableContainer add(final char i) { final long previous = bitmap.get(i / 64); final long newv = previous | (1L << i); bitmap.put(i / 64, newv); if (USE_BRANCHLESS) { - cardinality += (int)((previous ^ newv) >>> i); + cardinality += (int) ((previous ^ newv) >>> i); } else if (previous != newv) { cardinality++; } @@ -163,7 +169,7 @@ public MappeableArrayContainer and(final MappeableArrayContainer value2) { for (int k = 0; k < ca; ++k) { char v = c[k]; sarray[answer.cardinality] = v; - answer.cardinality += (int)this.bitValue(v); + answer.cardinality += (int) this.bitValue(v); } } else { @@ -171,7 +177,7 @@ public MappeableArrayContainer and(final MappeableArrayContainer value2) { for (int k = 0; k < ca; ++k) { char v = value2.content.get(k); sarray[answer.cardinality] = v; - answer.cardinality += (int)this.bitValue(v); + answer.cardinality += (int) this.bitValue(v); } } return answer; @@ -220,8 +226,8 @@ public MappeableContainer and(final MappeableBitmapContainer value2) { final MappeableArrayContainer ac = new MappeableArrayContainer(newCardinality); if (BufferUtil.isBackedBySimpleArray(this.bitmap) && BufferUtil.isBackedBySimpleArray(value2.bitmap)) { - org.roaringbitmap.Util.fillArrayAND(ac.content.array(), this.bitmap.array(), - value2.bitmap.array()); + org.roaringbitmap.Util.fillArrayAND( + ac.content.array(), this.bitmap.array(), value2.bitmap.array()); } else { BufferUtil.fillArrayAND(ac.content.array(), this.bitmap, value2.bitmap); } @@ -234,8 +240,6 @@ public MappeableContainer and(final MappeableRunContainer value2) { return value2.and(this); } - - @Override public MappeableContainer andNot(final MappeableArrayContainer value2) { final MappeableBitmapContainer answer = clone(); @@ -272,8 +276,6 @@ public MappeableContainer andNot(final MappeableArrayContainer value2) { return answer; } - - @Override public MappeableContainer andNot(final MappeableBitmapContainer value2) { @@ -319,8 +321,8 @@ public MappeableContainer andNot(final MappeableBitmapContainer value2) { final MappeableArrayContainer ac = new MappeableArrayContainer(newCardinality); if (BufferUtil.isBackedBySimpleArray(this.bitmap) && BufferUtil.isBackedBySimpleArray(value2.bitmap)) { - org.roaringbitmap.Util.fillArrayANDNOT(ac.content.array(), this.bitmap.array(), - value2.bitmap.array()); + org.roaringbitmap.Util.fillArrayANDNOT( + ac.content.array(), this.bitmap.array(), value2.bitmap.array()); } else { BufferUtil.fillArrayANDNOT(ac.content.array(), this.bitmap, value2.bitmap); } @@ -334,8 +336,7 @@ public MappeableContainer andNot(final MappeableRunContainer value2) { long[] b = answer.bitmap.array(); for (int rlepos = 0; rlepos < value2.nbrruns; ++rlepos) { int start = (value2.getValue(rlepos)); - int end = (value2.getValue(rlepos)) - + (value2.getLength(rlepos)) + 1; + int end = (value2.getValue(rlepos)) + (value2.getLength(rlepos)) + 1; int prevOnesInRange = Util.cardinalityInBitmapRange(b, start, end); Util.resetBitmapRange(b, start, end); answer.updateCardinality(prevOnesInRange, 0); @@ -358,8 +359,6 @@ public void clear() { } } - - @Override public MappeableBitmapContainer clone() { return new MappeableBitmapContainer(this.cardinality, this.bitmap); @@ -407,7 +406,6 @@ long bitValue(final char i) { return (bitmap.get(i >>> 6) >>> i) & 1; } - /** * Checks whether the container contains the value i. * @@ -455,7 +453,7 @@ public boolean equals(Object o) { /** * Fill the array with set bits - * + * * @param array container (should be sufficiently large) */ void fillArray(final char[] array) { @@ -510,8 +508,8 @@ public void fillLeastSignificant16bits(int[] x, int i, int mask) { public MappeableContainer flip(char i) { final long bef = bitmap.get(i >>> 6); final long mask = 1L << i; - if (cardinality == MappeableArrayContainer.DEFAULT_MAX_SIZE + 1) {// this - // is + if (cardinality == MappeableArrayContainer.DEFAULT_MAX_SIZE + 1) { // this + // is // the // uncommon // path @@ -523,19 +521,16 @@ public MappeableContainer flip(char i) { } long aft = bef ^ mask; // TODO: check whether a branchy version could be faster - cardinality += 1 - 2 * (int)((bef & mask) >>> i); + cardinality += 1 - 2 * (int) ((bef & mask) >>> i); bitmap.put(i >>> 6, aft); return this; } - @Override protected int getArraySizeInBytes() { return MAX_CAPACITY_BYTE; } - - @Override public int getCardinality() { return cardinality; @@ -598,11 +593,10 @@ public MappeableContainer iand(final MappeableArrayContainer b2) { BufferUtil.intersectArrayIntoBitmap(bitmap, b2.content, b2.cardinality); return this; } else { - return b2.and(this);// no inplace possible + return b2.and(this); // no inplace possible } } - @Override public MappeableContainer iand(final MappeableBitmapContainer b2) { if (BufferUtil.isBackedBySimpleArray(this.bitmap) @@ -670,7 +664,7 @@ public MappeableContainer iand(final MappeableRunContainer x) { int runEnd = runStart + (x.getLength(rlepos)); for (int runValue = runStart; runValue <= runEnd; ++runValue) { answer.content.put(answer.cardinality, (char) runValue); - answer.cardinality += (int)this.bitValue((char) runValue); + answer.cardinality += (int) this.bitValue((char) runValue); } } return answer; @@ -711,8 +705,6 @@ public MappeableContainer iandNot(final MappeableArrayContainer b2) { return this; } - - @Override public MappeableContainer iandNot(final MappeableBitmapContainer b2) { int newCardinality = 0; @@ -737,7 +729,6 @@ public MappeableContainer iandNot(final MappeableBitmapContainer b2) { org.roaringbitmap.Util.fillArrayANDNOT(ac.content.array(), b, b2Arr); ac.cardinality = newCardinality; return ac; - } int len = this.bitmap.limit(); for (int k = 0; k < len; ++k) { @@ -786,11 +777,10 @@ public MappeableContainer iandNot(final MappeableRunContainer x) { } else { return toArrayContainer(); } - } MappeableContainer ilazyor(MappeableArrayContainer value2) { - this.cardinality = -1;// invalid + this.cardinality = -1; // invalid if (!BufferUtil.isBackedBySimpleArray(bitmap)) { throw new RuntimeException("Should not happen. Internal bug."); } @@ -817,11 +807,10 @@ MappeableContainer ilazyor(MappeableBitmapContainer x) { this.bitmap.put(k, this.bitmap.get(k) | x.bitmap.get(k)); } } - this.cardinality = -1;// invalid + this.cardinality = -1; // invalid return this; } - MappeableContainer ilazyor(MappeableRunContainer x) { for (int rlepos = 0; rlepos < x.nbrruns; ++rlepos) { int start = (x.getValue(rlepos)); @@ -843,7 +832,6 @@ public MappeableContainer inot(final int firstOfRange, final int lastOfRange) { return this; } - @Override public boolean intersects(MappeableArrayContainer value2) { if (BufferUtil.isBackedBySimpleArray(value2.content)) { @@ -895,8 +883,6 @@ public boolean intersects(MappeableRunContainer x) { return x.intersects(this); } - - @Override public MappeableBitmapContainer ior(final MappeableArrayContainer value2) { if (!BufferUtil.isBackedBySimpleArray(this.bitmap)) { @@ -912,7 +898,7 @@ public MappeableBitmapContainer ior(final MappeableArrayContainer value2) { long aft = bef | (1L << v2[k]); b[i] = aft; if (USE_BRANCHLESS) { - cardinality += (int)((bef - aft) >>> 63); + cardinality += (int) ((bef - aft) >>> 63); } else { if (aft != bef) { cardinality++; @@ -929,7 +915,7 @@ public MappeableBitmapContainer ior(final MappeableArrayContainer value2) { long aft = bef | (1L << v2); b[i] = aft; if (USE_BRANCHLESS) { - cardinality += (int)((bef - aft) >>> 63); + cardinality += (int) ((bef - aft) >>> 63); } else { if (aft != bef) { cardinality++; @@ -1083,7 +1069,7 @@ public MappeableContainer ixor(final MappeableArrayContainer value2) { final int index = (vc) >>> 6; long ba = b[index]; // TODO: check whether a branchy version could be faster - this.cardinality += 1 - 2 * (int)((ba & mask) >>> vc); + this.cardinality += 1 - 2 * (int) ((ba & mask) >>> vc); b[index] = ba ^ mask; } @@ -1095,7 +1081,7 @@ public MappeableContainer ixor(final MappeableArrayContainer value2) { final int index = (v2) >>> 6; long ba = b[index]; // TODO: check whether a branchy version could be faster - this.cardinality += 1 - 2 * (int)((ba & mask) >>> v2); + this.cardinality += 1 - 2 * (int) ((ba & mask) >>> v2); b[index] = ba ^ mask; } } @@ -1131,7 +1117,6 @@ public MappeableContainer ixor(MappeableBitmapContainer b2) { org.roaringbitmap.Util.fillArrayXOR(ac.content.array(), b, b2Arr); ac.cardinality = newCardinality; return ac; - } int newCardinality = 0; int len = this.bitmap.limit(); @@ -1181,7 +1166,7 @@ public MappeableContainer ixor(final MappeableRunContainer x) { protected MappeableContainer lazyor(MappeableArrayContainer value2) { MappeableBitmapContainer answer = clone(); - answer.cardinality = -1;// invalid + answer.cardinality = -1; // invalid if (!BufferUtil.isBackedBySimpleArray(answer.bitmap)) { throw new RuntimeException("Should not happen. Internal bug."); } @@ -1197,7 +1182,7 @@ protected MappeableContainer lazyor(MappeableArrayContainer value2) { protected MappeableContainer lazyor(MappeableBitmapContainer x) { MappeableBitmapContainer answer = new MappeableBitmapContainer(); - answer.cardinality = -1;// invalid + answer.cardinality = -1; // invalid if (!BufferUtil.isBackedBySimpleArray(answer.bitmap)) { throw new RuntimeException("Should not happen. Internal bug."); } @@ -1275,15 +1260,13 @@ void loadData(final MappeableArrayContainer arrayContainer) { char[] ac = arrayContainer.content.array(); for (int k = 0; k < arrayContainer.cardinality; ++k) { final char x = ac[k]; - bitArray[(x) >>> 6] = - b[(x) >>> 6] | (1L << x); + bitArray[(x) >>> 6] = b[(x) >>> 6] | (1L << x); } } else { for (int k = 0; k < arrayContainer.cardinality; ++k) { final char x = arrayContainer.content.get(k); - bitArray[(x) >>> 6] = - bitmap.get((x) >>> 6) | (1L << x); + bitArray[(x) >>> 6] = bitmap.get((x) >>> 6) | (1L << x); } } } @@ -1340,7 +1323,6 @@ public MappeableContainer not(final int firstOfRange, final int lastOfRange) { return answer.inot(firstOfRange, lastOfRange); } - @Override int numberOfRuns() { if (BufferUtil.isBackedBySimpleArray(this.bitmap)) { @@ -1351,7 +1333,7 @@ int numberOfRuns() { for (int i = 0; i < src.length - 1; i++) { long word = nextWord; nextWord = src[i + 1]; - numRuns += Long.bitCount((~word) & (word << 1)) + (int)((word >>> 63) & ~nextWord); + numRuns += Long.bitCount((~word) & (word << 1)) + (int) ((word >>> 63) & ~nextWord); } long word = nextWord; @@ -1369,7 +1351,7 @@ int numberOfRuns() { for (int i = 0; i < len - 1; i++) { long word = nextWord; nextWord = bitmap.get(i + 1); - numRuns += Long.bitCount((~word) & (word << 1)) + (int)((word >>> 63) & ~nextWord); + numRuns += Long.bitCount((~word) & (word << 1)) + (int) ((word >>> 63) & ~nextWord); } long word = nextWord; @@ -1379,7 +1361,6 @@ int numberOfRuns() { } return numRuns; - } } @@ -1397,7 +1378,7 @@ private int numberOfRunsAdjustment() { final long word = nextWord; nextWord = b[i + 1]; - ans += (int)((word >>> 63) & ~nextWord); + ans += (int) ((word >>> 63) & ~nextWord); } final long word = nextWord; @@ -1413,7 +1394,7 @@ private int numberOfRunsAdjustment() { final long word = nextWord; nextWord = bitmap.get(i + 1); - ans += (int)((word >>> 63) & ~nextWord); + ans += (int) ((word >>> 63) & ~nextWord); } final long word = nextWord; @@ -1462,8 +1443,6 @@ private int numberOfRunsLowerBound(int mustNotExceed) { return numRuns; } - - @Override public MappeableContainer or(final MappeableArrayContainer value2) { final MappeableBitmapContainer answer = clone(); @@ -1483,7 +1462,7 @@ public MappeableContainer or(final MappeableArrayContainer value2) { long aft = w | (1L << v); bitArray[i] = aft; if (USE_BRANCHLESS) { - answer.cardinality += (int)((w - aft) >>> 63); + answer.cardinality += (int) ((w - aft) >>> 63); } else { if (w != aft) { answer.cardinality++; @@ -1499,7 +1478,7 @@ public MappeableContainer or(final MappeableArrayContainer value2) { long aft = w | (1L << v2); bitArray[i] = aft; if (USE_BRANCHLESS) { - answer.cardinality += (int)((w - aft) >>> 63); + answer.cardinality += (int) ((w - aft) >>> 63); } else { if (w != aft) { answer.cardinality++; @@ -1513,8 +1492,6 @@ public MappeableContainer or(final MappeableArrayContainer value2) { return answer; } - - @Override public MappeableContainer or(final MappeableBitmapContainer value2) { final MappeableBitmapContainer value1 = this.clone(); @@ -1526,8 +1503,6 @@ public MappeableContainer or(final MappeableRunContainer value2) { return value2.or(this); } - - /** * Find the index of the previous set bit less than or equal to i, returns -1 if none found. * @@ -1595,7 +1570,6 @@ public int rank(char lowbits) { return answer; } - @Override public void readExternal(ObjectInput in) throws IOException { // little endian @@ -1635,14 +1609,12 @@ public MappeableContainer remove(int begin, int end) { return answer; } - - @Override public MappeableContainer remove(final char i) { long X = bitmap.get(i >>> 6); long mask = 1L << i; - if (cardinality == MappeableArrayContainer.DEFAULT_MAX_SIZE + 1) {// this is + if (cardinality == MappeableArrayContainer.DEFAULT_MAX_SIZE + 1) { // this is // the // uncommon // path @@ -1658,12 +1630,11 @@ public MappeableContainer remove(final char i) { return this; } - @Override public MappeableContainer repairAfterLazy() { if (getCardinality() < 0) { computeCardinality(); - if(getCardinality() <= MappeableArrayContainer.DEFAULT_MAX_SIZE) { + if (getCardinality() <= MappeableArrayContainer.DEFAULT_MAX_SIZE) { return this.toArrayContainer(); } else if (isFull()) { return MappeableRunContainer.full(); @@ -1698,8 +1669,8 @@ public MappeableContainer runOptimize() { public char select(int j) { if (BufferUtil.isBackedBySimpleArray(this.bitmap)) { long[] b = this.bitmap.array(); - if (//cardinality != -1 && // omitted as (-1>>>1) > j as j < (1<<16) - cardinality >>> 1 < j && j < cardinality) { + if ( // cardinality != -1 && // omitted as (-1>>>1) > j as j < (1<<16) + cardinality >>> 1 < j && j < cardinality) { int leftover = cardinality - j; for (int k = b.length - 1; k >= 0; --k) { long w = b[k]; @@ -1726,8 +1697,8 @@ public char select(int j) { } } else { int len = this.bitmap.limit(); - if (//cardinality != -1 && // (-1>>>1) > j as j < (1<<16) - cardinality >>> 1 < j && j < cardinality) { + if ( // cardinality != -1 && // (-1>>>1) > j as j < (1<<16) + cardinality >>> 1 < j && j < cardinality) { int leftover = cardinality - j; for (int k = len - 1; k >= 0; --k) { int w = Long.bitCount(bitmap.get(k)); @@ -1781,6 +1752,7 @@ public char selectOneSide(int j) { } throw new IllegalArgumentException("Insufficient cardinality."); } + @Override public int serializedSizeInBytes() { return serializedSizeInBytes(0); @@ -1823,7 +1795,7 @@ public String toString() { final CharIterator i = this.getCharIterator(); sb.append('{'); while (i.hasNext()) { - sb.append((int)(i.next())); + sb.append((int) (i.next())); if (i.hasNext()) { sb.append(','); } @@ -1833,9 +1805,7 @@ public String toString() { } @Override - public void trim() { - - } + public void trim() {} @Override protected void writeArray(DataOutput out) throws IOException { @@ -1884,7 +1854,7 @@ public MappeableContainer xor(final MappeableArrayContainer value2) { final int index = (vc) >>> 6; long ba = bitArray[index]; // TODO: check whether a branchy version could be faster - answer.cardinality += 1 - 2 * (int)((ba & mask) >>> vc); + answer.cardinality += 1 - 2 * (int) ((ba & mask) >>> vc); bitArray[index] = ba ^ mask; } } else { @@ -1895,7 +1865,7 @@ public MappeableContainer xor(final MappeableArrayContainer value2) { final int index = (v2) >>> 6; long ba = bitArray[index]; // TODO: check whether a branchy version could be faster - answer.cardinality += 1 - 2 * (int)((ba & mask) >>> v2); + answer.cardinality += 1 - 2 * (int) ((ba & mask) >>> v2); bitArray[index] = ba ^ mask; } } @@ -1977,14 +1947,13 @@ public void forEach(char msb, IntConsumer ic) { } } - @Override public int andCardinality(final MappeableArrayContainer value2) { int answer = 0; int c = value2.cardinality; for (int k = 0; k < c; ++k) { char v = value2.content.get(k); - answer += (int)this.bitValue(v); + answer += (int) this.bitValue(v); } return answer; } @@ -2023,15 +1992,15 @@ public int first() { assertNonEmpty(cardinality == 0); long firstNonZeroWord; int i = 0; - if(BufferUtil.isBackedBySimpleArray(bitmap)) { + if (BufferUtil.isBackedBySimpleArray(bitmap)) { long[] array = bitmap.array(); - while(array[i] == 0) { + while (array[i] == 0) { ++i; } firstNonZeroWord = array[i]; } else { i = bitmap.position(); - while(bitmap.get(i) == 0) { + while (bitmap.get(i) == 0) { ++i; } firstNonZeroWord = bitmap.get(i); @@ -2044,14 +2013,14 @@ public int last() { assertNonEmpty(cardinality == 0); long lastNonZeroWord; int i = bitmap.limit() - 1; - if(BufferUtil.isBackedBySimpleArray(bitmap)) { + if (BufferUtil.isBackedBySimpleArray(bitmap)) { long[] array = this.bitmap.array(); - while(i > 0 && array[i] == 0) { + while (i > 0 && array[i] == 0) { --i; } lastNonZeroWord = array[i]; } else { - while(i > 0 && bitmap.get(i) == 0) { + while (i > 0 && bitmap.get(i) == 0) { --i; } lastNonZeroWord = bitmap.get(i); @@ -2081,13 +2050,13 @@ public int previousAbsentValue(char fromValue) { @Override protected boolean contains(MappeableBitmapContainer bitmapContainer) { - if((cardinality != -1) && (bitmapContainer.cardinality != -1)) { - if(cardinality < bitmapContainer.cardinality) { + if ((cardinality != -1) && (bitmapContainer.cardinality != -1)) { + if (cardinality < bitmapContainer.cardinality) { return false; } } - for(int i = 0; i < MAX_CAPACITY >>> 6; ++i ) { - if((this.bitmap.get(i) & bitmapContainer.bitmap.get(i)) != bitmapContainer.bitmap.get(i)) { + for (int i = 0; i < MAX_CAPACITY >>> 6; ++i) { + if ((this.bitmap.get(i) & bitmapContainer.bitmap.get(i)) != bitmapContainer.bitmap.get(i)) { return false; } } @@ -2096,7 +2065,7 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) { @Override public boolean intersects(int minimum, int supremum) { - if((minimum < 0) || (supremum < minimum) || (supremum > (1<<16))) { + if ((minimum < 0) || (supremum < minimum) || (supremum > (1 << 16))) { throw new RuntimeException("This should never happen (bug)."); } int start = minimum >>> 6; @@ -2172,28 +2141,23 @@ protected boolean contains(MappeableArrayContainer arrayContainer) { } } for (int i = 0; i < arrayContainer.cardinality; ++i) { - if(!contains(arrayContainer.content.get(i))) { + if (!contains(arrayContainer.content.get(i))) { return false; } } return true; } - - } - final class MappeableBitmapContainerCharIterator implements PeekableCharIterator { - private final static int len = MappeableBitmapContainer.MAX_CAPACITY >>> 6;// hard coded for speed + private static final int len = + MappeableBitmapContainer.MAX_CAPACITY >>> 6; // hard coded for speed private long w; int x; - private MappeableBitmapContainer parent; - MappeableBitmapContainerCharIterator() { - - } + MappeableBitmapContainerCharIterator() {} MappeableBitmapContainerCharIterator(MappeableBitmapContainer p) { wrap(p); @@ -2204,7 +2168,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -2274,18 +2238,16 @@ public char peekNext() { } } - final class ReverseMappeableBitmapContainerCharIterator implements CharIterator { - private final static int len = MappeableBitmapContainer.MAX_CAPACITY >>> 6;// hard coded for speed + private static final int len = + MappeableBitmapContainer.MAX_CAPACITY >>> 6; // hard coded for speed private long w; int x; private MappeableBitmapContainer parent; - ReverseMappeableBitmapContainerCharIterator() { - - } + ReverseMappeableBitmapContainerCharIterator() {} ReverseMappeableBitmapContainerCharIterator(MappeableBitmapContainer p) { wrap(p); @@ -2308,7 +2270,7 @@ public boolean hasNext() { @Override public char next() { int shift = Long.numberOfLeadingZeros(w) + 1; - char answer = (char)((x + 1) * 64 - shift); + char answer = (char) ((x + 1) * 64 - shift); w &= (0xFFFFFFFFFFFFFFFEL >>> shift); while (w == 0) { --x; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java index 8b52482b4..eb91e6c34 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainer.java @@ -4,7 +4,12 @@ package org.roaringbitmap.buffer; -import org.roaringbitmap.*; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.Container; +import org.roaringbitmap.ContainerBatchIterator; +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.PeekableCharIterator; +import org.roaringbitmap.WordStorage; import java.io.DataOutput; import java.io.Externalizable; @@ -16,8 +21,8 @@ * Base container class. This class is similar to org.roaringbitmap.Container but meant to be used * with memory mapping. */ -public abstract class MappeableContainer implements Iterable, Cloneable, Externalizable, - WordStorage { +public abstract class MappeableContainer + implements Iterable, Cloneable, Externalizable, WordStorage { /** * Create a container initialized with a range of consecutive values * @@ -44,7 +49,6 @@ public static MappeableContainer rangeOfOnes(final int start, final int last) { */ public abstract MappeableContainer add(int begin, int end); - /** * Add a char to the container. May generate a new container. * @@ -111,10 +115,8 @@ protected MappeableContainer and(MappeableContainer x) { return and((MappeableRunContainer) x); } return and((MappeableBitmapContainer) x); - } - protected abstract int andCardinality(MappeableArrayContainer x); protected abstract int andCardinality(MappeableBitmapContainer x); @@ -153,7 +155,6 @@ public int andCardinality(MappeableContainer x) { } } - /** * Computes the bitwise AND of this container with another (intersection). This container as well * as the provided container are left unaffected. @@ -161,10 +162,8 @@ public int andCardinality(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer and(MappeableRunContainer x); - /** * Computes the bitwise ANDNOT of this container with another (difference). This container as well * as the provided container are left unaffected. @@ -200,7 +199,6 @@ protected MappeableContainer andNot(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer andNot(MappeableRunContainer x); /** @@ -250,23 +248,22 @@ public MappeableContainer iorNot(MappeableContainer x, int endOfRange) { */ public abstract boolean contains(char x); - /** + /** * Checks whether the container is a subset of this container or not * @param subset the container to be tested * @return true if the parameter is a subset of this container */ public boolean contains(MappeableContainer subset) { - if(subset instanceof MappeableRunContainer) { - return contains((MappeableRunContainer)subset); - } else if(subset instanceof MappeableArrayContainer) { + if (subset instanceof MappeableRunContainer) { + return contains((MappeableRunContainer) subset); + } else if (subset instanceof MappeableArrayContainer) { return contains((MappeableArrayContainer) subset); - } else if(subset instanceof MappeableBitmapContainer){ - return contains((MappeableBitmapContainer)subset); + } else if (subset instanceof MappeableBitmapContainer) { + return contains((MappeableBitmapContainer) subset); } return false; } - protected abstract boolean contains(MappeableRunContainer runContainer); protected abstract boolean contains(MappeableArrayContainer arrayContainer); @@ -310,7 +307,6 @@ public boolean contains(MappeableContainer subset) { */ public abstract MappeableContainer flip(char x); - /** * Size of the underlying array * @@ -318,7 +314,6 @@ public boolean contains(MappeableContainer subset) { */ protected abstract int getArraySizeInBytes(); - /** * Computes the distinct number of char values in the container. Can be expected to run in * constant time. @@ -341,10 +336,11 @@ public String getContainerName() { return ContainerNames[2]; } } + /** * Name of the various possible containers */ - public static String[] ContainerNames = {"mappeablebitmap","mappeablearray","mappeablerun"}; + public static String[] ContainerNames = {"mappeablebitmap", "mappeablearray", "mappeablerun"}; /** * Iterator to visit the char values in the container in descending order. @@ -353,7 +349,6 @@ public String getContainerName() { */ public abstract CharIterator getReverseCharIterator(); - /** * Iterator to visit the char values in the container in ascending order. * @@ -412,7 +407,6 @@ public String getContainerName() { */ public abstract MappeableContainer iand(MappeableBitmapContainer x); - protected MappeableContainer iand(MappeableContainer x) { if (x instanceof MappeableArrayContainer) { return iand((MappeableArrayContainer) x); @@ -421,7 +415,6 @@ protected MappeableContainer iand(MappeableContainer x) { } return iand((MappeableBitmapContainer) x); - } /** @@ -432,7 +425,6 @@ protected MappeableContainer iand(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer iand(MappeableRunContainer x); /** @@ -473,11 +465,8 @@ protected MappeableContainer iandNot(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer iandNot(MappeableRunContainer x); - - /** * Computes the in-place bitwise NOT of this container (complement). Only those bits within the * range are affected. The current container is generally modified. May generate a new container. @@ -488,7 +477,6 @@ protected MappeableContainer iandNot(MappeableContainer x) { */ public abstract MappeableContainer inot(int rangeStart, int rangeEnd); - /** * Returns true if the current container intersects the other container. * @@ -566,7 +554,6 @@ protected MappeableContainer ior(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer ior(MappeableRunContainer x); /** @@ -580,7 +567,6 @@ protected MappeableContainer ior(MappeableContainer x) { protected abstract boolean isArrayBacked(); - /** * Computes the in-place bitwise XOR of this container with another (symmetric difference). The * current container is generally modified, whereas the provided container (x) is unaffected. May @@ -609,10 +595,8 @@ protected MappeableContainer ixor(MappeableContainer x) { } return ixor((MappeableBitmapContainer) x); - } - /** * Computes the in-place bitwise XOR of this container with another (symmetric difference). The * current container is generally modified, whereas the provided container (x) is unaffected. May @@ -621,11 +605,8 @@ protected MappeableContainer ixor(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer ixor(MappeableRunContainer x); - - /** * Computes the in-place bitwise OR of this container with another (union). The current container * is generally modified, whereas the provided container (x) is unaffected. May generate a new @@ -724,7 +705,6 @@ public MappeableContainer lazyOR(MappeableContainer x) { */ public abstract MappeableContainer or(MappeableArrayContainer x); - /** * Computes the bitwise OR of this container with another (union). This container as well as the * provided container are left unaffected. @@ -734,7 +714,6 @@ public MappeableContainer lazyOR(MappeableContainer x) { */ public abstract MappeableContainer or(MappeableBitmapContainer x); - protected MappeableContainer or(MappeableContainer x) { if (x instanceof MappeableArrayContainer) { return or((MappeableArrayContainer) x); @@ -752,7 +731,6 @@ protected MappeableContainer or(MappeableContainer x) { * @param x other container * @return aggregated container */ - public abstract MappeableContainer or(MappeableRunContainer x); /** @@ -797,7 +775,6 @@ protected MappeableContainer or(MappeableContainer x) { */ public abstract MappeableContainer runOptimize(); - /** * Return the jth value * @@ -807,7 +784,6 @@ protected MappeableContainer or(MappeableContainer x) { */ public abstract char select(int j); - /** * Report the number of bytes required to serialize this container. * @@ -815,8 +791,6 @@ protected MappeableContainer or(MappeableContainer x) { */ public abstract int serializedSizeInBytes(); - - /** * Convert to a non-mappeable container. * @@ -829,8 +803,6 @@ protected MappeableContainer or(MappeableContainer x) { */ public abstract void trim(); - - /** * Write just the underlying array. * @@ -872,7 +844,6 @@ protected MappeableContainer xor(MappeableContainer x) { } return xor((MappeableBitmapContainer) x); - } /** @@ -889,7 +860,7 @@ protected MappeableContainer xor(MappeableContainer x) { * If the container is already a bitmap, the container is returned unchanged. * @return a bitmap container */ - public abstract MappeableBitmapContainer toBitmapContainer() ; + public abstract MappeableBitmapContainer toBitmapContainer(); /** * Get the first integer held in the container @@ -933,16 +904,14 @@ protected MappeableContainer xor(MappeableContainer x) { */ public abstract int previousAbsentValue(char fromValue); - /** * Throw if the container is empty * @param condition a boolean expression * @throws NoSuchElementException if empty */ protected void assertNonEmpty(boolean condition) { - if(condition) { + if (condition) { throw new NoSuchElementException("Empty " + getContainerName()); } } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java index 287e4f2cf..ae19d9674 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableContainerPointer.java @@ -78,6 +78,4 @@ public interface MappeableContainerPointer * Move to the previous container */ void previous(); - - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java index a732ab097..1f7ff56dc 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MappeableRunContainer.java @@ -3,8 +3,17 @@ */ package org.roaringbitmap.buffer; +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static org.roaringbitmap.Util.resetBitmapRange; +import static org.roaringbitmap.Util.setBitmapRange; +import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; -import org.roaringbitmap.*; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.Container; +import org.roaringbitmap.ContainerBatchIterator; +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.PeekableCharIterator; +import org.roaringbitmap.RunContainer; import java.io.DataOutput; import java.io.IOException; @@ -16,10 +25,6 @@ import java.util.Iterator; import java.util.Optional; -import static java.nio.ByteOrder.LITTLE_ENDIAN; -import static org.roaringbitmap.Util.*; -import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; - /** * This container takes the form of runs of consecutive values (effectively, run-length encoding). * Uses a CharBuffer to store data, unlike org.roaringbitmap.RunContainer. Otherwise similar. @@ -32,8 +37,8 @@ public final class MappeableRunContainer extends MappeableContainer implements C private static final int DEFAULT_INIT_SIZE = 4; private static final long serialVersionUID = 1L; - private static int branchyBufferedUnsignedInterleavedBinarySearch(final CharBuffer sb, - final int begin, final int end, final char k) { + private static int branchyBufferedUnsignedInterleavedBinarySearch( + final CharBuffer sb, final int begin, final int end, final char k) { int low = begin; int high = end - 1; while (low <= high) { @@ -50,8 +55,8 @@ private static int branchyBufferedUnsignedInterleavedBinarySearch(final CharBuff return -(low + 1); } - private static int branchyBufferedUnsignedInterleavedBinarySearch(final ByteBuffer sb, - int position, final int begin, final int end, final char k) { + private static int branchyBufferedUnsignedInterleavedBinarySearch( + final ByteBuffer sb, int position, final int begin, final int end, final char k) { int low = begin; int high = end - 1; while (low <= high) { @@ -68,14 +73,13 @@ private static int branchyBufferedUnsignedInterleavedBinarySearch(final ByteBuff return -(low + 1); } - private static int bufferedUnsignedInterleavedBinarySearch(final CharBuffer sb, final int begin, - final int end, final char k) { + private static int bufferedUnsignedInterleavedBinarySearch( + final CharBuffer sb, final int begin, final int end, final char k) { return branchyBufferedUnsignedInterleavedBinarySearch(sb, begin, end, k); } - - private static int bufferedUnsignedInterleavedBinarySearch(final ByteBuffer sb, int position, - final int begin, final int end, final char k) { + private static int bufferedUnsignedInterleavedBinarySearch( + final ByteBuffer sb, int position, final int begin, final int end, final char k) { return branchyBufferedUnsignedInterleavedBinarySearch(sb, position, begin, end, k); } @@ -87,7 +91,6 @@ private static char getLength(char[] vl, int index) { return vl[2 * index + 1]; } - private static char getValue(char[] vl, int index) { return vl[2 * index]; } @@ -98,8 +101,7 @@ protected static int serializedSizeInBytes(int numberOfRuns) { protected CharBuffer valueslength; - protected int nbrruns = 0;// how many runs, this number should fit in 16 bits. - + protected int nbrruns = 0; // how many runs, this number should fit in 16 bits. /** * Create a container with default capacity @@ -117,16 +119,14 @@ public MappeableRunContainer(final int capacity) { valueslength = CharBuffer.allocate(2 * capacity); } - private MappeableRunContainer(int nbrruns, final CharBuffer valueslength) { this.nbrruns = nbrruns; - CharBuffer tmp = valueslength.duplicate();// for thread safety + CharBuffer tmp = valueslength.duplicate(); // for thread safety this.valueslength = CharBuffer.allocate(Math.max(2 * nbrruns, tmp.limit())); tmp.rewind(); this.valueslength.put(tmp); // may copy more than it needs to?? } - protected MappeableRunContainer(MappeableArrayContainer arr, int nbrRuns) { this.nbrruns = nbrRuns; valueslength = CharBuffer.allocate(2 * nbrRuns); @@ -296,7 +296,6 @@ protected MappeableRunContainer(MappeableBitmapContainer bc, int nbrRuns) { curWord = curWordWith1s & (curWordWith1s + 1); // We've lathered and rinsed, so repeat... } - } } @@ -339,10 +338,10 @@ public MappeableContainer add(char k) { // toBitmapOrArrayContainer(getCardinality()).add(k) int index = bufferedUnsignedInterleavedBinarySearch(valueslength, 0, nbrruns, k); if (index >= 0) { - return this;// already there + return this; // already there } - index = -index - 2;// points to preceding value, possibly -1 - if (index >= 0) {// possible match + index = -index - 2; // points to preceding value, possibly -1 + if (index >= 0) { // possible match int offset = (k) - (getValue(index)); int le = (getLength(index)); if (offset <= le) { @@ -353,8 +352,7 @@ public MappeableContainer add(char k) { if (index + 1 < nbrruns) { if ((getValue(index + 1)) == (k) + 1) { // indeed fusion is needed - setLength(index, - (char) (getValue(index + 1) + getLength(index + 1) - getValue(index))); + setLength(index, (char) (getValue(index + 1) + getLength(index + 1) - getValue(index))); recoverRoomAtIndex(index + 1); return this; } @@ -393,7 +391,6 @@ public boolean isEmpty() { return nbrruns == 0; } - @Override public MappeableContainer and(MappeableArrayContainer x) { MappeableArrayContainer ac = new MappeableArrayContainer(x.cardinality); @@ -407,17 +404,16 @@ public MappeableContainer and(MappeableArrayContainer x) { int rlelength = (this.getLength(rlepos)); while (arraypos < x.cardinality) { int arrayval = (x.content.get(arraypos)); - while (rleval + rlelength < arrayval) {// this will frequently be false + while (rleval + rlelength < arrayval) { // this will frequently be false ++rlepos; if (rlepos == this.nbrruns) { - return ac;// we are done + return ac; // we are done } rleval = (this.getValue(rlepos)); rlelength = (this.getLength(rlepos)); } if (rleval > arrayval) { - arraypos = - BufferUtil.advanceUntil(x.content, arraypos, x.cardinality, (char)rleval); + arraypos = BufferUtil.advanceUntil(x.content, arraypos, x.cardinality, (char) rleval); } else { ac.content.put(ac.cardinality, (char) arrayval); ac.cardinality++; @@ -467,7 +463,6 @@ public MappeableContainer and(MappeableBitmapContainer x) { } else { return answer.toArrayContainer(); } - } @Override @@ -496,10 +491,10 @@ public MappeableContainer and(MappeableRunContainer x) { xstart = (x.getValue(xrlepos)); xend = xstart + (x.getLength(xrlepos)) + 1; } - } else {// they overlap + } else { // they overlap final int lateststart = Math.max(start, xstart); int earliestend; - if (end == xend) {// improbable + if (end == xend) { // improbable earliestend = end; rlepos++; xrlepos++; @@ -519,7 +514,7 @@ public MappeableContainer and(MappeableRunContainer x) { end = start + (this.getLength(rlepos)) + 1; } - } else {// end > xend + } else { // end > xend earliestend = xend; xrlepos++; if (xrlepos < x.nbrruns) { @@ -547,8 +542,9 @@ public MappeableContainer andNot(MappeableArrayContainer x) { if (card <= MappeableArrayContainer.DEFAULT_MAX_SIZE) { // if the cardinality is small, we construct the solution in place MappeableArrayContainer ac = new MappeableArrayContainer(card); - ac.cardinality = org.roaringbitmap.Util.unsignedDifference(this.getCharIterator(), - x.getCharIterator(), ac.content.array()); + ac.cardinality = + org.roaringbitmap.Util.unsignedDifference( + this.getCharIterator(), x.getCharIterator(), ac.content.array()); return ac; } // otherwise, we generate a bitmap @@ -672,7 +668,6 @@ private void appendValueLength(int value, int index) { } } - // To check if a value length can be prepended with a given value private boolean canPrependValueLength(int value, int index) { if (index < this.nbrruns) { @@ -682,21 +677,16 @@ private boolean canPrependValueLength(int value, int index) { return false; } - - @Override public void clear() { nbrruns = 0; } - @Override public MappeableContainer clone() { return new MappeableRunContainer(nbrruns, valueslength); } - - // To set the last value of a value length private void closeValueLength(int value, int index) { int initialValue = (getValue(index)); @@ -710,7 +700,7 @@ public boolean contains(char x) { return true; } index = -index - 2; // points to preceding value, possibly -1 - if (index != -1) {// possible match + if (index != -1) { // possible match int offset = (x) - (getValue(index)); int le = (getLength(index)); return offset <= le; @@ -733,14 +723,12 @@ public static boolean contains(ByteBuffer buf, int position, char x, final int n return true; } index = -index - 2; // points to preceding value, possibly -1 - if (index != -1) {// possible match - int offset = (x) - - (buf.getChar(position + index * 2 * 2)); + if (index != -1) { // possible match + int offset = (x) - (buf.getChar(position + index * 2 * 2)); int le = (buf.getChar(position + index * 2 * 2 + 2)); return offset <= le; } return false; - } // a very cheap check... if you have more than 4096, then you should use a bitmap container. @@ -778,22 +766,22 @@ private void copyToOffset(int offset) { private static Optional computeNewCapacity(int oldCapacity, int minCapacity) { if (oldCapacity < minCapacity) { int newCapacity = oldCapacity; - while ((newCapacity = computeNewCapacity(newCapacity)) < minCapacity) { - } + while ((newCapacity = computeNewCapacity(newCapacity)) < minCapacity) {} return Optional.of(CharBuffer.allocate(newCapacity)); } return Optional.empty(); } private static int computeNewCapacity(int oldCapacity) { - return oldCapacity == 0 ? DEFAULT_INIT_SIZE - : oldCapacity < 64 ? oldCapacity * 2 - : oldCapacity < 1024 ? oldCapacity * 3 / 2 - : oldCapacity * 5 / 4; + return oldCapacity == 0 + ? DEFAULT_INIT_SIZE + : oldCapacity < 64 + ? oldCapacity * 2 + : oldCapacity < 1024 ? oldCapacity * 3 / 2 : oldCapacity * 5 / 4; } - private void copyValuesLength(CharBuffer src, int srcIndex, CharBuffer dst, int dstIndex, - int length) { + private void copyValuesLength( + CharBuffer src, int srcIndex, CharBuffer dst, int dstIndex, int length) { if (BufferUtil.isBackedBySimpleArray(src) && BufferUtil.isBackedBySimpleArray(dst)) { // common case. System.arraycopy(src.array(), 2 * srcIndex, dst.array(), 2 * dstIndex, 2 * length); @@ -816,7 +804,6 @@ private void decrementLength(int index) { valueslength.put(2 * index + 1, (char) (valueslength.get(2 * index + 1) - 1)); } - private void decrementValue() { valueslength.put(0, (char) (valueslength.get(0) - 1)); } @@ -881,7 +868,7 @@ private boolean equals(MappeableArrayContainer arrayContainer) { if (arrayContainer.select(pos) != runStart) { return false; } - if (arrayContainer.select(pos + length) != (char)((runStart) + length)) { + if (arrayContainer.select(pos + length) != (char) ((runStart) + length)) { return false; } pos += length + 1; @@ -901,7 +888,6 @@ public void fillLeastSignificant16bits(int[] x, int i, int mask) { } } - @Override public MappeableContainer flip(char x) { if (this.contains(x)) { @@ -995,7 +981,7 @@ public int hashCode() { public MappeableContainer iadd(int begin, int end) { // TODO: it might be better and simpler to do return // toBitmapOrArrayContainer(getCardinality()).iadd(begin,end) - if(end == begin) { + if (end == begin) { return this; } if ((begin > end) || (end > (1 << 16))) { @@ -1008,8 +994,9 @@ public MappeableContainer iadd(int begin, int end) { int bIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, - bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); + int eIndex = + bufferedUnsignedInterleavedBinarySearch( + this.valueslength, bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); if (bIndex >= 0 && eIndex >= 0) { mergeValuesLength(bIndex, eIndex); @@ -1089,8 +1076,6 @@ public MappeableContainer iadd(int begin, int end) { } } - - @Override public MappeableContainer iand(MappeableArrayContainer x) { return and(x); @@ -1101,7 +1086,6 @@ public MappeableContainer iand(MappeableBitmapContainer x) { return and(x); } - @Override public MappeableContainer iand(MappeableRunContainer x) { return and(x); @@ -1129,7 +1113,6 @@ MappeableContainer ilazyor(MappeableArrayContainer x) { return ilazyorToRun(x); } - private MappeableContainer ilazyorToRun(MappeableArrayContainer x) { if (isFull()) { return full(); @@ -1193,7 +1176,6 @@ private void initValueLength(int value, int index) { setLength(index, (char) (length - (value - initialValue))); } - @Override public MappeableContainer inot(int rangeStart, int rangeEnd) { if (rangeEnd <= rangeStart) { @@ -1268,11 +1250,11 @@ public MappeableContainer inot(int rangeStart, int rangeEnd) { // use local variables so we are always reading 1 location ahead. char bufferedValue = 0, bufferedLength = 0; // 65535 start and 65535 length would be illegal, - // could use as sentinel + // could use as sentinel char nextValue = 0, nextLength = 0; if (k < myNbrRuns) { // prime the readahead variables - bufferedValue = vl[2 * k];// getValue(k); - bufferedLength = vl[2 * k + 1];// getLength(k); + bufferedValue = vl[2 * k]; // getValue(k); + bufferedLength = vl[2 * k + 1]; // getLength(k); } ans.smartAppendExclusive(vl, (char) rangeStart, (char) (rangeEnd - rangeStart - 1)); @@ -1283,8 +1265,8 @@ public MappeableContainer inot(int rangeStart, int rangeEnd) { "internal error in inot, writer has overtaken reader!! " + k + " " + ans.nbrruns); } if (k + 1 < myNbrRuns) { - nextValue = vl[2 * (k + 1)];// getValue(k+1); // readahead for next iteration - nextLength = vl[2 * (k + 1) + 1];// getLength(k+1); + nextValue = vl[2 * (k + 1)]; // getValue(k+1); // readahead for next iteration + nextLength = vl[2 * (k + 1) + 1]; // getLength(k+1); } ans.smartAppendExclusive(vl, bufferedValue, bufferedLength); bufferedValue = nextValue; @@ -1307,7 +1289,7 @@ public boolean intersects(MappeableArrayContainer x) { int rlelength = (this.getLength(rlepos)); while (arraypos < x.cardinality) { int arrayval = (x.content.get(arraypos)); - while (rleval + rlelength < arrayval) {// this will frequently be false + while (rleval + rlelength < arrayval) { // this will frequently be false ++rlepos; if (rlepos == this.nbrruns) { return false; @@ -1360,7 +1342,7 @@ public boolean intersects(MappeableRunContainer x) { xstart = (x.getValue(xrlepos)); xend = xstart + (x.getLength(xrlepos)) + 1; } - } else {// they overlap + } else { // they overlap return true; } } @@ -1464,7 +1446,7 @@ public MappeableContainer ior(MappeableRunContainer x) { public MappeableContainer iremove(int begin, int end) { // TODO: it might be better and simpler to do return // toBitmapOrArrayContainer(getCardinality()).iremove(begin,end) - if(end == begin) { + if (end == begin) { return this; } if ((begin > end) || (end > (1 << 16))) { @@ -1477,8 +1459,9 @@ public MappeableContainer iremove(int begin, int end) { int bIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, 0, this.nbrruns, (char) begin); - int eIndex = bufferedUnsignedInterleavedBinarySearch(this.valueslength, - bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); + int eIndex = + bufferedUnsignedInterleavedBinarySearch( + this.valueslength, bIndex >= 0 ? bIndex : -bIndex - 1, this.nbrruns, (char) (end - 1)); if (bIndex >= 0) { if (eIndex < 0) { @@ -1501,7 +1484,7 @@ public MappeableContainer iremove(int begin, int end) { } } // last run is one charer - if (getLength(eIndex) == 0) {// special case where we remove last run + if (getLength(eIndex) == 0) { // special case where we remove last run recoverRoomsInRange(eIndex - 1, eIndex); } else { incrementValue(eIndex); @@ -1544,9 +1527,7 @@ public MappeableContainer iremove(int begin, int end) { recoverRoomsInRange(bIndex, eIndex); } } - } - } return this; } @@ -1615,7 +1596,6 @@ public void remove() { i.remove(); } }; - } @Override @@ -1623,7 +1603,6 @@ public MappeableContainer ixor(MappeableArrayContainer x) { return xor(x); } - @Override public MappeableContainer ixor(MappeableBitmapContainer x) { return xor(x); @@ -1700,8 +1679,6 @@ private MappeableRunContainer lazyandNot(MappeableArrayContainer x) { return answer; } - - protected MappeableContainer lazyor(MappeableArrayContainer x) { return lazyorToRun(x); } @@ -2009,10 +1986,10 @@ public MappeableContainer remove(char x) { incrementValue(index); decrementLength(index); } - return this;// already there + return this; // already there } - index = -index - 2;// points to preceding value, possibly -1 - if (index >= 0) {// possible match + index = -index - 2; // points to preceding value, possibly -1 + if (index >= 0) { // possible match int offset = (x) - (getValue(index)); int le = (getLength(index)); if (offset < le) { @@ -2041,7 +2018,6 @@ public MappeableContainer repairAfterLazy() { /** * Convert to Array or Bitmap container if the serialized form would be shorter */ - @Override public MappeableContainer runOptimize() { return toEfficientContainer(); // which had the same functionality. @@ -2066,19 +2042,14 @@ public int serializedSizeInBytes() { return serializedSizeInBytes(nbrruns); } - - private void setLength(int index, char v) { setLength(valueslength, index, v); } - - private void setLength(CharBuffer valueslength, int index, char v) { valueslength.put(2 * index + 1, v); } - private void setValue(int index, char v) { setValue(valueslength, index, v); } @@ -2087,17 +2058,16 @@ private void setValue(CharBuffer valueslength, int index, char v) { valueslength.put(2 * index, v); } - - // assume that the (maybe) inplace operations // will never actually *be* in place if they are // to return ArrayContainer or BitmapContainer private void smartAppend(char[] vl, char val) { int oldend; - if ((nbrruns == 0) || ( - (val) > (oldend = (vl[2 * (nbrruns - 1)]) - + (vl[2 * (nbrruns - 1) + 1])) + 1)) { // we add a new one + if ((nbrruns == 0) + || ((val) + > (oldend = (vl[2 * (nbrruns - 1)]) + (vl[2 * (nbrruns - 1) + 1])) + + 1)) { // we add a new one vl[2 * nbrruns] = val; vl[2 * nbrruns + 1] = 0; nbrruns++; @@ -2110,9 +2080,10 @@ private void smartAppend(char[] vl, char val) { void smartAppend(char start, char length) { int oldend; - if ((nbrruns == 0) || ((start) > (oldend = - (getValue(nbrruns - 1)) + (getLength(nbrruns - 1))) - + 1)) { // we add a new one + if ((nbrruns == 0) + || ((start) + > (oldend = (getValue(nbrruns - 1)) + (getLength(nbrruns - 1))) + + 1)) { // we add a new one ensureCapacity(nbrruns + 1); valueslength.put(2 * nbrruns, start); valueslength.put(2 * nbrruns + 1, length); @@ -2127,9 +2098,10 @@ void smartAppend(char start, char length) { private void smartAppend(char[] vl, char start, char length) { int oldend; - if ((nbrruns == 0) || ( - (start) > (oldend = (vl[2 * (nbrruns - 1)]) - + (vl[2 * (nbrruns - 1) + 1])) + 1)) { // we add a new one + if ((nbrruns == 0) + || ((start) + > (oldend = (vl[2 * (nbrruns - 1)]) + (vl[2 * (nbrruns - 1) + 1])) + + 1)) { // we add a new one vl[2 * nbrruns] = start; vl[2 * nbrruns + 1] = length; nbrruns++; @@ -2137,16 +2109,16 @@ private void smartAppend(char[] vl, char start, char length) { } int newend = (start) + (length) + 1; if (newend > oldend) { // we merge - vl[2 * (nbrruns - 1) + 1] = - (char) (newend - 1 - (vl[2 * (nbrruns - 1)])); + vl[2 * (nbrruns - 1) + 1] = (char) (newend - 1 - (vl[2 * (nbrruns - 1)])); } } private void smartAppendExclusive(char[] vl, char val) { int oldend; - if ((nbrruns == 0) || ( - (val) > (oldend = (getValue(nbrruns - 1)) - + (getLength(nbrruns - 1)) + 1))) { // we add a new one + if ((nbrruns == 0) + || ((val) + > (oldend = + (getValue(nbrruns - 1)) + (getLength(nbrruns - 1)) + 1))) { // we add a new one vl[2 * nbrruns] = val; vl[2 * nbrruns + 1] = 0; nbrruns++; @@ -2186,9 +2158,9 @@ private void smartAppendExclusive(char[] vl, char val) { private void smartAppendExclusive(char[] vl, char start, char length) { int oldend; - if ((nbrruns == 0) || ( - start > (oldend = getValue(nbrruns - 1) - + getLength(nbrruns - 1) + 1))) { // we add a new one + if ((nbrruns == 0) + || (start + > (oldend = getValue(nbrruns - 1) + getLength(nbrruns - 1) + 1))) { // we add a new one vl[2 * nbrruns] = start; vl[2 * nbrruns + 1] = length; nbrruns++; @@ -2266,7 +2238,6 @@ public Container toContainer() { return new RunContainer(this); } - // convert to bitmap or array *if needed* private MappeableContainer toEfficientContainer() { int sizeAsRunContainer = MappeableRunContainer.serializedSizeInBytes(this.nbrruns); @@ -2323,10 +2294,9 @@ public String toString() { StringBuilder sb = new StringBuilder("[]".length() + "-123456789,".length() * nbrruns); for (int k = 0; k < this.nbrruns; ++k) { sb.append('['); - sb.append((int)(this.getValue(k))); + sb.append((int) (this.getValue(k))); sb.append(','); - sb.append((this.getValue(k)) - + (this.getLength(k))); + sb.append((this.getValue(k)) + (this.getLength(k))); sb.append(']'); } return sb.toString(); @@ -2373,7 +2343,7 @@ protected void writeArray(ByteBuffer buffer) { source.position(0); source.limit(nbrruns * 2); CharBuffer target = buffer.asCharBuffer(); - target.put((char)nbrruns); + target.put((char) nbrruns); target.put(source); int bytesWritten = (nbrruns * 2 + 1) * 2; buffer.position(buffer.position() + bytesWritten); @@ -2461,21 +2431,18 @@ public MappeableContainer xor(MappeableRunContainer x) { return answer.toEfficientContainer(); } - @Override public void forEach(char msb, IntConsumer ic) { - int high = ((int)msb) << 16; - for(int k = 0; k < this.nbrruns; ++k) { + int high = ((int) msb) << 16; + for (int k = 0; k < this.nbrruns; ++k) { int base = (this.getValue(k) & 0xFFFF) | high; int le = this.getLength(k) & 0xFFFF; - for(int l = base; l - le <= base; ++l) { + for (int l = base; l - le <= base; ++l) { ic.accept(l); } } } - - @Override public int andCardinality(MappeableArrayContainer x) { if (this.nbrruns == 0) { @@ -2488,17 +2455,17 @@ public int andCardinality(MappeableArrayContainer x) { int rlelength = (this.getLength(rlepos)); while (arraypos < x.cardinality) { int arrayval = (x.content.get(arraypos)); - while (rleval + rlelength < arrayval) {// this will frequently be false + while (rleval + rlelength < arrayval) { // this will frequently be false ++rlepos; if (rlepos == this.nbrruns) { - return andCardinality;// we are done + return andCardinality; // we are done } rleval = (this.getValue(rlepos)); rlelength = (this.getLength(rlepos)); } if (rleval > arrayval) { - arraypos = BufferUtil.advanceUntil(x.content, arraypos, - x.cardinality, this.getValue(rlepos)); + arraypos = + BufferUtil.advanceUntil(x.content, arraypos, x.cardinality, this.getValue(rlepos)); } else { andCardinality++; arraypos++; @@ -2507,7 +2474,6 @@ public int andCardinality(MappeableArrayContainer x) { return andCardinality; } - @Override public int andCardinality(MappeableBitmapContainer x) { // could be implemented as return toBitmapOrArrayContainer().iand(x); @@ -2543,10 +2509,10 @@ public int andCardinality(MappeableRunContainer x) { xstart = (x.getValue(xrlepos)); xend = xstart + (x.getLength(xrlepos)) + 1; } - } else {// they overlap + } else { // they overlap final int lateststart = Math.max(start, xstart); int earliestend; - if (end == xend) {// improbable + if (end == xend) { // improbable earliestend = end; rlepos++; xrlepos++; @@ -2566,7 +2532,7 @@ public int andCardinality(MappeableRunContainer x) { end = start + (this.getLength(rlepos)) + 1; } - } else {// end > xend + } else { // end > xend earliestend = xend; xrlepos++; if (xrlepos < x.nbrruns) { @@ -2581,7 +2547,6 @@ public int andCardinality(MappeableRunContainer x) { return cardinality; } - @Override public MappeableBitmapContainer toBitmapContainer() { int card = this.getCardinality(); @@ -2674,17 +2639,17 @@ public int previousAbsentValue(char fromValue) { @Override protected boolean contains(MappeableRunContainer runContainer) { int i1 = 0, i2 = 0; - while(i1 < numberOfRuns() && i2 < runContainer.numberOfRuns()) { + while (i1 < numberOfRuns() && i2 < runContainer.numberOfRuns()) { int start1 = (getValue(i1)); int stop1 = start1 + (getLength(i1)); int start2 = (runContainer.getValue(i2)); int stop2 = start2 + (runContainer.getLength(i2)); - if(start1 > start2) { + if (start1 > start2) { return false; } else { - if(stop1 > stop2) { + if (stop1 > stop2) { i2++; - } else if(stop1 == stop2) { + } else if (stop1 == stop2) { i1++; i2++; } else { @@ -2703,11 +2668,11 @@ protected boolean contains(MappeableArrayContainer arrayContainer) { return false; } int ia = 0, ir = 0; - while(ia < arrayContainer.getCardinality() && ir < runCount) { + while (ia < arrayContainer.getCardinality() && ir < runCount) { int start = (getValue(ir)); int stop = start + (getLength(ir)); int value = (arrayContainer.content.get(ia)); - if(value < start) { + if (value < start) { return false; } else if (value > stop) { ++ir; @@ -2767,15 +2732,14 @@ protected boolean contains(MappeableBitmapContainer bitmapContainer) { @Override public boolean intersects(int minimum, int supremum) { - if((minimum < 0) || (supremum < minimum) || (supremum > (1<<16))) { + if ((minimum < 0) || (supremum < minimum) || (supremum > (1 << 16))) { throw new RuntimeException("This should never happen (bug)."); } for (int i = 0; i < numberOfRuns(); ++i) { char runFirstValue = getValue(i); char runLastValue = (char) (runFirstValue + getLength(i)); - if ((runFirstValue) < supremum - && (runLastValue) - ((char) minimum) >= 0){ + if ((runFirstValue) < supremum && (runLastValue) - ((char) minimum) >= 0) { return true; } } @@ -2797,11 +2761,8 @@ public boolean contains(int minimum, int supremum) { } return false; } - - } - final class MappeableRunContainerCharIterator implements PeekableCharIterator { private int pos; private int le = 0; @@ -2810,9 +2771,7 @@ final class MappeableRunContainerCharIterator implements PeekableCharIterator { private MappeableRunContainer parent; - MappeableRunContainerCharIterator() { - - } + MappeableRunContainerCharIterator() {} MappeableRunContainerCharIterator(MappeableRunContainer p) { wrap(p); @@ -2823,7 +2782,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -2864,7 +2823,7 @@ public int nextAsInt() { @Override public void remove() { - throw new RuntimeException("Not implemented");// TODO + throw new RuntimeException("Not implemented"); // TODO } void wrap(MappeableRunContainer p) { @@ -2899,10 +2858,8 @@ public void advanceIfNeeded(char minval) { public char peekNext() { return (char) (base + le); } - } - final class RawMappeableRunContainerCharIterator implements PeekableCharIterator { private int pos; private int le = 0; @@ -2912,7 +2869,6 @@ final class RawMappeableRunContainerCharIterator implements PeekableCharIterator private MappeableRunContainer parent; private char[] vl; - RawMappeableRunContainerCharIterator(MappeableRunContainer p) { wrap(p); } @@ -2922,7 +2878,7 @@ public PeekableCharIterator clone() { try { return (PeekableCharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -2954,7 +2910,6 @@ public char next() { return ans; } - @Override public int nextAsInt() { int ans = base + le; @@ -2972,7 +2927,7 @@ public int nextAsInt() { @Override public void remove() { - throw new RuntimeException("Not implemented");// TODO + throw new RuntimeException("Not implemented"); // TODO } private void wrap(MappeableRunContainer p) { @@ -3011,10 +2966,8 @@ public void advanceIfNeeded(char minval) { public char peekNext() { return (char) (base + le); } - } - final class RawReverseMappeableRunContainerCharIterator implements CharIterator { private int pos; private int le; @@ -3022,8 +2975,6 @@ final class RawReverseMappeableRunContainerCharIterator implements CharIterator private int base; private char[] vl; - - RawReverseMappeableRunContainerCharIterator(MappeableRunContainer p) { wrap(p); } @@ -3033,7 +2984,7 @@ public CharIterator clone() { try { return (CharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -3082,7 +3033,7 @@ public int nextAsInt() { @Override public void remove() { - throw new RuntimeException("Not implemented");// TODO + throw new RuntimeException("Not implemented"); // TODO } private void wrap(MappeableRunContainer p) { @@ -3098,10 +3049,8 @@ private void wrap(MappeableRunContainer p) { base = getValue(pos); } } - } - final class ReverseMappeableRunContainerCharIterator implements CharIterator { private int pos; private int le; @@ -3109,10 +3058,7 @@ final class ReverseMappeableRunContainerCharIterator implements CharIterator { private int base; private MappeableRunContainer parent; - - ReverseMappeableRunContainerCharIterator() { - - } + ReverseMappeableRunContainerCharIterator() {} ReverseMappeableRunContainerCharIterator(MappeableRunContainer p) { wrap(p); @@ -3123,7 +3069,7 @@ public CharIterator clone() { try { return (CharIterator) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -3164,7 +3110,7 @@ public int nextAsInt() { @Override public void remove() { - throw new RuntimeException("Not implemented");// TODO + throw new RuntimeException("Not implemented"); // TODO } void wrap(MappeableRunContainer p) { @@ -3176,5 +3122,4 @@ void wrap(MappeableRunContainer p) { base = parent.getValue(pos); } } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java index 3e30b536b..5b81c7f21 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringArray.java @@ -4,21 +4,24 @@ package org.roaringbitmap.buffer; +import static java.nio.ByteOrder.LITTLE_ENDIAN; import org.roaringbitmap.AppendableStorage; import org.roaringbitmap.InvalidRoaringFormat; import org.roaringbitmap.Util; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.LongBuffer; import java.util.Arrays; import java.util.NoSuchElementException; -import static java.nio.ByteOrder.LITTLE_ENDIAN; - - /** * Specialized array to store the containers used by a RoaringBitmap. This class is similar to * org.roaringbitmap.RoaringArray but meant to be used with memory mapping. This is not meant to be @@ -26,7 +29,10 @@ * * Objects of this class reside in RAM. */ -public final class MutableRoaringArray implements Cloneable, Externalizable, PointableRoaringArray, +public final class MutableRoaringArray + implements Cloneable, + Externalizable, + PointableRoaringArray, AppendableStorage { protected static final int INITIAL_CAPACITY = 4; @@ -38,7 +44,6 @@ public final class MutableRoaringArray implements Cloneable, Externalizable, Poi private static final long serialVersionUID = 5L; // TODO: OFK was 4L, not sure - char[] keys = null; MappeableContainer[] values = null; @@ -58,7 +63,6 @@ public MutableRoaringArray(int initialCapacity) { this.size = size; } - @Override public int advanceUntil(char x, int pos) { int lower = pos + 1; @@ -71,8 +75,7 @@ public int advanceUntil(char x, int pos) { int spansize = 1; // could set larger // bootstrap an upper limit - while (lower + spansize < size - && (keys[lower + spansize]) < (x)) { + while (lower + spansize < size && (keys[lower + spansize]) < (x)) { spansize *= 2; // hoping for compiler will reduce to shift } int upper = (lower + spansize < size) ? lower + spansize : size - 1; @@ -83,8 +86,8 @@ public int advanceUntil(char x, int pos) { return upper; } - if ((keys[upper]) < (x)) {// means array has no - // item key >= x + if ((keys[upper]) < (x)) { // means array has no + // item key >= x return size; } @@ -109,8 +112,7 @@ public int advanceUntil(char x, int pos) { @Override public void append(char key, MappeableContainer value) { if (size > 0 && key < keys[size - 1]) { - throw new IllegalArgumentException("append only: " + (key) - + " < " + (keys[size - 1])); + throw new IllegalArgumentException("append only: " + (key) + " < " + (keys[size - 1])); } extendArray(1); this.keys[this.size] = key; @@ -119,8 +121,7 @@ public void append(char key, MappeableContainer value) { } void append(MutableRoaringArray appendage) { - assert size == 0 || appendage.size == 0 - || keys[size - 1] < appendage.keys[0]; + assert size == 0 || appendage.size == 0 || keys[size - 1] < appendage.keys[0]; if (appendage.size != 0 && size != 0) { keys = Arrays.copyOf(keys, size + appendage.size); values = Arrays.copyOf(values, size + appendage.size); @@ -263,10 +264,12 @@ public void deserialize(DataInput in) throws IOException { if ((cookie & 0xFFFF) != SERIAL_COOKIE && cookie != SERIAL_COOKIE_NO_RUNCONTAINER) { throw new InvalidRoaringFormat("I failed to find a valid cookie."); } - this.size = ((cookie & 0xFFFF) == SERIAL_COOKIE) ? (cookie >>> 16) + 1 - : Integer.reverseBytes(in.readInt()); + this.size = + ((cookie & 0xFFFF) == SERIAL_COOKIE) + ? (cookie >>> 16) + 1 + : Integer.reverseBytes(in.readInt()); // logically we cannot have more than (1<<16) containers. - if(this.size > (1<<16)) { + if (this.size > (1 << 16)) { throw new InvalidRoaringFormat("Size too large"); } if ((this.keys == null) || (this.keys.length < this.size)) { @@ -355,7 +358,7 @@ public void deserialize(ByteBuffer bbf) { boolean hasRunContainers = (cookie & 0xFFFF) == SERIAL_COOKIE; this.size = hasRunContainers ? (cookie >>> 16) + 1 : buffer.getInt(); - if(this.size > (1<<16)) { + if (this.size > (1 << 16)) { throw new InvalidRoaringFormat("Size too large"); } if ((this.keys == null) || (this.keys.length < this.size)) { @@ -363,7 +366,6 @@ public void deserialize(ByteBuffer bbf) { this.values = new MappeableContainer[this.size]; } - byte[] bitmapOfRunContainers = null; boolean hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE; if (hasrun) { @@ -397,7 +399,7 @@ public void deserialize(ByteBuffer bbf) { container = new MappeableBitmapContainer(LongBuffer.wrap(array), cardinalities[k]); buffer.position(buffer.position() + 1024 * 8); } else if (bitmapOfRunContainers != null - && ((bitmapOfRunContainers[k / 8] & (1 << (k & 7))) != 0)) { + && ((bitmapOfRunContainers[k / 8] & (1 << (k & 7))) != 0)) { int nbrruns = (buffer.getChar()); int length = 2 * nbrruns; @@ -442,7 +444,6 @@ public int getContainerIndex(char x) { return this.binarySearch(0, size, x); } - @Override public MappeableContainer getContainerAtIndex(int i) { return this.values[i]; @@ -468,7 +469,7 @@ public MappeableContainerPointer clone() { try { return (MappeableContainerPointer) super.clone(); } catch (CloneNotSupportedException e) { - return null;// will not happen + return null; // will not happen } } @@ -516,16 +517,13 @@ public boolean isRunContainer() { @Override public char key() { return MutableRoaringArray.this.keys[k]; - } - @Override public void previous() { --k; } }; - } // involves a binary search @@ -547,17 +545,17 @@ public char getKeyAtIndex(int i) { @Override public boolean equals(Object o) { if (o instanceof ImmutableRoaringArray) { - ImmutableRoaringArray srb = (ImmutableRoaringArray)o; + ImmutableRoaringArray srb = (ImmutableRoaringArray) o; if (srb.size() != this.size()) { return false; } MappeableContainerPointer cp = this.getContainerPointer(); MappeableContainerPointer cpo = srb.getContainerPointer(); - while(cp.hasContainer() && cpo.hasContainer()) { - if(cp.key() != cpo.key()) { + while (cp.hasContainer() && cpo.hasContainer()) { + if (cp.key() != cpo.key()) { return false; } - if(!cp.getContainer().equals(cpo.getContainer())) { + if (!cp.getContainer().equals(cpo.getContainer())) { return false; } } @@ -587,10 +585,10 @@ public boolean hasRunCompression() { protected int headerSize() { if (hasRunCompression()) { - if (size < NO_OFFSET_THRESHOLD) {// for small bitmaps, we omit the offsets + if (size < NO_OFFSET_THRESHOLD) { // for small bitmaps, we omit the offsets return 4 + (size + 7) / 8 + 4 * size; } - return 4 + (size + 7) / 8 + 8 * size;// - 4 because we pack the size with the cookie + return 4 + (size + 7) / 8 + 8 * size; // - 4 because we pack the size with the cookie } else { return 4 + 4 + 8 * size; } @@ -619,7 +617,6 @@ protected void removeAtIndex(int i) { size--; } - protected void removeIndexRange(int begin, int end) { if (end <= begin) { return; @@ -639,7 +636,6 @@ protected void replaceKeyAndContainerAtIndex(int i, char key, MappeableContainer this.values[i] = c; } - protected void resize(int newLength) { Arrays.fill(this.keys, newLength, this.size, (char) 0); Arrays.fill(this.values, newLength, this.size, null); @@ -690,7 +686,6 @@ public void serialize(DataOutput out) throws IOException { for (int k = 0; k < size; ++k) { values[k].writeArray(out); } - } /** @@ -715,7 +710,7 @@ public void serialize(ByteBuffer buffer) { runMarker |= (1 << j); } } - buf.put((byte)runMarker); + buf.put((byte) runMarker); } int runMarkersLength = buf.position() - offset; if (this.size < NO_OFFSET_THRESHOLD) { @@ -777,10 +772,9 @@ public void writeExternal(ObjectOutput out) throws IOException { serialize(out); } - @Override public boolean containsForContainerAtIndex(int i, char x) { - return getContainerAtIndex(i).contains(x);// no faster way + return getContainerAtIndex(i).contains(x); // no faster way } @Override @@ -828,5 +822,4 @@ private void assertNonEmpty() { throw new NoSuchElementException("Empty MutableRoaringArray"); } } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java index 728945533..923a10b95 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java @@ -4,11 +4,20 @@ package org.roaringbitmap.buffer; -import org.roaringbitmap.*; - -import java.io.*; +import org.roaringbitmap.AppendableStorage; +import org.roaringbitmap.BitmapDataProvider; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.ContainerPointer; +import org.roaringbitmap.InvalidRoaringFormat; +import org.roaringbitmap.RoaringBitmap; + +import java.io.DataInput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; import java.nio.ByteBuffer; -import java.nio.CharBuffer; import java.util.Iterator; /** @@ -62,8 +71,12 @@ * @see org.roaringbitmap.RoaringBitmap */ public class MutableRoaringBitmap extends ImmutableRoaringBitmap - implements Cloneable, Serializable, Iterable, Externalizable, - BitmapDataProvider, AppendableStorage { + implements Cloneable, + Serializable, + Iterable, + Externalizable, + BitmapDataProvider, + AppendableStorage { private static final long serialVersionUID = 4L; // 3L; bumped by ofk for runcontainers /** @@ -84,56 +97,53 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap public static MutableRoaringBitmap addOffset(final ImmutableRoaringBitmap x, long offset) { // we need "offset" to be a long because we want to support values // between -0xFFFFFFFF up to +-0xFFFFFFFF - long container_offset_long = offset < 0 - ? (offset - (1<<16) + 1) / (1<<16) : offset / (1 << 16); - if((container_offset_long < -(1<<16) ) || (container_offset_long >= (1<<16) )) { + long container_offset_long = + offset < 0 ? (offset - (1 << 16) + 1) / (1 << 16) : offset / (1 << 16); + if ((container_offset_long < -(1 << 16)) || (container_offset_long >= (1 << 16))) { return new MutableRoaringBitmap(); // it is necessarily going to be empty } // next cast is necessarily safe, the result is between -0xFFFF and 0xFFFF int container_offset = (int) container_offset_long; // next case is safe - int in_container_offset = (int)(offset - container_offset_long * (1L<<16)); - if(in_container_offset == 0) { + int in_container_offset = (int) (offset - container_offset_long * (1L << 16)); + if (in_container_offset == 0) { MutableRoaringBitmap answer = new MutableRoaringBitmap(); - for(int pos = 0; pos < x.highLowContainer.size(); pos++) { + for (int pos = 0; pos < x.highLowContainer.size(); pos++) { int key = (x.highLowContainer.getKeyAtIndex(pos)); key += container_offset; - answer.getMappeableRoaringArray().append((char)key, - x.highLowContainer.getContainerAtIndex(pos).clone()); + answer + .getMappeableRoaringArray() + .append((char) key, x.highLowContainer.getContainerAtIndex(pos).clone()); } return answer; } else { MutableRoaringBitmap answer = new MutableRoaringBitmap(); - for(int pos = 0; pos < x.highLowContainer.size(); pos++) { + for (int pos = 0; pos < x.highLowContainer.size(); pos++) { int key = (x.highLowContainer.getKeyAtIndex(pos)); key += container_offset; if (key + 1 < 0 || key > 0xFFFF) { continue; } MappeableContainer c = x.highLowContainer.getContainerAtIndex(pos); - MappeableContainer[] offsetted = BufferUtil.addOffset(c, - (char)in_container_offset); + MappeableContainer[] offsetted = BufferUtil.addOffset(c, (char) in_container_offset); boolean keyok = key >= 0; boolean keypok = key + 1 <= 0xFFFF; - if( !offsetted[0].isEmpty() && keyok) { + if (!offsetted[0].isEmpty() && keyok) { int current_size = answer.highLowContainer.size(); int lastkey = 0; - if(current_size > 0) { - lastkey = (answer.highLowContainer.getKeyAtIndex( - current_size - 1)); + if (current_size > 0) { + lastkey = (answer.highLowContainer.getKeyAtIndex(current_size - 1)); } - if((current_size > 0) && (lastkey == key)) { - MappeableContainer prev = answer.highLowContainer - .getContainerAtIndex(current_size - 1); + if ((current_size > 0) && (lastkey == key)) { + MappeableContainer prev = answer.highLowContainer.getContainerAtIndex(current_size - 1); MappeableContainer orresult = prev.ior(offsetted[0]); - answer.getMappeableRoaringArray().setContainerAtIndex(current_size - 1, - orresult); + answer.getMappeableRoaringArray().setContainerAtIndex(current_size - 1, orresult); } else { - answer.getMappeableRoaringArray().append((char)key, offsetted[0]); + answer.getMappeableRoaringArray().append((char) key, offsetted[0]); } } - if( !offsetted[1].isEmpty() && keypok) { - answer.getMappeableRoaringArray().append((char)(key + 1), offsetted[1]); + if (!offsetted[1].isEmpty() && keypok) { + answer.getMappeableRoaringArray().append((char) (key + 1), offsetted[1]); } } answer.repairAfterLazy(); @@ -149,9 +159,9 @@ public static MutableRoaringBitmap addOffset(final ImmutableRoaringBitmap x, lon * @param rangeEnd exclusive ending of range * @return new bitmap */ - public static MutableRoaringBitmap add(MutableRoaringBitmap rb, final long rangeStart, - final long rangeEnd) { - rangeSanityCheck(rangeStart,rangeEnd); + public static MutableRoaringBitmap add( + MutableRoaringBitmap rb, final long rangeStart, final long rangeEnd) { + rangeSanityCheck(rangeStart, rangeEnd); if (rangeStart >= rangeEnd) { return rb.clone(); // empty range } @@ -162,27 +172,30 @@ public static MutableRoaringBitmap add(MutableRoaringBitmap rb, final long range final int lbLast = (BufferUtil.lowbits(rangeEnd - 1)); MutableRoaringBitmap answer = new MutableRoaringBitmap(); - ((MutableRoaringArray) answer.highLowContainer).appendCopiesUntil(rb.highLowContainer, - (char) hbStart); + ((MutableRoaringArray) answer.highLowContainer) + .appendCopiesUntil(rb.highLowContainer, (char) hbStart); if (hbStart == hbLast) { final int i = rb.highLowContainer.getIndex((char) hbStart); final MappeableContainer c = - i >= 0 ? rb.highLowContainer.getContainerAtIndex(i).add(lbStart, lbLast + 1) + i >= 0 + ? rb.highLowContainer.getContainerAtIndex(i).add(lbStart, lbLast + 1) : MappeableContainer.rangeOfOnes(lbStart, lbLast + 1); ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); - ((MutableRoaringArray) answer.highLowContainer).appendCopiesAfter(rb.highLowContainer, - (char) hbLast); + ((MutableRoaringArray) answer.highLowContainer) + .appendCopiesAfter(rb.highLowContainer, (char) hbLast); return answer; } int ifirst = rb.highLowContainer.getIndex((char) hbStart); int ilast = rb.highLowContainer.getIndex((char) hbLast); { - final MappeableContainer c = ifirst >= 0 - ? rb.highLowContainer.getContainerAtIndex(ifirst).add(lbStart, - BufferUtil.maxLowBitAsInteger() + 1) - : MappeableContainer.rangeOfOnes(lbStart, BufferUtil.maxLowBitAsInteger() + 1); + final MappeableContainer c = + ifirst >= 0 + ? rb.highLowContainer + .getContainerAtIndex(ifirst) + .add(lbStart, BufferUtil.maxLowBitAsInteger() + 1) + : MappeableContainer.rangeOfOnes(lbStart, BufferUtil.maxLowBitAsInteger() + 1); ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); } for (int hb = hbStart + 1; hb < hbLast; ++hb) { @@ -191,12 +204,13 @@ public static MutableRoaringBitmap add(MutableRoaringBitmap rb, final long range } { final MappeableContainer c = - ilast >= 0 ? rb.highLowContainer.getContainerAtIndex(ilast).add(0, lbLast + 1) + ilast >= 0 + ? rb.highLowContainer.getContainerAtIndex(ilast).add(0, lbLast + 1) : MappeableContainer.rangeOfOnes(0, lbLast + 1); ((MutableRoaringArray) answer.highLowContainer).append((char) hbLast, c); } - ((MutableRoaringArray) answer.highLowContainer).appendCopiesAfter(rb.highLowContainer, - (char) hbLast); + ((MutableRoaringArray) answer.highLowContainer) + .appendCopiesAfter(rb.highLowContainer, (char) hbLast); return answer; } @@ -211,8 +225,8 @@ public static MutableRoaringBitmap add(MutableRoaringBitmap rb, final long range * @deprecated use the version where longs specify the range */ @Deprecated - public static MutableRoaringBitmap add(MutableRoaringBitmap rb, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap add( + MutableRoaringBitmap rb, final int rangeStart, final int rangeEnd) { if (rangeStart >= 0) { return add(rb, (long) rangeStart, (long) rangeEnd); } @@ -221,9 +235,6 @@ public static MutableRoaringBitmap add(MutableRoaringBitmap rb, return add(rb, rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - - - /** * Bitwise AND (intersection) operation. The provided bitmaps are *not* modified. This operation * is thread-safe as long as the provided bitmaps remain unchanged. @@ -232,8 +243,8 @@ public static MutableRoaringBitmap add(MutableRoaringBitmap rb, * @param x2 other bitmap * @return result of the operation */ - public static MutableRoaringBitmap and(final MutableRoaringBitmap x1, - final MutableRoaringBitmap x2) { + public static MutableRoaringBitmap and( + final MutableRoaringBitmap x1, final MutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); @@ -268,8 +279,8 @@ public static MutableRoaringBitmap and(final MutableRoaringBitmap x1, * @param x2 other bitmap * @return result of the operation */ - public static MutableRoaringBitmap andNot(final MutableRoaringBitmap x1, - final MutableRoaringBitmap x2) { + public static MutableRoaringBitmap andNot( + final MutableRoaringBitmap x1, final MutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); @@ -325,13 +336,13 @@ public void add(final int... dat) { */ public void addN(final int[] dat, final int offset, final int n) { // let us validate the values first. - if((n < 0) || (offset < 0)) { + if ((n < 0) || (offset < 0)) { throw new IllegalArgumentException("Negative values do not make sense."); } - if(n == 0) { + if (n == 0) { return; // nothing to do } - if(offset + n > dat.length) { + if (offset + n > dat.length) { throw new IllegalArgumentException("Data source is too small."); } MutableRoaringArray mra = (MutableRoaringArray) highLowContainer; @@ -344,24 +355,24 @@ public void addN(final int[] dat, final int offset, final int n) { if (currentcontainerindex >= 0) { currentcont = highLowContainer.getContainerAtIndex(currentcontainerindex); MappeableContainer newcont = currentcont.add(BufferUtil.lowbits(val)); - if(newcont != currentcont) { + if (newcont != currentcont) { mra.setContainerAtIndex(currentcontainerindex, newcont); currentcont = newcont; } } else { - currentcontainerindex = - currentcontainerindex - 1; + currentcontainerindex = -currentcontainerindex - 1; final MappeableArrayContainer newac = new MappeableArrayContainer(); currentcont = newac.add(BufferUtil.lowbits(val)); mra.insertNewKeyValueAt(currentcontainerindex, currenthb, currentcont); } j++; - for( ; j < n; ++j) { + for (; j < n; ++j) { val = dat[j + offset]; char newhb = BufferUtil.highbits(val); - if(currenthb == newhb) {// easy case + if (currenthb == newhb) { // easy case // this could be quite frequent MappeableContainer newcont = currentcont.add(BufferUtil.lowbits(val)); - if(newcont != currentcont) { + if (newcont != currentcont) { mra.setContainerAtIndex(currentcontainerindex, newcont); currentcont = newcont; } @@ -371,12 +382,12 @@ public void addN(final int[] dat, final int offset, final int n) { if (currentcontainerindex >= 0) { currentcont = highLowContainer.getContainerAtIndex(currentcontainerindex); MappeableContainer newcont = currentcont.add(BufferUtil.lowbits(val)); - if(newcont != currentcont) { + if (newcont != currentcont) { mra.setContainerAtIndex(currentcontainerindex, newcont); currentcont = newcont; } } else { - currentcontainerindex = - currentcontainerindex - 1; + currentcontainerindex = -currentcontainerindex - 1; final MappeableArrayContainer newac = new MappeableArrayContainer(); currentcont = newac.add(BufferUtil.lowbits(val)); mra.insertNewKeyValueAt(currentcontainerindex, currenthb, currentcont); @@ -399,7 +410,6 @@ public static MutableRoaringBitmap bitmapOf(final int... dat) { return ans; } - /** * @see #add(long, long) */ @@ -422,7 +432,7 @@ public static MutableRoaringBitmap bitmapOfRange(long min, long max) { if (hbStart < hbLast) { int i = hbStart + 1; while (i < hbLast) { - MappeableContainer runContainer = MappeableContainer. rangeOfOnes(0, 1 << 16); + MappeableContainer runContainer = MappeableContainer.rangeOfOnes(0, 1 << 16); bitmap.append((char) i, runContainer); i++; } @@ -433,13 +443,13 @@ public static MutableRoaringBitmap bitmapOfRange(long min, long max) { } protected static void rangeSanityCheck(final long rangeStart, final long rangeEnd) { - if (rangeStart < 0 || rangeStart > (1L << 32)-1) { - throw new IllegalArgumentException("rangeStart="+ rangeStart - +" should be in [0, 0xffffffff]"); + if (rangeStart < 0 || rangeStart > (1L << 32) - 1) { + throw new IllegalArgumentException( + "rangeStart=" + rangeStart + " should be in [0, 0xffffffff]"); } if (rangeEnd > (1L << 32) || rangeEnd < 0) { - throw new IllegalArgumentException("rangeEnd="+ rangeEnd - +" should be in [0, 0xffffffff + 1]"); + throw new IllegalArgumentException( + "rangeEnd=" + rangeEnd + " should be in [0, 0xffffffff + 1]"); } } @@ -452,8 +462,8 @@ protected static void rangeSanityCheck(final long rangeStart, final long rangeEn * @param rangeEnd exclusive ending of range * @return a new Bitmap */ - public static MutableRoaringBitmap flip(MutableRoaringBitmap bm, final long rangeStart, - final long rangeEnd) { + public static MutableRoaringBitmap flip( + MutableRoaringBitmap bm, final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); if (rangeStart >= rangeEnd) { return bm.clone(); @@ -465,7 +475,6 @@ public static MutableRoaringBitmap flip(MutableRoaringBitmap bm, final long rang final int hbLast = (BufferUtil.highbits(rangeEnd - 1)); final int lbLast = (BufferUtil.lowbits(rangeEnd - 1)); - // copy the containers before the active area answer.getMappeableRoaringArray().appendCopiesUntil(bm.highLowContainer, (char) hbStart); @@ -486,8 +495,12 @@ public static MutableRoaringBitmap flip(MutableRoaringBitmap bm, final long rang } else { // *think* the range of ones must never be // empty. - answer.getMappeableRoaringArray().insertNewKeyValueAt(-j - 1, (char) hb, - MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); + answer + .getMappeableRoaringArray() + .insertNewKeyValueAt( + -j - 1, + (char) hb, + MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); } } // copy the containers after the active area. @@ -496,7 +509,6 @@ public static MutableRoaringBitmap flip(MutableRoaringBitmap bm, final long rang return answer; } - /** * Complements the bits in the given range, from rangeStart (inclusive) rangeEnd (exclusive). The * given bitmap is unchanged. @@ -508,8 +520,8 @@ public static MutableRoaringBitmap flip(MutableRoaringBitmap bm, final long rang * @deprecated use the version where longs specify the range */ @Deprecated - public static MutableRoaringBitmap flip(MutableRoaringBitmap rb, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap flip( + MutableRoaringBitmap rb, final int rangeStart, final int rangeEnd) { if (rangeStart >= 0) { return flip(rb, (long) rangeStart, (long) rangeEnd); } @@ -519,12 +531,13 @@ public static MutableRoaringBitmap flip(MutableRoaringBitmap rb, } // important: inputs should not have been computed lazily - protected static MutableRoaringBitmap lazyorfromlazyinputs(final MutableRoaringBitmap x1, - final MutableRoaringBitmap x2) { + protected static MutableRoaringBitmap lazyorfromlazyinputs( + final MutableRoaringBitmap x1, final MutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); MappeableContainerPointer i1 = x1.highLowContainer.getContainerPointer(); MappeableContainerPointer i2 = x2.highLowContainer.getContainerPointer(); - main: if (i1.hasContainer() && i2.hasContainer()) { + main: + if (i1.hasContainer() && i2.hasContainer()) { while (true) { if (i1.key() == i2.key()) { MappeableContainer c1 = i1.getContainer(); @@ -591,19 +604,25 @@ public static MutableRoaringBitmap or(ImmutableRoaringBitmap... bitmaps) { * @param x2 other bitmap * @return result of the operation */ - public static MutableRoaringBitmap or(final MutableRoaringBitmap x1, - final MutableRoaringBitmap x2) { + public static MutableRoaringBitmap or( + final MutableRoaringBitmap x1, final MutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = x1.highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - answer.getMappeableRoaringArray().append(s1, x1.highLowContainer.getContainerAtIndex(pos1) - .or(x2.highLowContainer.getContainerAtIndex(pos2))); + answer + .getMappeableRoaringArray() + .append( + s1, + x1.highLowContainer + .getContainerAtIndex(pos1) + .or(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -612,16 +631,22 @@ public static MutableRoaringBitmap or(final MutableRoaringBitmap x1, s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); } else if (s1 < s2) { - answer.getMappeableRoaringArray().appendCopy(x1.highLowContainer.getKeyAtIndex(pos1), - x1.highLowContainer.getContainerAtIndex(pos1)); + answer + .getMappeableRoaringArray() + .appendCopy( + x1.highLowContainer.getKeyAtIndex(pos1), + x1.highLowContainer.getContainerAtIndex(pos1)); pos1++; if (pos1 == length1) { break main; } s1 = x1.highLowContainer.getKeyAtIndex(pos1); } else { // s1 > s2 - answer.getMappeableRoaringArray().appendCopy(x2.highLowContainer.getKeyAtIndex(pos2), - x2.highLowContainer.getContainerAtIndex(pos2)); + answer + .getMappeableRoaringArray() + .appendCopy( + x2.highLowContainer.getKeyAtIndex(pos2), + x2.highLowContainer.getContainerAtIndex(pos2)); pos2++; if (pos2 == length2) { break main; @@ -646,8 +671,8 @@ public static MutableRoaringBitmap or(final MutableRoaringBitmap x1, * @param rangeEnd exclusive ending of range * @return new bitmap */ - public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, final long rangeStart, - final long rangeEnd) { + public static MutableRoaringBitmap remove( + MutableRoaringBitmap rb, final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); if (rangeStart >= rangeEnd) { return rb.clone(); // empty range @@ -657,8 +682,8 @@ public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, final long ra final int hbLast = (BufferUtil.highbits(rangeEnd - 1)); final int lbLast = (BufferUtil.lowbits(rangeEnd - 1)); MutableRoaringBitmap answer = new MutableRoaringBitmap(); - ((MutableRoaringArray) answer.highLowContainer).appendCopiesUntil(rb.highLowContainer, - (char) hbStart); + ((MutableRoaringArray) answer.highLowContainer) + .appendCopiesUntil(rb.highLowContainer, (char) hbStart); if (hbStart == hbLast) { final int i = rb.highLowContainer.getIndex((char) hbStart); @@ -669,15 +694,17 @@ public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, final long ra ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); } } - ((MutableRoaringArray) answer.highLowContainer).appendCopiesAfter(rb.highLowContainer, - (char) hbLast); + ((MutableRoaringArray) answer.highLowContainer) + .appendCopiesAfter(rb.highLowContainer, (char) hbLast); return answer; } int ifirst = rb.highLowContainer.getIndex((char) hbStart); int ilast = rb.highLowContainer.getIndex((char) hbLast); if ((ifirst >= 0) && (lbStart != 0)) { - final MappeableContainer c = rb.highLowContainer.getContainerAtIndex(ifirst).remove(lbStart, - BufferUtil.maxLowBitAsInteger() + 1); + final MappeableContainer c = + rb.highLowContainer + .getContainerAtIndex(ifirst) + .remove(lbStart, BufferUtil.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { ((MutableRoaringArray) answer.highLowContainer).append((char) hbStart, c); } @@ -689,8 +716,8 @@ public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, final long ra ((MutableRoaringArray) answer.highLowContainer).append((char) hbLast, c); } } - ((MutableRoaringArray) answer.highLowContainer).appendCopiesAfter(rb.highLowContainer, - (char) hbLast); + ((MutableRoaringArray) answer.highLowContainer) + .appendCopiesAfter(rb.highLowContainer, (char) hbLast); return answer; } @@ -704,8 +731,8 @@ public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, final long ra * @deprecated use the version where longs specify the range */ @Deprecated - public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, - final int rangeStart, final int rangeEnd) { + public static MutableRoaringBitmap remove( + MutableRoaringBitmap rb, final int rangeStart, final int rangeEnd) { if (rangeStart >= 0) { return remove(rb, (long) rangeStart, (long) rangeEnd); } @@ -714,7 +741,6 @@ public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, return remove(rb, rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - /** * Bitwise XOR (symmetric difference) operation. The provided bitmaps are *not* modified. This * operation is thread-safe as long as the provided bitmaps remain unchanged. @@ -723,20 +749,23 @@ public static MutableRoaringBitmap remove(MutableRoaringBitmap rb, * @param x2 other bitmap * @return result of the operation */ - public static MutableRoaringBitmap xor(final MutableRoaringBitmap x1, - final MutableRoaringBitmap x2) { + public static MutableRoaringBitmap xor( + final MutableRoaringBitmap x1, final MutableRoaringBitmap x2) { final MutableRoaringBitmap answer = new MutableRoaringBitmap(); int pos1 = 0, pos2 = 0; final int length1 = x1.highLowContainer.size(), length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = x1.highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - final MappeableContainer c = x1.highLowContainer.getContainerAtIndex(pos1) - .xor(x2.highLowContainer.getContainerAtIndex(pos2)); + final MappeableContainer c = + x1.highLowContainer + .getContainerAtIndex(pos1) + .xor(x2.highLowContainer.getContainerAtIndex(pos2)); if (!c.isEmpty()) { answer.getMappeableRoaringArray().append(s1, c); } @@ -748,16 +777,22 @@ public static MutableRoaringBitmap xor(final MutableRoaringBitmap x1, s1 = x1.highLowContainer.getKeyAtIndex(pos1); s2 = x2.highLowContainer.getKeyAtIndex(pos2); } else if (s1 < s2) { - answer.getMappeableRoaringArray().appendCopy(x1.highLowContainer.getKeyAtIndex(pos1), - x1.highLowContainer.getContainerAtIndex(pos1)); + answer + .getMappeableRoaringArray() + .appendCopy( + x1.highLowContainer.getKeyAtIndex(pos1), + x1.highLowContainer.getContainerAtIndex(pos1)); pos1++; if (pos1 == length1) { break main; } s1 = x1.highLowContainer.getKeyAtIndex(pos1); } else if (s1 - s2 > 0) { - answer.getMappeableRoaringArray().appendCopy(x2.highLowContainer.getKeyAtIndex(pos2), - x2.highLowContainer.getContainerAtIndex(pos2)); + answer + .getMappeableRoaringArray() + .appendCopy( + x2.highLowContainer.getKeyAtIndex(pos2), + x2.highLowContainer.getContainerAtIndex(pos2)); pos2++; if (pos2 == length2) { break main; @@ -794,8 +829,8 @@ public MutableRoaringBitmap(RoaringBitmap rb) { highLowContainer = new MutableRoaringArray(); ContainerPointer cp = rb.getContainerPointer(); while (cp.getContainer() != null) { - ((MutableRoaringArray) highLowContainer).append(cp.key(), - cp.getContainer().toMappeableContainer()); + ((MutableRoaringArray) highLowContainer) + .append(cp.key(), cp.getContainer().toMappeableContainer()); cp.advance(); } } @@ -814,8 +849,9 @@ public void add(final int x) { final char hb = BufferUtil.highbits(x); final int i = highLowContainer.getIndex(hb); if (i >= 0) { - getMappeableRoaringArray().setContainerAtIndex(i, - highLowContainer.getContainerAtIndex(i).add(BufferUtil.lowbits(x))); + getMappeableRoaringArray() + .setContainerAtIndex( + i, highLowContainer.getContainerAtIndex(i).add(BufferUtil.lowbits(x))); } else { final MappeableArrayContainer newac = new MappeableArrayContainer(); getMappeableRoaringArray().insertNewKeyValueAt(-i - 1, hb, newac.add(BufferUtil.lowbits(x))); @@ -851,13 +887,16 @@ public void add(final long rangeStart, final long rangeEnd) { highLowContainer.getContainerAtIndex(i).iadd(containerStart, containerLast + 1); ((MutableRoaringArray) highLowContainer).setContainerAtIndex(i, c); } else { - ((MutableRoaringArray) highLowContainer).insertNewKeyValueAt(-i - 1, (char) hb, - MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); + ((MutableRoaringArray) highLowContainer) + .insertNewKeyValueAt( + -i - 1, + (char) hb, + MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); } } } - /** + /** * * Add to the current bitmap all integers in [rangeStart,rangeEnd). * @@ -875,16 +914,15 @@ public void add(final int rangeStart, final int rangeEnd) { add(rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - - - /** * In-place bitwise AND (intersection) operation. The current bitmap is modified. * * @param array other bitmap */ public void and(final ImmutableRoaringBitmap array) { - if(array == this) { return; } + if (array == this) { + return; + } int pos1 = 0, pos2 = 0, intersectionSize = 0; final int length1 = highLowContainer.size(), length2 = array.highLowContainer.size(); @@ -909,14 +947,13 @@ public void and(final ImmutableRoaringBitmap array) { getMappeableRoaringArray().resize(intersectionSize); } - /** * In-place bitwise ANDNOT (difference) operation. The current bitmap is modified. * * @param x2 other bitmap */ public void andNot(final ImmutableRoaringBitmap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -960,12 +997,12 @@ public void andNot(final ImmutableRoaringBitmap x2) { * @param rangeEnd end point of the range (exclusive). */ public void orNot(ImmutableRoaringBitmap other, long rangeEnd) { - if(other == this) { + if (other == this) { throw new UnsupportedOperationException("orNot between a bitmap and itself?"); } rangeSanityCheck(0, rangeEnd); - int maxKey = (int)((rangeEnd - 1) >>> 16); - int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int)(rangeEnd & 0xFFFF); + int maxKey = (int) ((rangeEnd - 1) >>> 16); + int lastRun = (rangeEnd & 0xFFFF) == 0 ? 0x10000 : (int) (rangeEnd & 0xFFFF); int size = 0; int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(), length2 = other.highLowContainer.size(); @@ -973,8 +1010,8 @@ public void orNot(ImmutableRoaringBitmap other, long rangeEnd) { int s2 = length2 > 0 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; int remainder = 0; for (int i = highLowContainer.size() - 1; - i >= 0 && highLowContainer.getKeyAtIndex(i) > maxKey; - --i) { + i >= 0 && highLowContainer.getKeyAtIndex(i) > maxKey; + --i) { ++remainder; } int correction = 0; @@ -986,8 +1023,7 @@ public void orNot(ImmutableRoaringBitmap other, long rangeEnd) { } // it's almost certain that the bitmap will grow, so make a conservative overestimate, // this avoids temporary allocation, and can trim afterwards - int maxSize = Math.min(maxKey + 1 + remainder - correction - + highLowContainer.size(), 0x10000); + int maxSize = Math.min(maxKey + 1 + remainder - correction + highLowContainer.size(), 0x10000); if (maxSize == 0) { return; } @@ -995,27 +1031,36 @@ public void orNot(ImmutableRoaringBitmap other, long rangeEnd) { MappeableContainer[] newValues = new MappeableContainer[maxSize]; for (int key = 0; key <= maxKey && size < maxSize; ++key) { if (key == s1 && key == s2) { // actually need to do an or not - newValues[size] = highLowContainer.getContainerAtIndex(pos1) - .iorNot(other.highLowContainer.getContainerAtIndex(pos2), - key == maxKey ? lastRun : 0x10000); + newValues[size] = + highLowContainer + .getContainerAtIndex(pos1) + .iorNot( + other.highLowContainer.getContainerAtIndex(pos2), + key == maxKey ? lastRun : 0x10000); ++pos1; ++pos2; s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; s2 = pos2 < length2 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else if (key == s1) { // or in a hole - newValues[size] = key == maxKey - ? highLowContainer.getContainerAtIndex(pos1).ior( - MappeableRunContainer.rangeOfOnes(0, lastRun)) - : MappeableRunContainer.full(); + newValues[size] = + key == maxKey + ? highLowContainer + .getContainerAtIndex(pos1) + .ior(MappeableRunContainer.rangeOfOnes(0, lastRun)) + : MappeableRunContainer.full(); ++pos1; s1 = pos1 < length1 ? highLowContainer.getKeyAtIndex(pos1) : maxKey + 1; } else if (key == s2) { // insert the complement - newValues[size] = other.highLowContainer.getContainerAtIndex(pos2) + newValues[size] = + other + .highLowContainer + .getContainerAtIndex(pos2) .not(0, key == maxKey ? lastRun : 0x10000); ++pos2; s2 = pos2 < length2 ? other.highLowContainer.getKeyAtIndex(pos2) : maxKey + 1; } else { // key missing from both - newValues[size] = key == maxKey + newValues[size] = + key == maxKey ? MappeableRunContainer.rangeOfOnes(0, lastRun) : MappeableRunContainer.full(); } @@ -1023,25 +1068,30 @@ public void orNot(ImmutableRoaringBitmap other, long rangeEnd) { if (newValues[size].isEmpty()) { newValues[size] = null; } else { - newKeys[size] = (char)key; + newKeys[size] = (char) key; ++size; } } // copy over everything which will remain without being complemented if (remainder > 0) { - System.arraycopy(((MutableRoaringArray)highLowContainer).keys, - highLowContainer.size() - remainder, - newKeys, size, remainder); - System.arraycopy(((MutableRoaringArray)highLowContainer).values, - highLowContainer.size() - remainder, - newValues, size, remainder); - } - ((MutableRoaringArray)highLowContainer).keys = newKeys; - ((MutableRoaringArray)highLowContainer).values = newValues; - ((MutableRoaringArray)highLowContainer).size = size + remainder; + System.arraycopy( + ((MutableRoaringArray) highLowContainer).keys, + highLowContainer.size() - remainder, + newKeys, + size, + remainder); + System.arraycopy( + ((MutableRoaringArray) highLowContainer).values, + highLowContainer.size() - remainder, + newValues, + size, + remainder); + } + ((MutableRoaringArray) highLowContainer).keys = newKeys; + ((MutableRoaringArray) highLowContainer).values = newValues; + ((MutableRoaringArray) highLowContainer).size = size + remainder; } - /** * Add the value to the container (set the value to "true"), whether it already appears or not. * @@ -1114,7 +1164,6 @@ public MutableRoaringBitmap clone() { final MutableRoaringBitmap x = (MutableRoaringBitmap) super.clone(); x.highLowContainer = highLowContainer.clone(); return x; - } /** @@ -1128,12 +1177,11 @@ public MutableRoaringBitmap clone() { public void deserialize(DataInput in) throws IOException { try { getMappeableRoaringArray().deserialize(in); - } catch(InvalidRoaringFormat cookie) { - throw cookie.toIOException();// we convert it to an IOException + } catch (InvalidRoaringFormat cookie) { + throw cookie.toIOException(); // we convert it to an IOException } } - /** * Deserialize (retrieve) this bitmap. * See format specification at https://github.com/RoaringBitmap/RoaringFormatSpec @@ -1155,8 +1203,8 @@ public void deserialize(DataInput in) throws IOException { public void deserialize(ByteBuffer buffer) throws IOException { try { getMappeableRoaringArray().deserialize(buffer); - } catch(InvalidRoaringFormat cookie) { - throw cookie.toIOException();// we convert it to an IOException + } catch (InvalidRoaringFormat cookie) { + throw cookie.toIOException(); // we convert it to an IOException } } @@ -1178,13 +1226,11 @@ public void flip(final int x) { } } else { final MappeableArrayContainer newac = new MappeableArrayContainer(); - ((MutableRoaringArray) highLowContainer).insertNewKeyValueAt(-i - 1, hb, - newac.add(BufferUtil.lowbits(x))); + ((MutableRoaringArray) highLowContainer) + .insertNewKeyValueAt(-i - 1, hb, newac.add(BufferUtil.lowbits(x))); } } - - /** * Modifies the current bitmap by complementing the bits in the given range, from rangeStart * (inclusive) rangeEnd (exclusive). @@ -1192,7 +1238,7 @@ public void flip(final int x) { * @param rangeStart inclusive beginning of range * @param rangeEnd exclusive ending of range */ - public void flip(final long rangeStart, final long rangeEnd) { + public void flip(final long rangeStart, final long rangeEnd) { rangeSanityCheck(rangeStart, rangeEnd); if (rangeStart >= rangeEnd) { return; // empty range @@ -1219,14 +1265,16 @@ public void flip(final long rangeStart, final long rangeEnd) { getMappeableRoaringArray().removeAtIndex(i); } } else { - getMappeableRoaringArray().insertNewKeyValueAt(-i - 1, (char) hb, - MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); + getMappeableRoaringArray() + .insertNewKeyValueAt( + -i - 1, + (char) hb, + MappeableContainer.rangeOfOnes(containerStart, containerLast + 1)); } } } - - /** + /** * Modifies the current bitmap by complementing the bits in the given range, from rangeStart * (inclusive) rangeEnd (exclusive). * @@ -1245,9 +1293,6 @@ public void flip(final int rangeStart, final int rangeEnd) { } } - - - /** * @return a mutable copy of this bitmap */ @@ -1278,8 +1323,8 @@ public boolean hasNext() { private Iterator init() { if (pos < MutableRoaringBitmap.this.highLowContainer.size()) { - iter = MutableRoaringBitmap.this.highLowContainer.getContainerAtIndex(pos) - .getCharIterator(); + iter = + MutableRoaringBitmap.this.highLowContainer.getContainerAtIndex(pos).getCharIterator(); hs = (MutableRoaringBitmap.this.highLowContainer.getKeyAtIndex(pos)) << 16; } return this; @@ -1297,28 +1342,34 @@ public Integer next() { @Override public void remove() { - // todo: implement + // todo: implement throw new UnsupportedOperationException(); } - }.init(); } // call repairAfterLazy on result, eventually // important: x2 should not have been computed lazily protected void lazyor(final ImmutableRoaringBitmap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - getMappeableRoaringArray().setContainerAtIndex(pos1, highLowContainer - .getContainerAtIndex(pos1).lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); + getMappeableRoaringArray() + .setContainerAtIndex( + pos1, + highLowContainer + .getContainerAtIndex(pos1) + .lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -1333,8 +1384,8 @@ protected void lazyor(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { // s1 > s2 - getMappeableRoaringArray().insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + getMappeableRoaringArray() + .insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -1355,20 +1406,23 @@ protected void lazyor(final ImmutableRoaringBitmap x2) { // this method is like lazyor except that it will convert // the current container to a bitset protected void naivelazyor(final ImmutableRoaringBitmap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - MappeableBitmapContainer c1 = highLowContainer.getContainerAtIndex(pos1) - .toBitmapContainer(); - getMappeableRoaringArray().setContainerAtIndex(pos1, - c1.lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); + MappeableBitmapContainer c1 = + highLowContainer.getContainerAtIndex(pos1).toBitmapContainer(); + getMappeableRoaringArray() + .setContainerAtIndex(pos1, c1.lazyIOR(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -1383,8 +1437,8 @@ protected void naivelazyor(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { // s1 > s2 - getMappeableRoaringArray().insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + getMappeableRoaringArray() + .insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -1400,27 +1454,31 @@ protected void naivelazyor(final ImmutableRoaringBitmap x2) { } } - - - /** * In-place bitwise OR (union) operation. The current bitmap is modified. * * @param x2 other bitmap */ public void or(final ImmutableRoaringBitmap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } int pos1 = 0, pos2 = 0; int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - getMappeableRoaringArray().setContainerAtIndex(pos1, highLowContainer - .getContainerAtIndex(pos1).ior(x2.highLowContainer.getContainerAtIndex(pos2))); + getMappeableRoaringArray() + .setContainerAtIndex( + pos1, + highLowContainer + .getContainerAtIndex(pos1) + .ior(x2.highLowContainer.getContainerAtIndex(pos2))); pos1++; pos2++; if ((pos1 == length1) || (pos2 == length2)) { @@ -1435,8 +1493,8 @@ public void or(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { // s1 > s2 - getMappeableRoaringArray().insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + getMappeableRoaringArray() + .insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; @@ -1452,15 +1510,11 @@ public void or(final ImmutableRoaringBitmap x2) { } } - - @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { getMappeableRoaringArray().readExternal(in); - } - /** * If present remove the specified integers (effectively, sets its bit value to false) * @@ -1473,8 +1527,9 @@ public void remove(final int x) { if (i < 0) { return; } - getMappeableRoaringArray().setContainerAtIndex(i, - highLowContainer.getContainerAtIndex(i).remove(BufferUtil.lowbits(x))); + getMappeableRoaringArray() + .setContainerAtIndex( + i, highLowContainer.getContainerAtIndex(i).remove(BufferUtil.lowbits(x))); if (highLowContainer.getContainerAtIndex(i).isEmpty()) { getMappeableRoaringArray().removeAtIndex(i); } @@ -1513,8 +1568,10 @@ public void remove(final long rangeStart, final long rangeEnd) { int ilast = highLowContainer.getIndex((char) hbLast); if (ifirst >= 0) { if (lbStart != 0) { - final MappeableContainer c = highLowContainer.getContainerAtIndex(ifirst).iremove(lbStart, - BufferUtil.maxLowBitAsInteger() + 1); + final MappeableContainer c = + highLowContainer + .getContainerAtIndex(ifirst) + .iremove(lbStart, BufferUtil.maxLowBitAsInteger() + 1); if (!c.isEmpty()) { ((MutableRoaringArray) highLowContainer).setContainerAtIndex(ifirst, c); ifirst++; @@ -1541,7 +1598,6 @@ public void remove(final long rangeStart, final long rangeEnd) { ((MutableRoaringArray) highLowContainer).removeIndexRange(ifirst, ilast); } - /** * Remove from the current bitmap all integers in [rangeStart,rangeEnd). * @@ -1559,7 +1615,6 @@ public void remove(final int rangeStart, final int rangeEnd) { remove(rangeStart & 0xFFFFFFFFL, rangeEnd & 0xFFFFFFFFL); } - /** * Remove run-length encoding even when it is more space efficient * @@ -1587,7 +1642,6 @@ protected void repairAfterLazy() { } } - /** * Use a run-length encoding where it is estimated as more space efficient * @@ -1649,7 +1703,6 @@ public boolean runOptimize() { */ public ImmutableRoaringBitmap toImmutableRoaringBitmap() { return this; - } /** @@ -1665,15 +1718,13 @@ public void writeExternal(ObjectOutput out) throws IOException { getMappeableRoaringArray().writeExternal(out); } - - /** * In-place bitwise XOR (symmetric difference) operation. The current bitmap is modified. * * @param x2 other bitmap */ public void xor(final ImmutableRoaringBitmap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -1681,14 +1732,17 @@ public void xor(final ImmutableRoaringBitmap x2) { int length1 = highLowContainer.size(); final int length2 = x2.highLowContainer.size(); - main: if (pos1 < length1 && pos2 < length2) { + main: + if (pos1 < length1 && pos2 < length2) { char s1 = highLowContainer.getKeyAtIndex(pos1); char s2 = x2.highLowContainer.getKeyAtIndex(pos2); while (true) { if (s1 == s2) { - final MappeableContainer c = highLowContainer.getContainerAtIndex(pos1) - .ixor(x2.highLowContainer.getContainerAtIndex(pos2)); + final MappeableContainer c = + highLowContainer + .getContainerAtIndex(pos1) + .ixor(x2.highLowContainer.getContainerAtIndex(pos2)); if (!c.isEmpty()) { this.getMappeableRoaringArray().setContainerAtIndex(pos1, c); pos1++; @@ -1709,8 +1763,8 @@ public void xor(final ImmutableRoaringBitmap x2) { } s1 = highLowContainer.getKeyAtIndex(pos1); } else { // s1 > s2 - getMappeableRoaringArray().insertNewKeyValueAt(pos1, s2, - x2.highLowContainer.getContainerAtIndex(pos2).clone()); + getMappeableRoaringArray() + .insertNewKeyValueAt(pos1, s2, x2.highLowContainer.getContainerAtIndex(pos2).clone()); pos1++; length1++; pos2++; diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java index e499537d4..c8d535ee0 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmapSupplier.java @@ -19,5 +19,4 @@ public class MutableRoaringBitmapSupplier implements BitmapDataProviderSupplier public BitmapDataProvider newEmpty() { return new MutableRoaringBitmap(); } - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java index b5dc25791..1e7164397 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/PointableRoaringArray.java @@ -42,7 +42,6 @@ public interface PointableRoaringArray extends Cloneable { */ boolean containsForContainerAtIndex(int i, char x); - /** * Returns the cardinality of the container at the given index. This method is expected to be * fast. @@ -58,10 +57,9 @@ public interface PointableRoaringArray extends Cloneable { * @param x 16-bit key * @return matching container */ - //MappeableContainer getContainer(short x); - + // MappeableContainer getContainer(short x); - /** + /** * Returns either the index of the container corresponding to key x, or a negative value. * @param x 16-bit key * @return index of container (negative value if no container found) @@ -128,7 +126,6 @@ public interface PointableRoaringArray extends Cloneable { */ int serializedSizeInBytes(); - /** * @return number of keys */ diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java index 98cf8402b..a5534c590 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RoaringBatchIterator.java @@ -50,7 +50,7 @@ public void advanceIfNeeded(int target) { @Override public BatchIterator clone() { try { - RoaringBatchIterator it = (RoaringBatchIterator)super.clone(); + RoaringBatchIterator it = (RoaringBatchIterator) super.clone(); if (null != iterator) { it.iterator = iterator.clone(); } @@ -79,11 +79,11 @@ private void nextIterator() { if (null != containerPointer && containerPointer.hasContainer()) { MappeableContainer container = containerPointer.getContainer(); if (container instanceof MappeableArrayContainer) { - nextIterator((MappeableArrayContainer)container); + nextIterator((MappeableArrayContainer) container); } else if (container instanceof MappeableBitmapContainer) { - nextIterator((MappeableBitmapContainer)container); + nextIterator((MappeableBitmapContainer) container); } else if (container instanceof MappeableRunContainer) { - nextIterator((MappeableRunContainer)container); + nextIterator((MappeableRunContainer) container); } key = containerPointer.key() << 16; } else { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java index 66a2f7ee0..47fe31da6 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/RunBatchIterator.java @@ -2,8 +2,6 @@ import org.roaringbitmap.ContainerBatchIterator; - - public final class RunBatchIterator implements ContainerBatchIterator { private MappeableRunContainer runs; @@ -46,7 +44,7 @@ public boolean hasNext() { @Override public ContainerBatchIterator clone() { try { - return (ContainerBatchIterator)super.clone(); + return (ContainerBatchIterator) super.clone(); } catch (CloneNotSupportedException e) { // won't happen throw new IllegalStateException(e); diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/package-info.java b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/package-info.java index 3ba86b65c..ddf38a6b1 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/buffer/package-info.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/buffer/package-info.java @@ -2,8 +2,6 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - - /** * The org.roaringbitmap.buffer package provides * two classes ({@link org.roaringbitmap.buffer.MutableRoaringBitmap} and @@ -41,4 +39,3 @@ * */ package org.roaringbitmap.buffer; - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java b/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java index 02a1a4e68..bf1366c89 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapAnalyser.java @@ -40,11 +40,10 @@ public static BitmapStatistics analyse(RoaringBitmap r) { * @return the statistics */ public static BitmapStatistics analyse(Collection bitmaps) { - return bitmaps - .stream() - .reduce( - BitmapStatistics.empty, - (acc, r) -> acc.merge(BitmapAnalyser.analyse(r)), - BitmapStatistics::merge); + return bitmaps.stream() + .reduce( + BitmapStatistics.empty, + (acc, r) -> acc.merge(BitmapAnalyser.analyse(r)), + BitmapStatistics::merge); } } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java b/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java index 4bb08532c..b41aec6f8 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/insights/BitmapStatistics.java @@ -28,7 +28,6 @@ public class BitmapStatistics { this.bitmapsCount = bitmapsCount; } - /** * Calculates what fraction of all containers is the `containerTypeCount` * @param containerTypeCount denominator @@ -49,11 +48,15 @@ public ArrayContainersStats getArrayContainersStats() { @Override public String toString() { return "BitmapStatistics{" - + "bitmapsCount=" + bitmapsCount - + ", arrayContainersStats=" + arrayContainersStats - + ", bitmapContainerCount=" + bitmapContainerCount - + ", runContainerCount=" + runContainerCount - + '}'; + + "bitmapsCount=" + + bitmapsCount + + ", arrayContainersStats=" + + arrayContainersStats + + ", bitmapContainerCount=" + + bitmapContainerCount + + ", runContainerCount=" + + runContainerCount + + '}'; } public long containerCount() { @@ -62,14 +65,14 @@ public long containerCount() { BitmapStatistics merge(BitmapStatistics other) { return new BitmapStatistics( - arrayContainersStats.merge(other.arrayContainersStats), - bitmapContainerCount + other.bitmapContainerCount, - runContainerCount + other.runContainerCount, - bitmapsCount + other.bitmapsCount); + arrayContainersStats.merge(other.arrayContainersStats), + bitmapContainerCount + other.bitmapContainerCount, + runContainerCount + other.runContainerCount, + bitmapsCount + other.bitmapsCount); } - public final static BitmapStatistics empty = new BitmapStatistics( - ArrayContainersStats.empty, 0, 0, 0); + public static final BitmapStatistics empty = + new BitmapStatistics(ArrayContainersStats.empty, 0, 0, 0); @Override public boolean equals(Object o) { @@ -81,9 +84,9 @@ public boolean equals(Object o) { } BitmapStatistics that = (BitmapStatistics) o; return bitmapsCount == that.bitmapsCount - && bitmapContainerCount == that.bitmapContainerCount - && runContainerCount == that.runContainerCount - && Objects.equals(arrayContainersStats, that.arrayContainersStats); + && bitmapContainerCount == that.bitmapContainerCount + && runContainerCount == that.runContainerCount + && Objects.equals(arrayContainersStats, that.arrayContainersStats); } @Override @@ -123,8 +126,7 @@ public long getCardinalitySum() { ArrayContainersStats merge(ArrayContainersStats other) { return new ArrayContainersStats( - containersCount + other.containersCount, - cardinalitySum + other.cardinalitySum); + containersCount + other.containersCount, cardinalitySum + other.cardinalitySum); } /** @@ -139,7 +141,6 @@ public long averageCardinality() { } } - @Override public boolean equals(Object o) { if (this == o) { @@ -149,8 +150,7 @@ public boolean equals(Object o) { return false; } ArrayContainersStats that = (ArrayContainersStats) o; - return containersCount == that.containersCount - && cardinalitySum == that.cardinalitySum; + return containersCount == that.containersCount && cardinalitySum == that.cardinalitySum; } @Override @@ -161,13 +161,13 @@ public int hashCode() { @Override public String toString() { return "ArrayContainersStats{" - + "containersCount=" + containersCount - + ", cardinalitySum=" + cardinalitySum - + '}'; + + "containersCount=" + + containersCount + + ", cardinalitySum=" + + cardinalitySum + + '}'; } - public final static ArrayContainersStats empty = new ArrayContainersStats(0, 0); + public static final ArrayContainersStats empty = new ArrayContainersStats(0, 0); } - - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java b/roaringbitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java index 5b04dc4f7..8f2829910 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/insights/NaiveWriterRecommender.java @@ -34,55 +34,51 @@ public static String recommend(BitmapStatistics s) { } private static void denseArrayWarning(StringBuilder sb) { - sb - .append("Most of your containers are array containers, ") - .append("but with quite significant cardinality.\n") - .append("It should be better to start with .constantMemory() ") + sb.append("Most of your containers are array containers, ") + .append("but with quite significant cardinality.\n") + .append("It should be better to start with .constantMemory() ") .append("that can scale down to ArrayContainer anyway."); } private static void runContainerRecommendations(StringBuilder sb) { - sb - .append(".optimiseForRuns(), because over ") - .append(RunContainersDomination) - .append(" containers are of type RunContainer.\n") - .append("Make sure to try .constantMemory()") + sb.append(".optimiseForRuns(), because over ") + .append(RunContainersDomination) + .append(" containers are of type RunContainer.\n") + .append("Make sure to try .constantMemory()") .append("as inserting to RunContainers might not be that efficient."); } private static void constantMemoryRecommendation(BitmapStatistics s, StringBuilder sb) { long buffersSizeBytes = s.getBitmapsCount() * Long.BYTES * 1024L; long bufferSizeMiB = buffersSizeBytes / (1024 * 1024); - sb - .append(".constantMemory() is sensible default for most use cases.\n") - .append("Be prepared to allocate on heap ") - .append(bufferSizeMiB) + sb.append(".constantMemory() is sensible default for most use cases.\n") + .append("Be prepared to allocate on heap ") + .append(bufferSizeMiB) .append(" [MiB] just for buffers if you have them open at the same time."); } private static void arrayContainerRecommendations(BitmapStatistics s, StringBuilder sb) { double acFraction = s.containerFraction(s.getArrayContainersStats().getContainersCount()); sb.append(".optimiseForArrays(), because fraction of ArrayContainers ") - .append(acFraction) - .append(" is over arbitrary threshold ") - .append(ArrayContainersDomination) - .append("\n") - .append(".expectedContainerSize(") - .append(s.getArrayContainersStats().averageCardinality()) + .append(acFraction) + .append(" is over arbitrary threshold ") + .append(ArrayContainersDomination) + .append("\n") + .append(".expectedContainerSize(") + .append(s.getArrayContainersStats().averageCardinality()) .append(") to preallocate array containers for average number of elements.\n"); } private static void containerCountRecommendations(BitmapStatistics basedOn, StringBuilder sb) { long averageContainersCount = basedOn.containerCount() / basedOn.getBitmapsCount(); sb.append(".initialCapacity(") - .append(averageContainersCount) - .append("), because on average each bitmap has ") - .append(averageContainersCount) + .append(averageContainersCount) + .append("), because on average each bitmap has ") + .append(averageContainersCount) .append(" containers.\n"); } private static double ArrayContainersDomination = 0.75; private static int WorthUsingArraysCardinalityThreshold = 4096 / 2; private static double RunContainersDomination = 0.8; - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java index 8b5695e27..6fb3a7a35 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/HighLowContainer.java @@ -2,15 +2,21 @@ import static java.nio.ByteOrder.LITTLE_ENDIAN; +import org.roaringbitmap.Container; +import org.roaringbitmap.art.Art; +import org.roaringbitmap.art.ContainerIterator; +import org.roaringbitmap.art.Containers; +import org.roaringbitmap.art.KeyIterator; +import org.roaringbitmap.art.LeafNode; +import org.roaringbitmap.art.LeafNodeIterator; +import org.roaringbitmap.art.Node; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; import java.util.NoSuchElementException; -import org.roaringbitmap.Container; -import org.roaringbitmap.art.*; - public class HighLowContainer { private Art art; @@ -109,7 +115,7 @@ public boolean isEmpty() { } private void assertNonEmpty() { - if(isEmpty()) { + if (isEmpty()) { throw new NoSuchElementException("Empty " + this.getClass().getSimpleName()); } } @@ -130,7 +136,6 @@ public long first() { return LongUtils.toLong(high, low); } - /** * Gets the last value in the array * @return the last value in the array @@ -176,8 +181,8 @@ public static int compareUnsigned(byte[] a, byte[] b) { * @throws IOException indicate exception happened */ public void serialize(ByteBuffer buffer) throws IOException { - ByteBuffer byteBuffer = buffer.order() == LITTLE_ENDIAN ? buffer - : buffer.slice().order(LITTLE_ENDIAN); + ByteBuffer byteBuffer = + buffer.order() == LITTLE_ENDIAN ? buffer : buffer.slice().order(LITTLE_ENDIAN); if (art.isEmpty()) { byteBuffer.put(EMPTY_TAG); buffer.position(buffer.position() + byteBuffer.position()); @@ -198,8 +203,8 @@ public void serialize(ByteBuffer buffer) throws IOException { * @throws IOException indicate exception happened */ public void deserialize(ByteBuffer buffer) throws IOException { - ByteBuffer byteBuffer = buffer.order() == LITTLE_ENDIAN ? buffer - : buffer.slice().order(LITTLE_ENDIAN); + ByteBuffer byteBuffer = + buffer.order() == LITTLE_ENDIAN ? buffer : buffer.slice().order(LITTLE_ENDIAN); clear(); byte emptyTag = byteBuffer.get(); if (emptyTag == EMPTY_TAG) { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java index db42fc6ea..20047d57c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/ImmutableLongBitmapDataProvider.java @@ -75,10 +75,11 @@ public interface ImmutableLongBitmapDataProvider { * @return an Ordered, Distinct, Sorted and Sized IntStream in ascending order */ default LongStream stream() { - int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED - | Spliterator.SIZED; - Spliterator.OfLong x = Spliterators.spliterator(new RoaringOfLong(getLongIterator()), - getLongCardinality(), characteristics); + int characteristics = + Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.SIZED; + Spliterator.OfLong x = + Spliterators.spliterator( + new RoaringOfLong(getLongIterator()), getLongCardinality(), characteristics); return StreamSupport.longStream(x, false); } @@ -87,10 +88,12 @@ default LongStream stream() { */ default LongStream reverseStream() { int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SIZED; - Spliterator.OfLong x = Spliterators.spliterator(new RoaringOfLong(getLongIterator()), - getLongCardinality(), characteristics); + Spliterator.OfLong x = + Spliterators.spliterator( + new RoaringOfLong(getLongIterator()), getLongCardinality(), characteristics); return StreamSupport.longStream(x, false); } + /** * Estimate of the memory usage of this data structure. * @@ -185,7 +188,7 @@ default LongStream reverseStream() { */ long[] toArray(); - /** + /** * An internal class to help provide streams. * Sad but true the interface of LongIterator and PrimitiveIterator.OfLong * Does not match. Otherwise it would be easier to just make LongIterator diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java index e22105b4b..d3a34ee0e 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongBitmapDataProvider.java @@ -23,7 +23,6 @@ public interface LongBitmapDataProvider extends ImmutableLongBitmapDataProvider */ void removeLong(long x); - /** * Recover allocated but unused memory. */ diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java index 993b54492..f7a172edd 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongIterator.java @@ -25,5 +25,4 @@ public interface LongIterator extends Cloneable { * @return next long value */ long next(); - } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java index c1df22d2b..bdfc513fe 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/LongUtils.java @@ -11,13 +11,13 @@ public class LongUtils { * @return the high 48 bit */ public static byte[] highPart(long num) { - return new byte[]{ - (byte) ((num >>> 56) & 0xff), - (byte) ((num >>> 48) & 0xff), - (byte) ((num >>> 40) & 0xff), - (byte) ((num >>> 32) & 0xff), - (byte) ((num >>> 24) & 0xff), - (byte) ((num >>> 16) & 0xff) + return new byte[] { + (byte) ((num >>> 56) & 0xff), + (byte) ((num >>> 48) & 0xff), + (byte) ((num >>> 40) & 0xff), + (byte) ((num >>> 32) & 0xff), + (byte) ((num >>> 24) & 0xff), + (byte) ((num >>> 16) & 0xff) }; } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java index d2f482ae5..84293f272 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/PeekableLongIterator.java @@ -3,7 +3,6 @@ */ package org.roaringbitmap.longlong; - /** * Simple extension to the IntIterator interface. * It allows you to "skip" values using the advanceIfNeeded @@ -95,5 +94,3 @@ public interface PeekableLongIterator extends LongIterator { @Override PeekableLongIterator clone(); } - - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java index db353730d..92d6fda6c 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java @@ -1,5 +1,17 @@ package org.roaringbitmap.longlong; +import org.roaringbitmap.ArrayContainer; +import org.roaringbitmap.BitmapContainer; +import org.roaringbitmap.Container; +import org.roaringbitmap.PeekableCharIterator; +import org.roaringbitmap.RelativeRangeConsumer; +import org.roaringbitmap.RunContainer; +import org.roaringbitmap.Util; +import org.roaringbitmap.art.ContainerIterator; +import org.roaringbitmap.art.KeyIterator; +import org.roaringbitmap.art.LeafNode; +import org.roaringbitmap.art.LeafNodeIterator; + import java.io.DataInput; import java.io.DataOutput; import java.io.Externalizable; @@ -13,12 +25,6 @@ import java.util.NoSuchElementException; import java.util.Objects; -import org.roaringbitmap.*; -import org.roaringbitmap.art.ContainerIterator; -import org.roaringbitmap.art.KeyIterator; -import org.roaringbitmap.art.LeafNode; -import org.roaringbitmap.art.LeafNodeIterator; - /** * Roaring64Bitmap is a compressed 64 bit bitmap. It can contain all the numbers of long * rang[Long.MAX_VALUE, Long.MIN_VALUE]. Since java has no unsigned long,we treat the negative value @@ -233,17 +239,14 @@ public void forAllInRange(long start, int length, final RelativeRangeConsumer rr // Only part of the container is in range char containerRangeStart = LongUtils.lowPart(start); char containerRangeEnd = LongUtils.lowPart(end); - container.forAllInRange( - LongUtils.lowPart(start), - LongUtils.lowPart(end), - rrc); + container.forAllInRange(LongUtils.lowPart(start), LongUtils.lowPart(end), rrc); filledUntil += containerRangeEnd - containerRangeStart; - } else if (startInContainer) {// && !endInContainer + } else if (startInContainer) { // && !endInContainer // range begins within the container char containerRangeStart = LongUtils.lowPart(start); container.forAllFrom(containerRangeStart, rrc); filledUntil += BitmapContainer.MAX_CAPACITY - containerRangeStart; - } else if (endInContainer) {// && !startInContainer + } else if (endInContainer) { // && !startInContainer // range end within the container char containerRangeEnd = LongUtils.lowPart(end); container.forAllUntil(containerRangeStartOffset, containerRangeEnd, rrc); @@ -317,7 +320,9 @@ public long rankLong(long id) { * @param x2 other bitmap */ public void or(final Roaring64Bitmap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } KeyIterator highIte2 = x2.highLowContainer.highKeyIterator(); while (highIte2.hasNext()) { byte[] high = highIte2.next(); @@ -390,7 +395,7 @@ public static Roaring64Bitmap or(final Roaring64Bitmap x1, final Roaring64Bitmap * @param x2 other bitmap */ public void xor(final Roaring64Bitmap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -466,7 +471,9 @@ public static Roaring64Bitmap xor(final Roaring64Bitmap x1, final Roaring64Bitma * @param x2 other bitmap */ public void and(final Roaring64Bitmap x2) { - if(x2 == this) { return; } + if (x2 == this) { + return; + } KeyIterator thisIterator = highLowContainer.highKeyIterator(); while (thisIterator.hasNext()) { byte[] highKey = thisIterator.next(); @@ -597,7 +604,7 @@ public static long andCardinality(final Roaring64Bitmap x1, final Roaring64Bitma * @param x2 other bitmap */ public void andNot(final Roaring64Bitmap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -657,13 +664,13 @@ public static Roaring64Bitmap andNot(final Roaring64Bitmap x1, final Roaring64Bi */ public void flip(final long rangeStart, final long rangeEnd) { - if(rangeEnd >= 0 && rangeStart >= rangeEnd){ + if (rangeEnd >= 0 && rangeStart >= rangeEnd) { // both numbers in positive range, and start is beyond end, nothing to do. return; - } else if(rangeStart < 0 && rangeStart >= rangeEnd){ + } else if (rangeStart < 0 && rangeStart >= rangeEnd) { // both numbers in negative range, and start is beyond end, nothing to do. return; - } else if(rangeStart < 0 && rangeEnd > 0) { + } else if (rangeStart < 0 && rangeEnd > 0) { // start is neg which is "higher" and end is above zero thus, nothing to do. return; } @@ -682,7 +689,8 @@ public void flip(final long rangeStart, final long rangeEnd) { // last container may contain partial range final int containerLast = (hb == shEnd) ? lbLast : LongUtils.maxLowBitAsInteger(); - ContainerWithIndex cwi = highLowContainer.searchContainer( + ContainerWithIndex cwi = + highLowContainer.searchContainer( LongUtils.highPartInPlace(LongUtils.leftShiftHighPart(hb), hbStart)); if (cwi != null) { @@ -724,8 +732,8 @@ public void readExternal(ObjectInput in) throws IOException { */ @Override public String toString() { - final StringBuilder answer = new StringBuilder("{}".length() + "-1234567890123456789,".length() - * 256); + final StringBuilder answer = + new StringBuilder("{}".length() + "-1234567890123456789,".length() * 256); final LongIterator i = this.getLongIterator(); answer.append('{'); if (i.hasNext()) { @@ -744,7 +752,6 @@ public String toString() { return answer.toString(); } - /** * For better performance, consider the Use the {@link #forEach forEach} method. * @@ -790,7 +797,6 @@ public int getSizeInBytes() { return (int) getLongSizeInBytes(); } - /** * Estimate of the memory usage of this data structure. This can be expected to be within 1% of * the true memory usage in common usage scenarios. @@ -862,7 +868,6 @@ public boolean runOptimize() { return hasChanged; } - /** * Serialize this bitmap. * @@ -1041,8 +1046,8 @@ public void addRange(final long rangeStart, final long rangeEnd) { ContainerWithIndex containerWithIndex = highLowContainer.searchContainer(startHighKeyBytes); if (containerWithIndex != null) { long containerIdx = containerWithIndex.getContainerIdx(); - Container freshContainer = highLowContainer.getContainer(containerIdx) - .iadd(containerStart, containerLast + 1); + Container freshContainer = + highLowContainer.getContainer(containerIdx).iadd(containerStart, containerLast + 1); highLowContainer.replaceContainer(containerIdx, freshContainer); } else { Container freshContainer = Container.rangeOfOnes(containerStart, containerLast + 1); @@ -1052,7 +1057,7 @@ public void addRange(final long rangeStart, final long rangeEnd) { if (LongUtils.isMaxHigh(startHighKey)) { break; } - //increase the high + // increase the high rangeStartVal = rangeStartVal + (containerLast - containerStart) + 1; startHighKey = LongUtils.rightShiftHighPart(rangeStartVal); startHighKeyBytes = LongUtils.highPart(rangeStartVal); @@ -1110,7 +1115,7 @@ public void trim() { if (container.isEmpty()) { keyIterator.remove(); } else { - //TODO + // TODO container.trim(); } } @@ -1136,7 +1141,6 @@ public boolean equals(Object obj) { return Objects.equals(highLowContainer, other.highLowContainer); } - /** * Add the value if it is not already present, otherwise remove it. * @@ -1154,7 +1158,7 @@ public void flip(final long x) { } } - //mainly used for benchmark + // mainly used for benchmark @Override public Roaring64Bitmap clone() { long sizeInBytesL = this.serializedSizeInBytes(); @@ -1174,7 +1178,6 @@ public Roaring64Bitmap clone() { } } - private abstract class PeekableIterator implements PeekableLongIterator { private final LeafNodeIterator keyIte; private byte[] high; @@ -1185,6 +1188,7 @@ private abstract class PeekableIterator implements PeekableLongIterator { } abstract PeekableCharIterator getIterator(Container container); + abstract boolean compare(long next, long val); @Override @@ -1198,7 +1202,7 @@ public boolean hasNext() { long containerIdx = leafNode.getContainerIdx(); Container container = highLowContainer.getContainer(containerIdx); charIterator = getIterator(container); - if(charIterator.hasNext()){ + if (charIterator.hasNext()) { return true; } } @@ -1220,11 +1224,11 @@ public void advanceIfNeeded(long minval) { if (!hasNext()) { return; } - if(compare(this.peekNext(), minval)) { + if (compare(this.peekNext(), minval)) { return; } - //empty bitset - if(this.high == null) { + // empty bitset + if (this.high == null) { return; } @@ -1239,7 +1243,7 @@ public void advanceIfNeeded(long minval) { long containerIdx = leafNode.getContainerIdx(); Container container = highLowContainer.getContainer(containerIdx); charIterator = getIterator(container); - if(!charIterator.hasNext()){ + if (!charIterator.hasNext()) { return; } } else { @@ -1250,7 +1254,7 @@ public void advanceIfNeeded(long minval) { long containerIdx = leafNode.getContainerIdx(); Container container = highLowContainer.getContainer(containerIdx); charIterator = getIterator(container); - if(!charIterator.hasNext()){ + if (!charIterator.hasNext()) { return; } } else { @@ -1287,7 +1291,6 @@ public PeekableLongIterator clone() { } } - private class ForwardPeekableIterator extends PeekableIterator { public ForwardPeekableIterator(final LeafNodeIterator keyIte) { diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java index 201a3d304..6aa014e1f 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java @@ -3,13 +3,35 @@ */ package org.roaringbitmap.longlong; -import org.roaringbitmap.*; +import org.roaringbitmap.BitmapDataProvider; +import org.roaringbitmap.BitmapDataProviderSupplier; +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.RoaringBitmap; +import org.roaringbitmap.RoaringBitmapPrivate; +import org.roaringbitmap.RoaringBitmapSupplier; +import org.roaringbitmap.Util; import org.roaringbitmap.buffer.MutableRoaringBitmap; import org.roaringbitmap.buffer.MutableRoaringBitmapPrivate; -import java.io.*; -import java.util.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.UnsupportedEncodingException; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; import java.util.Map.Entry; +import java.util.NavigableMap; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.SortedMap; +import java.util.TreeMap; /** * Roaring64NavigableMap extends RoaringBitmap to the whole range of longs (or unsigned longs). It @@ -144,8 +166,8 @@ public Roaring64NavigableMap(boolean signedLongs, BitmapDataProviderSupplier sup * @param supplier provide the logic to instantiate new {@link BitmapDataProvider}, typically * instantiated once per high. */ - public Roaring64NavigableMap(boolean signedLongs, boolean cacheCardinalities, - BitmapDataProviderSupplier supplier) { + public Roaring64NavigableMap( + boolean signedLongs, boolean cacheCardinalities, BitmapDataProviderSupplier supplier) { this.signedLongs = signedLongs; this.supplier = supplier; @@ -310,7 +332,6 @@ public long getLongCardinality() { return 0L; } - return sortedCumulatedCardinality[indexOk - 1]; } else { long cardinality = 0L; @@ -459,13 +480,16 @@ public void remove() { @Override public void forEach(final LongConsumer lc) { for (final Entry highEntry : highToBitmap.entrySet()) { - highEntry.getValue().forEach(new IntConsumer() { - - @Override - public void accept(int low) { - lc.accept(RoaringIntPacking.pack(highEntry.getKey(), low)); - } - }); + highEntry + .getValue() + .forEach( + new IntConsumer() { + + @Override + public void accept(int low) { + lc.accept(RoaringIntPacking.pack(highEntry.getKey(), low)); + } + }); } } @@ -597,7 +621,6 @@ protected int ensureCumulatives(int high) { // We have added one valid cardinality indexOk++; } - } if (highToBitmap.isEmpty() || indexOk == highToBitmap.size()) { @@ -613,8 +636,8 @@ private int binarySearch(int[] array, int key) { if (signedLongs) { return Arrays.binarySearch(array, key); } else { - return unsignedBinarySearch(array, 0, array.length, key, - RoaringIntPacking.unsignedComparator()); + return unsignedBinarySearch( + array, 0, array.length, key, RoaringIntPacking.unsignedComparator()); } } @@ -627,8 +650,8 @@ private int binarySearch(int[] array, int from, int to, int key) { } // From Arrays.binarySearch (Comparator). Check with org.roaringbitmap.Util.unsignedBinarySearch - private static int unsignedBinarySearch(int[] a, int fromIndex, int toIndex, int key, - Comparator c) { + private static int unsignedBinarySearch( + int[] a, int fromIndex, int toIndex, int key, Comparator c) { int low = fromIndex; int high = toIndex - 1; @@ -665,14 +688,21 @@ private void ensureOne(Map.Entry e, int currentHigh } else { index = -sortedHighs.length - 1; } - assert index == binarySearch(sortedHighs, 0, indexOk, currentHigh) : "Computed " + index - + " differs from dummy binary-search index: " - + binarySearch(sortedHighs, 0, indexOk, currentHigh); + assert index == binarySearch(sortedHighs, 0, indexOk, currentHigh) + : "Computed " + + index + + " differs from dummy binary-search index: " + + binarySearch(sortedHighs, 0, indexOk, currentHigh); if (index >= 0) { // This would mean calling .ensureOne is useless: should never got here at the first time - throw new IllegalStateException("Unexpectedly found " + currentHigh + " in " - + Arrays.toString(sortedHighs) + " strictly before index" + indexOk); + throw new IllegalStateException( + "Unexpectedly found " + + currentHigh + + " in " + + Arrays.toString(sortedHighs) + + " strictly before index" + + indexOk); } else { int insertionPosition = -index - 1; @@ -715,8 +745,6 @@ private void ensureOne(Map.Entry e, int currentHigh } } - - private int highestHigh() { return RoaringIntPacking.highestHigh(signedLongs); } @@ -728,7 +756,9 @@ private int highestHigh() { * @param x2 other bitmap */ public void naivelazyor(final Roaring64NavigableMap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } for (Entry e2 : x2.highToBitmap.entrySet()) { // Keep object to prevent auto-boxing Integer high = e2.getKey(); @@ -737,7 +767,7 @@ public void naivelazyor(final Roaring64NavigableMap x2) { BitmapDataProvider lowBitmap2 = e2.getValue(); - if (lowBitmap1 == null){ + if (lowBitmap1 == null) { // Clone to prevent future modification of this modifying the input Bitmap BitmapDataProvider lowBitmap2Clone; if (lowBitmap2 instanceof RoaringBitmap) { @@ -745,23 +775,24 @@ public void naivelazyor(final Roaring64NavigableMap x2) { } else if (lowBitmap2 instanceof MutableRoaringBitmap) { lowBitmap2Clone = ((MutableRoaringBitmap) lowBitmap2).clone(); } else { - throw new UnsupportedOperationException(".naivelazyor(...) over " - + getClassName(lowBitmap2)); + throw new UnsupportedOperationException( + ".naivelazyor(...) over " + getClassName(lowBitmap2)); } pushBitmapForHigh(high, lowBitmap2Clone); - } else if (lowBitmap1 instanceof RoaringBitmap - && lowBitmap2 instanceof RoaringBitmap) { + } else if (lowBitmap1 instanceof RoaringBitmap && lowBitmap2 instanceof RoaringBitmap) { RoaringBitmapPrivate.naivelazyor((RoaringBitmap) lowBitmap1, (RoaringBitmap) lowBitmap2); } else if (lowBitmap1 instanceof MutableRoaringBitmap - && lowBitmap2 instanceof MutableRoaringBitmap) { - MutableRoaringBitmapPrivate.naivelazyor((MutableRoaringBitmap) lowBitmap1, - (MutableRoaringBitmap) lowBitmap2); + && lowBitmap2 instanceof MutableRoaringBitmap) { + MutableRoaringBitmapPrivate.naivelazyor( + (MutableRoaringBitmap) lowBitmap1, (MutableRoaringBitmap) lowBitmap2); } else { - throw new UnsupportedOperationException(".naivelazyor(...) over " - + getClassName(lowBitmap1) + " and " + getClassName(lowBitmap2)); + throw new UnsupportedOperationException( + ".naivelazyor(...) over " + + getClassName(lowBitmap1) + + " and " + + getClassName(lowBitmap2)); } - } } @@ -771,7 +802,9 @@ public void naivelazyor(final Roaring64NavigableMap x2) { * @param x2 other bitmap */ public void or(final Roaring64NavigableMap x2) { - if(this == x2) { return; } + if (this == x2) { + return; + } boolean firstBucket = true; for (Entry e2 : x2.highToBitmap.entrySet()) { @@ -802,7 +835,6 @@ public void or(final Roaring64NavigableMap x2) { // Clone to prevent future modification of this modifying the input Bitmap BitmapDataProvider lowBitmap2Clone = ((MutableRoaringBitmap) lowBitmap2).clone(); - pushBitmapForHigh(high, lowBitmap2Clone); } else { ((MutableRoaringBitmap) lowBitmap1).or((MutableRoaringBitmap) lowBitmap2); @@ -828,7 +860,7 @@ public void or(final Roaring64NavigableMap x2) { * @param x2 other bitmap */ public void xor(final Roaring64NavigableMap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -887,7 +919,9 @@ public void xor(final Roaring64NavigableMap x2) { * @param x2 other bitmap */ public void and(final Roaring64NavigableMap x2) { - if(x2 == this) { return; } + if (x2 == this) { + return; + } boolean firstBucket = true; Iterator> thisIterator = highToBitmap.entrySet().iterator(); @@ -926,14 +960,13 @@ public void and(final Roaring64NavigableMap x2) { } } - /** * In-place bitwise ANDNOT (difference) operation. The current bitmap is modified. * * @param x2 other bitmap */ public void andNot(final Roaring64NavigableMap x2) { - if(x2 == this) { + if (x2 == this) { clear(); return; } @@ -996,8 +1029,8 @@ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExcept */ @Override public String toString() { - final StringBuilder answer = new StringBuilder("{}".length() + "-1234567890123456789,".length() - * 256); + final StringBuilder answer = + new StringBuilder("{}".length() + "-1234567890123456789,".length() * 256); final LongIterator i = this.getLongIterator(); answer.append('{'); if (i.hasNext()) { @@ -1019,13 +1052,11 @@ public String toString() { } else { answer.append(RoaringIntPacking.toUnsignedString(i.next())); } - } answer.append("}"); return answer.toString(); } - /** * * For better performance, consider the Use the {@link #forEach forEach} method. @@ -1039,8 +1070,8 @@ public LongIterator getLongIterator() { return toIterator(it, false); } - protected LongIterator toIterator(final Iterator> it, - final boolean reversed) { + protected LongIterator toIterator( + final Iterator> it, final boolean reversed) { return new LongIterator() { protected int currentKey; @@ -1117,7 +1148,6 @@ public boolean contains(long x) { return lowBitmap.contains(low); } - @Override public int getSizeInBytes() { return (int) getLongSizeInBytes(); @@ -1161,11 +1191,11 @@ public void repairAfterLazy() { for (BitmapDataProvider lowBitmap : highToBitmap.values()) { if (lowBitmap instanceof RoaringBitmap) { RoaringBitmapPrivate.repairAfterLazy((RoaringBitmap) lowBitmap); - } else if(lowBitmap instanceof MutableRoaringBitmap){ + } else if (lowBitmap instanceof MutableRoaringBitmap) { MutableRoaringBitmapPrivate.repairAfterLazy((MutableRoaringBitmap) lowBitmap); } else { throw new UnsupportedOperationException( - ".repairAfterLazy is not supported for " + lowBitmap.getClass()); + ".repairAfterLazy is not supported for " + lowBitmap.getClass()); } } } @@ -1187,7 +1217,6 @@ public boolean runOptimize() { return hasChanged; } - /** * Serialize this bitmap. * @@ -1364,7 +1393,6 @@ public void deserializePortable(DataInput in) throws IOException { resetPerfHelpers(); } - @Override public long serializedSizeInBytes() { long nbBytes = 0L; @@ -1476,7 +1504,7 @@ public void addRange(final long rangeStart, final long rangeEnd) { int compareHigh = compare(startHigh, endHigh); if (compareHigh > 0 - || compareHigh == 0 && Util.toUnsignedLong(startLow) >= Util.toUnsignedLong(endLow)) { + || compareHigh == 0 && Util.toUnsignedLong(startLow) >= Util.toUnsignedLong(endLow)) { throw new IllegalArgumentException("Invalid range [" + rangeStart + "," + rangeEnd + ")"); } @@ -1545,7 +1573,6 @@ public void removeLong(long x) { // Invalidate only if actually modified invalidateAboveHigh(high); } - } @Override @@ -1575,8 +1602,6 @@ public boolean equals(Object obj) { return Objects.equals(highToBitmap, other.highToBitmap); } - - /** * Add the value if it is not already present, otherwise remove it. * @@ -1611,7 +1636,7 @@ public void flip(final long x) { } private void assertNonEmpty() { - if(isEmpty()) { + if (isEmpty()) { throw new NoSuchElementException("Empty " + this.getClass().getSimpleName()); } } diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java index bf5697242..7140bb210 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/RoaringIntPacking.java @@ -46,7 +46,6 @@ public static long pack(int high, int low) { return (((long) high) << 32) | (low & 0xffffffffL); } - /** * * @param signedLongs true if long put in a {@link Roaring64NavigableMap} should be considered as diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/package-info.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/package-info.java index f76b1745f..38a5c22bb 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/package-info.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/package-info.java @@ -2,8 +2,6 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - - /** * The org.roaringbitmap.longlong package provides * one class ({@link org.roaringbitmap.longlong.Roaring64NavigableMap}) that users @@ -24,4 +22,3 @@ * */ package org.roaringbitmap.longlong; - diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/package-info.java b/roaringbitmap/src/main/java/org/roaringbitmap/package-info.java index cf53e36e6..edabd83a5 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/package-info.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/package-info.java @@ -2,8 +2,6 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - - /** * The org.roaringbitmap package provides * one class ({@link org.roaringbitmap.RoaringBitmap}) that users @@ -34,4 +32,3 @@ * */ package org.roaringbitmap; - diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java index 2f9e9d509..71c7606b4 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/CloneBatchIteratorTest.java @@ -1,14 +1,14 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + import com.google.common.primitives.Ints; import org.junit.jupiter.api.Test; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - public class CloneBatchIteratorTest { @Test @@ -31,8 +31,8 @@ public void testIndependenceOfClones() { @Test public void testIndependenceOfClones2() { - int[] c1 = new int[]{1, 10, 20}; - int[] c2 = new int[]{65560, 70000}; + int[] c1 = new int[] {1, 10, 20}; + int[] c2 = new int[] {65560, 70000}; RoaringBitmap bitmap = new RoaringBitmap(); for (int x : Ints.concat(c1, c2)) { bitmap.add(x); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java index 80ee43810..8802ba591 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/ContainerBatchIteratorTest.java @@ -1,5 +1,9 @@ package org.roaringbitmap; +import static java.util.Arrays.copyOfRange; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -14,152 +18,162 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import static java.util.Arrays.copyOfRange; -import static org.junit.jupiter.api.Assertions.*; - @Execution(ExecutionMode.CONCURRENT) public class ContainerBatchIteratorTest { - private static int[][] DATA; + private static int[][] DATA; - @BeforeAll - public static void setup() { - DATA = Stream.of(IntStream.range(0, 20000).toArray(), - IntStream.range(0, 1 << 16).toArray(), - IntStream.range(0, 1 << 16).filter(i -> i < 500 || i > 2000).filter(i -> i < (1 << 15) || i > ((1 << 15) | (1 << 8))).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 12) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 11) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 10) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 9) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 8) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 7) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 6) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 5) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 4) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 3) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 2) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 1) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 3) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 5) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 7) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 9) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 271) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 1000) == 0).toArray(), - IntStream.empty().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray()).toArray(int[][]::new); - } + @BeforeAll + public static void setup() { + DATA = + Stream.of( + IntStream.range(0, 20000).toArray(), + IntStream.range(0, 1 << 16).toArray(), + IntStream.range(0, 1 << 16) + .filter(i -> i < 500 || i > 2000) + .filter(i -> i < (1 << 15) || i > ((1 << 15) | (1 << 8))) + .toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 12) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 11) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 10) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 9) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 8) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 7) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 6) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 5) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 4) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 3) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 2) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 1) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 3) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 5) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 7) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 9) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 271) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 1000) == 0).toArray(), + IntStream.empty().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray()) + .toArray(int[][]::new); + } - @AfterAll - public static void clear() { - DATA = null; - } + @AfterAll + public static void clear() { + DATA = null; + } + public static Stream params() { + return Stream.of(DATA) + .flatMap( + array -> + IntStream.concat( + IntStream.of(512, 1024, 2048, 4096, 8192, 65536), + IntStream.range(0, 100) + .map(i -> ThreadLocalRandom.current().nextInt(1, 65536))) + .mapToObj(i -> Arguments.of(array, i))); + } - public static Stream params() { - return Stream.of(DATA) - .flatMap(array -> IntStream.concat(IntStream.of( - 512, 1024, 2048, 4096, 8192, 65536 - ), IntStream.range(0, 100).map(i -> ThreadLocalRandom.current().nextInt(1, 65536))) - .mapToObj(i -> Arguments.of(array, i))); + @ParameterizedTest(name = "{1}") + @MethodSource("params") + public void test(int[] expectedValues, int batchSize) { + int[] buffer = new int[batchSize]; + Container container = createContainer(expectedValues); + ContainerBatchIterator it = container.getBatchIterator(); + int cardinality = 0; + while (it.hasNext()) { + int from = cardinality; + cardinality += it.next(0, buffer); + assertArrayEquals( + copyOfRange(expectedValues, from, cardinality), + copyOfRange(buffer, 0, cardinality - from), + "Failure with batch size " + batchSize); } + assertEquals(expectedValues.length, cardinality); + } - @ParameterizedTest(name = "{1}") - @MethodSource("params") - public void test(int[] expectedValues, int batchSize) { - int[] buffer = new int[batchSize]; - Container container = createContainer(expectedValues); - ContainerBatchIterator it = container.getBatchIterator(); - int cardinality = 0; - while (it.hasNext()) { - int from = cardinality; - cardinality += it.next(0, buffer); - assertArrayEquals( - copyOfRange(expectedValues, from, cardinality), copyOfRange(buffer, 0, cardinality - from), - "Failure with batch size " + batchSize); - } - assertEquals(expectedValues.length, cardinality); + @ParameterizedTest(name = "{1}") + @MethodSource("params") + public void testAdvanceIfNeeded(int[] expectedValues, int batchSize) { + if (expectedValues.length < 2) { + return; } - - @ParameterizedTest(name = "{1}") - @MethodSource("params") - public void testAdvanceIfNeeded(int[] expectedValues, int batchSize) { - if (expectedValues.length < 2) { - return; - } - int[] buffer = new int[batchSize]; - Container container = createContainer(expectedValues); - ContainerBatchIterator it = container.getBatchIterator(); - int cardinality = expectedValues.length / 2; - int advanceUntil = expectedValues[cardinality]; - it.advanceIfNeeded((char) advanceUntil); - while (it.hasNext()) { - int from = cardinality; - cardinality += it.next(0, buffer); - assertArrayEquals( - copyOfRange(expectedValues, from, cardinality), copyOfRange(buffer, 0, cardinality - from), - "Failure with batch size " + batchSize + " and container type " + container.getContainerName()); - } - assertEquals(expectedValues.length, cardinality); + int[] buffer = new int[batchSize]; + Container container = createContainer(expectedValues); + ContainerBatchIterator it = container.getBatchIterator(); + int cardinality = expectedValues.length / 2; + int advanceUntil = expectedValues[cardinality]; + it.advanceIfNeeded((char) advanceUntil); + while (it.hasNext()) { + int from = cardinality; + cardinality += it.next(0, buffer); + assertArrayEquals( + copyOfRange(expectedValues, from, cardinality), + copyOfRange(buffer, 0, cardinality - from), + "Failure with batch size " + + batchSize + + " and container type " + + container.getContainerName()); } + assertEquals(expectedValues.length, cardinality); + } - // https://github.com/RoaringBitmap/RoaringBitmap/issues/730 - @Test - public void testHasNextBitmapIterator() { - BitmapContainer container = new BitmapContainer(); // create an empty container - assertFalse(container.getBatchIterator().hasNext()); - } + // https://github.com/RoaringBitmap/RoaringBitmap/issues/730 + @Test + public void testHasNextBitmapIterator() { + BitmapContainer container = new BitmapContainer(); // create an empty container + assertFalse(container.getBatchIterator().hasNext()); + } - private Container createContainer(int[] expectedValues) { - Container container = new ArrayContainer(); - for (int value : expectedValues) { - container = container.add((char) value); - } - return container.runOptimize(); + private Container createContainer(int[] expectedValues) { + Container container = new ArrayContainer(); + for (int value : expectedValues) { + container = container.add((char) value); } + return container.runOptimize(); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/KryoTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/KryoTest.java index 258ba7271..6c0c1ebde 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/KryoTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/KryoTest.java @@ -1,5 +1,7 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.io.Input; @@ -8,85 +10,85 @@ import com.esotericsoftware.kryo.io.Output; import org.junit.jupiter.api.Test; -import java.io.*; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; public class KryoTest { - public static Kryo createKryo() { - Kryo kryo = new Kryo(); - kryo.setRegistrationRequired(false); - kryo.register(RoaringBitmap.class, new RoaringSerializer()); - return kryo; - } + public static Kryo createKryo() { + Kryo kryo = new Kryo(); + kryo.setRegistrationRequired(false); + kryo.register(RoaringBitmap.class, new RoaringSerializer()); + return kryo; + } - public static void writeRoaringToFile(File f, - RoaringBitmap roaring, - Serializer serializer) throws FileNotFoundException { - Kryo kryo = createKryo(); - Output kryoOutputMap = new Output(new FileOutputStream(f)); - kryo.writeObjectOrNull(kryoOutputMap, roaring, serializer); - kryoOutputMap.flush(); - kryoOutputMap.close(); - } - - public static RoaringBitmap readRoaringFromFile(File f, - Serializer serializer) throws FileNotFoundException { - Kryo kryo = createKryo(); - Input inputMap = new Input(new FileInputStream(f)); - RoaringBitmap roaring = kryo.readObjectOrNull(inputMap, RoaringBitmap.class, serializer); - inputMap.close(); - return roaring; - } + public static void writeRoaringToFile( + File f, RoaringBitmap roaring, Serializer serializer) + throws FileNotFoundException { + Kryo kryo = createKryo(); + Output kryoOutputMap = new Output(new FileOutputStream(f)); + kryo.writeObjectOrNull(kryoOutputMap, roaring, serializer); + kryoOutputMap.flush(); + kryoOutputMap.close(); + } - @Test - public void roaringTest() throws IOException { - RoaringSerializer serializer = new RoaringSerializer(); - RoaringBitmap roaringDense = new RoaringBitmap(); - for (int i = 0; i < 100_000; i++) { - roaringDense.add(i); - } - File tmpfiledense = File.createTempFile("roaring_dense", "bin"); - tmpfiledense.deleteOnExit(); - writeRoaringToFile(tmpfiledense, roaringDense, serializer); - RoaringBitmap denseRoaringFromFile = readRoaringFromFile(tmpfiledense, serializer); - assertEquals(denseRoaringFromFile, roaringDense); + public static RoaringBitmap readRoaringFromFile(File f, Serializer serializer) + throws FileNotFoundException { + Kryo kryo = createKryo(); + Input inputMap = new Input(new FileInputStream(f)); + RoaringBitmap roaring = kryo.readObjectOrNull(inputMap, RoaringBitmap.class, serializer); + inputMap.close(); + return roaring; + } - RoaringBitmap roaringSparse = new RoaringBitmap(); - for (int i = 0; i < 100_000; i++) { - if (i % 11 == 0) { - roaringSparse.add(i); - } - } - File tmpfilesparse = File.createTempFile("roaring_sparse", "bin"); - writeRoaringToFile(tmpfilesparse, roaringSparse, serializer); - RoaringBitmap sparseRoaringFromFile = readRoaringFromFile(tmpfilesparse, serializer); - assertEquals(sparseRoaringFromFile, roaringSparse); + @Test + public void roaringTest() throws IOException { + RoaringSerializer serializer = new RoaringSerializer(); + RoaringBitmap roaringDense = new RoaringBitmap(); + for (int i = 0; i < 100_000; i++) { + roaringDense.add(i); } + File tmpfiledense = File.createTempFile("roaring_dense", "bin"); + tmpfiledense.deleteOnExit(); + writeRoaringToFile(tmpfiledense, roaringDense, serializer); + RoaringBitmap denseRoaringFromFile = readRoaringFromFile(tmpfiledense, serializer); + assertEquals(denseRoaringFromFile, roaringDense); + RoaringBitmap roaringSparse = new RoaringBitmap(); + for (int i = 0; i < 100_000; i++) { + if (i % 11 == 0) { + roaringSparse.add(i); + } + } + File tmpfilesparse = File.createTempFile("roaring_sparse", "bin"); + writeRoaringToFile(tmpfilesparse, roaringSparse, serializer); + RoaringBitmap sparseRoaringFromFile = readRoaringFromFile(tmpfilesparse, serializer); + assertEquals(sparseRoaringFromFile, roaringSparse); + } } class RoaringSerializer extends Serializer { - @Override - public void write(Kryo kryo, Output output, RoaringBitmap bitmap) { - try { - bitmap.serialize(new KryoDataOutput(output)); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException(); - } + @Override + public void write(Kryo kryo, Output output, RoaringBitmap bitmap) { + try { + bitmap.serialize(new KryoDataOutput(output)); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(); } + } - @Override - public RoaringBitmap read(Kryo kryo, Input input, Class type) { - RoaringBitmap bitmap = new RoaringBitmap(); - try { - bitmap.deserialize(new KryoDataInput(input)); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException(); - } - return bitmap; + @Override + public RoaringBitmap read(Kryo kryo, Input input, Class type) { + RoaringBitmap bitmap = new RoaringBitmap(); + try { + bitmap.deserialize(new KryoDataInput(input)); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(); } - + return bitmap; + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java index 77314b3f9..46ff3e179 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/OrNotTruncationTest.java @@ -1,5 +1,7 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -10,45 +12,44 @@ import java.util.function.Consumer; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class OrNotTruncationTest { - private static final Consumer NO_OP = x -> { - }; - + private static final Consumer NO_OP = x -> {}; public static Stream params() { return Stream.of( - Arguments.of(new RoaringBitmap(), NO_OP), - Arguments.of(new RoaringBitmap(), (Consumer) x -> x.add(2)), - Arguments.of(new RoaringBitmap(), (Consumer) x -> x.add(2L, 5L)), - Arguments.of(new RoaringBitmap(), (Consumer) x -> x.add(3L, 5L)), - Arguments.of(new RoaringBitmap(), (Consumer) x -> { - x.add(1L, 10L); - x.remove(2L, 10L); - }), - Arguments.of(new RoaringBitmap(), (Consumer) x -> { - for (int i : new int[]{0, 1, 2, 3, 4, 5, 6}) - x.add(i); - }), - Arguments.of(RoaringBitmap.bitmapOf(2), NO_OP), - Arguments.of(RoaringBitmap.bitmapOf(2, 3, 4), NO_OP), - Arguments.of(testCase().withArrayAt(0).build(), NO_OP), - Arguments.of(testCase().withRunAt(0).build(), NO_OP), - Arguments.of(testCase().withBitmapAt(0).build(), NO_OP), - Arguments.of(testCase().withArrayAt(0).withRunAt(1).build(), NO_OP), - Arguments.of(testCase().withRunAt(0).withRunAt(1).build(), NO_OP), - Arguments.of(testCase().withBitmapAt(0).withRunAt(1).build(), NO_OP), - Arguments.of(testCase().withArrayAt(1).build(), NO_OP), - Arguments.of(testCase().withRunAt(1).build(), NO_OP), - Arguments.of(testCase().withBitmapAt(1).build(), NO_OP), - Arguments.of(testCase().withArrayAt(1).withRunAt(2).build(), NO_OP), - Arguments.of(testCase().withRunAt(1).withRunAt(2).build(), NO_OP), - Arguments.of(testCase().withBitmapAt(1).withRunAt(2).build(), NO_OP) - ); + Arguments.of(new RoaringBitmap(), NO_OP), + Arguments.of(new RoaringBitmap(), (Consumer) x -> x.add(2)), + Arguments.of(new RoaringBitmap(), (Consumer) x -> x.add(2L, 5L)), + Arguments.of(new RoaringBitmap(), (Consumer) x -> x.add(3L, 5L)), + Arguments.of( + new RoaringBitmap(), + (Consumer) + x -> { + x.add(1L, 10L); + x.remove(2L, 10L); + }), + Arguments.of( + new RoaringBitmap(), + (Consumer) + x -> { + for (int i : new int[] {0, 1, 2, 3, 4, 5, 6}) x.add(i); + }), + Arguments.of(RoaringBitmap.bitmapOf(2), NO_OP), + Arguments.of(RoaringBitmap.bitmapOf(2, 3, 4), NO_OP), + Arguments.of(testCase().withArrayAt(0).build(), NO_OP), + Arguments.of(testCase().withRunAt(0).build(), NO_OP), + Arguments.of(testCase().withBitmapAt(0).build(), NO_OP), + Arguments.of(testCase().withArrayAt(0).withRunAt(1).build(), NO_OP), + Arguments.of(testCase().withRunAt(0).withRunAt(1).build(), NO_OP), + Arguments.of(testCase().withBitmapAt(0).withRunAt(1).build(), NO_OP), + Arguments.of(testCase().withArrayAt(1).build(), NO_OP), + Arguments.of(testCase().withRunAt(1).build(), NO_OP), + Arguments.of(testCase().withBitmapAt(1).build(), NO_OP), + Arguments.of(testCase().withArrayAt(1).withRunAt(2).build(), NO_OP), + Arguments.of(testCase().withRunAt(1).withRunAt(2).build(), NO_OP), + Arguments.of(testCase().withBitmapAt(1).withRunAt(2).build(), NO_OP)); } @ParameterizedTest @@ -61,5 +62,4 @@ public void testTruncation(RoaringBitmap other, Consumer init) { one.orNot(other, 7); assertTrue(one.contains(10)); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java index 1d5f78c9d..c800eb7ac 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/ParallelAggregationTest.java @@ -1,20 +1,21 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + +import org.roaringbitmap.buffer.BufferFastAggregation; +import org.roaringbitmap.buffer.BufferParallelAggregation; +import org.roaringbitmap.buffer.ImmutableRoaringBitmap; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.buffer.BufferFastAggregation; -import org.roaringbitmap.buffer.BufferParallelAggregation; -import org.roaringbitmap.buffer.ImmutableRoaringBitmap; import java.util.concurrent.ForkJoinPool; import java.util.stream.IntStream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class ParallelAggregationTest { @@ -62,10 +63,10 @@ public void disjointOR() { assertEquals(FastAggregation.or(one, two, three), ParallelAggregation.or(one, two, three)); } - @Test public void wideOr() { - RoaringBitmap[] input = IntStream.range(0, 20) + RoaringBitmap[] input = + IntStream.range(0, 20) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); assertEquals(FastAggregation.or(input), ParallelAggregation.or(input)); @@ -73,16 +74,17 @@ public void wideOr() { @Test public void hugeOr1() { - RoaringBitmap[] input = IntStream.range(0, 513) + RoaringBitmap[] input = + IntStream.range(0, 513) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); assertEquals(FastAggregation.or(input), ParallelAggregation.or(input)); } - @Test public void hugeOr2() { - RoaringBitmap[] input = IntStream.range(0, 1999) + RoaringBitmap[] input = + IntStream.range(0, 1999) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); assertEquals(FastAggregation.or(input), ParallelAggregation.or(input)); @@ -90,7 +92,8 @@ public void hugeOr2() { @Test public void hugeOr3() { - RoaringBitmap[] input = IntStream.range(0, 4096) + RoaringBitmap[] input = + IntStream.range(0, 4096) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); assertEquals(FastAggregation.or(input), ParallelAggregation.or(input)); @@ -98,66 +101,75 @@ public void hugeOr3() { @Test public void hugeOrNoParallelismAvailable1() { - RoaringBitmap[] input = IntStream.range(0, 513) + RoaringBitmap[] input = + IntStream.range(0, 513) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - NO_PARALLELISM_AVAILABLE.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), + NO_PARALLELISM_AVAILABLE.submit(() -> ParallelAggregation.or(input)).join()); } - @Test public void hugeOrNoParallelismAvailable2() { - RoaringBitmap[] input = IntStream.range(0, 2000) + RoaringBitmap[] input = + IntStream.range(0, 2000) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - NO_PARALLELISM_AVAILABLE.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), + NO_PARALLELISM_AVAILABLE.submit(() -> ParallelAggregation.or(input)).join()); } @Test public void hugeOrNoParallelismAvailable3() { - RoaringBitmap[] input = IntStream.range(0, 4096) + RoaringBitmap[] input = + IntStream.range(0, 4096) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - NO_PARALLELISM_AVAILABLE.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), + NO_PARALLELISM_AVAILABLE.submit(() -> ParallelAggregation.or(input)).join()); } @Test public void hugeOrInFJP1() { - RoaringBitmap[] input = IntStream.range(0, 513) + RoaringBitmap[] input = + IntStream.range(0, 513) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - POOL.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), POOL.submit(() -> ParallelAggregation.or(input)).join()); } @Test public void regressionTest() { - RoaringBitmap[] input = IntStream.range(0, 513) + RoaringBitmap[] input = + IntStream.range(0, 513) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - BIG_POOL.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), BIG_POOL.submit(() -> ParallelAggregation.or(input)).join()); } @Test public void hugeOrInFJP2() { - RoaringBitmap[] input = IntStream.range(0, 2000) + RoaringBitmap[] input = + IntStream.range(0, 2000) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - POOL.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), POOL.submit(() -> ParallelAggregation.or(input)).join()); } @Test public void hugeOrInFJP3() { - RoaringBitmap[] input = IntStream.range(0, 4096) + RoaringBitmap[] input = + IntStream.range(0, 4096) .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build()) .toArray(RoaringBitmap[]::new); - assertEquals(FastAggregation.or(input), - POOL.submit(() -> ParallelAggregation.or(input)).join()); + assertEquals( + FastAggregation.or(input), POOL.submit(() -> ParallelAggregation.or(input)).join()); } @Test @@ -176,7 +188,6 @@ public void singleContainerXOR() { assertEquals(FastAggregation.xor(one, two, three), ParallelAggregation.xor(one, two, three)); } - @Test public void missingMiddleContainerXOR() { RoaringBitmap one = testCase().withRunAt(0).withBitmapAt(1).withArrayAt(2).build(); @@ -214,123 +225,216 @@ public void singleContainerOR_Buffer() { ImmutableRoaringBitmap one = testCase().withRunAt(0).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap two = testCase().withBitmapAt(0).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap three = testCase().withArrayAt(0).build().toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); + assertEquals( + BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); } @Test public void twoContainerOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withArrayAt(1).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap one = + testCase().withRunAt(0).withArrayAt(1).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap two = testCase().withBitmapAt(1).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap three = testCase().withArrayAt(1).build().toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); + assertEquals( + BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); } @Test public void disjointOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withArrayAt(2).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap one = + testCase().withRunAt(0).withArrayAt(2).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap two = testCase().withBitmapAt(1).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap three = testCase().withArrayAt(3).build().toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); + assertEquals( + BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); } @Test public void disjointBigKeysOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withArrayAt(2).withBitmapAt((1 << 15) | 1).build() - .toMutableRoaringBitmap(); - ImmutableRoaringBitmap two = testCase().withBitmapAt(1).withRunAt((1 << 15) | 2).build() - .toMutableRoaringBitmap(); - ImmutableRoaringBitmap three = testCase().withArrayAt(3).withRunAt((1 << 15) | 3).build() - .toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); + ImmutableRoaringBitmap one = + testCase() + .withRunAt(0) + .withArrayAt(2) + .withBitmapAt((1 << 15) | 1) + .build() + .toMutableRoaringBitmap(); + ImmutableRoaringBitmap two = + testCase().withBitmapAt(1).withRunAt((1 << 15) | 2).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap three = + testCase().withArrayAt(3).withRunAt((1 << 15) | 3).build().toMutableRoaringBitmap(); + assertEquals( + BufferFastAggregation.or(one, two, three), BufferParallelAggregation.or(one, two, three)); } @Test public void wideOr_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 20) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); + ImmutableRoaringBitmap[] input = + IntStream.range(0, 20) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); assertEquals(BufferFastAggregation.or(input), BufferParallelAggregation.or(input)); } @Test public void hugeOr1_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 513) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); + ImmutableRoaringBitmap[] input = + IntStream.range(0, 513) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); assertEquals(BufferFastAggregation.or(input), BufferParallelAggregation.or(input)); } - @Test public void hugeOr2_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 1999) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); + ImmutableRoaringBitmap[] input = + IntStream.range(0, 1999) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); assertEquals(BufferFastAggregation.or(input), BufferParallelAggregation.or(input)); } @Test public void hugeOr3_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 4096) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); + ImmutableRoaringBitmap[] input = + IntStream.range(0, 4096) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); assertEquals(BufferFastAggregation.or(input), BufferParallelAggregation.or(input)); } @Test public void hugeOrNoParallelismAvailable1_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 513) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); - assertEquals(BufferFastAggregation.or(input), + ImmutableRoaringBitmap[] input = + IntStream.range(0, 513) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); + assertEquals( + BufferFastAggregation.or(input), NO_PARALLELISM_AVAILABLE.submit(() -> BufferParallelAggregation.or(input)).join()); } - @Test public void hugeOrNoParallelismAvailable2_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 2000) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); - assertEquals(BufferFastAggregation.or(input), + ImmutableRoaringBitmap[] input = + IntStream.range(0, 2000) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); + assertEquals( + BufferFastAggregation.or(input), NO_PARALLELISM_AVAILABLE.submit(() -> BufferParallelAggregation.or(input)).join()); } @Test public void hugeOrNoParallelismAvailable3_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 4096) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); - assertEquals(BufferFastAggregation.or(input), + ImmutableRoaringBitmap[] input = + IntStream.range(0, 4096) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); + assertEquals( + BufferFastAggregation.or(input), NO_PARALLELISM_AVAILABLE.submit(() -> BufferParallelAggregation.or(input)).join()); } - @Test public void hugeOrInFJP1_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 513) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); - assertEquals(BufferFastAggregation.or(input), + ImmutableRoaringBitmap[] input = + IntStream.range(0, 513) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); + assertEquals( + BufferFastAggregation.or(input), POOL.submit(() -> BufferParallelAggregation.or(input)).join()); } - @Test public void hugeOrInFJP2_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 2000) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); - assertEquals(BufferFastAggregation.or(input), + ImmutableRoaringBitmap[] input = + IntStream.range(0, 2000) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); + assertEquals( + BufferFastAggregation.or(input), POOL.submit(() -> BufferParallelAggregation.or(input)).join()); } @Test public void hugeOrInFJP3_Buffer() { - ImmutableRoaringBitmap[] input = IntStream.range(0, 4096) - .mapToObj(i -> testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap()) - .toArray(ImmutableRoaringBitmap[]::new); - assertEquals(BufferFastAggregation.or(input), + ImmutableRoaringBitmap[] input = + IntStream.range(0, 4096) + .mapToObj( + i -> + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap()) + .toArray(ImmutableRoaringBitmap[]::new); + assertEquals( + BufferFastAggregation.or(input), POOL.submit(() -> BufferParallelAggregation.or(input)).join()); } @@ -339,46 +443,56 @@ public void singleContainerXOR_Buffer() { ImmutableRoaringBitmap one = testCase().withRunAt(0).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap two = testCase().withBitmapAt(0).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap three = testCase().withArrayAt(0).build().toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); + assertEquals( + BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); } - @Test public void missingMiddleContainerXOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withBitmapAt(1).withArrayAt(2).build() - .toMutableRoaringBitmap(); - ImmutableRoaringBitmap two = testCase().withBitmapAt(0).withArrayAt(2).build().toMutableRoaringBitmap(); - ImmutableRoaringBitmap three = testCase().withArrayAt(0).withBitmapAt(1).withArrayAt(2).build() - .toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); + ImmutableRoaringBitmap one = + testCase().withRunAt(0).withBitmapAt(1).withArrayAt(2).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap two = + testCase().withBitmapAt(0).withArrayAt(2).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap three = + testCase().withArrayAt(0).withBitmapAt(1).withArrayAt(2).build().toMutableRoaringBitmap(); + assertEquals( + BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); } @Test public void twoContainerXOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withArrayAt(1).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap one = + testCase().withRunAt(0).withArrayAt(1).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap two = testCase().withBitmapAt(1).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap three = testCase().withArrayAt(1).build().toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); + assertEquals( + BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); } @Test public void disjointXOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withArrayAt(2).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap one = + testCase().withRunAt(0).withArrayAt(2).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap two = testCase().withBitmapAt(1).build().toMutableRoaringBitmap(); ImmutableRoaringBitmap three = testCase().withArrayAt(3).build().toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); + assertEquals( + BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); } @Test public void disjointBigKeysXOR_Buffer() { - ImmutableRoaringBitmap one = testCase().withRunAt(0).withArrayAt(2).withBitmapAt((1 << 15) | 1).build() - .toMutableRoaringBitmap(); - ImmutableRoaringBitmap two = testCase().withBitmapAt(1).withRunAt((1 << 15) | 2).build() - .toMutableRoaringBitmap(); - ImmutableRoaringBitmap three = testCase().withArrayAt(3).withRunAt((1 << 15) | 3).build() - .toMutableRoaringBitmap(); - assertEquals(BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); + ImmutableRoaringBitmap one = + testCase() + .withRunAt(0) + .withArrayAt(2) + .withBitmapAt((1 << 15) | 1) + .build() + .toMutableRoaringBitmap(); + ImmutableRoaringBitmap two = + testCase().withBitmapAt(1).withRunAt((1 << 15) | 2).build().toMutableRoaringBitmap(); + ImmutableRoaringBitmap three = + testCase().withArrayAt(3).withRunAt((1 << 15) | 3).build().toMutableRoaringBitmap(); + assertEquals( + BufferFastAggregation.xor(one, two, three), BufferParallelAggregation.xor(one, two, three)); } - - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java index 29af1a14e..41e3805d6 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/PreviousValueTest.java @@ -1,20 +1,25 @@ package org.roaringbitmap; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.roaringbitmap.buffer.MutableRoaringBitmap; +import org.junit.jupiter.api.Test; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class PreviousValueTest { @Test public void regressionTest() throws IOException { int testValue = 1828834057; - String[] data = new String(Files.readAllBytes(Paths.get("src/test/resources/testdata/prevvalue-regression.txt"))).split(","); + String[] data = + new String( + Files.readAllBytes( + Paths.get("src/test/resources/testdata/prevvalue-regression.txt"))) + .split(","); RoaringBitmap bitmap = new RoaringBitmap(); Arrays.stream(data).map(Integer::parseInt).forEach(bitmap::add); assertEquals(bitmap.last(), bitmap.previousValue(testValue)); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java index 789753f13..62bf588e4 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RangeBitmapTest.java @@ -1,5 +1,15 @@ package org.roaringbitmap; +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.RangeBitmapTest.Distribution.EXP; +import static org.roaringbitmap.RangeBitmapTest.Distribution.NORMAL; +import static org.roaringbitmap.RangeBitmapTest.Distribution.POINT; +import static org.roaringbitmap.RangeBitmapTest.Distribution.UNIFORM; + import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -27,31 +37,24 @@ import java.util.stream.LongStream; import java.util.stream.Stream; -import static java.nio.ByteOrder.LITTLE_ENDIAN; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.roaringbitmap.RangeBitmapTest.Distribution.EXP; -import static org.roaringbitmap.RangeBitmapTest.Distribution.NORMAL; -import static org.roaringbitmap.RangeBitmapTest.Distribution.POINT; -import static org.roaringbitmap.RangeBitmapTest.Distribution.UNIFORM; - /** * When contributing test, please be mindful of the computational requirements. * We can use fuzzers to hunt for difficult-to-find bugs, but we should not * abuse the continuous-integration infrastructure. */ - @Execution(ExecutionMode.CONCURRENT) public class RangeBitmapTest { @Test public void betweenRegressionTest() throws IOException { - String[] lines = new String(Files.readAllBytes(Paths.get("src/test/resources/testdata/rangebitmap_regression.txt"))).split(","); + String[] lines = + new String( + Files.readAllBytes( + Paths.get("src/test/resources/testdata/rangebitmap_regression.txt"))) + .split(","); RangeBitmap.Appender appender = RangeBitmap.appender(2175288L); for (String line : lines) { - appender.add(Long.parseLong(line)); + appender.add(Long.parseLong(line)); } RangeBitmap bitmap = appender.build(); for (int i = 0; i < 4; i++) { @@ -236,17 +239,22 @@ public void verifyBufferCleanerCalled() { AtomicInteger cleanerInvocations = new AtomicInteger(); AtomicInteger supplierInvocations = new AtomicInteger(); Consumer cleaner = buffer -> cleanerInvocations.incrementAndGet(); - IntFunction supplier = capacity -> { - supplierInvocations.incrementAndGet(); - return ByteBuffer.allocate(capacity).order(LITTLE_ENDIAN); - }; + IntFunction supplier = + capacity -> { + supplierInvocations.incrementAndGet(); + return ByteBuffer.allocate(capacity).order(LITTLE_ENDIAN); + }; RangeBitmap.Appender appender = RangeBitmap.appender(1_000_000, supplier, cleaner); LongStream.range(0, 1_000_000).forEach(appender::add); ByteBuffer target = ByteBuffer.allocate(appender.serializedSizeInBytes()); appender.serialize(target); - assertEquals(supplierInvocations.get() - 2, cleanerInvocations.get(), + assertEquals( + supplierInvocations.get() - 2, + cleanerInvocations.get(), "two internal buffers remain active and uncleaned at any time, the rest must be cleaned"); - assertTrue(supplierInvocations.get() > 2, "this test requires more than 2 buffer allocations to ensure cleaning occurs"); + assertTrue( + supplierInvocations.get() > 2, + "this test requires more than 2 buffer allocations to ensure cleaning occurs"); } @Test @@ -265,15 +273,17 @@ public void testSerializeBigSlices() { RangeBitmap.Appender appender = RangeBitmap.appender(-1L); IntStream.range(0, 1_000_000) .mapToDouble(i -> random.nextGaussian()) - .mapToLong(value -> { - long bits = Double.doubleToLongBits(value); - if ((bits & Long.MIN_VALUE) == Long.MIN_VALUE) { - bits = bits == Long.MIN_VALUE ? Long.MIN_VALUE : ~bits; - } else { - bits ^= Long.MIN_VALUE; - } - return bits; - }).forEach(appender::add); + .mapToLong( + value -> { + long bits = Double.doubleToLongBits(value); + if ((bits & Long.MIN_VALUE) == Long.MIN_VALUE) { + bits = bits == Long.MIN_VALUE ? Long.MIN_VALUE : ~bits; + } else { + bits ^= Long.MIN_VALUE; + } + return bits; + }) + .forEach(appender::add); ByteBuffer buffer = ByteBuffer.allocate(appender.serializedSizeInBytes()); appender.serialize(buffer); buffer.flip(); @@ -283,11 +293,27 @@ public void testSerializeBigSlices() { } @ParameterizedTest - @ValueSource(longs = {1L, 0xFL, 0xFFL, 0xFFFL, 0xFFFFL, - 0xFFFFFL, 0xFFFFFFL, 0xFFFFFFL, 0xFFFFFFFL, 0xFFFFFFFFL, - 0xFFFFFFFFFL, 0xFFFFFFFFFFL, 0xFFFFFFFFFFFL, - 0xFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFL, - 0xFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL}) + @ValueSource( + longs = { + 1L, + 0xFL, + 0xFFL, + 0xFFFL, + 0xFFFFL, + 0xFFFFFL, + 0xFFFFFFL, + 0xFFFFFFL, + 0xFFFFFFFL, + 0xFFFFFFFFL, + 0xFFFFFFFFFL, + 0xFFFFFFFFFFL, + 0xFFFFFFFFFFFL, + 0xFFFFFFFFFFFFL, + 0xFFFFFFFFFFFFFL, + 0xFFFFFFFFFFFFFFL, + 0xFFFFFFFFFFFFFFFL, + 0xFFFFFFFFFFFFFFFFL + }) public void testSerializeEmpty(long maxValue) { RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); ByteBuffer buffer = ByteBuffer.allocate(appender.serializedSizeInBytes()); @@ -341,24 +367,24 @@ public void testConstructRelativeToMinValue(LongSupplier dist) { public static Stream distributions() { return Stream.of( - NORMAL.of(42, 1_000, 100), - NORMAL.of(42, 10_000, 10), - NORMAL.of(42, 1_000_000, 1000), - UNIFORM.of(42, 0, 1_000_000), - UNIFORM.of(42, 500_000, 10_000_000), - EXP.of(42, 0.0001), - EXP.of(42, 0.9999), - POINT.of(0, 0), - POINT.of(0, 1), - POINT.of(0, 2), - POINT.of(0, 3), - POINT.of(0, 4), - POINT.of(0, 7), - POINT.of(0, 8), - POINT.of(0, 15), - POINT.of(0, 31), - POINT.of(0, Long.MAX_VALUE) - ).map(Arguments::of); + NORMAL.of(42, 1_000, 100), + NORMAL.of(42, 10_000, 10), + NORMAL.of(42, 1_000_000, 1000), + UNIFORM.of(42, 0, 1_000_000), + UNIFORM.of(42, 500_000, 10_000_000), + EXP.of(42, 0.0001), + EXP.of(42, 0.9999), + POINT.of(0, 0), + POINT.of(0, 1), + POINT.of(0, 2), + POINT.of(0, 3), + POINT.of(0, 4), + POINT.of(0, 7), + POINT.of(0, 8), + POINT.of(0, 15), + POINT.of(0, 31), + POINT.of(0, Long.MAX_VALUE)) + .map(Arguments::of); } @ParameterizedTest @@ -369,18 +395,25 @@ public void testAgainstReferenceImplementation(LongSupplier dist) { RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); LongStream.range(0, 1_000_000) .map(i -> Math.min(dist.getAsLong(), maxValue)) - .forEach(v -> { - builder.add(v); - appender.add(v); - }); + .forEach( + v -> { + builder.add(v); + appender.add(v); + }); ReferenceImplementation referenceImplementation = builder.seal(); RangeBitmap sut = appender.build(); - assertAll(LongStream.range(0, 7) - .map(i -> (long) Math.pow(10, i)) - .mapToObj(threshold -> () -> { - assertEquals(referenceImplementation.lessThanOrEqualTo(threshold), sut.lte(threshold)); - assertEquals(referenceImplementation.lessThanOrEqualTo(threshold).getCardinality(), sut.lteCardinality(threshold)); - })); + assertAll( + LongStream.range(0, 7) + .map(i -> (long) Math.pow(10, i)) + .mapToObj( + threshold -> + () -> { + assertEquals( + referenceImplementation.lessThanOrEqualTo(threshold), sut.lte(threshold)); + assertEquals( + referenceImplementation.lessThanOrEqualTo(threshold).getCardinality(), + sut.lteCardinality(threshold)); + })); } @ParameterizedTest @@ -391,89 +424,132 @@ public void testAgainstPrecomputed(LongSupplier dist) { ReferenceImplementation.Builder builder = ReferenceImplementation.builder(); RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); RoaringBitmapWriter[] recorders = - LongStream.range(0, 7).map(i -> (long) Math.pow(10, i)).mapToObj(i -> RoaringBitmapWriter.writer().runCompress(true).get()).toArray(RoaringBitmapWriter[]::new); + LongStream.range(0, 7) + .map(i -> (long) Math.pow(10, i)) + .mapToObj(i -> RoaringBitmapWriter.writer().runCompress(true).get()) + .toArray(RoaringBitmapWriter[]::new); LongStream.range(0, 1_000_000) - .forEach(i -> { - long v = Math.min(dist.getAsLong(), maxValue); - for (int p = 0; p < 7; ++p) { - if (v <= (long) Math.pow(10, p)) { - recorders[p].add((int) i); - } - } - builder.add(v); - appender.add(v); - }); - RoaringBitmap[] precomputed = Arrays.stream(recorders).map(RoaringBitmapWriter::get).toArray(RoaringBitmap[]::new); + .forEach( + i -> { + long v = Math.min(dist.getAsLong(), maxValue); + for (int p = 0; p < 7; ++p) { + if (v <= (long) Math.pow(10, p)) { + recorders[p].add((int) i); + } + } + builder.add(v); + appender.add(v); + }); + RoaringBitmap[] precomputed = + Arrays.stream(recorders).map(RoaringBitmapWriter::get).toArray(RoaringBitmap[]::new); RoaringBitmap all = RoaringBitmap.bitmapOfRange(0, 1_000_000); RangeBitmap sut = appender.build(); - assertAll(IntStream.range(0, 7).mapToObj(i -> () -> { - assertEquals(precomputed[i], sut.lte((long) Math.pow(10, i))); - assertEquals(precomputed[i].getCardinality(), sut.lteCardinality((long) Math.pow(10, i))); - })); - assertAll(IntStream.range(0, 7).mapToObj(i -> () -> { - assertEquals(all, RoaringBitmap.or((sut.lte((long) Math.pow(10, i))), sut.gt((long) Math.pow(10, i)))); - assertEquals(all.getCardinality(), sut.lteCardinality((long) Math.pow(10, i)) + sut.gtCardinality((long) Math.pow(10, i))); - })); - assertAll(IntStream.range(0, 7).mapToObj(i -> () -> { - assertEquals(all, RoaringBitmap.or((sut.lt((long) Math.pow(10, i))), sut.gte((long) Math.pow(10, i)))); - assertEquals(all.getCardinality(), sut.ltCardinality((long) Math.pow(10, i)) + sut.gteCardinality((long) Math.pow(10, i))); - })); - assertAll(IntStream.range(0, 7).mapToObj(i -> () -> { - assertEquals(RoaringBitmap.andNot(all, precomputed[i]), sut.gt((long) Math.pow(10, i))); - assertEquals(RoaringBitmap.andNot(all, precomputed[i]).getCardinality(), sut.gtCardinality((long) Math.pow(10, i))); - })); + assertAll( + IntStream.range(0, 7) + .mapToObj( + i -> + () -> { + assertEquals(precomputed[i], sut.lte((long) Math.pow(10, i))); + assertEquals( + precomputed[i].getCardinality(), + sut.lteCardinality((long) Math.pow(10, i))); + })); + assertAll( + IntStream.range(0, 7) + .mapToObj( + i -> + () -> { + assertEquals( + all, + RoaringBitmap.or( + (sut.lte((long) Math.pow(10, i))), sut.gt((long) Math.pow(10, i)))); + assertEquals( + all.getCardinality(), + sut.lteCardinality((long) Math.pow(10, i)) + + sut.gtCardinality((long) Math.pow(10, i))); + })); + assertAll( + IntStream.range(0, 7) + .mapToObj( + i -> + () -> { + assertEquals( + all, + RoaringBitmap.or( + (sut.lt((long) Math.pow(10, i))), sut.gte((long) Math.pow(10, i)))); + assertEquals( + all.getCardinality(), + sut.ltCardinality((long) Math.pow(10, i)) + + sut.gteCardinality((long) Math.pow(10, i))); + })); + assertAll( + IntStream.range(0, 7) + .mapToObj( + i -> + () -> { + assertEquals( + RoaringBitmap.andNot(all, precomputed[i]), + sut.gt((long) Math.pow(10, i))); + assertEquals( + RoaringBitmap.andNot(all, precomputed[i]).getCardinality(), + sut.gtCardinality((long) Math.pow(10, i))); + })); } - @ParameterizedTest @MethodSource("distributions") public void testContextualRangeEvaluationAgainstNonContextual(LongSupplier dist) { long maxValue = 10_000_000; RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); LongStream.range(0, 1_000_000) - .forEach(i -> { - long v = Math.min(dist.getAsLong(), maxValue); - appender.add(v); - }); + .forEach( + i -> { + long v = Math.min(dist.getAsLong(), maxValue); + appender.add(v); + }); RangeBitmap sut = appender.build(); - IntStream.range(1, 8).forEach(i -> { - long min = (long) Math.pow(10, i - 1); - long max = (long) Math.pow(10, i); - RoaringBitmap lte = sut.lte(max); - RoaringBitmap gte = sut.gte(min); - RoaringBitmap expected = RoaringBitmap.and(lte, gte); - assertEquals(expected, sut.gte(min, lte)); - assertEquals(expected.getCardinality(), sut.gteCardinality(min, lte), "" + i); - assertEquals(expected, sut.lte(max, gte)); - assertEquals(expected.getCardinality(), sut.lteCardinality(max, gte)); - assertEquals(expected, sut.lt(max + 1, gte)); - assertEquals(expected.getCardinality(), sut.ltCardinality(max + 1, gte)); - assertEquals(expected, sut.gt(min - 1, lte)); - assertEquals(expected.getCardinality(), sut.gtCardinality(min - 1, lte)); - }); + IntStream.range(1, 8) + .forEach( + i -> { + long min = (long) Math.pow(10, i - 1); + long max = (long) Math.pow(10, i); + RoaringBitmap lte = sut.lte(max); + RoaringBitmap gte = sut.gte(min); + RoaringBitmap expected = RoaringBitmap.and(lte, gte); + assertEquals(expected, sut.gte(min, lte)); + assertEquals(expected.getCardinality(), sut.gteCardinality(min, lte), "" + i); + assertEquals(expected, sut.lte(max, gte)); + assertEquals(expected.getCardinality(), sut.lteCardinality(max, gte)); + assertEquals(expected, sut.lt(max + 1, gte)); + assertEquals(expected.getCardinality(), sut.ltCardinality(max + 1, gte)); + assertEquals(expected, sut.gt(min - 1, lte)); + assertEquals(expected.getCardinality(), sut.gtCardinality(min - 1, lte)); + }); } - @ParameterizedTest @MethodSource("distributions") public void testDoubleEndedRangeEvaluationAgainstNonContextual(LongSupplier dist) { long maxValue = 10_000_000; RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); LongStream.range(0, 1_000_000) - .forEach(i -> { - long v = Math.min(dist.getAsLong(), maxValue); - appender.add(v); - }); + .forEach( + i -> { + long v = Math.min(dist.getAsLong(), maxValue); + appender.add(v); + }); RangeBitmap sut = appender.build(); - IntStream.range(1, 8).forEach(i -> { - long min = (long) Math.pow(10, i - 1); - long max = (long) Math.pow(10, i); - RoaringBitmap lte = sut.lte(max); - RoaringBitmap gte = sut.gte(min); - RoaringBitmap expected = RoaringBitmap.and(lte, gte); - assertEquals(expected, sut.between(min, max)); - assertEquals(expected.getCardinality(), sut.betweenCardinality(min, max)); - }); + IntStream.range(1, 8) + .forEach( + i -> { + long min = (long) Math.pow(10, i - 1); + long max = (long) Math.pow(10, i); + RoaringBitmap lte = sut.lte(max); + RoaringBitmap gte = sut.gte(min); + RoaringBitmap expected = RoaringBitmap.and(lte, gte); + assertEquals(expected, sut.between(min, max)); + assertEquals(expected.getCardinality(), sut.betweenCardinality(min, max)); + }); } @Test @@ -514,101 +590,276 @@ public void testBetween2() { assertEquals(7, sut.betweenCardinality(2, 8)); assertEquals(RoaringBitmap.bitmapOfRange(3, 8), sut.between(3, 7)); assertEquals(5, sut.betweenCardinality(3, 7)); - assertEquals(RoaringBitmap.bitmapOfRange(0x10000 - 5, 0x10000 + 6), sut.between(0x10000 - 5, 0x10000 + 5)); + assertEquals( + RoaringBitmap.bitmapOfRange(0x10000 - 5, 0x10000 + 6), + sut.between(0x10000 - 5, 0x10000 + 5)); assertEquals(11, RoaringBitmap.bitmapOfRange(0x10000 - 5, 0x10000 + 6).getCardinality()); assertEquals(11, sut.betweenCardinality(0x10000 - 5, 0x10000 + 5)); } @Test public void testBetween3() { - long[] values = {-4616189618054758400L, 4601552919265804287L, -4586634745500139520L, 4571364728013586431L}; + long[] values = { + -4616189618054758400L, 4601552919265804287L, -4586634745500139520L, 4571364728013586431L + }; RangeBitmap.Appender appender = RangeBitmap.appender(-4586634745500139520L); Arrays.stream(values).forEach(appender::add); int numSequentialValues = 1 << 20; LongStream.range(0, numSequentialValues).forEach(appender::add); RangeBitmap sut = appender.build(); RoaringBitmap sequentialValues = RoaringBitmap.bitmapOfRange(4, numSequentialValues + 4); - assertEquals(RoaringBitmap.bitmapOf(0), sut.between(-4620693217682128896L, -4616189618054758400L)); + assertEquals( + RoaringBitmap.bitmapOf(0), sut.between(-4620693217682128896L, -4616189618054758400L)); assertEquals(1, sut.betweenCardinality(-4620693217682128896L, -4616189618054758400L)); assertEquals(RoaringBitmap.bitmapOfRange(5, 47), sut.between(1, 42)); assertEquals(42, sut.betweenCardinality(1, 42)); - assertEquals(RoaringBitmap.or(RoaringBitmap.bitmapOf(3), sequentialValues), sut.between(0, 4571364728013586431L)); - assertEquals(RoaringBitmap.or(RoaringBitmap.bitmapOf(3), sequentialValues).getCardinality(), sut.betweenCardinality(0, 4571364728013586431L)); - assertEquals(RoaringBitmap.or(RoaringBitmap.bitmapOf(1, 3), sequentialValues), sut.between(0, 4601552919265804287L)); - assertEquals(RoaringBitmap.or(RoaringBitmap.bitmapOf(1, 3), sequentialValues).getCardinality(), sut.betweenCardinality(0, 4601552919265804287L)); + assertEquals( + RoaringBitmap.or(RoaringBitmap.bitmapOf(3), sequentialValues), + sut.between(0, 4571364728013586431L)); + assertEquals( + RoaringBitmap.or(RoaringBitmap.bitmapOf(3), sequentialValues).getCardinality(), + sut.betweenCardinality(0, 4571364728013586431L)); + assertEquals( + RoaringBitmap.or(RoaringBitmap.bitmapOf(1, 3), sequentialValues), + sut.between(0, 4601552919265804287L)); + assertEquals( + RoaringBitmap.or(RoaringBitmap.bitmapOf(1, 3), sequentialValues).getCardinality(), + sut.betweenCardinality(0, 4601552919265804287L)); assertEquals(RoaringBitmap.bitmapOf(0), sut.between(Long.MAX_VALUE, -4616189618054758400L)); assertEquals(1, sut.betweenCardinality(Long.MAX_VALUE, -4616189618054758400L)); assertEquals(RoaringBitmap.bitmapOf(0, 2), sut.between(Long.MAX_VALUE, -4586634745500139520L)); assertEquals(2, sut.betweenCardinality(Long.MAX_VALUE, -4586634745500139520L)); - assertEquals(RoaringBitmap.bitmapOfRange(0, numSequentialValues + 4), sut.between(0, 0xFFFFFFFFFFFFFFFFL)); - assertEquals(RoaringBitmap.bitmapOfRange(0, numSequentialValues + 4).getCardinality(), sut.betweenCardinality(0, 0xFFFFFFFFFFFFFFFFL)); - assertEquals(RoaringBitmap.bitmapOfRange(0, 4), sut.between(4571364728013586431L, -4586634745500139520L)); + assertEquals( + RoaringBitmap.bitmapOfRange(0, numSequentialValues + 4), + sut.between(0, 0xFFFFFFFFFFFFFFFFL)); + assertEquals( + RoaringBitmap.bitmapOfRange(0, numSequentialValues + 4).getCardinality(), + sut.betweenCardinality(0, 0xFFFFFFFFFFFFFFFFL)); + assertEquals( + RoaringBitmap.bitmapOfRange(0, 4), + sut.between(4571364728013586431L, -4586634745500139520L)); assertEquals(4, sut.betweenCardinality(4571364728013586431L, -4586634745500139520L)); assertEquals(RoaringBitmap.bitmapOf(0, 2), sut.between(Long.MAX_VALUE, 0xFFFFFFFFFFFFFFFFL)); assertEquals(2, sut.betweenCardinality(Long.MAX_VALUE, 0xFFFFFFFFFFFFFFFFL)); - assertEquals(RoaringBitmap.or(RoaringBitmap.bitmapOf(1, 3), sequentialValues), sut.between(0, Long.MAX_VALUE)); - assertEquals(RoaringBitmap.orCardinality(RoaringBitmap.bitmapOf(1, 3), sequentialValues), sut.betweenCardinality(0, Long.MAX_VALUE)); + assertEquals( + RoaringBitmap.or(RoaringBitmap.bitmapOf(1, 3), sequentialValues), + sut.between(0, Long.MAX_VALUE)); + assertEquals( + RoaringBitmap.orCardinality(RoaringBitmap.bitmapOf(1, 3), sequentialValues), + sut.betweenCardinality(0, Long.MAX_VALUE)); assertEquals(new RoaringBitmap(), sut.between(-42, 0xFFFFFFFFFFFFFFFFL)); assertEquals(0, sut.betweenCardinality(-42, 0xFFFFFFFFFFFFFFFFL)); } @Test public void testBetween4() { - long[] values = {-4616189618054758400L, 4601552919265804287L, -4586634745500139520L, 4571364728013586431L, - -4556648864387432448L, 4541763675970600959L, -4526534890170089472L, 4511741717132607487L, - -4496888740970496000L, 4481700220488384511L, -4466831549978902528L, 4452010031096791039L, - -4436860832214679552L, 4421918433705197567L, -4407127634823086080L, 4392016835940974591L, - -4377002437431492608L, 4362241638549381119L, -4347168339667269632L, 4332083628657787647L, - -4317352126650676160L, 4302315448862314671L, -4287162073302051438L, 4272459181524432137L, - -4257458266522935884L, 4242237835737300334L, -4227562883636919499L, 4212596893231971325L, - -4197310978827808127L, 4182663311568480478L, -4167731427214848790L, 4152444271493337051L, - -4137760542057730537L, 4122861964394837603L, -4107616442036749309L, 4092854650044723837L, - -4077988598447005469L, 4062783733670385380L, -4047945708713107023L, 4033111420850910690L, - -4017946260743693147L, 4003033789531285016L, -3988230520942059423L, 3973104134926055302L, - -3958118962292622004L, 3943345985962156897L, -3928257465269603386L, 3913201295154700195L, - -3898457901108180877L, 3883406358270559600L, -3868280854677658470L, 3853566349580304959L, - -3838550917929140944L, 3823357705861632449L, -3808671412628698674L, 3793691245808059326L, - -3778431912183317079L, 3763773169599230700L, -3748827441089650601L, 3733522980173203346L, - -3718871697978100924L, 3703959600631664618L, -3688697178669147109L, 3673967073435426414L, - -3659087819021747723L, 3643866450725177229L, -3629059369867805881L, 3614212188630648294L, - -3599030911804729185L, 3584148659439886491L, -3569332799664175299L, 3554190674665064179L, - -3539235012624956505L, 3524449740213939054L, -3509345849420695115L, 3494318498244586478L, - -3479563096306902762L, 3464496543605325988L, -3449399183507341415L, 3434672951953772672L, - -3419642862232339617L, 3404477134046585572L, -3389779389196254110L, 3374784907853867652L, - -3359552413957401235L, 3344882488153199927L, -3329922780618476166L, 3314625085832642195L, - -3299982327065677369L, 3285056578327499206L, -3269777092125304377L, 3255078982340978658L, - -3240186396490052060L, 3224948363896921682L, -3210172528595600116L, 3195312328376755120L, - -3180114777823726749L, 3165263038697213921L, -3150434465072198619L, 3135276447761457361L, - -3120350583805656195L, 3105552895526177699L, -3090433484897357453L, 3075435233412954391L, - -3060667706603726686L, 3045585997812719925L, -3030517055382416577L, 3015778983133980657L, - -3000734092543963630L, 2985596115986804532L, -2970886807957891842L, 2955877872642278850L, - -2940672479945612186L, 2925991261974827647L, -2911017439231874848L, 2895746210461470323L, - -2881092424188076561L, 2866152891066862228L, -2850856174385872187L, 2836190371749287492L, - -2821284324586802134L, 2806029465354223306L, -2791285180001867583L, 2776411833970953486L, - -2761197851152838739L, 2746376922523362867L, -2731535511191248833L, 2716361446746634160L, - -2701465671166845646L, 2686655446064028545L, -2671520364406035042L, 2656551496101331837L, - -2641771726300562525L, 2626674713770128755L, -2611634465851251049L, 2596884437556387778L, - -2581824601908336563L, 2566714647334991567L, -2551993663479489668L, 2536970133380640164L, - -2521792105902541959L, 2507099485757353896L, -2492111410296396691L, 2476866905372250427L, - -2462201984162915723L, 2447248532371775213L, -2431939108066722645L, 2417301236599432233L, - -2402381596985847092L, 2387109747189393536L, -2372397319144302929L, 2357510699235361700L, - -2342280124069713038L, 2327490306091863256L, -2312635931988238351L, 2297445664079235090L, - -2282580269995175180L, 2267757385935804494L, -2252606480582119011L, 2237667281706838269L, - -2222875149643809597L, 2207762684285551627L, -2192751410418844296L, 2177989309602243369L, - -2162914383302020084L, 2147832723701497720L, -2133099950273986391L, 2118061683210125099L, - -2102911287541423996L, 2088207154142320474L, -2073204687113968945L, 2057987166378687038L, - -2043311001757325518L, 2028343495701151489L, -2013060423143036769L, 1998411571781188921L, - -1983478207299406984L, 1968189201417707433L, -1953508941032453066L, 1938608917931913404L, - -1923361588776766700L, 1908603184529225747L, -1893735721371305496L, 1878529092144433054L, - -1863694375531377859L, 1848858709192421875L, -1833691825989254769L, 1818782585581752070L, - -1803977970823815880L, 1788849902096923513L, -1773867884546405676L, 1759093593598059126L, - -1744003429633153813L, 1728950340653910252L, -1714205662800866089L, 1699152515205088754L, - -1684030020533730232L, 1669314261719067301L, -1654297262921266511L, 1639106989253701968L, + long[] values = { + -4616189618054758400L, + 4601552919265804287L, + -4586634745500139520L, + 4571364728013586431L, + -4556648864387432448L, + 4541763675970600959L, + -4526534890170089472L, + 4511741717132607487L, + -4496888740970496000L, + 4481700220488384511L, + -4466831549978902528L, + 4452010031096791039L, + -4436860832214679552L, + 4421918433705197567L, + -4407127634823086080L, + 4392016835940974591L, + -4377002437431492608L, + 4362241638549381119L, + -4347168339667269632L, + 4332083628657787647L, + -4317352126650676160L, + 4302315448862314671L, + -4287162073302051438L, + 4272459181524432137L, + -4257458266522935884L, + 4242237835737300334L, + -4227562883636919499L, + 4212596893231971325L, + -4197310978827808127L, + 4182663311568480478L, + -4167731427214848790L, + 4152444271493337051L, + -4137760542057730537L, + 4122861964394837603L, + -4107616442036749309L, + 4092854650044723837L, + -4077988598447005469L, + 4062783733670385380L, + -4047945708713107023L, + 4033111420850910690L, + -4017946260743693147L, + 4003033789531285016L, + -3988230520942059423L, + 3973104134926055302L, + -3958118962292622004L, + 3943345985962156897L, + -3928257465269603386L, + 3913201295154700195L, + -3898457901108180877L, + 3883406358270559600L, + -3868280854677658470L, + 3853566349580304959L, + -3838550917929140944L, + 3823357705861632449L, + -3808671412628698674L, + 3793691245808059326L, + -3778431912183317079L, + 3763773169599230700L, + -3748827441089650601L, + 3733522980173203346L, + -3718871697978100924L, + 3703959600631664618L, + -3688697178669147109L, + 3673967073435426414L, + -3659087819021747723L, + 3643866450725177229L, + -3629059369867805881L, + 3614212188630648294L, + -3599030911804729185L, + 3584148659439886491L, + -3569332799664175299L, + 3554190674665064179L, + -3539235012624956505L, + 3524449740213939054L, + -3509345849420695115L, + 3494318498244586478L, + -3479563096306902762L, + 3464496543605325988L, + -3449399183507341415L, + 3434672951953772672L, + -3419642862232339617L, + 3404477134046585572L, + -3389779389196254110L, + 3374784907853867652L, + -3359552413957401235L, + 3344882488153199927L, + -3329922780618476166L, + 3314625085832642195L, + -3299982327065677369L, + 3285056578327499206L, + -3269777092125304377L, + 3255078982340978658L, + -3240186396490052060L, + 3224948363896921682L, + -3210172528595600116L, + 3195312328376755120L, + -3180114777823726749L, + 3165263038697213921L, + -3150434465072198619L, + 3135276447761457361L, + -3120350583805656195L, + 3105552895526177699L, + -3090433484897357453L, + 3075435233412954391L, + -3060667706603726686L, + 3045585997812719925L, + -3030517055382416577L, + 3015778983133980657L, + -3000734092543963630L, + 2985596115986804532L, + -2970886807957891842L, + 2955877872642278850L, + -2940672479945612186L, + 2925991261974827647L, + -2911017439231874848L, + 2895746210461470323L, + -2881092424188076561L, + 2866152891066862228L, + -2850856174385872187L, + 2836190371749287492L, + -2821284324586802134L, + 2806029465354223306L, + -2791285180001867583L, + 2776411833970953486L, + -2761197851152838739L, + 2746376922523362867L, + -2731535511191248833L, + 2716361446746634160L, + -2701465671166845646L, + 2686655446064028545L, + -2671520364406035042L, + 2656551496101331837L, + -2641771726300562525L, + 2626674713770128755L, + -2611634465851251049L, + 2596884437556387778L, + -2581824601908336563L, + 2566714647334991567L, + -2551993663479489668L, + 2536970133380640164L, + -2521792105902541959L, + 2507099485757353896L, + -2492111410296396691L, + 2476866905372250427L, + -2462201984162915723L, + 2447248532371775213L, + -2431939108066722645L, + 2417301236599432233L, + -2402381596985847092L, + 2387109747189393536L, + -2372397319144302929L, + 2357510699235361700L, + -2342280124069713038L, + 2327490306091863256L, + -2312635931988238351L, + 2297445664079235090L, + -2282580269995175180L, + 2267757385935804494L, + -2252606480582119011L, + 2237667281706838269L, + -2222875149643809597L, + 2207762684285551627L, + -2192751410418844296L, + 2177989309602243369L, + -2162914383302020084L, + 2147832723701497720L, + -2133099950273986391L, + 2118061683210125099L, + -2102911287541423996L, + 2088207154142320474L, + -2073204687113968945L, + 2057987166378687038L, + -2043311001757325518L, + 2028343495701151489L, + -2013060423143036769L, + 1998411571781188921L, + -1983478207299406984L, + 1968189201417707433L, + -1953508941032453066L, + 1938608917931913404L, + -1923361588776766700L, + 1908603184529225747L, + -1893735721371305496L, + 1878529092144433054L, + -1863694375531377859L, + 1848858709192421875L, + -1833691825989254769L, + 1818782585581752070L, + -1803977970823815880L, + 1788849902096923513L, + -1773867884546405676L, + 1759093593598059126L, + -1744003429633153813L, + 1728950340653910252L, + -1714205662800866089L, + 1699152515205088754L, + -1684030020533730232L, + 1669314261719067301L, + -1654297262921266511L, + 1639106989253701968L, }; RangeBitmap.Appender appender = RangeBitmap.appender(0xFFFFFFFFFFFFFFFFL); Arrays.stream(values).forEach(appender::add); RangeBitmap sut = appender.build(); - assertEquals(RoaringBitmap.bitmapOf(0), sut.between(-4620693217682128896L, -4616189618054758400L)); + assertEquals( + RoaringBitmap.bitmapOf(0), sut.between(-4620693217682128896L, -4616189618054758400L)); assertEquals(1, sut.betweenCardinality(-4620693217682128896L, -4616189618054758400L)); } @@ -619,11 +870,12 @@ public void testContextualBetweenCardinality(LongSupplier dist) { RangeBitmap.Appender appender = RangeBitmap.appender(maxValue); long[] thresholds = new long[256]; LongStream.range(0, 1_000_000) - .forEach(i -> { - long v = Math.min(dist.getAsLong(), maxValue); - thresholds[(int)i & 255] = v; - appender.add(v); - }); + .forEach( + i -> { + long v = Math.min(dist.getAsLong(), maxValue); + thresholds[(int) i & 255] = v; + appender.add(v); + }); RangeBitmap sut = appender.build(); long numRows = sut.gteCardinality(0L); RoaringBitmap context = new RoaringBitmap(); @@ -633,7 +885,7 @@ public void testContextualBetweenCardinality(LongSupplier dist) { Arrays.sort(thresholds); for (int i = 0; i < thresholds.length; i += 2) { long min = thresholds[i]; - long max = thresholds[i+1]; + long max = thresholds[i + 1]; long contextualCardinality = sut.betweenCardinality(min, max, context); RoaringBitmap bitmap = sut.between(min, max); bitmap.and(context); @@ -701,26 +953,28 @@ public void testExtremeValues() { } // creates very large integer values so stresses edge cases in the top slice - private static final DoubleToLongFunction DOUBLE_ENCODER = value -> { - if (value == Double.NEGATIVE_INFINITY) { - return 0; - } - if (value == Double.POSITIVE_INFINITY || Double.isNaN(value)) { - return 0xFFFFFFFFFFFFFFFFL; - } - long bits = Double.doubleToLongBits(value); - if ((bits & Long.MIN_VALUE) == Long.MIN_VALUE) { - bits = bits == Long.MIN_VALUE ? Long.MIN_VALUE : ~bits; - } else { - bits ^= Long.MIN_VALUE; - } - return bits; - }; + private static final DoubleToLongFunction DOUBLE_ENCODER = + value -> { + if (value == Double.NEGATIVE_INFINITY) { + return 0; + } + if (value == Double.POSITIVE_INFINITY || Double.isNaN(value)) { + return 0xFFFFFFFFFFFFFFFFL; + } + long bits = Double.doubleToLongBits(value); + if ((bits & Long.MIN_VALUE) == Long.MIN_VALUE) { + bits = bits == Long.MIN_VALUE ? Long.MIN_VALUE : ~bits; + } else { + bits ^= Long.MIN_VALUE; + } + return bits; + }; @Test public void testIndexDoubleValues() { RangeBitmap.Appender appender = RangeBitmap.appender(-1L); - double[] doubles = IntStream.range(0, 200).mapToDouble(i -> Math.pow(-1, i) * Math.pow(10, i)).toArray(); + double[] doubles = + IntStream.range(0, 200).mapToDouble(i -> Math.pow(-1, i) * Math.pow(10, i)).toArray(); Arrays.stream(doubles).mapToLong(DOUBLE_ENCODER).forEach(appender::add); RangeBitmap bitmap = appender.build(); for (double value : doubles) { @@ -740,7 +994,8 @@ public void testIndexDoubleValues() { @Test public void testBetweenDoubleValues() { RangeBitmap.Appender appender = RangeBitmap.appender(-1L); - double[] doubles = IntStream.range(0, 200).mapToDouble(i -> Math.pow(-1, i) * Math.pow(10, i)).toArray(); + double[] doubles = + IntStream.range(0, 200).mapToDouble(i -> Math.pow(-1, i) * Math.pow(10, i)).toArray(); Arrays.stream(doubles).mapToLong(DOUBLE_ENCODER).forEach(appender::add); RangeBitmap bitmap = appender.build(); for (double value : doubles) { @@ -759,7 +1014,7 @@ public void testBetweenDoubleValues() { } @ParameterizedTest - @ValueSource(longs = {1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64}) + @ValueSource(longs = {1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64}) public void extremelySmallBitmapTest(long value) { RangeBitmap.Appender accumulator = RangeBitmap.appender(value); accumulator.add(value); @@ -772,7 +1027,7 @@ public void extremelySmallBitmapTest(long value) { } @ParameterizedTest - @ValueSource(longs = {1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64}) + @ValueSource(longs = {1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64}) public void testModulo65536(long value) { int count = 65537; RangeBitmap.Appender accumulator = RangeBitmap.appender(value); @@ -786,15 +1041,17 @@ public void testModulo65536(long value) { assertEquals(accumulator.build().between(value, value).getCardinality(), count); assertEquals(accumulator.build().betweenCardinality(value, value), count); } + @Test public void regressionTestIssue586() { // see https://github.com/RoaringBitmap/RoaringBitmap/issues/586 assertAll( - () -> regresssionTestIssue586(0x0FFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFF0L, 0xFFFFFFFFFFFFFF0L), - () -> regresssionTestIssue586(0x0FFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFF0L, 0xFFFFFFFFFFFFFFF0L), - () -> regresssionTestIssue586(0x0FFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFF1L, 0xFFFFFFFFFFFFFFF0L), - () -> regresssionTestIssue586(0, 10_000_000_000L, 10_000_000L) - ); + () -> regresssionTestIssue586(0x0FFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFF0L, 0xFFFFFFFFFFFFFF0L), + () -> + regresssionTestIssue586(0x0FFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFF0L, 0xFFFFFFFFFFFFFFF0L), + () -> + regresssionTestIssue586(0x0FFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFF1L, 0xFFFFFFFFFFFFFFF0L), + () -> regresssionTestIssue586(0, 10_000_000_000L, 10_000_000L)); } @Test @@ -806,7 +1063,7 @@ public void regressionTestIssue588() { RoaringBitmap bitmap = RoaringBitmap.bitmapOf(valueInBitmap); assertTrue(bitmap.intersects(minValueThatWorks, baseValue)); - assertTrue(bitmap.intersects(minValueThatWorks-1, baseValue)); + assertTrue(bitmap.intersects(minValueThatWorks - 1, baseValue)); } private static void regresssionTestIssue586(long low, long high, long value) { @@ -848,15 +1105,18 @@ public void testEqWithContext(int max) { RangeBitmap bitmap = appender.build(); for (int offset = 0; offset < max; offset++) { assertEquals(expected[offset], bitmap.eq(offset, expected[offset])); - assertEquals(expected[offset].getLongCardinality(), bitmap.eqCardinality(offset, expected[offset])); + assertEquals( + expected[offset].getLongCardinality(), bitmap.eqCardinality(offset, expected[offset])); assertTrue(bitmap.eq(offset, expected[(offset + 1) % max]).isEmpty()); assertEquals(0L, bitmap.eqCardinality(offset, expected[(offset + 1) % max])); assertTrue(bitmap.eq(offset, new RoaringBitmap()).isEmpty()); assertEquals(0L, bitmap.eqCardinality(offset, new RoaringBitmap())); assertTrue(bitmap.eq(offset, RoaringBitmap.bitmapOf(maxRow + 1)).isEmpty()); assertEquals(0L, bitmap.eqCardinality(offset, RoaringBitmap.bitmapOf(maxRow + 1))); - RoaringBitmap overlapOnlyWithLast = RoaringBitmap.bitmapOfRange(expected[offset].last(), 2 * maxRow); - assertEquals(RoaringBitmap.bitmapOf(expected[offset].last()), bitmap.eq(offset, overlapOnlyWithLast)); + RoaringBitmap overlapOnlyWithLast = + RoaringBitmap.bitmapOfRange(expected[offset].last(), 2 * maxRow); + assertEquals( + RoaringBitmap.bitmapOf(expected[offset].last()), bitmap.eq(offset, overlapOnlyWithLast)); assertEquals(1L, bitmap.eqCardinality(offset, overlapOnlyWithLast)); } } @@ -898,7 +1158,8 @@ public void testNeqWithContext(int max) { RangeBitmap bitmap = appender.build(); for (int offset = 0; offset < max; offset++) { assertEquals(expected[offset], bitmap.neq(offset, expected[offset])); - assertEquals(expected[offset].getLongCardinality(), bitmap.neqCardinality(offset, expected[offset])); + assertEquals( + expected[offset].getLongCardinality(), bitmap.neqCardinality(offset, expected[offset])); assertTrue(bitmap.neq(offset, new RoaringBitmap()).isEmpty()); assertEquals(0L, bitmap.neqCardinality(offset, new RoaringBitmap())); assertTrue(bitmap.neq(offset, RoaringBitmap.bitmapOf(maxRow + 1)).isEmpty()); @@ -1060,7 +1321,7 @@ LongSupplier of(long seed, double... params) { POINT { @Override LongSupplier of(long seed, double... params) { - return () -> (long)params[0]; + return () -> (long) params[0]; } }; @@ -1085,6 +1346,7 @@ public void rangeMaskRandom() { assertEquals(rangeMaskOriginal(value), rangeMaskOptimized(value)); } } + @Test public void rangeMaskExpressionSimplification() { for (int lz = 0; lz < 64; lz++) { @@ -1110,12 +1372,16 @@ public void rangeMaskRandom2() { assertEquals(rangeMaskOriginal2(value), rangeMaskSimplified2(value), "" + value); } } + @Test public void rangeMaskExpressionSimplification2() { for (int sliceCount = 1; sliceCount <= 64; sliceCount++) { long original = sliceCount == 64 ? -1L : (1L << sliceCount) - 1; long simplified = -1L >>> (64 - sliceCount); - assertEquals(Long.toBinaryString(original), Long.toBinaryString(simplified), "sliceCount=" + sliceCount); + assertEquals( + Long.toBinaryString(original), + Long.toBinaryString(simplified), + "sliceCount=" + sliceCount); } } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java index 99ff1c6c8..58ca04910 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringArrayTest.java @@ -1,13 +1,13 @@ package org.roaringbitmap; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import org.junit.jupiter.api.Test; public class RoaringArrayTest { - @Test public void whenAppendEmpty_ShouldBeUnchanged() { RoaringArray array = new RoaringArray(); @@ -47,12 +47,12 @@ public void whenAppendToEmpty_ShouldEqualAppendage() { public void whenAppendNonEmpty_SizeShouldEqualSumOfSizes() { RoaringArray array = new RoaringArray(); array.size = 2; - array.keys = new char[]{0, 2, 0, 0}; + array.keys = new char[] {0, 2, 0, 0}; array.values = new Container[4]; RoaringArray appendage = new RoaringArray(); appendage.size = 3; - appendage.keys = new char[]{5, 6, 7, 0}; + appendage.keys = new char[] {5, 6, 7, 0}; appendage.values = new Container[4]; array.append(appendage); @@ -60,17 +60,16 @@ public void whenAppendNonEmpty_SizeShouldEqualSumOfSizes() { assertEquals(5, array.size); } - @Test public void whenAppendNonEmpty_ResultantKeysShouldBeMonotonic() { RoaringArray array = new RoaringArray(); array.size = 2; - array.keys = new char[]{0, 2, 0, 0}; + array.keys = new char[] {0, 2, 0, 0}; array.values = new Container[4]; RoaringArray appendage = new RoaringArray(); appendage.size = 3; - appendage.keys = new char[]{5, 6, 7, 0}; + appendage.keys = new char[] {5, 6, 7, 0}; appendage.values = new Container[4]; array.append(appendage); @@ -87,5 +86,4 @@ public void resizeOnlyIfNecessary() { array.extendArray(1); assertSame(keys, array.keys, "Keys were not reallocated"); } - -} \ No newline at end of file +} diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java index 438889e6d..01332c140 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitSetTest.java @@ -1,10 +1,11 @@ package org.roaringbitmap; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.util.HashSet; import java.util.Iterator; import java.util.Random; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; // From https://github.com/openjdk/jdk/blob/master/test/jdk/java/util/BitSet/BSMethods.java @SuppressWarnings("all") @@ -32,8 +33,7 @@ public void testSetGetClearFlip() { // Make sure each bit is set appropriately for (int x = 0; x < highestPossibleSetBit; x++) { - if (testSet.get(x) != history.contains(Integer.valueOf(x))) - failCount++; + if (testSet.get(x) != history.contains(Integer.valueOf(x))) failCount++; } // Clear the bits @@ -44,11 +44,8 @@ public void testSetGetClearFlip() { } // Verify they were cleared - for (int x = 0; x < highestPossibleSetBit; x++) - if (testSet.get(x)) - failCount++; - if (testSet.length() != 0) - failCount++; + for (int x = 0; x < highestPossibleSetBit; x++) if (testSet.get(x)) failCount++; + if (testSet.length() != 0) failCount++; // Set them with set(int, boolean) setBitIterator = history.iterator(); @@ -59,8 +56,7 @@ public void testSetGetClearFlip() { // Make sure each bit is set appropriately for (int x = 0; x < highestPossibleSetBit; x++) { - if (testSet.get(x) != history.contains(Integer.valueOf(x))) - failCount++; + if (testSet.get(x) != history.contains(Integer.valueOf(x))) failCount++; } // Clear them with set(int, boolean) @@ -71,11 +67,8 @@ public void testSetGetClearFlip() { } // Verify they were cleared - for (int x = 0; x < highestPossibleSetBit; x++) - if (testSet.get(x)) - failCount++; - if (testSet.length() != 0) - failCount++; + for (int x = 0; x < highestPossibleSetBit; x++) if (testSet.get(x)) failCount++; + if (testSet.length() != 0) failCount++; // Flip them on setBitIterator = history.iterator(); @@ -86,8 +79,7 @@ public void testSetGetClearFlip() { // Verify they were flipped for (int x = 0; x < highestPossibleSetBit; x++) { - if (testSet.get(x) != history.contains(Integer.valueOf(x))) - failCount++; + if (testSet.get(x) != history.contains(Integer.valueOf(x))) failCount++; } // Flip them off @@ -98,11 +90,8 @@ public void testSetGetClearFlip() { } // Verify they were flipped - for (int x = 0; x < highestPossibleSetBit; x++) - if (testSet.get(x)) - failCount++; - if (testSet.length() != 0) - failCount++; + for (int x = 0; x < highestPossibleSetBit; x++) if (testSet.get(x)) failCount++; + if (testSet.length() != 0) failCount++; checkSanity(testSet); } @@ -121,8 +110,7 @@ public void testClear() { int numberOfSetBits = generator.nextInt(100) + 1; int highestPossibleSetBit = generator.nextInt(1000) + 1; - for (int x = 0; x < numberOfSetBits; x++) - b1.set(generator.nextInt(highestPossibleSetBit)); + for (int x = 0; x < numberOfSetBits; x++) b1.set(generator.nextInt(highestPossibleSetBit)); RoaringBitSet b2 = (RoaringBitSet) b1.clone(); @@ -134,8 +122,7 @@ public void testClear() { b1.clear(rangeStart, rangeEnd); // Use a loop on b2 - for (int x = rangeStart; x < rangeEnd; x++) - b2.clear(x); + for (int x = rangeStart; x < rangeEnd; x++) b2.clear(x); // Verify their equality if (!b1.equals(b2)) { @@ -158,8 +145,7 @@ public void testFlip() { int numberOfSetBits = generator.nextInt(100) + 1; int highestPossibleSetBit = generator.nextInt(1000) + 1; - for (int x = 0; x < numberOfSetBits; x++) - b1.set(generator.nextInt(highestPossibleSetBit)); + for (int x = 0; x < numberOfSetBits; x++) b1.set(generator.nextInt(highestPossibleSetBit)); RoaringBitSet b2 = (RoaringBitSet) b1.clone(); @@ -171,12 +157,10 @@ public void testFlip() { b1.flip(rangeStart, rangeEnd); // Use a loop on b2 - for (int x = rangeStart; x < rangeEnd; x++) - b2.flip(x); + for (int x = rangeStart; x < rangeEnd; x++) b2.flip(x); // Verify their equality - if (!b1.equals(b2)) - failCount++; + if (!b1.equals(b2)) failCount++; checkEquality(b1, b2); } @@ -195,8 +179,7 @@ public void testSet() { int numberOfSetBits = generator.nextInt(100) + 1; int highestPossibleSetBit = generator.nextInt(1000) + 1; - for (int x = 0; x < numberOfSetBits; x++) - b1.set(generator.nextInt(highestPossibleSetBit)); + for (int x = 0; x < numberOfSetBits; x++) b1.set(generator.nextInt(highestPossibleSetBit)); RoaringBitSet b2 = (RoaringBitSet) b1.clone(); @@ -208,8 +191,7 @@ public void testSet() { b1.set(rangeStart, rangeEnd); // Use a loop on b2 - for (int x = rangeStart; x < rangeEnd; x++) - b2.set(x); + for (int x = rangeStart; x < rangeEnd; x++) b2.set(x); // Verify their equality if (!b1.equals(b2)) { @@ -226,8 +208,7 @@ public void testSet() { int numberOfSetBits = generator.nextInt(100) + 1; int highestPossibleSetBit = generator.nextInt(1000) + 1; - for (int x = 0; x < numberOfSetBits; x++) - b1.set(generator.nextInt(highestPossibleSetBit)); + for (int x = 0; x < numberOfSetBits; x++) b1.set(generator.nextInt(highestPossibleSetBit)); RoaringBitSet b2 = (RoaringBitSet) b1.clone(); boolean setOrClear = generator.nextBoolean(); @@ -240,8 +221,7 @@ public void testSet() { b1.set(rangeStart, rangeEnd, setOrClear); // Use a loop on b2 - for (int x = rangeStart; x < rangeEnd; x++) - b2.set(x, setOrClear); + for (int x = rangeStart; x < rangeEnd; x++) b2.set(x, setOrClear); // Verify their equality if (!b1.equals(b2)) { @@ -264,8 +244,7 @@ public void testGet() { int numberOfSetBits = generator.nextInt(100) + 1; int highestPossibleSetBit = generator.nextInt(1000) + 1; - for (int x = 0; x < numberOfSetBits; x++) - b1.set(generator.nextInt(highestPossibleSetBit)); + for (int x = 0; x < numberOfSetBits; x++) b1.set(generator.nextInt(highestPossibleSetBit)); // Get a new set from a random range int rangeStart = generator.nextInt(100); @@ -274,8 +253,7 @@ public void testGet() { RoaringBitSet b2 = (RoaringBitSet) b1.get(rangeStart, rangeEnd); RoaringBitSet b3 = new RoaringBitSet(); - for (int x = rangeStart; x < rangeEnd; x++) - b3.set(x - rangeStart, b1.get(x)); + for (int x = rangeStart; x < rangeEnd; x++) b3.set(x - rangeStart, b1.get(x)); // Verify their equality if (!b2.equals(b3)) { @@ -296,12 +274,10 @@ public void testAndNot() { RoaringBitSet b2 = new RoaringBitSet(); // Set some random bits in first set and remember them - for (int x = 0; x < 10; x++) - b1.set(generator.nextInt(255)); + for (int x = 0; x < 10; x++) b1.set(generator.nextInt(255)); // Set some random bits in second set and remember them - for (int x = 10; x < 20; x++) - b2.set(generator.nextInt(255)); + for (int x = 10; x < 20; x++) b2.set(generator.nextInt(255)); // andNot the sets together RoaringBitSet b3 = (RoaringBitSet) b1.clone(); @@ -312,8 +288,7 @@ public void testAndNot() { boolean bit1 = b1.get(x); boolean bit2 = b2.get(x); boolean bit3 = b3.get(x); - if (!(bit3 == (bit1 & (!bit2)))) - failCount++; + if (!(bit3 == (bit1 & (!bit2)))) failCount++; } checkSanity(b1, b2, b3); } @@ -329,12 +304,10 @@ public void testAnd() { RoaringBitSet b2 = new RoaringBitSet(); // Set some random bits in first set and remember them - for (int x = 0; x < 10; x++) - b1.set(generator.nextInt(255)); + for (int x = 0; x < 10; x++) b1.set(generator.nextInt(255)); // Set more random bits in second set and remember them - for (int x = 10; x < 20; x++) - b2.set(generator.nextInt(255)); + for (int x = 10; x < 20; x++) b2.set(generator.nextInt(255)); // And the sets together RoaringBitSet b3 = (RoaringBitSet) b1.clone(); @@ -345,8 +318,7 @@ public void testAnd() { boolean bit1 = b1.get(x); boolean bit2 = b2.get(x); boolean bit3 = b3.get(x); - if (!(bit3 == (bit1 & bit2))) - failCount++; + if (!(bit3 == (bit1 & bit2))) failCount++; } checkSanity(b1, b2, b3); } @@ -355,8 +327,7 @@ public void testAnd() { RoaringBitSet b4 = makeSet(2, 127); b4.and(makeSet(2, 64)); checkSanity(b4); - if (!(b4.equals(makeSet(2)))) - failCount++; + if (!(b4.equals(makeSet(2)))) failCount++; Assertions.assertEquals(failCount, 0); } @@ -391,8 +362,7 @@ public void testOr() { // Verify the set bits of b3 from the history for (int x = 0; x < 20; x++) { - if (!b3.get(history[x])) - failCount++; + if (!b3.get(history[x])) failCount++; } // Examine each bit of b3 for errors @@ -400,8 +370,7 @@ public void testOr() { boolean bit1 = b1.get(x); boolean bit2 = b2.get(x); boolean bit3 = b3.get(x); - if (!(bit3 == (bit1 | bit2))) - failCount++; + if (!(bit3 == (bit1 | bit2))) failCount++; } checkSanity(b1, b2, b3); } @@ -417,12 +386,10 @@ public void testXor() { RoaringBitSet b2 = new RoaringBitSet(); // Set some random bits in first set and remember them - for (int x = 0; x < 10; x++) - b1.set(generator.nextInt(255)); + for (int x = 0; x < 10; x++) b1.set(generator.nextInt(255)); // Set more random bits in second set and remember them - for (int x = 10; x < 20; x++) - b2.set(generator.nextInt(255)); + for (int x = 10; x < 20; x++) b2.set(generator.nextInt(255)); // Xor the sets together RoaringBitSet b3 = (RoaringBitSet) b1.clone(); @@ -433,8 +400,7 @@ public void testXor() { boolean bit1 = b1.get(x); boolean bit2 = b2.get(x); boolean bit3 = b3.get(x); - if (!(bit3 == (bit1 ^ bit2))) - failCount++; + if (!(bit3 == (bit1 ^ bit2))) failCount++; } checkSanity(b1, b2, b3); b3.xor(b3); @@ -445,8 +411,7 @@ public void testXor() { RoaringBitSet b4 = makeSet(2, 64, 127); b4.xor(makeSet(64, 127)); checkSanity(b4); - if (!(b4.equals(makeSet(2)))) - failCount++; + if (!(b4.equals(makeSet(2)))) failCount++; Assertions.assertEquals(failCount, 0); } @@ -462,11 +427,9 @@ public void testLength() { for (int x = 0; x < 100; x++) { int nextBitToSet = generator.nextInt(255); - if (nextBitToSet > highestSetBit) - highestSetBit = nextBitToSet; + if (nextBitToSet > highestSetBit) highestSetBit = nextBitToSet; b1.set(nextBitToSet); - if (b1.length() != highestSetBit + 1) - failCount++; + if (b1.length() != highestSetBit + 1) failCount++; } checkSanity(b1); } @@ -480,12 +443,10 @@ public void testLength() { int rangeEnd = rangeStart + generator.nextInt(100); b1.flip(rangeStart); b1.flip(rangeStart); - if (b1.length() != 0) - failCount++; + if (b1.length() != 0) failCount++; b1.flip(rangeStart, rangeEnd); b1.flip(rangeStart, rangeEnd); - if (b1.length() != 0) - failCount++; + if (b1.length() != 0) failCount++; } checkSanity(b1); } @@ -500,8 +461,7 @@ public void testLength() { b1.set(bit1); b2.set(bit2); b1.or(b2); - if (b1.length() != highestSetBit + 1) - failCount++; + if (b1.length() != highestSetBit + 1) failCount++; checkSanity(b1, b2); } Assertions.assertEquals(failCount, 0); @@ -525,8 +485,7 @@ public void testEquals() { } // Verify their equality despite different storage sizes - if (!b1.equals(b2)) - failCount++; + if (!b1.equals(b2)) failCount++; checkEquality(b1, b2); } Assertions.assertEquals(failCount, 0); @@ -552,8 +511,7 @@ public void testNextSetBit() { // Verify their retrieval using nextSetBit() int historyIndex = 0; for (int x = testSet.nextSetBit(0); x >= 0; x = testSet.nextSetBit(x + 1)) { - if (x != history[historyIndex++]) - failCount++; + if (x != history[historyIndex++]) failCount++; } checkSanity(testSet); @@ -571,8 +529,7 @@ public void testNextClearBit() { int[] history = new int[10]; // Set all the bits - for (int x = 0; x < 256; x++) - b.set(x); + for (int x = 0; x < 256; x++) b.set(x); // Clear some random bits and remember them int nextBitToClear = 0; @@ -585,8 +542,7 @@ public void testNextClearBit() { // Verify their retrieval using nextClearBit() int historyIndex = 0; for (int x = b.nextClearBit(0); x < 256; x = b.nextClearBit(x + 1)) { - if (x != history[historyIndex++]) - failCount++; + if (x != history[historyIndex++]) failCount++; } checkSanity(b); @@ -594,12 +550,10 @@ public void testNextClearBit() { // regression test for 4350178 RoaringBitSet bs = new RoaringBitSet(); - if (bs.nextClearBit(0) != 0) - failCount++; + if (bs.nextClearBit(0) != 0) failCount++; for (int i = 0; i < 64; i++) { bs.set(i); - if (bs.nextClearBit(0) != i + 1) - failCount++; + if (bs.nextClearBit(0) != i + 1) failCount++; } checkSanity(bs); @@ -632,15 +586,13 @@ public void testIntersects() { b1.set(nextBitToSet); b2.set(nextBitToSet); - if (!b1.intersects(b2)) - failCount++; + if (!b1.intersects(b2)) failCount++; // Remove the common set bits b1.andNot(b2); // Make sure they don't intersect - if (b1.intersects(b2)) - failCount++; + if (b1.intersects(b2)) failCount++; checkSanity(b1, b2); } @@ -678,8 +630,7 @@ public void testEmpty() { int failCount = 0; RoaringBitSet b1 = new RoaringBitSet(); - if (!b1.isEmpty()) - failCount++; + if (!b1.isEmpty()) failCount++; int nextBitToSet = 0; int numberOfSetBits = generator.nextInt(100) + 1; @@ -687,11 +638,9 @@ public void testEmpty() { for (int x = 0; x < numberOfSetBits; x++) { nextBitToSet = generator.nextInt(highestPossibleSetBit); b1.set(nextBitToSet); - if (b1.isEmpty()) - failCount++; + if (b1.isEmpty()) failCount++; b1.clear(nextBitToSet); - if (!b1.isEmpty()) - failCount++; + if (!b1.isEmpty()) failCount++; } Assertions.assertEquals(failCount, 0); @@ -816,10 +765,8 @@ public void testLogicalIdentities() { } b1.or(b2); b3.and(b4); - for (int x = 0; x < highestPossibleSetBit; x++) - b3.flip(x); - if (!b1.equals(b3)) - failCount++; + for (int x = 0; x < highestPossibleSetBit; x++) b3.flip(x); + if (!b1.equals(b3)) failCount++; checkSanity(b1, b2, b3, b4); } @@ -842,16 +789,13 @@ public void testLogicalIdentities() { RoaringBitSet b5 = (RoaringBitSet) b1.clone(); RoaringBitSet b6 = (RoaringBitSet) b2.clone(); - for (int x = 0; x < highestPossibleSetBit; x++) - b2.flip(x); + for (int x = 0; x < highestPossibleSetBit; x++) b2.flip(x); b1.and(b2); - for (int x = 0; x < highestPossibleSetBit; x++) - b3.flip(x); + for (int x = 0; x < highestPossibleSetBit; x++) b3.flip(x); b3.and(b4); b1.or(b3); b5.xor(b6); - if (!b1.equals(b5)) - failCount++; + if (!b1.equals(b5)) failCount++; checkSanity(b1, b2, b3, b4, b5, b6); } Assertions.assertEquals(failCount, 0); @@ -886,8 +830,7 @@ private static void checkEquality(RoaringBitSet s, RoaringBitSet t) { private static RoaringBitSet makeSet(int... elts) { RoaringBitSet s = new RoaringBitSet(); - for (int elt : elts) - s.set(elt); + for (int elt : elts) s.set(elt); return s; } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java index 64de803be..00fcdcff7 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapBatchIteratorTest.java @@ -1,5 +1,12 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.RoaringBitmapWriter.writer; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -9,240 +16,287 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; -import org.roaringbitmap.buffer.MutableRoaringBitmap; import java.util.Arrays; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.RoaringBitmapWriter.writer; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class RoaringBitmapBatchIteratorTest { - private static RoaringBitmap[] BITMAPS; - private static final int[] SIZES = { - 128, 256, 1024, 8192, 5, 127, 1023 - }; - - private static void initBitmaps() { - BITMAPS = new RoaringBitmap[] { - testCase().withArrayAt(0).withArrayAt(2).withArrayAt(4).withArrayAt((1 << 15) | (1 << 14)).build(), - testCase().withRunAt(0).withRunAt(2).withRunAt(4).withRunAt((1 << 15) | (1 << 14)).build(), - testCase().withBitmapAt(0).withRunAt(2).withBitmapAt(4).withBitmapAt((1 << 15) | (1 << 14)).build(), - testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).withBitmapAt((1 << 15) | (1 << 14)).build(), - testCase().withRunAt(0).withArrayAt(2).withBitmapAt(4).withRunAt((1 << 15) | (1 << 14)).build(), - testCase().withBitmapAt(0).withRunAt(2).withArrayAt(4).withBitmapAt((1 << 15) | (1 << 14)).build(), - testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).withArrayAt((1 << 15) | (1 << 14)).build(), - testCase().withBitmapAt(0).withArrayAt(2).withBitmapAt(4).withRunAt((1 << 15) | (1 << 14)).build(), - testCase().withRunAt((1 << 15) | (1 << 11)).withBitmapAt((1 << 15) | (1 << 12)).withArrayAt((1 << 15) | (1 << 13)).withBitmapAt((1 << 15) | (1 << 14)).build(), - RoaringBitmap.bitmapOf(IntStream.range(1 << 10, 1 << 26).filter(i -> (i & 1) == 0).toArray()), - RoaringBitmap.bitmapOf(IntStream.range(1 << 10, 1 << 25).filter(i -> ((i >>> 8) & 1) == 0).toArray()), - RoaringBitmap.bitmapOf(IntStream.range(0,127).toArray()), - RoaringBitmap.bitmapOf(IntStream.range(0,1024).toArray()), - RoaringBitmap.bitmapOf(IntStream.concat(IntStream.range(0,256), IntStream.range(1 << 16, (1 << 16) | 256)).toArray()), - RoaringBitmap.bitmapOf(8511), - new RoaringBitmap() + private static RoaringBitmap[] BITMAPS; + private static final int[] SIZES = {128, 256, 1024, 8192, 5, 127, 1023}; + + private static void initBitmaps() { + BITMAPS = + new RoaringBitmap[] { + testCase() + .withArrayAt(0) + .withArrayAt(2) + .withArrayAt(4) + .withArrayAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withRunAt(0) + .withRunAt(2) + .withRunAt(4) + .withRunAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withBitmapAt(0) + .withRunAt(2) + .withBitmapAt(4) + .withBitmapAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withArrayAt(0) + .withBitmapAt(2) + .withRunAt(4) + .withBitmapAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withRunAt(0) + .withArrayAt(2) + .withBitmapAt(4) + .withRunAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withBitmapAt(0) + .withRunAt(2) + .withArrayAt(4) + .withBitmapAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withArrayAt(0) + .withBitmapAt(2) + .withRunAt(4) + .withArrayAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withBitmapAt(0) + .withArrayAt(2) + .withBitmapAt(4) + .withRunAt((1 << 15) | (1 << 14)) + .build(), + testCase() + .withRunAt((1 << 15) | (1 << 11)) + .withBitmapAt((1 << 15) | (1 << 12)) + .withArrayAt((1 << 15) | (1 << 13)) + .withBitmapAt((1 << 15) | (1 << 14)) + .build(), + RoaringBitmap.bitmapOf( + IntStream.range(1 << 10, 1 << 26).filter(i -> (i & 1) == 0).toArray()), + RoaringBitmap.bitmapOf( + IntStream.range(1 << 10, 1 << 25).filter(i -> ((i >>> 8) & 1) == 0).toArray()), + RoaringBitmap.bitmapOf(IntStream.range(0, 127).toArray()), + RoaringBitmap.bitmapOf(IntStream.range(0, 1024).toArray()), + RoaringBitmap.bitmapOf( + IntStream.concat(IntStream.range(0, 256), IntStream.range(1 << 16, (1 << 16) | 256)) + .toArray()), + RoaringBitmap.bitmapOf(8511), + new RoaringBitmap() }; - } + } - @BeforeAll - public static void beforeAll() throws InterruptedException { - int tryIndex = 0; - int maxTryIndex = 3; - while (++tryIndex < maxTryIndex) { - try { - initBitmaps(); - } catch (OutOfMemoryError e) { - if (tryIndex == maxTryIndex) { - throw e; - } - e.printStackTrace(); - System.out.println("RoaringBitmapBatchIteratorTest.beforeAll Issue on try #" + tryIndex + ". Sleeping 5s for other tests to complete"); - TimeUnit.SECONDS.sleep(5); - } + @BeforeAll + public static void beforeAll() throws InterruptedException { + int tryIndex = 0; + int maxTryIndex = 3; + while (++tryIndex < maxTryIndex) { + try { + initBitmaps(); + } catch (OutOfMemoryError e) { + if (tryIndex == maxTryIndex) { + throw e; } + e.printStackTrace(); + System.out.println( + "RoaringBitmapBatchIteratorTest.beforeAll Issue on try #" + + tryIndex + + ". Sleeping 5s for other tests to complete"); + TimeUnit.SECONDS.sleep(5); + } } + } - @AfterAll - public static void clear() { - BITMAPS = null; - } + @AfterAll + public static void clear() { + BITMAPS = null; + } + public static Stream params() { + return Stream.of(BITMAPS) + .flatMap(bitmap -> IntStream.of(SIZES).mapToObj(i -> Arguments.of(bitmap, i))); + } - public static Stream params() { - return Stream.of(BITMAPS) - .flatMap(bitmap -> IntStream.of(SIZES).mapToObj(i -> Arguments.of(bitmap, i))); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAsIntIterator(RoaringBitmap bitmap, int size) { + IntIterator it = bitmap.getBatchIterator().asIntIterator(new int[size]); + RoaringBitmapWriter w = + writer().constantMemory().initialCapacity(bitmap.highLowContainer.size).get(); + while (it.hasNext()) { + w.add(it.next()); } + RoaringBitmap copy = w.get(); + assertEquals(bitmap, copy); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAsIntIterator(RoaringBitmap bitmap, int size) { - IntIterator it = bitmap.getBatchIterator().asIntIterator(new int[size]); - RoaringBitmapWriter w = writer().constantMemory() - .initialCapacity(bitmap.highLowContainer.size).get(); - while (it.hasNext()) { - w.add(it.next()); - } - RoaringBitmap copy = w.get(); - assertEquals(bitmap, copy); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void test(RoaringBitmap bitmap, int batchSize) { + int[] buffer = new int[batchSize]; + RoaringBitmap result = new RoaringBitmap(); + RoaringBatchIterator it = bitmap.getBatchIterator(); + int cardinality = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + cardinality += batch; } + assertEquals(bitmap, result); + assertEquals(bitmap.getCardinality(), cardinality); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void test(RoaringBitmap bitmap, int batchSize) { - int[] buffer = new int[batchSize]; - RoaringBitmap result = new RoaringBitmap(); - RoaringBatchIterator it = bitmap.getBatchIterator(); - int cardinality = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - cardinality += batch; - } - assertEquals(bitmap, result); - assertEquals(bitmap.getCardinality(), cardinality); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAdvancedIfNeeded(RoaringBitmap bitmap, int batchSize) { + final int cardinality = bitmap.getCardinality(); + if (cardinality < 2) { + return; } - - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAdvancedIfNeeded(RoaringBitmap bitmap, int batchSize) { - final int cardinality = bitmap.getCardinality(); - if (cardinality < 2) { - return; - } - int midpoint = bitmap.select(cardinality / 2); - int[] buffer = new int[batchSize]; - RoaringBitmap result = new RoaringBitmap(); - RoaringBatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded(midpoint); - int consumed = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - consumed += batch; - } - RoaringBitmap expected = bitmap.clone(); - expected.remove(0, midpoint & 0xFFFFFFFFL); - assertEquals(expected, result); - assertEquals(expected.getCardinality(), consumed); + int midpoint = bitmap.select(cardinality / 2); + int[] buffer = new int[batchSize]; + RoaringBitmap result = new RoaringBitmap(); + RoaringBatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(midpoint); + int consumed = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + consumed += batch; } + RoaringBitmap expected = bitmap.clone(); + expected.remove(0, midpoint & 0xFFFFFFFFL); + assertEquals(expected, result); + assertEquals(expected.getCardinality(), consumed); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAdvancedIfNeededToAbsentValue(RoaringBitmap bitmap, int batchSize) { - long firstAbsent = bitmap.nextAbsentValue(0); - int[] buffer = new int[batchSize]; - RoaringBitmap result = new RoaringBitmap(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded((int) firstAbsent); - int consumed = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - consumed += batch; - } - RoaringBitmap expected = bitmap.clone(); - expected.remove(0, firstAbsent & 0xFFFFFFFFL); - assertEquals(expected, result); - assertEquals(expected.getCardinality(), consumed); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAdvancedIfNeededToAbsentValue(RoaringBitmap bitmap, int batchSize) { + long firstAbsent = bitmap.nextAbsentValue(0); + int[] buffer = new int[batchSize]; + RoaringBitmap result = new RoaringBitmap(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded((int) firstAbsent); + int consumed = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + consumed += batch; } + RoaringBitmap expected = bitmap.clone(); + expected.remove(0, firstAbsent & 0xFFFFFFFFL); + assertEquals(expected, result); + assertEquals(expected.getCardinality(), consumed); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAdvancedIfNeededBeyondLastValue(RoaringBitmap bitmap, int batchSize) { - long advanceTo = bitmap.isEmpty() ? 0 : bitmap.last() + 1; - int[] buffer = new int[batchSize]; - RoaringBitmap result = new RoaringBitmap(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded((int) advanceTo); - int consumed = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - consumed += batch; - } - assertEquals(0, consumed); - assertTrue(result.isEmpty()); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAdvancedIfNeededBeyondLastValue( + RoaringBitmap bitmap, int batchSize) { + long advanceTo = bitmap.isEmpty() ? 0 : bitmap.last() + 1; + int[] buffer = new int[batchSize]; + RoaringBitmap result = new RoaringBitmap(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded((int) advanceTo); + int consumed = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + consumed += batch; } + assertEquals(0, consumed); + assertTrue(result.isEmpty()); + } - @Test - public void testTimelyTermination() { - RoaringBitmap bm = RoaringBitmap.bitmapOf(8511); - BatchIterator bi = bm.getBatchIterator(); - int[] batch = new int[10]; - assertTrue(bi.hasNext()); - int n = bi.nextBatch(batch); - assertEquals(n, 1); - assertEquals(batch[0], 8511); - assertFalse(bi.hasNext()); - } + @Test + public void testTimelyTermination() { + RoaringBitmap bm = RoaringBitmap.bitmapOf(8511); + BatchIterator bi = bm.getBatchIterator(); + int[] batch = new int[10]; + assertTrue(bi.hasNext()); + int n = bi.nextBatch(batch); + assertEquals(n, 1); + assertEquals(batch[0], 8511); + assertFalse(bi.hasNext()); + } - @Test - public void testTimelyTerminationAfterAdvanceIfNeeded() { - RoaringBitmap bm = RoaringBitmap.bitmapOf(8511); - BatchIterator bi = bm.getBatchIterator(); - assertTrue(bi.hasNext()); - bi.advanceIfNeeded(8512); - assertFalse(bi.hasNext()); - } + @Test + public void testTimelyTerminationAfterAdvanceIfNeeded() { + RoaringBitmap bm = RoaringBitmap.bitmapOf(8511); + BatchIterator bi = bm.getBatchIterator(); + assertTrue(bi.hasNext()); + bi.advanceIfNeeded(8512); + assertFalse(bi.hasNext()); + } - @Test - public void testBatchIteratorWithAdvanceIfNeeded() { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(3 << 16, (3 << 16) + 5, (3 << 16) + 10); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded(6); - assertTrue(it.hasNext()); - int[] batch = new int[10]; - int n = it.nextBatch(batch); - assertEquals(n, 3); - assertEquals(batch[0], 3 << 16); - assertEquals(batch[1], (3 << 16) + 5); - assertEquals(batch[2], (3 << 16) + 10); - } + @Test + public void testBatchIteratorWithAdvanceIfNeeded() { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(3 << 16, (3 << 16) + 5, (3 << 16) + 10); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(6); + assertTrue(it.hasNext()); + int[] batch = new int[10]; + int n = it.nextBatch(batch); + assertEquals(n, 3); + assertEquals(batch[0], 3 << 16); + assertEquals(batch[1], (3 << 16) + 5); + assertEquals(batch[2], (3 << 16) + 10); + } - @ParameterizedTest - @ValueSource(ints = {10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 24}) - public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24); - bitmap.runOptimize(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded(number); - assertTrue(it.hasNext()); - int[] batch = new int[10]; - int n = it.nextBatch(batch); - int i = Arrays.binarySearch(batch, 0, n, number); - assertTrue(i >= 0, "key " + number + " not found"); - assertEquals(batch[i], number); - } + @ParameterizedTest + @ValueSource(ints = {10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 24}) + public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24); + bitmap.runOptimize(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(number); + assertTrue(it.hasNext()); + int[] batch = new int[10]; + int n = it.nextBatch(batch); + int i = Arrays.binarySearch(batch, 0, n, number); + assertTrue(i >= 0, "key " + number + " not found"); + assertEquals(batch[i], number); + } - @Test - public void testBatchIteratorFillsBufferAcrossContainers() { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(3 << 4, 3 << 8, 3 << 12, 3 << 16, 3 << 20, 3 << 24, 3 << 28); - assertEquals(5, bitmap.highLowContainer.size()); - BatchIterator it = bitmap.getBatchIterator(); - int[] batch = new int[3]; - int n = it.nextBatch(batch); - assertEquals(3, n); - assertArrayEquals(new int[]{3 << 4, 3 << 8, 3 << 12}, batch); - n = it.nextBatch(batch); - assertEquals(3, n); - assertArrayEquals(new int[]{3 << 16, 3 << 20, 3 << 24}, batch); - n = it.nextBatch(batch); - assertEquals(1, n); - assertArrayEquals(new int[]{3 << 28}, Arrays.copyOfRange(batch, 0, 1)); - n = it.nextBatch(batch); - assertEquals(0, n); - } + @Test + public void testBatchIteratorFillsBufferAcrossContainers() { + RoaringBitmap bitmap = + RoaringBitmap.bitmapOf(3 << 4, 3 << 8, 3 << 12, 3 << 16, 3 << 20, 3 << 24, 3 << 28); + assertEquals(5, bitmap.highLowContainer.size()); + BatchIterator it = bitmap.getBatchIterator(); + int[] batch = new int[3]; + int n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[] {3 << 4, 3 << 8, 3 << 12}, batch); + n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[] {3 << 16, 3 << 20, 3 << 24}, batch); + n = it.nextBatch(batch); + assertEquals(1, n); + assertArrayEquals(new int[] {3 << 28}, Arrays.copyOfRange(batch, 0, 1)); + n = it.nextBatch(batch); + assertEquals(0, n); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java index ff90b2edd..d8f5939e4 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapIntervalIntersectionTest.java @@ -1,5 +1,8 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -9,35 +12,55 @@ import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - public class RoaringBitmapIntervalIntersectionTest { private static Arguments[] ARGS; @BeforeAll public static void setup() { - ARGS = new Arguments[] { - Arguments.of(RoaringBitmap.bitmapOf(1, 2, 3), 0, 1 << 16, RoaringBitmap.bitmapOf(1, 2, 3), 1, 1), - Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30), 0, 1 << 16), - Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30), 0, 256), - Arguments.of(RoaringBitmap.bitmapOf(1, 1 << 31 | 1 << 30), 0, 256), - Arguments.of(RoaringBitmap.bitmapOf(1, 1 << 16, 1 << 31 | 1 << 30), 0, 1L << 32), - Arguments.of(testCase().withArrayAt(10).withBitmapAt(20).withRunAt(30) - .withRange(70000L, 150000L).build(), 70000L, 150000L), - Arguments.of(testCase().withArrayAt(10).withBitmapAt(20).withRunAt(30) - .withRange(70000L, 150000L).build(), 71000L, 140000L), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(1).withRunAt(20).build(), 67000, 150000), - Arguments.of(testCase().withBitmapAt(0).withArrayAt(1).withRunAt(20).build(), 67000, 150000), - Arguments.of(testCase().withBitmapAt(0).withRunAt(1).withArrayAt(20).build(), 67000, 150000), - Arguments.of(testCase().withArrayAt(0) - .withArrayAt(1) - .withArrayAt(2) - .withBitmapAt(200) - .withRunAt(205).build(), 199 * (1 << 16), 200 * (1 << 16) + (1 << 14)) - }; + ARGS = + new Arguments[] { + Arguments.of( + RoaringBitmap.bitmapOf(1, 2, 3), 0, 1 << 16, RoaringBitmap.bitmapOf(1, 2, 3), 1, 1), + Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30), 0, 1 << 16), + Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30), 0, 256), + Arguments.of(RoaringBitmap.bitmapOf(1, 1 << 31 | 1 << 30), 0, 256), + Arguments.of(RoaringBitmap.bitmapOf(1, 1 << 16, 1 << 31 | 1 << 30), 0, 1L << 32), + Arguments.of( + testCase() + .withArrayAt(10) + .withBitmapAt(20) + .withRunAt(30) + .withRange(70000L, 150000L) + .build(), + 70000L, + 150000L), + Arguments.of( + testCase() + .withArrayAt(10) + .withBitmapAt(20) + .withRunAt(30) + .withRange(70000L, 150000L) + .build(), + 71000L, + 140000L), + Arguments.of( + testCase().withArrayAt(0).withBitmapAt(1).withRunAt(20).build(), 67000, 150000), + Arguments.of( + testCase().withBitmapAt(0).withArrayAt(1).withRunAt(20).build(), 67000, 150000), + Arguments.of( + testCase().withBitmapAt(0).withRunAt(1).withArrayAt(20).build(), 67000, 150000), + Arguments.of( + testCase() + .withArrayAt(0) + .withArrayAt(1) + .withArrayAt(2) + .withBitmapAt(200) + .withRunAt(205) + .build(), + 199 * (1 << 16), + 200 * (1 << 16) + (1 << 14)) + }; } @AfterAll @@ -49,7 +72,6 @@ public static Stream params() { return Stream.of(ARGS); } - @ParameterizedTest @MethodSource("params") public void testIntersects(RoaringBitmap bitmap, long minimum, long supremum) { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java index b1d4477ac..5922a7e2c 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapSubsetTest.java @@ -1,6 +1,12 @@ package org.roaringbitmap; -import com.google.common.collect.*; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.common.collect.ContiguousSet; +import com.google.common.collect.DiscreteDomain; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Range; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -9,152 +15,126 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class RoaringBitmapSubsetTest { + private static final Predicate DIVISIBLE_BY_4 = i -> i % 4 == 0; - private static final Predicate DIVISIBLE_BY_4 = i -> i % 4 == 0; - - private static final Predicate DIVISIBLE_BY_3 = i -> i % 3 == 0; - - public static Stream params() { - return Stream.of( - Arguments.of( // array vs array - ImmutableSet.of(1, 2, 3, 4), - ImmutableSet.of(2, 3) - ), - Arguments.of( // array vs empty - ImmutableSet.of(1, 2, 3, 4), - ImmutableSet.of() - ), - Arguments.of( // identical arrays - ImmutableSet.of(1, 2, 3, 4), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // disjoint arrays - ImmutableSet.of(10, 12, 14, 15), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of(// disjoint arrays, cardinality mismatch - ImmutableSet.of(10, 12, 14), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // run vs array, subset - ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // run vs array, subset - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // run vs empty - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of() - ), - Arguments.of( // identical runs, 1 container - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()) - ), - Arguments.of( // identical runs, 2 containers - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()) - ), - Arguments.of( // disjoint array vs run, either side of container boundary - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of((1 << 16) + 1, (1 << 16) + 2, (1 << 16) + 3, (1 << 16) + 4) - ), - Arguments.of( // disjoint array vs run - ContiguousSet.create(Range.closed(3, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of(1, 2) - ), - Arguments.of( // run vs run, overlap with shift - ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), - ContiguousSet.create(Range.closed(1 << 4, 1 << 12), DiscreteDomain.integers()) - ), - Arguments.of( // run vs run, subset - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), - ImmutableSet.of(1, 1 << 8) - ), - Arguments.of( // run vs run, overlap with shift, 2 containers - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), - ImmutableSet.of(1 << 6, 1 << 26) - ), - Arguments.of( // run vs 2 container run, overlap - ImmutableSet.of(1, 1 << 16), - ContiguousSet.create(Range.closed(0, 1 << 20), DiscreteDomain.integers()) - ), - Arguments.of( // bitmap vs intersecting array - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.of(4, 8) - ), - Arguments.of( // bitmap vs bitmap, cardinality mismatch - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 16), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // bitmap vs empty - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.of() - ), - Arguments.of( // identical bitmaps - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // bitmap vs overlapping but disjoint array - ImmutableSet.of(3, 7), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // bitmap vs overlapping but disjoint bitmap - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_3::test)), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // disjoint, large (signed-negative) keys - ImmutableSet.of(0xbf09001d, 0xbf090169), - ImmutableSet.of(0x8088000e, 0x80880029) - )); - } + private static final Predicate DIVISIBLE_BY_3 = i -> i % 3 == 0; + public static Stream params() { + return Stream.of( + Arguments.of( // array vs array + ImmutableSet.of(1, 2, 3, 4), ImmutableSet.of(2, 3)), + Arguments.of( // array vs empty + ImmutableSet.of(1, 2, 3, 4), ImmutableSet.of()), + Arguments.of( // identical arrays + ImmutableSet.of(1, 2, 3, 4), ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // disjoint arrays + ImmutableSet.of(10, 12, 14, 15), ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // disjoint arrays, cardinality mismatch + ImmutableSet.of(10, 12, 14), ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // run vs array, subset + ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), + ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // run vs array, subset + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // run vs empty + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of()), + Arguments.of( // identical runs, 1 container + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers())), + Arguments.of( // identical runs, 2 containers + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers())), + Arguments.of( // disjoint array vs run, either side of container boundary + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of((1 << 16) + 1, (1 << 16) + 2, (1 << 16) + 3, (1 << 16) + 4)), + Arguments.of( // disjoint array vs run + ContiguousSet.create(Range.closed(3, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of(1, 2)), + Arguments.of( // run vs run, overlap with shift + ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), + ContiguousSet.create(Range.closed(1 << 4, 1 << 12), DiscreteDomain.integers())), + Arguments.of( // run vs run, subset + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), + ImmutableSet.of(1, 1 << 8)), + Arguments.of( // run vs run, overlap with shift, 2 containers + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), + ImmutableSet.of(1 << 6, 1 << 26)), + Arguments.of( // run vs 2 container run, overlap + ImmutableSet.of(1, 1 << 16), + ContiguousSet.create(Range.closed(0, 1 << 20), DiscreteDomain.integers())), + Arguments.of( // bitmap vs intersecting array + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.of(4, 8)), + Arguments.of( // bitmap vs bitmap, cardinality mismatch + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // bitmap vs empty + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.of()), + Arguments.of( // identical bitmaps + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // bitmap vs overlapping but disjoint array + ImmutableSet.of(3, 7), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // bitmap vs overlapping but disjoint bitmap + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_3::test)), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // disjoint, large (signed-negative) keys + ImmutableSet.of(0xbf09001d, 0xbf090169), ImmutableSet.of(0x8088000e, 0x80880029))); + } - @ParameterizedTest(name = "assert that {1} is subset of {0}") - @MethodSource("params") - public void testProperSubset(Set superSet, Set subSet) { - RoaringBitmap superSetRB = create(superSet); - RoaringBitmap subSetRB = create(subSet); - assertEquals(superSet.containsAll(subSet), superSetRB.contains(subSetRB)); - // reverse the test - assertEquals(subSet.containsAll(superSet), subSetRB.contains(superSetRB)); - } + @ParameterizedTest(name = "assert that {1} is subset of {0}") + @MethodSource("params") + public void testProperSubset(Set superSet, Set subSet) { + RoaringBitmap superSetRB = create(superSet); + RoaringBitmap subSetRB = create(subSet); + assertEquals(superSet.containsAll(subSet), superSetRB.contains(subSetRB)); + // reverse the test + assertEquals(subSet.containsAll(superSet), subSetRB.contains(superSetRB)); + } - private RoaringBitmap create(Set set) { - RoaringBitmap rb = new RoaringBitmap(); - if (set instanceof ContiguousSet) { - ContiguousSet contiguousSet = (ContiguousSet) set; - rb.add(contiguousSet.first().longValue(), contiguousSet.last().longValue()); - } else { - for (Integer i : set) { - rb.add(i); - } - } - return rb; + private RoaringBitmap create(Set set) { + RoaringBitmap rb = new RoaringBitmap(); + if (set instanceof ContiguousSet) { + ContiguousSet contiguousSet = (ContiguousSet) set; + rb.add(contiguousSet.first().longValue(), contiguousSet.last().longValue()); + } else { + for (Integer i : set) { + rb.add(i); + } } - - + return rb; + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java index 78ca1c4cb..e5c838c79 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/RoaringBitmapWriterRandomisedTest.java @@ -1,5 +1,8 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.roaringbitmap.RoaringBitmapWriter.writer; +import static org.roaringbitmap.Util.toUnsignedLong; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -13,150 +16,144 @@ import java.util.Random; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.roaringbitmap.RoaringBitmapWriter.writer; -import static org.roaringbitmap.Util.toUnsignedLong; - @Execution(ExecutionMode.CONCURRENT) public class RoaringBitmapWriterRandomisedTest { - private static int[][] ARRAYS; - - @BeforeAll - public static void init() { - ARRAYS = new int[][] { - new int[]{0, 1, 2, 3}, - randomArray(0), - randomArray(10), - randomArray(100), - randomArray(1000), - randomArray(10_000), - randomArray(100_000), - randomArray(1000_000), - randomArray(10_000_000) + private static int[][] ARRAYS; + + @BeforeAll + public static void init() { + ARRAYS = + new int[][] { + new int[] {0, 1, 2, 3}, + randomArray(0), + randomArray(10), + randomArray(100), + randomArray(1000), + randomArray(10_000), + randomArray(100_000), + randomArray(1000_000), + randomArray(10_000_000) }; + } + + @AfterAll + public static void clear() { + ARRAYS = null; + } + + public static Stream tests() { + return Stream.of(ARRAYS).map(Arguments::of); + } + + @ParameterizedTest(name = "-") + @MethodSource("tests") + public void shouldBuildSameBitmapAsBitmapOf(int[] values) { + RoaringBitmapWriter writer = + writer().expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))).get(); + for (int i : values) { + writer.add(i); } - - @AfterAll - public static void clear() { - ARRAYS = null; + writer.flush(); + verify(writer.getUnderlying(), values); + } + + @ParameterizedTest(name = "-") + @MethodSource("tests") + public void shouldBuildSameBitmapAsBitmapOfWithAddMany(int[] values) { + RoaringBitmapWriter writer = + writer().expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))).get(); + writer.addMany(values); + writer.flush(); + verify(writer.getUnderlying(), values); + } + + @ParameterizedTest(name = "-") + @MethodSource("tests") + public void getShouldFlushToTheUnderlyingBitmap(int[] values) { + RoaringBitmapWriter writer = + writer().expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))).get(); + writer.addMany(values); + verify(writer.get(), values); + } + + @ParameterizedTest(name = "-") + @MethodSource("tests") + public void getShouldFlushToTheUnderlyingBitmap_ConstantMemory(int[] values) { + RoaringBitmapWriter writer = writer().constantMemory().get(); + writer.addMany(values); + verify(writer.get(), values); + } + + @ParameterizedTest(name = "-") + @MethodSource("tests") + public void shouldBuildSameBitmapAsBitmapOf_ConstantMemory(int[] values) { + RoaringBitmapWriter writer = + writer() + .constantMemory() + .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) + .get(); + for (int i : values) { + writer.add(i); } - - public static Stream tests() { - return Stream.of(ARRAYS).map(Arguments::of); + writer.flush(); + verify(writer.getUnderlying(), values); + } + + @ParameterizedTest(name = "-") + @MethodSource("tests") + public void shouldBuildSameBitmapAsBitmapOfWithAddMany_ConstantMemory(int[] values) { + RoaringBitmapWriter writer = + writer() + .constantMemory() + .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) + .get(); + writer.addMany(values); + writer.flush(); + verify(writer.getUnderlying(), values); + } + + private void verify(RoaringBitmap rb, int[] values) { + RoaringBitmap baseline = RoaringBitmap.bitmapOf(values); + RoaringArray baselineHLC = baseline.highLowContainer; + RoaringArray rbHLC = rb.highLowContainer; + assertEquals(baselineHLC.size, rbHLC.size); + for (int i = 0; i < baselineHLC.size; ++i) { + Container baselineContainer = baselineHLC.getContainerAtIndex(i); + Container rbContainer = rbHLC.getContainerAtIndex(i); + assertEquals(baselineContainer, rbContainer); } - - @ParameterizedTest(name = "-") - @MethodSource("tests") - public void shouldBuildSameBitmapAsBitmapOf(int[] values) { - RoaringBitmapWriter writer = writer() - .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) - .get(); - for (int i : values) { - writer.add(i); + assertEquals(baseline, rb); + } + + private static int[] randomArray(int size) { + Random random = new Random(1234); + int[] data = new int[size]; + int last = 0; + int i = 0; + while (i < size) { + if (random.nextGaussian() > 0.1) { + int runLength = random.nextInt(Math.min(size - i, 1 << 16)); + for (int j = 1; j < runLength; ++j) { + data[i + j] = last + 1; + last = data[i + j]; } - writer.flush(); - verify(writer.getUnderlying(), values); - } - - @ParameterizedTest(name = "-") - @MethodSource("tests") - public void shouldBuildSameBitmapAsBitmapOfWithAddMany(int[] values) { - RoaringBitmapWriter writer = writer() - .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) - .get(); - writer.addMany(values); - writer.flush(); - verify(writer.getUnderlying(), values); - } - - @ParameterizedTest(name = "-") - @MethodSource("tests") - public void getShouldFlushToTheUnderlyingBitmap(int[] values) { - RoaringBitmapWriter writer = writer() - .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) - .get(); - writer.addMany(values); - verify(writer.get(), values); - } - - @ParameterizedTest(name = "-") - @MethodSource("tests") - public void getShouldFlushToTheUnderlyingBitmap_ConstantMemory(int[] values) { - RoaringBitmapWriter writer = writer() - .constantMemory() - .get(); - writer.addMany(values); - verify(writer.get(), values); - } - - @ParameterizedTest(name = "-") - @MethodSource("tests") - public void shouldBuildSameBitmapAsBitmapOf_ConstantMemory(int[] values) { - RoaringBitmapWriter writer = writer() - .constantMemory() - .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) - .get(); - for (int i : values) { - writer.add(i); - } - writer.flush(); - verify(writer.getUnderlying(), values); - } - - @ParameterizedTest(name = "-") - @MethodSource("tests") - public void shouldBuildSameBitmapAsBitmapOfWithAddMany_ConstantMemory(int[] values) { - RoaringBitmapWriter writer = writer() - .constantMemory() - .expectedRange(toUnsignedLong(min()), toUnsignedLong(max(values))) - .get(); - writer.addMany(values); - writer.flush(); - verify(writer.getUnderlying(), values); - } - - private void verify(RoaringBitmap rb, int[] values) { - RoaringBitmap baseline = RoaringBitmap.bitmapOf(values); - RoaringArray baselineHLC = baseline.highLowContainer; - RoaringArray rbHLC = rb.highLowContainer; - assertEquals(baselineHLC.size, rbHLC.size); - for (int i = 0; i < baselineHLC.size; ++i) { - Container baselineContainer = baselineHLC.getContainerAtIndex(i); - Container rbContainer = rbHLC.getContainerAtIndex(i); - assertEquals(baselineContainer, rbContainer); - } - assertEquals(baseline, rb); - } - - private static int[] randomArray(int size) { - Random random = new Random(1234); - int[] data = new int[size]; - int last = 0; - int i = 0; - while (i < size) { - if (random.nextGaussian() > 0.1) { - int runLength = random.nextInt(Math.min(size - i, 1 << 16)); - for (int j = 1; j < runLength; ++j) { - data[i + j] = last + 1; - last = data[i + j]; - } - i += runLength; - } else { - data[i] = last + 1 + random.nextInt(999); - last = data[i]; - ++i; - } - } - Arrays.sort(data); - return data; - } - - private int max(int[] values) { - return values.length == 0 ? 0 : values[values.length - 1]; - } - - private int min() { - return 0; + i += runLength; + } else { + data[i] = last + 1 + random.nextInt(999); + last = data[i]; + ++i; + } } -} \ No newline at end of file + Arrays.sort(data); + return data; + } + + private int max(int[] values) { + return values.length == 0 ? 0 : values[values.length - 1]; + } + + private int min() { + return 0; + } +} diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/SeededTestData.java b/roaringbitmap/src/test/java/org/roaringbitmap/SeededTestData.java index 13a0317ac..9ba36234f 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/SeededTestData.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/SeededTestData.java @@ -1,16 +1,17 @@ package org.roaringbitmap; +import static org.roaringbitmap.RoaringBitmapWriter.writer; + import java.util.Arrays; import java.util.SplittableRandom; import java.util.stream.IntStream; -import static org.roaringbitmap.RoaringBitmapWriter.writer; - public class SeededTestData { private static final ThreadLocal bits = ThreadLocal.withInitial(() -> new long[1 << 10]); - private static final ThreadLocal RNG = ThreadLocal.withInitial(() -> new SplittableRandom(0xfeef1f0)); + private static final ThreadLocal RNG = + ThreadLocal.withInitial(() -> new SplittableRandom(0xfeef1f0)); public static RoaringBitmap randomBitmap(int maxKeys, double rleLimit, double denseLimit) { try { @@ -31,7 +32,8 @@ public static RoaringBitmap randomBitmap(int maxKeys) { } } - public static T randomBitmap(int maxKeys, RoaringBitmapWriter writer) { + public static T randomBitmap( + int maxKeys, RoaringBitmapWriter writer) { try { SplittableRandom random = RNG.get(); double rleLimit = random.nextDouble(); @@ -42,18 +44,26 @@ public static T randomBitmap(int maxKeys, Roaring } } - private static RoaringBitmap randomBitmap(int maxKeys, double rleLimit, double denseLimit, SplittableRandom random) { - return randomBitmap(maxKeys, rleLimit, denseLimit, random, writer().initialCapacity(maxKeys).optimiseForArrays().get()); + private static RoaringBitmap randomBitmap( + int maxKeys, double rleLimit, double denseLimit, SplittableRandom random) { + return randomBitmap( + maxKeys, + rleLimit, + denseLimit, + random, + writer().initialCapacity(maxKeys).optimiseForArrays().get()); } - private static T randomBitmap(int maxKeys, - double rleLimit, - double denseLimit, - SplittableRandom random, - RoaringBitmapWriter writer) { + private static T randomBitmap( + int maxKeys, + double rleLimit, + double denseLimit, + SplittableRandom random, + RoaringBitmapWriter writer) { int[] keys = createSorted16BitInts(random.nextInt(1, maxKeys), random); IntStream.of(keys) - .forEach(key -> { + .forEach( + key -> { double choice = random.nextDouble(); final IntStream stream; if (choice < rleLimit) { @@ -96,9 +106,9 @@ private static IntStream rleRegion(SplittableRandom random) { int numRuns = random.nextInt(1, 2048); int[] runs = createSorted16BitInts(numRuns * 2, random); return IntStream.range(0, numRuns) - .map(i -> i * 2) - .mapToObj(i -> IntStream.range(runs[i], runs[i + 1])) - .flatMapToInt(i -> i); + .map(i -> i * 2) + .mapToObj(i -> IntStream.range(runs[i], runs[i + 1])) + .flatMapToInt(i -> i); } private static IntStream sparseRegion(SplittableRandom random) { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java index 91ce47b7d..6b854688b 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestAdversarialInputs.java @@ -1,63 +1,63 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.*; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.stream.IntStream; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - - public class TestAdversarialInputs { - public static Stream badFiles() { - return IntStream.rangeClosed(1, 7) - .mapToObj(i -> Arguments.of("/testdata/crashproneinput" + i + ".bin")); - } - - // open a stream without copying files - public static InputStream openInputstream(String resourceName) throws IOException { - InputStream resourceAsStream = TestAdversarialInputs.class.getResourceAsStream(resourceName); - if(resourceAsStream == null) { - throw new IOException("Cannot get resource \"" + resourceName + "\"."); - } - return resourceAsStream; - } + public static Stream badFiles() { + return IntStream.rangeClosed(1, 7) + .mapToObj(i -> Arguments.of("/testdata/crashproneinput" + i + ".bin")); + } - @Test - public void testInputGoodFile1() throws IOException { - InputStream inputStream = openInputstream("/testdata/bitmapwithruns.bin"); - RoaringBitmap rb = new RoaringBitmap(); - // should not throw an exception - rb.deserialize(new DataInputStream(inputStream)); - assertEquals(rb.getCardinality(), 200100); - } - - @Test - public void testInputGoodFile2() throws IOException { - InputStream inputStream = openInputstream("/testdata/bitmapwithoutruns.bin"); - RoaringBitmap rb = new RoaringBitmap(); - // should not throw an exception - rb.deserialize(new DataInputStream(inputStream)); - assertEquals(rb.getCardinality(), 200100); - } - - @ParameterizedTest - @MethodSource("badFiles") - public void testInputBadFile8(String fileName) { - assertThrows(IOException.class, () -> deserialize(fileName)); - } - - - private void deserialize(String fileName) throws IOException { - InputStream inputStream = openInputstream(fileName); - RoaringBitmap rb = new RoaringBitmap(); - // should not work - rb.deserialize(new DataInputStream(inputStream)); - } + // open a stream without copying files + public static InputStream openInputstream(String resourceName) throws IOException { + InputStream resourceAsStream = TestAdversarialInputs.class.getResourceAsStream(resourceName); + if (resourceAsStream == null) { + throw new IOException("Cannot get resource \"" + resourceName + "\"."); + } + return resourceAsStream; + } + + @Test + public void testInputGoodFile1() throws IOException { + InputStream inputStream = openInputstream("/testdata/bitmapwithruns.bin"); + RoaringBitmap rb = new RoaringBitmap(); + // should not throw an exception + rb.deserialize(new DataInputStream(inputStream)); + assertEquals(rb.getCardinality(), 200100); + } + + @Test + public void testInputGoodFile2() throws IOException { + InputStream inputStream = openInputstream("/testdata/bitmapwithoutruns.bin"); + RoaringBitmap rb = new RoaringBitmap(); + // should not throw an exception + rb.deserialize(new DataInputStream(inputStream)); + assertEquals(rb.getCardinality(), 200100); + } + + @ParameterizedTest + @MethodSource("badFiles") + public void testInputBadFile8(String fileName) { + assertThrows(IOException.class, () -> deserialize(fileName)); + } + + private void deserialize(String fileName) throws IOException { + InputStream inputStream = openInputstream(fileName); + RoaringBitmap rb = new RoaringBitmap(); + // should not work + rb.deserialize(new DataInputStream(inputStream)); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java index 30b1583bd..7bbf5aa7e 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestArrayContainer.java @@ -1,5 +1,13 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; +import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; + import com.google.common.primitives.Ints; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -13,955 +21,959 @@ import java.util.List; import java.util.NoSuchElementException; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.ValidationRangeConsumer.Value.*; - @Execution(ExecutionMode.CONCURRENT) public class TestArrayContainer { - @Test - public void testConst() { - ArrayContainer ac1 = new ArrayContainer(5, 15); - char[] data = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - ArrayContainer ac2 = new ArrayContainer(data); - assertEquals(ac1, ac2); - } - - @Test - public void testRemove() { - ArrayContainer ac1 = new ArrayContainer(5, 15); - ac1.remove((char)14); - ArrayContainer ac2 = new ArrayContainer(5, 14); - assertEquals(ac1, ac2); - } - - @Test - public void arrayContainersNeverFull() { - assertFalse(new ArrayContainer(5, 15).isFull()); - } - - @Test - public void testToString() { - ArrayContainer ac1 = new ArrayContainer(5, 15); - ac1.add((char) -3); - ac1.add((char) -17); - assertEquals("{5,6,7,8,9,10,11,12,13,14,65519,65533}", ac1.toString()); - } - - @Test - public void testIandNot() { - ArrayContainer ac1 = new ArrayContainer(5, 15); - ArrayContainer ac2 = new ArrayContainer(10, 15); - BitmapContainer bc = new BitmapContainer(5, 10); - ArrayContainer ac3 = ac1.iandNot(bc); - assertEquals(ac2, ac3); - } - - @Test - public void testReverseArrayContainerShortIterator() { - //Test Clone - ArrayContainer ac1 = new ArrayContainer(5, 15); - ReverseArrayContainerCharIterator rac1 = new ReverseArrayContainerCharIterator(ac1); - CharIterator rac2 = rac1.clone(); - assertNotNull(rac2); - assertEquals(asList(rac1), asList(rac2)); - } - - private static List asList(CharIterator ints) { - int[] values = new int[10]; - int size = 0; - while (ints.hasNext()) { - if (!(size < values.length)) { - values = Arrays.copyOf(values, values.length * 2); - } - values[size++] = ints.next(); - } - return Ints.asList(Arrays.copyOf(values, size)); - } - - @Test - public void roundtrip() throws Exception { - Container ac = new ArrayContainer(); - ac = ac.add(1, 5); - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try (ObjectOutputStream oo = new ObjectOutputStream(bos)) { - ac.writeExternal(oo); - } - Container ac2 = new ArrayContainer(); - final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - ac2.readExternal(new ObjectInputStream(bis)); - - assertEquals(4, ac2.getCardinality()); - for (int i = 1; i < 5; i++) { - assertTrue(ac2.contains((char) i)); - } - } - - @Test - public void intersectsArray() { - Container ac = new ArrayContainer(); - ac = ac.add(1, 10); - Container ac2 = new ArrayContainer(); - ac2 = ac2.add(5, 25); - assertTrue(ac.intersects(ac2)); - } - - @Test - public void orFullToRunContainer() { - ArrayContainer ac = new ArrayContainer(0, 1 << 12); - BitmapContainer half = new BitmapContainer(1 << 12, 1 << 16); - Container result = ac.or(half); - assertEquals(1 << 16, result.getCardinality()); - assertTrue(result instanceof RunContainer); - } - - @Test - public void orFullToRunContainer2() { - ArrayContainer ac = new ArrayContainer(0, 1 << 15); - ArrayContainer half = new ArrayContainer(1 << 15, 1 << 16); - Container result = ac.or(half); - assertEquals(1 << 16, result.getCardinality()); - assertTrue(result instanceof RunContainer); - } - - @Test - public void iandBitmap() { - Container ac = new ArrayContainer(); - ac = ac.add(1, 10); - Container bc = new BitmapContainer(); - bc = bc.add(5, 25); - ac.iand(bc); - assertEquals(5, ac.getCardinality()); - for (int i = 5; i < 10; i++) { - assertTrue(ac.contains((char) i)); - } - } - - @Test - public void iandRun() { - Container ac = new ArrayContainer(); - ac = ac.add(1, 10); - Container rc = new RunContainer(); - rc = rc.add(5, 25); - ac = ac.iand(rc); - assertEquals(5, ac.getCardinality()); - for (int i = 5; i < 10; i++) { - assertTrue(ac.contains((char) i)); - } - } - - @Test - public void addEmptyRange() { - Container ac = new ArrayContainer(); - ac = ac.add(1,1); - assertEquals(0, ac.getCardinality()); - } - - @Test - public void addInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - Container ac = new ArrayContainer(); - ac.add(13, 1); + @Test + public void testConst() { + ArrayContainer ac1 = new ArrayContainer(5, 15); + char[] data = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + ArrayContainer ac2 = new ArrayContainer(data); + assertEquals(ac1, ac2); + } + + @Test + public void testRemove() { + ArrayContainer ac1 = new ArrayContainer(5, 15); + ac1.remove((char) 14); + ArrayContainer ac2 = new ArrayContainer(5, 14); + assertEquals(ac1, ac2); + } + + @Test + public void arrayContainersNeverFull() { + assertFalse(new ArrayContainer(5, 15).isFull()); + } + + @Test + public void testToString() { + ArrayContainer ac1 = new ArrayContainer(5, 15); + ac1.add((char) -3); + ac1.add((char) -17); + assertEquals("{5,6,7,8,9,10,11,12,13,14,65519,65533}", ac1.toString()); + } + + @Test + public void testIandNot() { + ArrayContainer ac1 = new ArrayContainer(5, 15); + ArrayContainer ac2 = new ArrayContainer(10, 15); + BitmapContainer bc = new BitmapContainer(5, 10); + ArrayContainer ac3 = ac1.iandNot(bc); + assertEquals(ac2, ac3); + } + + @Test + public void testReverseArrayContainerShortIterator() { + // Test Clone + ArrayContainer ac1 = new ArrayContainer(5, 15); + ReverseArrayContainerCharIterator rac1 = new ReverseArrayContainerCharIterator(ac1); + CharIterator rac2 = rac1.clone(); + assertNotNull(rac2); + assertEquals(asList(rac1), asList(rac2)); + } + + private static List asList(CharIterator ints) { + int[] values = new int[10]; + int size = 0; + while (ints.hasNext()) { + if (!(size < values.length)) { + values = Arrays.copyOf(values, values.length * 2); + } + values[size++] = ints.next(); + } + return Ints.asList(Arrays.copyOf(values, size)); + } + + @Test + public void roundtrip() throws Exception { + Container ac = new ArrayContainer(); + ac = ac.add(1, 5); + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ObjectOutputStream oo = new ObjectOutputStream(bos)) { + ac.writeExternal(oo); + } + Container ac2 = new ArrayContainer(); + final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ac2.readExternal(new ObjectInputStream(bis)); + + assertEquals(4, ac2.getCardinality()); + for (int i = 1; i < 5; i++) { + assertTrue(ac2.contains((char) i)); + } + } + + @Test + public void intersectsArray() { + Container ac = new ArrayContainer(); + ac = ac.add(1, 10); + Container ac2 = new ArrayContainer(); + ac2 = ac2.add(5, 25); + assertTrue(ac.intersects(ac2)); + } + + @Test + public void orFullToRunContainer() { + ArrayContainer ac = new ArrayContainer(0, 1 << 12); + BitmapContainer half = new BitmapContainer(1 << 12, 1 << 16); + Container result = ac.or(half); + assertEquals(1 << 16, result.getCardinality()); + assertTrue(result instanceof RunContainer); + } + + @Test + public void orFullToRunContainer2() { + ArrayContainer ac = new ArrayContainer(0, 1 << 15); + ArrayContainer half = new ArrayContainer(1 << 15, 1 << 16); + Container result = ac.or(half); + assertEquals(1 << 16, result.getCardinality()); + assertTrue(result instanceof RunContainer); + } + + @Test + public void iandBitmap() { + Container ac = new ArrayContainer(); + ac = ac.add(1, 10); + Container bc = new BitmapContainer(); + bc = bc.add(5, 25); + ac.iand(bc); + assertEquals(5, ac.getCardinality()); + for (int i = 5; i < 10; i++) { + assertTrue(ac.contains((char) i)); + } + } + + @Test + public void iandRun() { + Container ac = new ArrayContainer(); + ac = ac.add(1, 10); + Container rc = new RunContainer(); + rc = rc.add(5, 25); + ac = ac.iand(rc); + assertEquals(5, ac.getCardinality()); + for (int i = 5; i < 10; i++) { + assertTrue(ac.contains((char) i)); + } + } + + @Test + public void addEmptyRange() { + Container ac = new ArrayContainer(); + ac = ac.add(1, 1); + assertEquals(0, ac.getCardinality()); + } + + @Test + public void addInvalidRange() { + assertThrows( + IllegalArgumentException.class, + () -> { + Container ac = new ArrayContainer(); + ac.add(13, 1); }); - } - - @Test - public void iaddEmptyRange() { - Container ac = new ArrayContainer(); - ac = ac.iadd(1,1); - assertEquals(0, ac.getCardinality()); - } - - @Test - public void iaddInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - Container ac = new ArrayContainer(); - ac.iadd(13, 1); + } + + @Test + public void iaddEmptyRange() { + Container ac = new ArrayContainer(); + ac = ac.iadd(1, 1); + assertEquals(0, ac.getCardinality()); + } + + @Test + public void iaddInvalidRange() { + assertThrows( + IllegalArgumentException.class, + () -> { + Container ac = new ArrayContainer(); + ac.iadd(13, 1); }); - } - - @Test - public void iaddSanityTest() { - Container ac = new ArrayContainer(); - ac = ac.iadd(10,20); - //insert disjoint at end - ac = ac.iadd(30,70); - //insert disjoint between - ac = ac.iadd(25,26); - //insert disjoint at start - ac = ac.iadd(1,2); - //insert overlap at end - ac = ac.iadd(60,80); - //insert overlap between - ac = ac.iadd(10,30); - //insert overlap at start - ac = ac.iadd(1,20); - assertEquals(79, ac.getCardinality()); - } - - @Test - public void clear() { - Container ac = new ArrayContainer(); - ac = ac.add(1, 10); - ac.clear(); - assertEquals(0, ac.getCardinality()); - } - - @Test - public void testLazyORFull() { - ArrayContainer ac = new ArrayContainer(0, 1 << 15); - ArrayContainer ac2 = new ArrayContainer(1 << 15, 1 << 16); - Container rbc = ac.lazyor(ac2); - assertEquals(-1, rbc.getCardinality()); - Container repaired = rbc.repairAfterLazy(); - assertEquals(1 << 16, repaired.getCardinality()); - assertTrue(repaired instanceof RunContainer); - } - - @Test - public void testFirst_Empty() { - assertThrows(NoSuchElementException.class, () -> new ArrayContainer().first()); - } - - @Test - public void testLast_Empty() { - assertThrows(NoSuchElementException.class, () -> new ArrayContainer().last()); - } - - @Test - public void testFirstLast() { - Container rc = new ArrayContainer(); - final int firstInclusive = 1; - int lastExclusive = firstInclusive; - for (int i = 0; i < 1 << 16 - 10; ++i) { - int newLastExclusive = lastExclusive + 10; - rc = rc.add(lastExclusive, newLastExclusive); - assertEquals(firstInclusive, rc.first()); - assertEquals(newLastExclusive - 1, rc.last()); - lastExclusive = newLastExclusive; - } - } - - @Test - public void testContainsBitmapContainer_ExcludeShiftedSet() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new BitmapContainer().add(2,12); - assertFalse(ac.contains(subset)); - } - - @Test - public void testContainsBitmapContainer_AlwaysFalse() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new BitmapContainer().add(0,10); - assertFalse(ac.contains(subset)); - } - - @Test - public void testContainsBitmapContainer_ExcludeSuperSet() { - Container ac = new ArrayContainer().add(0,10); - Container superset = new BitmapContainer().add(0,20); - assertFalse(ac.contains(superset)); - } - - @Test - public void testContainsBitmapContainer_ExcludeDisJointSet() { - Container ac = new ArrayContainer().add(0,10); - Container disjoint = new BitmapContainer().add(20, 40); - assertFalse(ac.contains(disjoint)); - assertFalse(disjoint.contains(ac)); - } - - @Test - public void testContainsRunContainer_EmptyContainsEmpty() { - Container ac = new ArrayContainer(); - Container subset = new RunContainer(); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsRunContainer_IncludeProperSubset() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new RunContainer().add(0,9); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsRunContainer_IncludeSelf() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new RunContainer().add(0,10); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsRunContainer_ExcludeSuperSet() { - Container ac = new ArrayContainer().add(0,10); - Container superset = new RunContainer().add(0,20); - assertFalse(ac.contains(superset)); - } - - @Test - public void testContainsRunContainer_IncludeProperSubsetDifferentStart() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new RunContainer().add(1,9); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsRunContainer_ExcludeShiftedSet() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new RunContainer().add(2,12); - assertFalse(ac.contains(subset)); - } - - @Test - public void testContainsRunContainer_ExcludeDisJointSet() { - Container ac = new ArrayContainer().add(0,10); - Container disjoint = new RunContainer().add(20, 40); - assertFalse(ac.contains(disjoint)); - assertFalse(disjoint.contains(ac)); - } - - @Test - public void testContainsRunContainer_Issue723Case1() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new RunContainer().add(5,6); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsRunContainer_Issue723Case2() { - Container ac = new ArrayContainer().add(0,10); - Container rc = new RunContainer().add(5,11); - assertFalse(ac.contains(rc)); - } - - @Test - public void testContainsArrayContainer_EmptyContainsEmpty() { - Container ac = new ArrayContainer(); - Container subset = new ArrayContainer(); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsArrayContainer_IncludeProperSubset() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new ArrayContainer().add(0,9); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsArrayContainer_IncludeProperSubsetDifferentStart() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new ArrayContainer().add(2,9); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsArrayContainer_ExcludeShiftedSet() { - Container ac = new ArrayContainer().add(0,10); - Container shifted = new ArrayContainer().add(2,12); - assertFalse(ac.contains(shifted)); - } - - @Test - public void testContainsArrayContainer_IncludeSelf() { - Container ac = new ArrayContainer().add(0,10); - Container subset = new ArrayContainer().add(0,10); - assertTrue(ac.contains(subset)); - } - - @Test - public void testContainsArrayContainer_ExcludeSuperSet() { - Container ac = new ArrayContainer().add(0,10); - Container superset = new ArrayContainer().add(0,20); - assertFalse(ac.contains(superset)); - } - - @Test - public void testContainsArrayContainer_ExcludeDisJointSet() { - Container ac = new ArrayContainer().add(0, 10); - Container disjoint = new ArrayContainer().add(20, 40); - assertFalse(ac.contains(disjoint)); - assertFalse(disjoint.contains(ac)); - } - - @Test - public void iorNotIncreaseCapacity() { - Container ac1 = new ArrayContainer(); - Container ac2 = new ArrayContainer(); - ac1.add((char) 128); - ac1.add((char) 256); - ac2.add((char) 1024); - - ac1.ior(ac2); - assertTrue(ac1.contains((char) 128)); - assertTrue(ac1.contains((char) 256)); - assertTrue(ac1.contains((char) 1024)); - } - - @Test - public void iorIncreaseCapacity() { - Container ac1 = new ArrayContainer(); - Container ac2 = new ArrayContainer(); - ac1.add((char) 128); - ac1.add((char) 256); - ac1.add((char) 512); - ac1.add((char) 513); - ac2.add((char) 1024); - - ac1.ior(ac2); - assertTrue(ac1.contains((char) 128)); - assertTrue(ac1.contains((char) 256)); - assertTrue(ac1.contains((char) 512)); - assertTrue(ac1.contains((char) 513)); - assertTrue(ac1.contains((char) 1024)); - } - - @Test - public void iorSanityCheck() { - Container ac = new ArrayContainer().add(0, 10); - Container disjoint = new ArrayContainer().add(20, 40); - ac.ior(disjoint); - assertTrue(ac.contains(disjoint)); - } + } + + @Test + public void iaddSanityTest() { + Container ac = new ArrayContainer(); + ac = ac.iadd(10, 20); + // insert disjoint at end + ac = ac.iadd(30, 70); + // insert disjoint between + ac = ac.iadd(25, 26); + // insert disjoint at start + ac = ac.iadd(1, 2); + // insert overlap at end + ac = ac.iadd(60, 80); + // insert overlap between + ac = ac.iadd(10, 30); + // insert overlap at start + ac = ac.iadd(1, 20); + assertEquals(79, ac.getCardinality()); + } + + @Test + public void clear() { + Container ac = new ArrayContainer(); + ac = ac.add(1, 10); + ac.clear(); + assertEquals(0, ac.getCardinality()); + } + + @Test + public void testLazyORFull() { + ArrayContainer ac = new ArrayContainer(0, 1 << 15); + ArrayContainer ac2 = new ArrayContainer(1 << 15, 1 << 16); + Container rbc = ac.lazyor(ac2); + assertEquals(-1, rbc.getCardinality()); + Container repaired = rbc.repairAfterLazy(); + assertEquals(1 << 16, repaired.getCardinality()); + assertTrue(repaired instanceof RunContainer); + } + + @Test + public void testFirst_Empty() { + assertThrows(NoSuchElementException.class, () -> new ArrayContainer().first()); + } + + @Test + public void testLast_Empty() { + assertThrows(NoSuchElementException.class, () -> new ArrayContainer().last()); + } + + @Test + public void testFirstLast() { + Container rc = new ArrayContainer(); + final int firstInclusive = 1; + int lastExclusive = firstInclusive; + for (int i = 0; i < 1 << 16 - 10; ++i) { + int newLastExclusive = lastExclusive + 10; + rc = rc.add(lastExclusive, newLastExclusive); + assertEquals(firstInclusive, rc.first()); + assertEquals(newLastExclusive - 1, rc.last()); + lastExclusive = newLastExclusive; + } + } + + @Test + public void testContainsBitmapContainer_ExcludeShiftedSet() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new BitmapContainer().add(2, 12); + assertFalse(ac.contains(subset)); + } + + @Test + public void testContainsBitmapContainer_AlwaysFalse() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new BitmapContainer().add(0, 10); + assertFalse(ac.contains(subset)); + } + + @Test + public void testContainsBitmapContainer_ExcludeSuperSet() { + Container ac = new ArrayContainer().add(0, 10); + Container superset = new BitmapContainer().add(0, 20); + assertFalse(ac.contains(superset)); + } + + @Test + public void testContainsBitmapContainer_ExcludeDisJointSet() { + Container ac = new ArrayContainer().add(0, 10); + Container disjoint = new BitmapContainer().add(20, 40); + assertFalse(ac.contains(disjoint)); + assertFalse(disjoint.contains(ac)); + } + + @Test + public void testContainsRunContainer_EmptyContainsEmpty() { + Container ac = new ArrayContainer(); + Container subset = new RunContainer(); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_IncludeProperSubset() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new RunContainer().add(0, 9); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_IncludeSelf() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new RunContainer().add(0, 10); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_ExcludeSuperSet() { + Container ac = new ArrayContainer().add(0, 10); + Container superset = new RunContainer().add(0, 20); + assertFalse(ac.contains(superset)); + } + + @Test + public void testContainsRunContainer_IncludeProperSubsetDifferentStart() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new RunContainer().add(1, 9); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_ExcludeShiftedSet() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new RunContainer().add(2, 12); + assertFalse(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_ExcludeDisJointSet() { + Container ac = new ArrayContainer().add(0, 10); + Container disjoint = new RunContainer().add(20, 40); + assertFalse(ac.contains(disjoint)); + assertFalse(disjoint.contains(ac)); + } + + @Test + public void testContainsRunContainer_Issue723Case1() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new RunContainer().add(5, 6); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsRunContainer_Issue723Case2() { + Container ac = new ArrayContainer().add(0, 10); + Container rc = new RunContainer().add(5, 11); + assertFalse(ac.contains(rc)); + } + + @Test + public void testContainsArrayContainer_EmptyContainsEmpty() { + Container ac = new ArrayContainer(); + Container subset = new ArrayContainer(); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsArrayContainer_IncludeProperSubset() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new ArrayContainer().add(0, 9); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsArrayContainer_IncludeProperSubsetDifferentStart() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new ArrayContainer().add(2, 9); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsArrayContainer_ExcludeShiftedSet() { + Container ac = new ArrayContainer().add(0, 10); + Container shifted = new ArrayContainer().add(2, 12); + assertFalse(ac.contains(shifted)); + } + + @Test + public void testContainsArrayContainer_IncludeSelf() { + Container ac = new ArrayContainer().add(0, 10); + Container subset = new ArrayContainer().add(0, 10); + assertTrue(ac.contains(subset)); + } + + @Test + public void testContainsArrayContainer_ExcludeSuperSet() { + Container ac = new ArrayContainer().add(0, 10); + Container superset = new ArrayContainer().add(0, 20); + assertFalse(ac.contains(superset)); + } + + @Test + public void testContainsArrayContainer_ExcludeDisJointSet() { + Container ac = new ArrayContainer().add(0, 10); + Container disjoint = new ArrayContainer().add(20, 40); + assertFalse(ac.contains(disjoint)); + assertFalse(disjoint.contains(ac)); + } + + @Test + public void iorNotIncreaseCapacity() { + Container ac1 = new ArrayContainer(); + Container ac2 = new ArrayContainer(); + ac1.add((char) 128); + ac1.add((char) 256); + ac2.add((char) 1024); + + ac1.ior(ac2); + assertTrue(ac1.contains((char) 128)); + assertTrue(ac1.contains((char) 256)); + assertTrue(ac1.contains((char) 1024)); + } + + @Test + public void iorIncreaseCapacity() { + Container ac1 = new ArrayContainer(); + Container ac2 = new ArrayContainer(); + ac1.add((char) 128); + ac1.add((char) 256); + ac1.add((char) 512); + ac1.add((char) 513); + ac2.add((char) 1024); + + ac1.ior(ac2); + assertTrue(ac1.contains((char) 128)); + assertTrue(ac1.contains((char) 256)); + assertTrue(ac1.contains((char) 512)); + assertTrue(ac1.contains((char) 513)); + assertTrue(ac1.contains((char) 1024)); + } + + @Test + public void iorSanityCheck() { + Container ac = new ArrayContainer().add(0, 10); + Container disjoint = new ArrayContainer().add(20, 40); + ac.ior(disjoint); + assertTrue(ac.contains(disjoint)); + } + + @Test + public void iorNot() { + Container rc1 = new ArrayContainer(); + Container rc2 = new ArrayContainer(); + + rc1.iadd(257, 258); + rc2.iadd(128, 256); + rc1 = rc1.iorNot(rc2, 258); + assertEquals(130, rc1.getCardinality()); + + PeekableCharIterator iterator = rc1.getCharIterator(); + for (int i = 0; i < 128; i++) { + assertTrue(iterator.hasNext()); + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(257, iterator.next()); + + assertFalse(iterator.hasNext()); + } + + @Test + public void iorNot2() { + Container rc1 = new ArrayContainer(); + Container rc2 = new ArrayContainer(); + rc2.iadd(128, 256).iadd(257, 260); + rc1 = rc1.iorNot(rc2, 261); + assertEquals(130, rc1.getCardinality()); + + PeekableCharIterator iterator = rc1.getCharIterator(); + for (int i = 0; i < 128; i++) { + assertTrue(iterator.hasNext()); + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(260, iterator.next()); + + assertFalse(iterator.hasNext()); + } + + @Test + public void iorNot3() { + Container rc1 = new ArrayContainer(); + Container rc2 = new BitmapContainer(); + + rc1.iadd(257, 258); + rc2.iadd(128, 256); + rc1 = rc1.iorNot(rc2, 258); + assertEquals(130, rc1.getCardinality()); + + PeekableCharIterator iterator = rc1.getCharIterator(); + for (int i = 0; i < 128; i++) { + assertTrue(iterator.hasNext()); + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(257, iterator.next()); + + assertFalse(iterator.hasNext()); + } + + @Test + public void iorNot4() { + Container rc1 = new ArrayContainer(); + Container rc2 = new RunContainer(); + + rc1.iadd(257, 258); + rc2.iadd(128, 256); + rc1 = rc1.iorNot(rc2, 258); + assertEquals(130, rc1.getCardinality()); + + PeekableCharIterator iterator = rc1.getCharIterator(); + for (int i = 0; i < 128; i++) { + assertTrue(iterator.hasNext()); + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(257, iterator.next()); + + assertFalse(iterator.hasNext()); + } + + @Test + public void orNot() { + final Container rc1 = new ArrayContainer(); + + { + Container rc2 = new ArrayContainer(); + rc2.iadd(128, 256); + Container res = rc1.orNot(rc2, 257); + assertEquals(129, res.getCardinality()); - @Test - public void iorNot() { - Container rc1 = new ArrayContainer(); - Container rc2 = new ArrayContainer(); - - rc1.iadd(257, 258); - rc2.iadd(128, 256); - rc1 = rc1.iorNot(rc2, 258); - assertEquals(130, rc1.getCardinality()); - - PeekableCharIterator iterator = rc1.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } + PeekableCharIterator iterator = res.getCharIterator(); + for (int i = 0; i < 128; i++) { assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); - assertTrue(iterator.hasNext()); - assertEquals(257, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - @Test - public void iorNot2() { - Container rc1 = new ArrayContainer(); - Container rc2 = new ArrayContainer(); - rc2.iadd(128, 256).iadd(257, 260); - rc1 = rc1.iorNot(rc2, 261); - assertEquals(130, rc1.getCardinality()); - - PeekableCharIterator iterator = rc1.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(260, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - @Test - public void iorNot3() { - Container rc1 = new ArrayContainer(); - Container rc2 = new BitmapContainer(); - - rc1.iadd(257, 258); - rc2.iadd(128, 256); - rc1 = rc1.iorNot(rc2, 258); - assertEquals(130, rc1.getCardinality()); - - PeekableCharIterator iterator = rc1.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(257, iterator.next()); - - assertFalse(iterator.hasNext()); + assertFalse(iterator.hasNext()); } - @Test - public void iorNot4() { - Container rc1 = new ArrayContainer(); - Container rc2 = new RunContainer(); - - rc1.iadd(257, 258); - rc2.iadd(128, 256); - rc1 = rc1.iorNot(rc2, 258); - assertEquals(130, rc1.getCardinality()); - - PeekableCharIterator iterator = rc1.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); + { + Container rc2 = new BitmapContainer(); + rc2.iadd(128, 256); + Container res = rc1.orNot(rc2, 257); + assertEquals(129, res.getCardinality()); + PeekableCharIterator iterator = res.getCharIterator(); + for (int i = 0; i < 128; i++) { assertTrue(iterator.hasNext()); - assertEquals(257, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - @Test - public void orNot() { - final Container rc1 = new ArrayContainer(); - - { - Container rc2 = new ArrayContainer(); - rc2.iadd(128, 256); - Container res = rc1.orNot(rc2, 257); - assertEquals(129, res.getCardinality()); - - PeekableCharIterator iterator = res.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - { - Container rc2 = new BitmapContainer(); - rc2.iadd(128, 256); - Container res = rc1.orNot(rc2, 257); - assertEquals(129, res.getCardinality()); - - PeekableCharIterator iterator = res.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - { - Container rc2 = new RunContainer(); - rc2.iadd(128, 256); - Container res = rc1.orNot(rc2, 257); - assertEquals(129, res.getCardinality()); - - PeekableCharIterator iterator = res.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); - - assertFalse(iterator.hasNext()); - } + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + assertFalse(iterator.hasNext()); } - @Test - public void orNot2() { - Container rc1 = new ArrayContainer(); - Container rc2 = new ArrayContainer(); - rc2.iadd(128, 256).iadd(257, 260); - rc1 = rc1.orNot(rc2, 261); - assertEquals(130, rc1.getCardinality()); - - PeekableCharIterator iterator = rc1.getCharIterator(); - for (int i = 0; i < 128; i++) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertTrue(iterator.hasNext()); - assertEquals(256, iterator.next()); + { + Container rc2 = new RunContainer(); + rc2.iadd(128, 256); + Container res = rc1.orNot(rc2, 257); + assertEquals(129, res.getCardinality()); + PeekableCharIterator iterator = res.getCharIterator(); + for (int i = 0; i < 128; i++) { assertTrue(iterator.hasNext()); - assertEquals(260, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - @Test - public void testIntersectsWithRange() { - Container container = new ArrayContainer().add(0, 10); - assertTrue(container.intersects(0, 1)); - assertTrue(container.intersects(0, 101)); - assertTrue(container.intersects(0, lower16Bits(-1))); - assertFalse(container.intersects(11, lower16Bits(-1))); - } - - - @Test - public void testIntersectsWithRange2() { - Container container = new ArrayContainer().add(lower16Bits(-50), lower16Bits(-10)); - assertFalse(container.intersects(0, 1)); - assertTrue(container.intersects(0, lower16Bits(-40))); - assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); - assertFalse(container.intersects(lower16Bits(-9), lower16Bits(-1))); - assertTrue(container.intersects(11, 1 << 16)); - } - - - @Test - public void testIntersectsWithRange3() { - Container container = new ArrayContainer() - .add((char) 1) - .add((char) 300) - .add((char) 1024); - assertTrue(container.intersects(0, 300)); - assertTrue(container.intersects(1, 300)); - assertFalse(container.intersects(2, 300)); - assertFalse(container.intersects(2, 299)); - assertTrue(container.intersects(0, lower16Bits(-1))); - assertFalse(container.intersects(1025, 1 << 16)); - } - - - @Test - public void testContainsRange() { - Container ac = new ArrayContainer().add(20, 100); - assertFalse(ac.contains(1, 21)); - assertFalse(ac.contains(1, 19)); - assertTrue(ac.contains(20, 100)); - assertTrue(ac.contains(20, 99)); - assertTrue(ac.contains(21, 100)); - assertFalse(ac.contains(21, 101)); - assertFalse(ac.contains(19, 99)); - assertFalse(ac.contains(190, 9999)); - } - - @Test - public void testContainsRange2() { - Container ac = new ArrayContainer() - .add((char)1).add((char)10) - .add(20, 100); - assertFalse(ac.contains(1, 21)); - assertFalse(ac.contains(1, 20)); - assertTrue(ac.contains(1, 2)); - } - - @Test - public void testContainsRangeUnsigned() { - Container ac = new ArrayContainer().add(1 << 15, 1 << 8 | 1 << 15); - assertTrue(ac.contains(1 << 15, 1 << 8 | 1 << 15)); - assertTrue(ac.contains(1 + (1 << 15), (1 << 8 | 1 << 15) - 1)); - assertFalse(ac.contains(1 + (1 << 15), (1 << 8 | 1 << 15) + 1)); - assertFalse(ac.contains((1 << 15) - 1, (1 << 8 | 1 << 15) - 1)); - assertFalse(ac.contains(0, 1 << 15)); - assertFalse(ac.contains(1 << 8 | 1 << 15 | 1, 1 << 16)); - } - - @Test - public void testNextValueBeforeStart() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(10, container.nextValue((char)5)); - } - - @Test - public void testNextValue() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(10, container.nextValue((char)10)); - assertEquals(20, container.nextValue((char)11)); - assertEquals(30, container.nextValue((char)30)); - } - - @Test - public void testNextValueAfterEnd() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(-1, container.nextValue((char)31)); - } - - @Test - public void testNextValue2() { - Container container = new ArrayContainer().iadd(64, 129); - assertTrue(container instanceof ArrayContainer); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(-1, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)5000)); - } - - @Test - public void testNextValueBetweenRuns() { - Container container = new ArrayContainer().iadd(64, 129).iadd(256, 321); - assertTrue(container instanceof ArrayContainer); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(256, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)512)); - } - - @Test - public void testNextValue3() { - Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertTrue(container instanceof ArrayContainer); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)63)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(200, container.nextValue((char)129)); - assertEquals(200, container.nextValue((char)199)); - assertEquals(200, container.nextValue((char)200)); - assertEquals(250, container.nextValue((char)250)); - assertEquals(5000, container.nextValue((char)2500)); - assertEquals(5000, container.nextValue((char)5000)); - assertEquals(5200, container.nextValue((char)5200)); - assertEquals(-1, container.nextValue((char)5201)); - } - - @Test - public void testPreviousValue1() { - Container container = new ArrayContainer().iadd(64, 129); - assertTrue(container instanceof ArrayContainer); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - } - - @Test - public void testPreviousValue2() { - Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertTrue(container instanceof ArrayContainer); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - assertEquals(128, container.previousValue((char)199)); - assertEquals(200, container.previousValue((char)200)); - assertEquals(250, container.previousValue((char)250)); - assertEquals(500, container.previousValue((char)2500)); - assertEquals(5000, container.previousValue((char)5000)); - assertEquals(5200, container.previousValue((char)5200)); - } - - @Test - public void testPreviousValueBeforeStart() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(-1, container.previousValue((char)5)); - } - - @Test - public void testPreviousValueSparse() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(-1, container.previousValue((char)9)); - assertEquals(10, container.previousValue((char)10)); - assertEquals(10, container.previousValue((char)11)); - assertEquals(20, container.previousValue((char)21)); - assertEquals(30, container.previousValue((char)30)); - } - - @Test - public void testPreviousValueUnsigned() { - ArrayContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}); - assertEquals(-1, container.previousValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 8))); - } - - @Test - public void testNextValueUnsigned() { - ArrayContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 7))); - assertEquals(-1, container.nextValue((char)((1 << 15) | 8))); - } - - @Test - public void testPreviousValueAfterEnd() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(30, container.previousValue((char)31)); - } - - @Test - public void testPreviousAbsentValue1() { - Container container = new ArrayContainer().iadd(64, 129); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - } - - @Test - public void testPreviousAbsentValue2() { - Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - assertEquals(199, container.previousAbsentValue((char)199)); - assertEquals(199, container.previousAbsentValue((char)200)); - assertEquals(199, container.previousAbsentValue((char)250)); - assertEquals(2500, container.previousAbsentValue((char)2500)); - assertEquals(4999, container.previousAbsentValue((char)5000)); - assertEquals(4999, container.previousAbsentValue((char)5200)); - } - - @Test - public void testPreviousAbsentValueEmpty() { - ArrayContainer container = new ArrayContainer(); - for (int i = 0; i < 1000; i++) { - assertEquals(i, container.previousAbsentValue((char)i)); - } - } - - @Test - public void testPreviousAbsentValueSparse() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(9, container.previousAbsentValue((char)9)); - assertEquals(9, container.previousAbsentValue((char)10)); - assertEquals(11, container.previousAbsentValue((char)11)); - assertEquals(21, container.previousAbsentValue((char)21)); - assertEquals(29, container.previousAbsentValue((char)30)); - } - - @Test - public void testPreviousAbsentValueUnsigned() { - ArrayContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.previousAbsentValue((char)((1 << 15) | 8))); - } - - - @Test - public void testNextAbsentValue1() { - Container container = new ArrayContainer().iadd(64, 129); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - } - - @Test - public void testNextAbsentValue2() { - Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - assertEquals(199, container.nextAbsentValue((char)199)); - assertEquals(501, container.nextAbsentValue((char)200)); - assertEquals(501, container.nextAbsentValue((char)250)); - assertEquals(2500, container.nextAbsentValue((char)2500)); - assertEquals(5201, container.nextAbsentValue((char)5000)); - assertEquals(5201, container.nextAbsentValue((char)5200)); - } - - @Test - public void testNextAbsentValueEmpty() { - ArrayContainer container = new ArrayContainer(); - for (int i = 0; i < 1000; i++) { - assertEquals(i, container.nextAbsentValue((char)i)); - } - } - - @Test - public void testNextAbsentValueSparse() { - ArrayContainer container = new ArrayContainer(new char[] { 10, 20, 30}); - assertEquals(9, container.nextAbsentValue((char)9)); - assertEquals(11, container.nextAbsentValue((char)10)); - assertEquals(11, container.nextAbsentValue((char)11)); - assertEquals(21, container.nextAbsentValue((char)21)); - assertEquals(31, container.nextAbsentValue((char)30)); - } - - @Test - public void testNextAbsentValueUnsigned() { - ArrayContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}); - assertEquals(((1 << 15) | 4), container.nextAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 8))); - } - - @Test - public void testRangeConsumer() { - char[] entries = new char[] {3, 4, 7, 8, 10, 65530, 65534, 65535}; - ArrayContainer container = new ArrayContainer(entries); - - ValidationRangeConsumer consumer = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - ABSENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, PRESENT - }); - container.forAllUntil(0, (char) 11, consumer); - assertEquals(11, consumer.getNumberOfValuesConsumed()); - - ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - PRESENT, ABSENT, ABSENT, PRESENT, PRESENT - }); - container.forAllInRange((char) 4, (char) 9, consumer2); - assertEquals(5, consumer2.getNumberOfValuesConsumed()); - - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - PRESENT, ABSENT, ABSENT, ABSENT, PRESENT, PRESENT - }); - container.forAllFrom((char) 65530, consumer3); - assertEquals(6, consumer3.getNumberOfValuesConsumed()); - - ValidationRangeConsumer consumer4 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); - container.forAll(0, consumer4); - consumer4.assertAllAbsentExcept(entries, 0); - - ValidationRangeConsumer consumer5 = ValidationRangeConsumer.ofSize(2 * BitmapContainer.MAX_CAPACITY); - consumer5.acceptAllAbsent(0, BitmapContainer.MAX_CAPACITY); - container.forAll(BitmapContainer.MAX_CAPACITY, consumer5); - consumer5.assertAllAbsentExcept(entries, BitmapContainer.MAX_CAPACITY); - - container = new ArrayContainer(); - ValidationRangeConsumer consumer6 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); - container.forAll(0, consumer6); - consumer6.assertAllAbsent(); - - container = new ArrayContainer(); - Container c = container.iadd(0, ArrayContainer.DEFAULT_MAX_SIZE); - assertTrue(container == c, "Container type changed!"); - ValidationRangeConsumer consumer7 = ValidationRangeConsumer.ofSize(ArrayContainer.DEFAULT_MAX_SIZE); - container.forAllUntil(0, (char) ArrayContainer.DEFAULT_MAX_SIZE, consumer7); - consumer7.assertAllPresent(); - } - - private static int lower16Bits(int x) { - return ((char)x) & 0xFFFF; - } + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + + assertFalse(iterator.hasNext()); + } + } + + @Test + public void orNot2() { + Container rc1 = new ArrayContainer(); + Container rc2 = new ArrayContainer(); + rc2.iadd(128, 256).iadd(257, 260); + rc1 = rc1.orNot(rc2, 261); + assertEquals(130, rc1.getCardinality()); + + PeekableCharIterator iterator = rc1.getCharIterator(); + for (int i = 0; i < 128; i++) { + assertTrue(iterator.hasNext()); + assertEquals(i, iterator.next()); + } + assertTrue(iterator.hasNext()); + assertEquals(256, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(260, iterator.next()); + + assertFalse(iterator.hasNext()); + } + + @Test + public void testIntersectsWithRange() { + Container container = new ArrayContainer().add(0, 10); + assertTrue(container.intersects(0, 1)); + assertTrue(container.intersects(0, 101)); + assertTrue(container.intersects(0, lower16Bits(-1))); + assertFalse(container.intersects(11, lower16Bits(-1))); + } + + @Test + public void testIntersectsWithRange2() { + Container container = new ArrayContainer().add(lower16Bits(-50), lower16Bits(-10)); + assertFalse(container.intersects(0, 1)); + assertTrue(container.intersects(0, lower16Bits(-40))); + assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); + assertFalse(container.intersects(lower16Bits(-9), lower16Bits(-1))); + assertTrue(container.intersects(11, 1 << 16)); + } + + @Test + public void testIntersectsWithRange3() { + Container container = new ArrayContainer().add((char) 1).add((char) 300).add((char) 1024); + assertTrue(container.intersects(0, 300)); + assertTrue(container.intersects(1, 300)); + assertFalse(container.intersects(2, 300)); + assertFalse(container.intersects(2, 299)); + assertTrue(container.intersects(0, lower16Bits(-1))); + assertFalse(container.intersects(1025, 1 << 16)); + } + + @Test + public void testContainsRange() { + Container ac = new ArrayContainer().add(20, 100); + assertFalse(ac.contains(1, 21)); + assertFalse(ac.contains(1, 19)); + assertTrue(ac.contains(20, 100)); + assertTrue(ac.contains(20, 99)); + assertTrue(ac.contains(21, 100)); + assertFalse(ac.contains(21, 101)); + assertFalse(ac.contains(19, 99)); + assertFalse(ac.contains(190, 9999)); + } + + @Test + public void testContainsRange2() { + Container ac = new ArrayContainer().add((char) 1).add((char) 10).add(20, 100); + assertFalse(ac.contains(1, 21)); + assertFalse(ac.contains(1, 20)); + assertTrue(ac.contains(1, 2)); + } + + @Test + public void testContainsRangeUnsigned() { + Container ac = new ArrayContainer().add(1 << 15, 1 << 8 | 1 << 15); + assertTrue(ac.contains(1 << 15, 1 << 8 | 1 << 15)); + assertTrue(ac.contains(1 + (1 << 15), (1 << 8 | 1 << 15) - 1)); + assertFalse(ac.contains(1 + (1 << 15), (1 << 8 | 1 << 15) + 1)); + assertFalse(ac.contains((1 << 15) - 1, (1 << 8 | 1 << 15) - 1)); + assertFalse(ac.contains(0, 1 << 15)); + assertFalse(ac.contains(1 << 8 | 1 << 15 | 1, 1 << 16)); + } + + @Test + public void testNextValueBeforeStart() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(10, container.nextValue((char) 5)); + } + + @Test + public void testNextValue() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(10, container.nextValue((char) 10)); + assertEquals(20, container.nextValue((char) 11)); + assertEquals(30, container.nextValue((char) 30)); + } + + @Test + public void testNextValueAfterEnd() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(-1, container.nextValue((char) 31)); + } + + @Test + public void testNextValue2() { + Container container = new ArrayContainer().iadd(64, 129); + assertTrue(container instanceof ArrayContainer); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(-1, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 5000)); + } + + @Test + public void testNextValueBetweenRuns() { + Container container = new ArrayContainer().iadd(64, 129).iadd(256, 321); + assertTrue(container instanceof ArrayContainer); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(256, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 512)); + } + + @Test + public void testNextValue3() { + Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertTrue(container instanceof ArrayContainer); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 63)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(200, container.nextValue((char) 129)); + assertEquals(200, container.nextValue((char) 199)); + assertEquals(200, container.nextValue((char) 200)); + assertEquals(250, container.nextValue((char) 250)); + assertEquals(5000, container.nextValue((char) 2500)); + assertEquals(5000, container.nextValue((char) 5000)); + assertEquals(5200, container.nextValue((char) 5200)); + assertEquals(-1, container.nextValue((char) 5201)); + } + + @Test + public void testPreviousValue1() { + Container container = new ArrayContainer().iadd(64, 129); + assertTrue(container instanceof ArrayContainer); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + } + + @Test + public void testPreviousValue2() { + Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertTrue(container instanceof ArrayContainer); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + assertEquals(128, container.previousValue((char) 199)); + assertEquals(200, container.previousValue((char) 200)); + assertEquals(250, container.previousValue((char) 250)); + assertEquals(500, container.previousValue((char) 2500)); + assertEquals(5000, container.previousValue((char) 5000)); + assertEquals(5200, container.previousValue((char) 5200)); + } + + @Test + public void testPreviousValueBeforeStart() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(-1, container.previousValue((char) 5)); + } + + @Test + public void testPreviousValueSparse() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(-1, container.previousValue((char) 9)); + assertEquals(10, container.previousValue((char) 10)); + assertEquals(10, container.previousValue((char) 11)); + assertEquals(20, container.previousValue((char) 21)); + assertEquals(30, container.previousValue((char) 30)); + } + + @Test + public void testPreviousValueUnsigned() { + ArrayContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}); + assertEquals(-1, container.previousValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 8))); + } + + @Test + public void testNextValueUnsigned() { + ArrayContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 7))); + assertEquals(-1, container.nextValue((char) ((1 << 15) | 8))); + } + + @Test + public void testPreviousValueAfterEnd() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(30, container.previousValue((char) 31)); + } + + @Test + public void testPreviousAbsentValue1() { + Container container = new ArrayContainer().iadd(64, 129); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + } + + @Test + public void testPreviousAbsentValue2() { + Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + assertEquals(199, container.previousAbsentValue((char) 199)); + assertEquals(199, container.previousAbsentValue((char) 200)); + assertEquals(199, container.previousAbsentValue((char) 250)); + assertEquals(2500, container.previousAbsentValue((char) 2500)); + assertEquals(4999, container.previousAbsentValue((char) 5000)); + assertEquals(4999, container.previousAbsentValue((char) 5200)); + } + + @Test + public void testPreviousAbsentValueEmpty() { + ArrayContainer container = new ArrayContainer(); + for (int i = 0; i < 1000; i++) { + assertEquals(i, container.previousAbsentValue((char) i)); + } + } + + @Test + public void testPreviousAbsentValueSparse() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(9, container.previousAbsentValue((char) 9)); + assertEquals(9, container.previousAbsentValue((char) 10)); + assertEquals(11, container.previousAbsentValue((char) 11)); + assertEquals(21, container.previousAbsentValue((char) 21)); + assertEquals(29, container.previousAbsentValue((char) 30)); + } + + @Test + public void testPreviousAbsentValueUnsigned() { + ArrayContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.previousAbsentValue((char) ((1 << 15) | 8))); + } + + @Test + public void testNextAbsentValue1() { + Container container = new ArrayContainer().iadd(64, 129); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + } + + @Test + public void testNextAbsentValue2() { + Container container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + assertEquals(199, container.nextAbsentValue((char) 199)); + assertEquals(501, container.nextAbsentValue((char) 200)); + assertEquals(501, container.nextAbsentValue((char) 250)); + assertEquals(2500, container.nextAbsentValue((char) 2500)); + assertEquals(5201, container.nextAbsentValue((char) 5000)); + assertEquals(5201, container.nextAbsentValue((char) 5200)); + } + + @Test + public void testNextAbsentValueEmpty() { + ArrayContainer container = new ArrayContainer(); + for (int i = 0; i < 1000; i++) { + assertEquals(i, container.nextAbsentValue((char) i)); + } + } + + @Test + public void testNextAbsentValueSparse() { + ArrayContainer container = new ArrayContainer(new char[] {10, 20, 30}); + assertEquals(9, container.nextAbsentValue((char) 9)); + assertEquals(11, container.nextAbsentValue((char) 10)); + assertEquals(11, container.nextAbsentValue((char) 11)); + assertEquals(21, container.nextAbsentValue((char) 21)); + assertEquals(31, container.nextAbsentValue((char) 30)); + } + + @Test + public void testNextAbsentValueUnsigned() { + ArrayContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}); + assertEquals(((1 << 15) | 4), container.nextAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 8))); + } + + @Test + public void testRangeConsumer() { + char[] entries = new char[] {3, 4, 7, 8, 10, 65530, 65534, 65535}; + ArrayContainer container = new ArrayContainer(entries); + + ValidationRangeConsumer consumer = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + ABSENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, + PRESENT + }); + container.forAllUntil(0, (char) 11, consumer); + assertEquals(11, consumer.getNumberOfValuesConsumed()); + + ValidationRangeConsumer consumer2 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] {PRESENT, ABSENT, ABSENT, PRESENT, PRESENT}); + container.forAllInRange((char) 4, (char) 9, consumer2); + assertEquals(5, consumer2.getNumberOfValuesConsumed()); + + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + PRESENT, ABSENT, ABSENT, ABSENT, PRESENT, PRESENT + }); + container.forAllFrom((char) 65530, consumer3); + assertEquals(6, consumer3.getNumberOfValuesConsumed()); + + ValidationRangeConsumer consumer4 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + container.forAll(0, consumer4); + consumer4.assertAllAbsentExcept(entries, 0); + + ValidationRangeConsumer consumer5 = + ValidationRangeConsumer.ofSize(2 * BitmapContainer.MAX_CAPACITY); + consumer5.acceptAllAbsent(0, BitmapContainer.MAX_CAPACITY); + container.forAll(BitmapContainer.MAX_CAPACITY, consumer5); + consumer5.assertAllAbsentExcept(entries, BitmapContainer.MAX_CAPACITY); + + container = new ArrayContainer(); + ValidationRangeConsumer consumer6 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + container.forAll(0, consumer6); + consumer6.assertAllAbsent(); + + container = new ArrayContainer(); + Container c = container.iadd(0, ArrayContainer.DEFAULT_MAX_SIZE); + assertTrue(container == c, "Container type changed!"); + ValidationRangeConsumer consumer7 = + ValidationRangeConsumer.ofSize(ArrayContainer.DEFAULT_MAX_SIZE); + container.forAllUntil(0, (char) ArrayContainer.DEFAULT_MAX_SIZE, consumer7); + consumer7.assertAllPresent(); + } + + private static int lower16Bits(int x) { + return ((char) x) & 0xFFFF; + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java index c5bc18e23..a4db0f37a 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java @@ -1,5 +1,9 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -7,12 +11,9 @@ import java.util.BitSet; import java.util.Random; -import static org.junit.jupiter.api.Assertions.*; - - public class TestBitSetUtil { - private static BitSet appendRandomBitset(final Random random, final int offset, - final BitSet bitset, final int nbits) { + private static BitSet appendRandomBitset( + final Random random, final int offset, final BitSet bitset, final int nbits) { for (int i = 0; i < nbits; i++) { final boolean b = random.nextBoolean(); bitset.set(offset + i, b); @@ -25,16 +26,18 @@ private static BitSet randomBitset(final Random random, final int offset, final return appendRandomBitset(random, offset, bitset, length); } - private void assertEqualBitsets(final BitSet bitset, final RoaringBitmap bitmap) { assertTrue(BitSetUtil.equals(bitset, bitmap), "bitset and bitmap do not match"); assertEquals(bitset, BitSetUtil.bitsetOf(bitmap), "bitsetOf doesn't match"); - assertEquals(bitset, BitSetUtil.bitsetOfWithoutCopy(bitmap), "bitsetOfWithoutCopy doesn't match"); - assertEquals(bitset, BitSet.valueOf(BitSetUtil.toByteArray(bitmap)), "toByteArray doesn't match"); + assertEquals( + bitset, BitSetUtil.bitsetOfWithoutCopy(bitmap), "bitsetOfWithoutCopy doesn't match"); + assertEquals( + bitset, BitSet.valueOf(BitSetUtil.toByteArray(bitmap)), "toByteArray doesn't match"); RoaringBitmap runBitmap = bitmap.clone(); runBitmap.runOptimize(); - assertEquals(bitset, BitSetUtil.bitsetOf(runBitmap), "bitsetOf doesn't match for run optimized bitmap"); + assertEquals( + bitset, BitSetUtil.bitsetOf(runBitmap), "bitsetOf doesn't match for run optimized bitmap"); } @Test @@ -145,8 +148,8 @@ public void testSmallBitSet10000000() { } /* - The ByteBuffer->RoaringBitmap just replicate similar tests written for BitSet/long[]->RoaringBitmap - */ + The ByteBuffer->RoaringBitmap just replicate similar tests written for BitSet/long[]->RoaringBitmap + */ @Test public void testEmptyByteBuffer() { @@ -211,7 +214,7 @@ public void testRandomByteBuffer() { final Random random = new Random(8934); final int runs = 100; final int maxNbits = 500000; - for (int i = 0;i < runs; ++i) { + for (int i = 0; i < runs; ++i) { final int offset = random.nextInt(maxNbits) & Integer.MAX_VALUE; final BitSet bitset = randomBitset(random, offset, random.nextInt(maxNbits)); final RoaringBitmap bitmap = BitSetUtil.bitmapOf(toByteBuffer(bitset), false); @@ -247,9 +250,12 @@ public void testByteArrayWithFastRank() { public void testBitmapOfNegative() { final RoaringBitmap bitmap = new RoaringBitmap(); bitmap.add(-1); - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - BitSetUtil.bitsetOf(bitmap); - }); + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> { + BitSetUtil.bitsetOf(bitmap); + }); assertEquals("bitmap has negative bits set", exception.getMessage()); } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java index 3db95ee71..b3dfbb179 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestBitmapContainer.java @@ -4,6 +4,13 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; +import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -21,10 +28,6 @@ import java.util.Random; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; -import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; - @Execution(ExecutionMode.CONCURRENT) public class TestBitmapContainer { private static BitmapContainer emptyContainer() { @@ -49,12 +52,12 @@ public void testToString() { @Test public void testXOR() { - BitmapContainer bc = new BitmapContainer(100,10000); + BitmapContainer bc = new BitmapContainer(100, 10000); BitmapContainer bc2 = new BitmapContainer(); BitmapContainer bc3 = new BitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -66,19 +69,19 @@ public void testXOR() { @Test public void testANDNOT() { - BitmapContainer bc = new BitmapContainer(100,10000); + BitmapContainer bc = new BitmapContainer(100, 10000); BitmapContainer bc2 = new BitmapContainer(); BitmapContainer bc3 = new BitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); } } RunContainer rc = new RunContainer(); - rc.iadd(0, 1<<16); + rc.iadd(0, 1 << 16); bc = (BitmapContainer) bc.iand(rc); bc = (BitmapContainer) bc.iandNot(bc2); assertEquals(bc, bc3); @@ -88,15 +91,14 @@ public void testANDNOT() { assertEquals(0, bc3.getCardinality()); } - @Test public void testAND() { - BitmapContainer bc = new BitmapContainer(100,10000); + BitmapContainer bc = new BitmapContainer(100, 10000); BitmapContainer bc2 = new BitmapContainer(); BitmapContainer bc3 = new BitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -107,16 +109,14 @@ public void testAND() { assertEquals(0, bc.iand(bc3).getCardinality()); } - - @Test public void testOR() { - BitmapContainer bc = new BitmapContainer(100,10000); + BitmapContainer bc = new BitmapContainer(100, 10000); BitmapContainer bc2 = new BitmapContainer(); BitmapContainer bc3 = new BitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -127,7 +127,7 @@ public void testOR() { bc2 = (BitmapContainer) bc2.ior(bc); assertEquals(bc, bc2); RunContainer rc = new RunContainer(); - rc.iadd(0, 1<<16); + rc.iadd(0, 1 << 16); assertEquals(0, bc.iandNot(rc).getCardinality()); } @@ -182,19 +182,19 @@ public void testLazyORFull3() { @Test public void runConstructorForBitmap() { System.out.println("runConstructorForBitmap"); - for(int start = 0; start <= (1<<16); start += 4096 ) { - for(int end = start; end <= (1<<16); end += 4096 ) { - BitmapContainer bc = new BitmapContainer(start,end); + for (int start = 0; start <= (1 << 16); start += 4096) { + for (int end = start; end <= (1 << 16); end += 4096) { + BitmapContainer bc = new BitmapContainer(start, end); BitmapContainer bc2 = new BitmapContainer(); - BitmapContainer bc3 = (BitmapContainer) bc2.add(start,end); + BitmapContainer bc3 = (BitmapContainer) bc2.add(start, end); bc2.iadd(start, end); - assertEquals(bc.getCardinality(), end-start); - assertEquals(bc2.getCardinality(), end-start); + assertEquals(bc.getCardinality(), end - start); + assertEquals(bc2.getCardinality(), end - start); assertEquals(bc, bc2); assertEquals(bc, bc3); - assertEquals(0,bc2.remove(start, end).getCardinality()); - assertEquals(bc2.getCardinality(), end-start); - assertEquals(0,bc2.not(start, end).getCardinality()); + assertEquals(0, bc2.remove(start, end).getCardinality()); + assertEquals(bc2.getCardinality(), end - start); + assertEquals(0, bc2.not(start, end).getCardinality()); } } } @@ -202,73 +202,73 @@ public void runConstructorForBitmap() { @Test public void runConstructorForBitmap2() { System.out.println("runConstructorForBitmap2"); - for(int start = 0; start <= (1<<16); start += 63 ) { - for(int end = start; end <= (1<<16); end += 63 ) { - BitmapContainer bc = new BitmapContainer(start,end); + for (int start = 0; start <= (1 << 16); start += 63) { + for (int end = start; end <= (1 << 16); end += 63) { + BitmapContainer bc = new BitmapContainer(start, end); BitmapContainer bc2 = new BitmapContainer(); - BitmapContainer bc3 = (BitmapContainer) bc2.add(start,end); + BitmapContainer bc3 = (BitmapContainer) bc2.add(start, end); bc2.iadd(start, end); - assertEquals(bc.getCardinality(), end-start); - assertEquals(bc2.getCardinality(), end-start); + assertEquals(bc.getCardinality(), end - start); + assertEquals(bc2.getCardinality(), end - start); assertEquals(bc, bc2); assertEquals(bc, bc3); - assertEquals(0,bc2.remove(start, end).getCardinality()); - assertEquals(bc2.getCardinality(), end-start); - assertEquals(0,bc2.not(start, end).getCardinality()); + assertEquals(0, bc2.remove(start, end).getCardinality()); + assertEquals(bc2.getCardinality(), end - start); + assertEquals(0, bc2.not(start, end).getCardinality()); } } } @Test public void testRangeCardinality() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); bc = (BitmapContainer) bc.add(200, 2000); assertEquals(8280, bc.cardinality); } @Test public void testRangeCardinality2() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); bc.iadd(200, 2000); assertEquals(8280, bc.cardinality); } @Test public void testRangeCardinality3() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc.ior(rc); assertEquals(8677, bc.cardinality); } @Test public void testRangeCardinality4() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc = (BitmapContainer) bc.andNot(rc); assertEquals(5274, bc.cardinality); } @Test public void testRangeCardinality5() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc.iandNot(rc); assertEquals(5274, bc.cardinality); } @Test public void testRangeCardinality6() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 5200}, 3); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 5200}, 3); bc = (BitmapContainer) bc.iand(rc); assertEquals(5046, bc.cardinality); } @Test public void testRangeCardinality7() { - BitmapContainer bc = generateContainer((char)100, (char)10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + BitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc.ixor(rc); assertEquals(6031, bc.cardinality); } @@ -299,10 +299,9 @@ public void numberOfRunsLowerBound1() { // a big parameter like 100000 ensures that the full lower bound // is taken - assertTrue(bc.numberOfRunsLowerBound(100000) <= bc.numberOfRuns()); - assertEquals(bc.numberOfRuns(), - bc.numberOfRunsLowerBound(100000) + bc.numberOfRunsAdjustment()); + assertEquals( + bc.numberOfRuns(), bc.numberOfRunsLowerBound(100000) + bc.numberOfRunsAdjustment()); /* * the unrolled guys are commented out, did not help performance and slated for removal @@ -315,49 +314,50 @@ public void numberOfRunsLowerBound1() { * bc.numberOfRunsLowerBoundUnrolled2(100000)); */ } - } @Test public void testNextTooLarge() { - assertThrows(ArrayIndexOutOfBoundsException.class, - () -> emptyContainer().nextSetBit(Short.MAX_VALUE + 1)); + assertThrows( + ArrayIndexOutOfBoundsException.class, + () -> emptyContainer().nextSetBit(Short.MAX_VALUE + 1)); } @Test public void testNextTooSmall() { - assertThrows(ArrayIndexOutOfBoundsException.class, - () -> emptyContainer().nextSetBit(-1)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> emptyContainer().nextSetBit(-1)); } @Test public void testPreviousTooLarge() { - assertThrows(ArrayIndexOutOfBoundsException.class, - () -> emptyContainer().prevSetBit(Short.MAX_VALUE + 1)); + assertThrows( + ArrayIndexOutOfBoundsException.class, + () -> emptyContainer().prevSetBit(Short.MAX_VALUE + 1)); } - @Test public void testPreviousTooSmall() { - assertThrows(ArrayIndexOutOfBoundsException.class, - () -> emptyContainer().prevSetBit(-1)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> emptyContainer().prevSetBit(-1)); } - @Test public void addInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - Container bc = new BitmapContainer(); - bc.add(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container bc = new BitmapContainer(); + bc.add(13, 1); + }); } @Test public void iaddInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - Container bc = new BitmapContainer(); - bc.iadd(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container bc = new BitmapContainer(); + bc.iadd(13, 1); + }); } @Test @@ -526,7 +526,6 @@ public void orNot() { assertFalse(iterator.hasNext()); } - } @Test @@ -606,23 +605,25 @@ public void orFullToRunContainer4() { @Test public void iremoveEmptyRange() { Container bc = new BitmapContainer(); - bc = bc.iremove(1,1); + bc = bc.iremove(1, 1); assertEquals(0, bc.getCardinality()); } @Test public void iremoveInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - Container ac = new BitmapContainer(); - ac.iremove(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container ac = new BitmapContainer(); + ac.iremove(13, 1); + }); } @Test public void iremove() { Container bc = new BitmapContainer(); - bc = bc.add(1,10); - bc = bc.iremove(5,10); + bc = bc.add(1, 10); + bc = bc.iremove(5, 10); assertEquals(4, bc.getCardinality()); for (int i = 1; i < 5; i++) { assertTrue(bc.contains((char) i)); @@ -632,8 +633,8 @@ public void iremove() { @Test public void iremove2() { Container bc = new BitmapContainer(); - bc = bc.add(1,8092); - bc = bc.iremove(1,10); + bc = bc.add(1, 8092); + bc = bc.iremove(1, 10); assertEquals(8082, bc.getCardinality()); for (int i = 10; i < 8092; i++) { assertTrue(bc.contains((char) i)); @@ -643,7 +644,7 @@ public void iremove2() { @Test public void ixorRun() { Container bc = new BitmapContainer(); - bc = bc.add(1,10); + bc = bc.add(1, 10); Container rc = new RunContainer(); rc = rc.add(5, 15); bc = bc.ixor(rc); @@ -659,7 +660,7 @@ public void ixorRun() { @Test public void ixorRun2() { Container bc = new BitmapContainer(); - bc = bc.add(1,8092); + bc = bc.add(1, 8092); Container rc = new RunContainer(); rc = rc.add(1, 10); bc = bc.ixor(rc); @@ -671,26 +672,30 @@ public void ixorRun2() { @Test public void selectInvalidPosition() { - assertThrows(IllegalArgumentException.class, () -> { - Container bc = new BitmapContainer(); - bc = bc.add(1, 13); - bc.select(100); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container bc = new BitmapContainer(); + bc = bc.add(1, 13); + bc.select(100); + }); } @Test public void removeInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - Container ac = new BitmapContainer(); - ac.remove(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container ac = new BitmapContainer(); + ac.remove(13, 1); + }); } @Test public void remove() { Container bc = new BitmapContainer(); - bc = bc.add(1,8092); - bc = bc.remove(1,10); + bc = bc.add(1, 8092); + bc = bc.remove(1, 10); assertEquals(8082, bc.getCardinality()); for (int i = 10; i < 8092; i++) { assertTrue(bc.contains((char) i)); @@ -700,7 +705,7 @@ public void remove() { @Test public void iandRun() { Container bc = new BitmapContainer(); - bc = bc.add(0,8092); + bc = bc.add(0, 8092); Container rc = new RunContainer(); rc = rc.add(1, 10); bc = bc.iand(rc); @@ -743,42 +748,42 @@ public void testContainsBitmapContainer_EmptyContainsEmpty() { @Test public void testContainsBitmapContainer_IncludeProperSubset() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new BitmapContainer().add(0,9); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new BitmapContainer().add(0, 9); assertTrue(bc.contains(subset)); } @Test public void testContainsBitmapContainer_IncludeSelf() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new BitmapContainer().add(0,10); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new BitmapContainer().add(0, 10); assertTrue(bc.contains(subset)); } @Test public void testContainsBitmapContainer_ExcludeSuperSet() { - Container bc = new BitmapContainer().add(0,10); - Container superset = new BitmapContainer().add(0,20); + Container bc = new BitmapContainer().add(0, 10); + Container superset = new BitmapContainer().add(0, 20); assertFalse(bc.contains(superset)); } @Test public void testContainsBitmapContainer_IncludeProperSubsetDifferentStart() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new RunContainer().add(2,9); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new RunContainer().add(2, 9); assertTrue(bc.contains(subset)); } @Test public void testContainsBitmapContainer_ExcludeShiftedSet() { - Container bc = new BitmapContainer().add(0,10); - Container shifted = new BitmapContainer().add(2,12); + Container bc = new BitmapContainer().add(0, 10); + Container shifted = new BitmapContainer().add(2, 12); assertFalse(bc.contains(shifted)); } @Test public void testContainsBitmapContainer_ExcludeDisJointSet() { - Container bc = new BitmapContainer().add(0,10); + Container bc = new BitmapContainer().add(0, 10); Container disjoint = new BitmapContainer().add(20, 40); assertFalse(bc.contains(disjoint)); assertFalse(disjoint.contains(bc)); @@ -793,42 +798,42 @@ public void testContainsRunContainer_EmptyContainsEmpty() { @Test public void testContainsRunContainer_IncludeProperSubset() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new RunContainer().add(0,9); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new RunContainer().add(0, 9); assertTrue(bc.contains(subset)); } @Test public void testContainsRunContainer_IncludeSelf() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new RunContainer().add(0,10); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new RunContainer().add(0, 10); assertTrue(bc.contains(subset)); } @Test public void testContainsRunContainer_ExcludeSuperSet() { - Container bc = new BitmapContainer().add(0,10); - Container superset = new RunContainer().add(0,20); + Container bc = new BitmapContainer().add(0, 10); + Container superset = new RunContainer().add(0, 20); assertFalse(bc.contains(superset)); } @Test public void testContainsRunContainer_IncludeProperSubsetDifferentStart() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new RunContainer().add(2,9); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new RunContainer().add(2, 9); assertTrue(bc.contains(subset)); } @Test public void testContainsRunContainer_ExcludeShiftedSet() { - Container bc = new BitmapContainer().add(0,10); - Container shifted = new RunContainer().add(2,12); + Container bc = new BitmapContainer().add(0, 10); + Container shifted = new RunContainer().add(2, 12); assertFalse(bc.contains(shifted)); } @Test public void testContainsRunContainer_ExcludeDisJointSet() { - Container bc = new BitmapContainer().add(0,10); + Container bc = new BitmapContainer().add(0, 10); Container disjoint = new RunContainer().add(20, 40); assertFalse(bc.contains(disjoint)); assertFalse(disjoint.contains(bc)); @@ -843,36 +848,36 @@ public void testContainsArrayContainer_EmptyContainsEmpty() { @Test public void testContainsArrayContainer_IncludeProperSubset() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new ArrayContainer().add(0,9); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new ArrayContainer().add(0, 9); assertTrue(bc.contains(subset)); } @Test public void testContainsArrayContainer_IncludeSelf() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new ArrayContainer().add(0,10); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new ArrayContainer().add(0, 10); assertTrue(bc.contains(subset)); } @Test public void testContainsArrayContainer_ExcludeSuperSet() { - Container bc = new BitmapContainer().add(0,10); - Container superset = new ArrayContainer().add(0,20); + Container bc = new BitmapContainer().add(0, 10); + Container superset = new ArrayContainer().add(0, 20); assertFalse(bc.contains(superset)); } @Test public void testContainsArrayContainer_IncludeProperSubsetDifferentStart() { - Container bc = new BitmapContainer().add(0,10); - Container subset = new ArrayContainer().add(2,9); + Container bc = new BitmapContainer().add(0, 10); + Container subset = new ArrayContainer().add(2, 9); assertTrue(bc.contains(subset)); } @Test public void testContainsArrayContainer_ExcludeShiftedSet() { - Container bc = new BitmapContainer().add(0,10); - Container shifted = new ArrayContainer().add(2,12); + Container bc = new BitmapContainer().add(0, 10); + Container shifted = new ArrayContainer().add(2, 12); assertFalse(bc.contains(shifted)); } @@ -895,24 +900,24 @@ public void testIntersectsWithRange() { public static Stream bitmapsForRangeIntersection() { return Stream.of( - Arguments.of(new BitmapContainer().add((char)60), 0, 61, true), - Arguments.of(new BitmapContainer().add((char)60), 0, 60, false), - Arguments.of(new BitmapContainer().add((char)1000), 0, 1001, true), - Arguments.of(new BitmapContainer().add((char)1000), 0, 1000, false), - Arguments.of(new BitmapContainer().add((char)1000), 0, 10000, true) - ); + Arguments.of(new BitmapContainer().add((char) 60), 0, 61, true), + Arguments.of(new BitmapContainer().add((char) 60), 0, 60, false), + Arguments.of(new BitmapContainer().add((char) 1000), 0, 1001, true), + Arguments.of(new BitmapContainer().add((char) 1000), 0, 1000, false), + Arguments.of(new BitmapContainer().add((char) 1000), 0, 10000, true)); } @ParameterizedTest @MethodSource("bitmapsForRangeIntersection") - public void testIntersectsWithRangeUpperBoundaries(Container container, int min, int sup, boolean intersects) { + public void testIntersectsWithRangeUpperBoundaries( + Container container, int min, int sup, boolean intersects) { assertEquals(intersects, container.intersects(min, sup)); } @Test public void testIntersectsWithRangeHitScan() { - Container container = new BitmapContainer().add(0, 10) - .add(500, 512).add(lower16Bits(-50), lower16Bits(-10)); + Container container = + new BitmapContainer().add(0, 10).add(500, 512).add(lower16Bits(-50), lower16Bits(-10)); assertTrue(container.intersects(0, 1)); assertTrue(container.intersects(0, 101)); assertTrue(container.intersects(0, 1 << 16)); @@ -920,7 +925,6 @@ public void testIntersectsWithRangeHitScan() { assertTrue(container.intersects(501, 511)); } - @Test public void testIntersectsWithRangeUnsigned() { Container container = new BitmapContainer().add(lower16Bits(-50), lower16Bits(-10)); @@ -928,7 +932,7 @@ public void testIntersectsWithRangeUnsigned() { assertTrue(container.intersects(0, lower16Bits(-40))); assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); assertFalse(container.intersects(lower16Bits(-9), lower16Bits(-1))); - //assertTrue(container.intersects(11, (char)-1)); // forbidden + // assertTrue(container.intersects(11, (char)-1)); // forbidden } @Test @@ -940,7 +944,6 @@ public void testIntersectsAtEndWord() { assertFalse(container.intersects(lower16Bits(-10), lower16Bits(-1))); } - @Test public void testIntersectsAtEndWord2() { Container container = new BitmapContainer().add(lower16Bits(500), lower16Bits(-500)); @@ -978,7 +981,6 @@ public void testContainsRangeMultiWord() { assertFalse(container.contains(64 * 10, 2 + 64 * 13)); } - @Test public void testContainsRangeSubWord() { long[] bitmap = evenBits(); @@ -1020,267 +1022,278 @@ public void testNextSetBitBeforeStart() { @Test public void testNextValue() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(10, container.nextValue((char)10)); - assertEquals(20, container.nextValue((char)11)); - assertEquals(30, container.nextValue((char)30)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(10, container.nextValue((char) 10)); + assertEquals(20, container.nextValue((char) 11)); + assertEquals(30, container.nextValue((char) 30)); } @Test public void testNextValueAfterEnd() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(-1, container.nextValue((char)31)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(-1, container.nextValue((char) 31)); } @Test public void testNextValue2() { BitmapContainer container = new BitmapContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(-1, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)5000)); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(-1, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 5000)); } @Test public void testNextValueBetweenRuns() { - BitmapContainer container = new BitmapContainer().iadd(64, 129).iadd(256, 321).toBitmapContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(256, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)512)); + BitmapContainer container = + new BitmapContainer().iadd(64, 129).iadd(256, 321).toBitmapContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(256, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 512)); } @Test public void testNextValue3() { - BitmapContainer container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)63)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(200, container.nextValue((char)129)); - assertEquals(200, container.nextValue((char)199)); - assertEquals(200, container.nextValue((char)200)); - assertEquals(250, container.nextValue((char)250)); - assertEquals(5000, container.nextValue((char)2500)); - assertEquals(5000, container.nextValue((char)5000)); - assertEquals(5200, container.nextValue((char)5200)); - assertEquals(-1, container.nextValue((char)5201)); + BitmapContainer container = + new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 63)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(200, container.nextValue((char) 129)); + assertEquals(200, container.nextValue((char) 199)); + assertEquals(200, container.nextValue((char) 200)); + assertEquals(250, container.nextValue((char) 250)); + assertEquals(5000, container.nextValue((char) 2500)); + assertEquals(5000, container.nextValue((char) 5000)); + assertEquals(5200, container.nextValue((char) 5200)); + assertEquals(-1, container.nextValue((char) 5201)); } @Test public void testNextValueUnsigned() { - BitmapContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}).toBitmapContainer(); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 7))); - assertEquals(-1, container.nextValue((char)((1 << 15) | 8))); + BitmapContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}) + .toBitmapContainer(); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 7))); + assertEquals(-1, container.nextValue((char) ((1 << 15) | 8))); } @Test public void testPreviousValue1() { BitmapContainer container = new ArrayContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); } @Test public void testPreviousValue2() { - BitmapContainer container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - assertEquals(128, container.previousValue((char)199)); - assertEquals(200, container.previousValue((char)200)); - assertEquals(250, container.previousValue((char)250)); - assertEquals(500, container.previousValue((char)2500)); - assertEquals(5000, container.previousValue((char)5000)); - assertEquals(5200, container.previousValue((char)5200)); + BitmapContainer container = + new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + assertEquals(128, container.previousValue((char) 199)); + assertEquals(200, container.previousValue((char) 200)); + assertEquals(250, container.previousValue((char) 250)); + assertEquals(500, container.previousValue((char) 2500)); + assertEquals(5000, container.previousValue((char) 5000)); + assertEquals(5200, container.previousValue((char) 5200)); } @Test public void testPreviousValueBeforeStart() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)5)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 5)); } @Test public void testPreviousValueSparse() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)9)); - assertEquals(10, container.previousValue((char)10)); - assertEquals(10, container.previousValue((char)11)); - assertEquals(20, container.previousValue((char)21)); - assertEquals(30, container.previousValue((char)30)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 9)); + assertEquals(10, container.previousValue((char) 10)); + assertEquals(10, container.previousValue((char) 11)); + assertEquals(20, container.previousValue((char) 21)); + assertEquals(30, container.previousValue((char) 30)); } @Test public void testPreviousValueAfterEnd() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(30, container.previousValue((char)31)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(30, container.previousValue((char) 31)); } @Test public void testPreviousEvenBits() { BitmapContainer container = new BitmapContainer(evenBits(), 1 << 15); - assertEquals(0, container.previousValue((char)0)); - assertEquals(0, container.previousValue((char)1)); - assertEquals(2, container.previousValue((char)2)); - assertEquals(2, container.previousValue((char)3)); + assertEquals(0, container.previousValue((char) 0)); + assertEquals(0, container.previousValue((char) 1)); + assertEquals(2, container.previousValue((char) 2)); + assertEquals(2, container.previousValue((char) 3)); } @Test public void testPreviousValueUnsigned() { - BitmapContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 8))); + BitmapContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}) + .toBitmapContainer(); + assertEquals(-1, container.previousValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 8))); } - @Test public void testPreviousAbsentValue1() { BitmapContainer container = new ArrayContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); } @Test public void testPreviousAbsentValue2() { - BitmapContainer container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - assertEquals(199, container.previousAbsentValue((char)199)); - assertEquals(199, container.previousAbsentValue((char)200)); - assertEquals(199, container.previousAbsentValue((char)250)); - assertEquals(2500, container.previousAbsentValue((char)2500)); - assertEquals(4999, container.previousAbsentValue((char)5000)); - assertEquals(4999, container.previousAbsentValue((char)5200)); + BitmapContainer container = + new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + assertEquals(199, container.previousAbsentValue((char) 199)); + assertEquals(199, container.previousAbsentValue((char) 200)); + assertEquals(199, container.previousAbsentValue((char) 250)); + assertEquals(2500, container.previousAbsentValue((char) 2500)); + assertEquals(4999, container.previousAbsentValue((char) 5000)); + assertEquals(4999, container.previousAbsentValue((char) 5200)); } @Test public void testPreviousAbsentValueEmpty() { BitmapContainer container = new ArrayContainer().toBitmapContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.previousAbsentValue((char)i)); + assertEquals(i, container.previousAbsentValue((char) i)); } } @Test public void testPreviousAbsentValueSparse() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(9, container.previousAbsentValue((char)9)); - assertEquals(9, container.previousAbsentValue((char)10)); - assertEquals(11, container.previousAbsentValue((char)11)); - assertEquals(21, container.previousAbsentValue((char)21)); - assertEquals(29, container.previousAbsentValue((char)30)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(9, container.previousAbsentValue((char) 9)); + assertEquals(9, container.previousAbsentValue((char) 10)); + assertEquals(11, container.previousAbsentValue((char) 11)); + assertEquals(21, container.previousAbsentValue((char) 21)); + assertEquals(29, container.previousAbsentValue((char) 30)); } @Test public void testPreviousAbsentEvenBits() { BitmapContainer container = new BitmapContainer(evenBits(), 1 << 15); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i - 1, container.previousAbsentValue((char)i)); - assertEquals(i + 1, container.previousAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i - 1, container.previousAbsentValue((char) i)); + assertEquals(i + 1, container.previousAbsentValue((char) (i + 1))); } } @Test public void testPreviousAbsentValueUnsigned() { - BitmapContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}).toBitmapContainer(); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.previousAbsentValue((char)((1 << 15) | 8))); + BitmapContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}) + .toBitmapContainer(); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.previousAbsentValue((char) ((1 << 15) | 8))); } - @Test public void testNextAbsentValue1() { BitmapContainer container = new ArrayContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); } @Test public void testNextAbsentValue2() { - BitmapContainer container = new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - assertEquals(199, container.nextAbsentValue((char)199)); - assertEquals(501, container.nextAbsentValue((char)200)); - assertEquals(501, container.nextAbsentValue((char)250)); - assertEquals(2500, container.nextAbsentValue((char)2500)); - assertEquals(5201, container.nextAbsentValue((char)5000)); - assertEquals(5201, container.nextAbsentValue((char)5200)); + BitmapContainer container = + new ArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + assertEquals(199, container.nextAbsentValue((char) 199)); + assertEquals(501, container.nextAbsentValue((char) 200)); + assertEquals(501, container.nextAbsentValue((char) 250)); + assertEquals(2500, container.nextAbsentValue((char) 2500)); + assertEquals(5201, container.nextAbsentValue((char) 5000)); + assertEquals(5201, container.nextAbsentValue((char) 5200)); } @Test public void testNextAbsentValueEmpty() { BitmapContainer container = new ArrayContainer().toBitmapContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.nextAbsentValue((char)i)); + assertEquals(i, container.nextAbsentValue((char) i)); } } @Test public void testNextAbsentValueSparse() { - BitmapContainer container = new ArrayContainer(new char[] { 10, 20, 30}).toBitmapContainer(); - assertEquals(9, container.nextAbsentValue((char)9)); - assertEquals(11, container.nextAbsentValue((char)10)); - assertEquals(11, container.nextAbsentValue((char)11)); - assertEquals(21, container.nextAbsentValue((char)21)); - assertEquals(31, container.nextAbsentValue((char)30)); + BitmapContainer container = new ArrayContainer(new char[] {10, 20, 30}).toBitmapContainer(); + assertEquals(9, container.nextAbsentValue((char) 9)); + assertEquals(11, container.nextAbsentValue((char) 10)); + assertEquals(11, container.nextAbsentValue((char) 11)); + assertEquals(21, container.nextAbsentValue((char) 21)); + assertEquals(31, container.nextAbsentValue((char) 30)); } @Test public void testNextAbsentEvenBits() { BitmapContainer container = new BitmapContainer(evenBits(), 1 << 15); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i + 1, container.nextAbsentValue((char)i)); - assertEquals(i + 1, container.nextAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i + 1, container.nextAbsentValue((char) i)); + assertEquals(i + 1, container.nextAbsentValue((char) (i + 1))); } } @Test public void testNextAbsentValueUnsigned() { - BitmapContainer container = new ArrayContainer(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}).toBitmapContainer(); - assertEquals(((1 << 15) | 4), container.nextAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 8))); + BitmapContainer container = + new ArrayContainer(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}) + .toBitmapContainer(); + assertEquals(((1 << 15) | 4), container.nextAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 8))); } @Test @@ -1288,43 +1301,52 @@ public void testRangeConsumer() { char[] entries = new char[] {3, 4, 7, 8, 10, 65530, 65534, 65535}; BitmapContainer container = new ArrayContainer(entries).toBitmapContainer(); - ValidationRangeConsumer consumer = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - ABSENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, PRESENT - }); + ValidationRangeConsumer consumer = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + ABSENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, + PRESENT + }); container.forAllUntil(0, (char) 11, consumer); assertEquals(11, consumer.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - PRESENT, ABSENT, ABSENT, PRESENT, PRESENT - }); + ValidationRangeConsumer consumer2 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] {PRESENT, ABSENT, ABSENT, PRESENT, PRESENT}); container.forAllInRange((char) 4, (char) 9, consumer2); assertEquals(5, consumer2.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - PRESENT, ABSENT, ABSENT, ABSENT, PRESENT, PRESENT - }); + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + PRESENT, ABSENT, ABSENT, ABSENT, PRESENT, PRESENT + }); container.forAllFrom((char) 65530, consumer3); assertEquals(6, consumer3.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer4 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer4 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); container.forAll(0, consumer4); consumer4.assertAllAbsentExcept(entries, 0); - ValidationRangeConsumer consumer5 = ValidationRangeConsumer.ofSize(2 * BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer5 = + ValidationRangeConsumer.ofSize(2 * BitmapContainer.MAX_CAPACITY); consumer5.acceptAllAbsent(0, BitmapContainer.MAX_CAPACITY); container.forAll(BitmapContainer.MAX_CAPACITY, consumer5); consumer5.assertAllAbsentExcept(entries, BitmapContainer.MAX_CAPACITY); // Completely Empty container = new BitmapContainer(); - ValidationRangeConsumer consumer6 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer6 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); container.forAll(0, consumer6); consumer6.assertAllAbsent(); // Completely Full container = new BitmapContainer(); container.iadd(0, BitmapContainer.MAX_CAPACITY); - ValidationRangeConsumer consumer7 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer7 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); container.forAll(0, consumer7); consumer7.assertAllPresent(); @@ -1350,6 +1372,6 @@ private static long[] evenBits() { } private static int lower16Bits(int x) { - return (char)x; + return (char) x; } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestConcatenation.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestConcatenation.java index 8cba22bde..fbd6d5ede 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestConcatenation.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestConcatenation.java @@ -1,5 +1,11 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + +import org.roaringbitmap.buffer.MutableRoaringBitmap; + import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.google.common.io.Files; @@ -10,7 +16,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.buffer.MutableRoaringBitmap; import java.io.File; import java.io.IOException; @@ -18,10 +23,6 @@ import java.util.Arrays; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class TestConcatenation { @@ -29,37 +30,38 @@ public class TestConcatenation { @BeforeAll public static void setup() { - DATA = new Arguments[]{ - // the data set reported in issue #260 - Arguments.of(read("src/test/resources/testdata/testIssue260.txt"), 5950), - Arguments.of(read("src/test/resources/testdata/offset_failure_case_1.txt"), 20), - Arguments.of(read("src/test/resources/testdata/offset_failure_case_2.txt"), 20), - Arguments.of(read("src/test/resources/testdata/offset_failure_case_3.txt"), 20), - // a range of test cases with offsets being divisors of 65536 - Arguments.of(testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build(), 1 << 16), - Arguments.of(testCase().withRunAt(0).withBitmapAt(1).withBitmapAt(2).build(), 1 << 16), - Arguments.of(testCase().withBitmapAt(0).withBitmapAt(1).withRunAt(2).build(), 1 << 16), - Arguments.of(testCase().withBitmapAt(0).withRunAt(2).withArrayAt(4).build(), 1 << 16), - Arguments.of(testCase().withRunAt(0).withBitmapAt(2).withBitmapAt(4).build(), 1 << 16), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).build(), 1 << 16), - // awkward offsets - Arguments.of(testCase().withBitmapAt(0).build(), 20), - Arguments.of(testCase().withRunAt(0).build(), 20), - Arguments.of(testCase().withArrayAt(0).build(), 20), - Arguments.of(testCase().withBitmapAt(0).withRunAt(1).build(), 20), - Arguments.of(testCase().withRunAt(0).withBitmapAt(1).build(), 20), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(1).build(), 20), - Arguments.of(testCase().withBitmapAt(0).withRunAt(2).build(), 20), - Arguments.of(testCase().withRunAt(0).withBitmapAt(2).build(), 20), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(2).build(), 20), - Arguments.of(testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build(), 20), - Arguments.of(testCase().withRunAt(0).withBitmapAt(1).withBitmapAt(2).build(), 20), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(1).withRunAt(2).build(), 20), - Arguments.of(testCase().withBitmapAt(0).withRunAt(2).withArrayAt(4).build(), 20), - Arguments.of(testCase().withRunAt(0).withBitmapAt(2).withBitmapAt(4).build(), 20), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).build(), 20), - Arguments.of(testCase().withRange(0, 1 << 16).build(), 20) - }; + DATA = + new Arguments[] { + // the data set reported in issue #260 + Arguments.of(read("src/test/resources/testdata/testIssue260.txt"), 5950), + Arguments.of(read("src/test/resources/testdata/offset_failure_case_1.txt"), 20), + Arguments.of(read("src/test/resources/testdata/offset_failure_case_2.txt"), 20), + Arguments.of(read("src/test/resources/testdata/offset_failure_case_3.txt"), 20), + // a range of test cases with offsets being divisors of 65536 + Arguments.of(testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build(), 1 << 16), + Arguments.of(testCase().withRunAt(0).withBitmapAt(1).withBitmapAt(2).build(), 1 << 16), + Arguments.of(testCase().withBitmapAt(0).withBitmapAt(1).withRunAt(2).build(), 1 << 16), + Arguments.of(testCase().withBitmapAt(0).withRunAt(2).withArrayAt(4).build(), 1 << 16), + Arguments.of(testCase().withRunAt(0).withBitmapAt(2).withBitmapAt(4).build(), 1 << 16), + Arguments.of(testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).build(), 1 << 16), + // awkward offsets + Arguments.of(testCase().withBitmapAt(0).build(), 20), + Arguments.of(testCase().withRunAt(0).build(), 20), + Arguments.of(testCase().withArrayAt(0).build(), 20), + Arguments.of(testCase().withBitmapAt(0).withRunAt(1).build(), 20), + Arguments.of(testCase().withRunAt(0).withBitmapAt(1).build(), 20), + Arguments.of(testCase().withArrayAt(0).withBitmapAt(1).build(), 20), + Arguments.of(testCase().withBitmapAt(0).withRunAt(2).build(), 20), + Arguments.of(testCase().withRunAt(0).withBitmapAt(2).build(), 20), + Arguments.of(testCase().withArrayAt(0).withBitmapAt(2).build(), 20), + Arguments.of(testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build(), 20), + Arguments.of(testCase().withRunAt(0).withBitmapAt(1).withBitmapAt(2).build(), 20), + Arguments.of(testCase().withArrayAt(0).withBitmapAt(1).withRunAt(2).build(), 20), + Arguments.of(testCase().withBitmapAt(0).withRunAt(2).withArrayAt(4).build(), 20), + Arguments.of(testCase().withRunAt(0).withBitmapAt(2).withBitmapAt(4).build(), 20), + Arguments.of(testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).build(), 20), + Arguments.of(testCase().withRange(0, 1 << 16).build(), 20) + }; } @AfterAll @@ -67,7 +69,6 @@ public static void clear() { DATA = null; } - public static Stream params() { return Stream.of(DATA); } @@ -90,7 +91,8 @@ public void testElementwiseOffsetAppliedCorrectlyBuffer(RoaringBitmap bitmap, in for (int i = 0; i < array1.length; ++i) { array1[i] += offset; } - MutableRoaringBitmap shifted = MutableRoaringBitmap.addOffset(bitmap.toMutableRoaringBitmap(), offset); + MutableRoaringBitmap shifted = + MutableRoaringBitmap.addOffset(bitmap.toMutableRoaringBitmap(), offset); assertArrayEquals(array1, shifted.toArray(), failureMessage(bitmap)); } @@ -104,7 +106,8 @@ public void testCardinalityPreserved(RoaringBitmap bitmap, int offset) { @ParameterizedTest(name = "{1}") @MethodSource("params") public void testCardinalityPreservedBuffer(RoaringBitmap bitmap, int offset) { - MutableRoaringBitmap shifted = MutableRoaringBitmap.addOffset(bitmap.toMutableRoaringBitmap(), offset); + MutableRoaringBitmap shifted = + MutableRoaringBitmap.addOffset(bitmap.toMutableRoaringBitmap(), offset); assertEquals(bitmap.getCardinality(), shifted.getCardinality(), failureMessage(bitmap)); } @@ -121,8 +124,10 @@ public void canSerializeAndDeserialize(RoaringBitmap bitmap, int offset) throws @ParameterizedTest(name = "{1}") @MethodSource("params") - public void canSerializeAndDeserializeBuffer(RoaringBitmap bitmap, int offset) throws IOException { - MutableRoaringBitmap shifted = MutableRoaringBitmap.addOffset(bitmap.toMutableRoaringBitmap(), offset); + public void canSerializeAndDeserializeBuffer(RoaringBitmap bitmap, int offset) + throws IOException { + MutableRoaringBitmap shifted = + MutableRoaringBitmap.addOffset(bitmap.toMutableRoaringBitmap(), offset); ByteArrayDataOutput out = ByteStreams.newDataOutput(); shifted.serialize(out); MutableRoaringBitmap deserialized = new MutableRoaringBitmap(); @@ -132,10 +137,12 @@ public void canSerializeAndDeserializeBuffer(RoaringBitmap bitmap, int offset) t private static RoaringBitmap read(String classPathResource) { try { - RoaringBitmapWriter writer = RoaringBitmapWriter.writer().constantMemory().get(); - Arrays.stream(Files.readFirstLine(new File(classPathResource), StandardCharsets.UTF_8).split(",")) - .mapToInt(Integer::parseInt) - .forEach(writer::add); + RoaringBitmapWriter writer = + RoaringBitmapWriter.writer().constantMemory().get(); + Arrays.stream( + Files.readFirstLine(new File(classPathResource), StandardCharsets.UTF_8).split(",")) + .mapToInt(Integer::parseInt) + .forEach(writer::add); writer.flush(); return writer.getUnderlying(); } catch (IOException e) { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestContainer.java index d747f0897..9332513bb 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestContainer.java @@ -3,23 +3,30 @@ */ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; +import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import org.junit.jupiter.api.Test; - -import java.util.*; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; -import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; -import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.stream.IntStream; +import java.util.stream.Stream; /** * Various tests on Container and its subclasses, ArrayContainer and BitmapContainer @@ -27,7 +34,7 @@ @SuppressWarnings({"static-method"}) public class TestContainer { - private final static Class[] CONTAINER_TYPES = + private static final Class[] CONTAINER_TYPES = new Class[] {ArrayContainer.class, BitmapContainer.class, RunContainer.class}; @Test @@ -254,10 +261,25 @@ public void inotTest10() { final Container c1 = c.inot(65190, 65201); assertTrue(c1 instanceof ArrayContainer); assertEquals(14, c1.getCardinality()); - assertTrue(checkContent(c1, - new char[] {0, 2, 4, (char) 65190, (char) 65191, (char) 65192, (char) 65193, - (char) 65194, (char) 65195, (char) 65196, (char) 65197, (char) 65198, - (char) 65199, (char) 65200})); + assertTrue( + checkContent( + c1, + new char[] { + 0, + 2, + 4, + (char) 65190, + (char) 65191, + (char) 65192, + (char) 65193, + (char) 65194, + (char) 65195, + (char) 65196, + (char) 65197, + (char) 65198, + (char) 65199, + (char) 65200 + })); } @Test @@ -320,7 +342,6 @@ public void inotTest5() { c = c.inot(4, 1000); // back, as a bitmap assertTrue(c instanceof BitmapContainer); assertTrue(checkContent(c, content)); - } @Test @@ -628,8 +649,6 @@ public void notTest9() { assertTrue(checkContent(c2, content)); } - - @Test public void numberOfRuns() { char[] positions = {3, 4, 5, 10, 11, 13, 15, 62, 63, 64, 65}; @@ -645,8 +664,6 @@ public void numberOfRuns() { assertEquals(rc.numberOfRuns(), bc.numberOfRuns()); } - - @Test public void numberOfRuns1() { System.out.println("numberOfRuns1"); @@ -673,8 +690,8 @@ public void numberOfRuns1() { assertEquals(rc.numberOfRuns(), ac.numberOfRuns()); assertEquals(rc.numberOfRuns(), bc.numberOfRuns()); // a limit of 50k assures that the no early bail-out can be taken - assertEquals(bc.numberOfRuns(), - bc.numberOfRunsLowerBound(50000) + bc.numberOfRunsAdjustment()); + assertEquals( + bc.numberOfRuns(), bc.numberOfRunsLowerBound(50000) + bc.numberOfRunsAdjustment()); // inferior approaches to be removed in a future cleanup, now commented... // assertEquals(bc.numberOfRunsLowerBound(), bc.numberOfRunsLowerBoundUnrolled()); // assertEquals(bc.numberOfRunsLowerBound(), bc.numberOfRunsLowerBoundUnrolled2()); @@ -682,8 +699,6 @@ public void numberOfRuns1() { } } - - @Test public void or1() { System.out.println("or1"); @@ -699,7 +714,6 @@ public void or1() { assertTrue(checkContent(result, new char[] {1, 3, 5, (char) 50000, (char) 50001})); } - @Test public void or2() { System.out.println("or2"); @@ -716,8 +730,9 @@ public void or2() { ac1.add((char) 50004); Container result = ac.or(ac1.getCharIterator()); - assertTrue(checkContent(result, - new char[] {1, 4, 5, (char) 50000, (char) 50002, (char) 50003, (char) 50004})); + assertTrue( + checkContent( + result, new char[] {1, 4, 5, (char) 50000, (char) 50002, (char) 50003, (char) 50004})); } @Test @@ -742,12 +757,14 @@ public void or3() { ac1.add((char) 50004); Container result = ac.or(ac1.getCharIterator()); - assertTrue(checkContent(result, new char[] {1, 3, 4, 5, (char) 50000, (char) 50001, - (char) 50002, (char) 50003, (char) 50004})); + assertTrue( + checkContent( + result, + new char[] { + 1, 3, 4, 5, (char) 50000, (char) 50001, (char) 50002, (char) 50003, (char) 50004 + })); } - - @Test public void or4() { System.out.println("or4"); @@ -770,14 +787,24 @@ public void or4() { ac1.add((char) 50003); ac1.add((char) 50004); - Container result = ac.or(ac1.getCharIterator()); - assertTrue(checkContent(result, new char[] {1, 3, 4, 5, (char) 50000, (char) 50001, - (char) 50002, (char) 50003, (char) 50004, (char) 50011})); + assertTrue( + checkContent( + result, + new char[] { + 1, + 3, + 4, + 5, + (char) 50000, + (char) 50001, + (char) 50002, + (char) 50003, + (char) 50004, + (char) 50011 + })); } - - @Test public void or5() { System.out.println("or5"); @@ -806,13 +833,13 @@ public void or6() { System.out.println("or6"); RunContainer rc1 = new RunContainer(); for (int i = 0; i < 6144; i += 6) { - rc1.iadd(i, i+1); + rc1.iadd(i, i + 1); } RunContainer rc2 = new RunContainer(); for (int i = 3; i < 6144; i += 6) { - rc2.iadd(i, i+1); + rc2.iadd(i, i + 1); } Container result = rc1.or(rc2); @@ -823,28 +850,32 @@ public void or6() { @Test public void testXorContainer() throws Exception { Container rc1 = new RunContainer(new char[] {10, 12, 90, 10}, 2); - Container rc2 = new RunContainer(new char[]{1, 10, 40, 400, 900, 10}, 3); + Container rc2 = new RunContainer(new char[] {1, 10, 40, 400, 900, 10}, 3); Container bc1 = new BitmapContainer().add(10, 20); Container bc2 = new BitmapContainer().add(21, 30); Container ac1 = new ArrayContainer(4, new char[] {10, 12, 90, 104}); - Container ac2 = new ArrayContainer(2, new char[]{1, 10, 40, 400, 900, 1910}); - for(Set test : Sets.powerSet(ImmutableSet.of(rc1, rc2, bc1, bc2, ac1, ac2))) { + Container ac2 = new ArrayContainer(2, new char[] {1, 10, 40, 400, 900, 1910}); + for (Set test : Sets.powerSet(ImmutableSet.of(rc1, rc2, bc1, bc2, ac1, ac2))) { Iterator it = test.iterator(); - if(test.size() == 1) { // compare with self + if (test.size() == 1) { // compare with self Container x = it.next(); - assertEquals(x.xor(x).getCardinality(), x.xorCardinality(x), x.getContainerName() + ": " + x); - } else if(test.size() == 2) { + assertEquals( + x.xor(x).getCardinality(), x.xorCardinality(x), x.getContainerName() + ": " + x); + } else if (test.size() == 2) { Container x = it.next(); Container y = it.next(); assertEquals( - x.xor(y).getCardinality(), x.xorCardinality(y), x.getContainerName() + " " + x + " " + y.getContainerName() + " " + y); - assertEquals(y.xor(x).getCardinality(), y.xorCardinality(x), y.getContainerName() + " " + y + " " + x.getContainerName() + " " + x); + x.xor(y).getCardinality(), + x.xorCardinality(y), + x.getContainerName() + " " + x + " " + y.getContainerName() + " " + y); + assertEquals( + y.xor(x).getCardinality(), + y.xorCardinality(x), + y.getContainerName() + " " + y + " " + x.getContainerName() + " " + x); } } } - - @Test public void rangeOfOnesTest1() { final Container c = Container.rangeOfOnes(4, 11); // sparse @@ -853,8 +884,6 @@ public void rangeOfOnesTest1() { assertTrue(checkContent(c, new char[] {4, 5, 6, 7, 8, 9, 10})); } - - @Test public void rangeOfOnesTest2() { final Container c = Container.rangeOfOnes(1000, 35001); // dense @@ -862,7 +891,6 @@ public void rangeOfOnesTest2() { assertEquals(35000 - 1000 + 1, c.getCardinality()); } - @Test public void rangeOfOnesTest2A() { final Container c = Container.rangeOfOnes(1000, 35001); // dense @@ -873,7 +901,6 @@ public void rangeOfOnesTest2A() { assertTrue(checkContent(c, s)); } - @Test public void rangeOfOnesTest3() { // bdry cases @@ -885,8 +912,6 @@ public void rangeOfOnesTest4() { Container.rangeOfOnes(1, ArrayContainer.DEFAULT_MAX_SIZE + 2); } - - @Test public void testRunOptimize1() { ArrayContainer ac = new ArrayContainer(); @@ -898,8 +923,6 @@ public void testRunOptimize1() { assertEquals(ac, c); } - - public void testRunOptimize1A() { ArrayContainer ac = new ArrayContainer(); for (char s : new char[] {1, 2, 3, 4, 6, 8, 9, (char) 50000, (char) 50003}) { @@ -910,7 +933,6 @@ public void testRunOptimize1A() { assertSame(ac, c); } - @Test public void testRunOptimize2() { BitmapContainer bc = new BitmapContainer(); @@ -922,8 +944,6 @@ public void testRunOptimize2() { assertEquals(bc, c); } - - @Test public void testRunOptimize2A() { BitmapContainer bc = new BitmapContainer(); @@ -938,7 +958,7 @@ public void testRunOptimize2A() { @Test public void testRunOptimize3() { RunContainer rc = new RunContainer(); - for (char s : new char[] {1, 2,3, 4, 5, 6, 7, 8, 9, (char) 50000, (char) 50001}) { + for (char s : new char[] {1, 2, 3, 4, 5, 6, 7, 8, 9, (char) 50000, (char) 50001}) { rc.add(s); } Container c = rc.runOptimize(); @@ -957,7 +977,6 @@ public void testRunOptimize3A() { assertEquals(c, rc); } - @Test public void testRunOptimize3B() { RunContainer rc = new RunContainer(); @@ -1021,12 +1040,11 @@ public void xor2() { ac1.add((char) 50004); Container result = ac.xor(ac1.getCharIterator()); - assertTrue(checkContent(result, - new char[] {1, 4, 5, (char) 50000, (char) 50002, (char) 50003, (char) 50004})); + assertTrue( + checkContent( + result, new char[] {1, 4, 5, (char) 50000, (char) 50002, (char) 50003, (char) 50004})); } - - @Test public void xor3() { System.out.println("xor3"); @@ -1049,8 +1067,9 @@ public void xor3() { ac1.add((char) 50004); Container result = ac.xor(ac1.getCharIterator()); - assertTrue(checkContent(result, - new char[] {3, 4, (char) 50001, (char) 50002, (char) 50003, (char) 50004})); + assertTrue( + checkContent( + result, new char[] {3, 4, (char) 50001, (char) 50002, (char) 50003, (char) 50004})); } @Test @@ -1058,7 +1077,7 @@ public void testConsistentToString() { ArrayContainer ac = new ArrayContainer(); BitmapContainer bc = new BitmapContainer(); RunContainer rc = new RunContainer(); - for (char i : new char[]{0, 2, 17, Short.MAX_VALUE, (char)-3, (char)-1}) { + for (char i : new char[] {0, 2, 17, Short.MAX_VALUE, (char) -3, (char) -1}) { ac.add(i); bc.add(i); rc.add(i); @@ -1067,10 +1086,8 @@ public void testConsistentToString() { assertEquals(expected, ac.toString()); assertEquals(expected, bc.toString()); - String normalizedRCstr = rc.toString() - .replaceAll("\\d+\\]\\[", "") - .replace('[', '{') - .replaceFirst(",\\d+\\]", "}"); + String normalizedRCstr = + rc.toString().replaceAll("\\d+\\]\\[", "").replace('[', '{').replaceFirst(",\\d+\\]", "}"); assertEquals(expected, normalizedRCstr); } @@ -1096,14 +1113,15 @@ public void xor4() { ac1.add((char) 50003); ac1.add((char) 50004); - Container result = ac.xor(ac1.getCharIterator()); - assertTrue(checkContent(result, new char[] {3, 4, (char) 50001, (char) 50002, (char) 50003, - (char) 50004, (char) 50011})); + assertTrue( + checkContent( + result, + new char[] { + 3, 4, (char) 50001, (char) 50002, (char) 50003, (char) 50004, (char) 50011 + })); } - - @Test public void xor5() { System.out.println("xor5"); @@ -1139,7 +1157,8 @@ private Container getContainerInstance(Class ct) { private void testForAllMaterialization(char[] data) { for (Class ct1 : CONTAINER_TYPES) { Container container = getContainerInstance(ct1); - ValidationRangeConsumer.Value[] expected = new ValidationRangeConsumer.Value[Character.MAX_VALUE + 1]; + ValidationRangeConsumer.Value[] expected = + new ValidationRangeConsumer.Value[Character.MAX_VALUE + 1]; Arrays.fill(expected, ABSENT); for (char c : data) { container = container.add(c); @@ -1161,14 +1180,14 @@ private char[] allValues() { @Test public void forAll() { testForAllMaterialization(new char[0]); - testForAllMaterialization(new char[]{0}); - testForAllMaterialization(new char[]{1}); - testForAllMaterialization(new char[]{Character.MAX_VALUE}); - testForAllMaterialization(new char[]{0, 2, 5, 7}); - testForAllMaterialization(new char[]{49, 63, 65, 32768, 3280}); - testForAllMaterialization(new char[]{0, Character.MAX_VALUE}); - testForAllMaterialization(new char[]{Character.MAX_VALUE - 1, Character.MAX_VALUE}); - testForAllMaterialization(new char[]{Character.MAX_VALUE - 1}); + testForAllMaterialization(new char[] {0}); + testForAllMaterialization(new char[] {1}); + testForAllMaterialization(new char[] {Character.MAX_VALUE}); + testForAllMaterialization(new char[] {0, 2, 5, 7}); + testForAllMaterialization(new char[] {49, 63, 65, 32768, 3280}); + testForAllMaterialization(new char[] {0, Character.MAX_VALUE}); + testForAllMaterialization(new char[] {Character.MAX_VALUE - 1, Character.MAX_VALUE}); + testForAllMaterialization(new char[] {Character.MAX_VALUE - 1}); testForAllMaterialization(allValues()); } @@ -1176,7 +1195,8 @@ public void forAll() { private void testForAllFromMaterialization(char start, char[] data) { for (Class ct1 : CONTAINER_TYPES) { Container container = getContainerInstance(ct1); - ValidationRangeConsumer.Value[] expected = new ValidationRangeConsumer.Value[Character.MAX_VALUE + 1 - start]; + ValidationRangeConsumer.Value[] expected = + new ValidationRangeConsumer.Value[Character.MAX_VALUE + 1 - start]; Arrays.fill(expected, ABSENT); for (char c : data) { container = container.add(c); @@ -1196,13 +1216,14 @@ private void testForAllFromMaterialization(char start, char[] data) { @ValueSource(ints = {0, 1, 50, 63, 64, 65, 32768, 3280, 65534, 65535}) public void forAllFrom(int start) { testForAllFromMaterialization((char) start, new char[0]); - testForAllFromMaterialization((char) start, new char[]{0}); - testForAllFromMaterialization((char) start, new char[]{1}); - testForAllFromMaterialization((char) start, new char[]{0, 2, 5, 7}); - testForAllFromMaterialization((char) start, new char[]{49, 63, 65, 32768, 3280}); - testForAllFromMaterialization((char) start, new char[]{0, Character.MAX_VALUE}); - testForAllFromMaterialization((char) start, new char[]{Character.MAX_VALUE - 1, Character.MAX_VALUE}); - testForAllFromMaterialization((char) start, new char[]{Character.MAX_VALUE - 1}); + testForAllFromMaterialization((char) start, new char[] {0}); + testForAllFromMaterialization((char) start, new char[] {1}); + testForAllFromMaterialization((char) start, new char[] {0, 2, 5, 7}); + testForAllFromMaterialization((char) start, new char[] {49, 63, 65, 32768, 3280}); + testForAllFromMaterialization((char) start, new char[] {0, Character.MAX_VALUE}); + testForAllFromMaterialization( + (char) start, new char[] {Character.MAX_VALUE - 1, Character.MAX_VALUE}); + testForAllFromMaterialization((char) start, new char[] {Character.MAX_VALUE - 1}); testForAllFromMaterialization((char) start, allValues()); } @@ -1230,13 +1251,14 @@ private void testForAllUntilMaterialization(char end, char[] data) { @ValueSource(ints = {0, 1, 50, 63, 64, 65, 32768, 3280, 65534, 65535}) public void forAllUntil(int end) { testForAllUntilMaterialization((char) end, new char[0]); - testForAllUntilMaterialization((char) end, new char[]{0}); - testForAllUntilMaterialization((char) end, new char[]{1}); - testForAllUntilMaterialization((char) end, new char[]{0, 2, 5, 7}); - testForAllUntilMaterialization((char) end, new char[]{49, 63, 65, 32768, 3280}); - testForAllUntilMaterialization((char) end, new char[]{0, Character.MAX_VALUE}); - testForAllUntilMaterialization((char) end, new char[]{Character.MAX_VALUE - 1, Character.MAX_VALUE}); - testForAllUntilMaterialization((char) end, new char[]{Character.MAX_VALUE - 1}); + testForAllUntilMaterialization((char) end, new char[] {0}); + testForAllUntilMaterialization((char) end, new char[] {1}); + testForAllUntilMaterialization((char) end, new char[] {0, 2, 5, 7}); + testForAllUntilMaterialization((char) end, new char[] {49, 63, 65, 32768, 3280}); + testForAllUntilMaterialization((char) end, new char[] {0, Character.MAX_VALUE}); + testForAllUntilMaterialization( + (char) end, new char[] {Character.MAX_VALUE - 1, Character.MAX_VALUE}); + testForAllUntilMaterialization((char) end, new char[] {Character.MAX_VALUE - 1}); testForAllUntilMaterialization((char) end, allValues()); } @@ -1261,7 +1283,8 @@ private void testForAllInRangeMaterialization(char start, char end, char[] data) } else { final Container container = getContainerInstance(ct1); final ValidationRangeConsumer consumer = ValidationRangeConsumer.ofSize(0); - assertThrows(IllegalArgumentException.class, () -> container.forAllInRange(start, end, consumer)); + assertThrows( + IllegalArgumentException.class, () -> container.forAllInRange(start, end, consumer)); } } } @@ -1278,17 +1301,21 @@ private static Stream provideArgsForAllInRange() { } return cartesianProduct.stream(); } + @ParameterizedTest @MethodSource("provideArgsForAllInRange") public void forAllInRange(int start, int end) { testForAllInRangeMaterialization((char) start, (char) end, new char[0]); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{0}); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{1}); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{0, 2, 5, 7}); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{49, 63, 65, 32768, 3280}); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{0, Character.MAX_VALUE}); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{Character.MAX_VALUE - 1, Character.MAX_VALUE}); - testForAllInRangeMaterialization((char) start, (char) end, new char[]{Character.MAX_VALUE - 1}); + testForAllInRangeMaterialization((char) start, (char) end, new char[] {0}); + testForAllInRangeMaterialization((char) start, (char) end, new char[] {1}); + testForAllInRangeMaterialization((char) start, (char) end, new char[] {0, 2, 5, 7}); + testForAllInRangeMaterialization( + (char) start, (char) end, new char[] {49, 63, 65, 32768, 3280}); + testForAllInRangeMaterialization((char) start, (char) end, new char[] {0, Character.MAX_VALUE}); + testForAllInRangeMaterialization( + (char) start, (char) end, new char[] {Character.MAX_VALUE - 1, Character.MAX_VALUE}); + testForAllInRangeMaterialization( + (char) start, (char) end, new char[] {Character.MAX_VALUE - 1}); testForAllInRangeMaterialization((char) start, (char) end, allValues()); } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java index 466adcc4f..f48da513e 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestEmptyRoaringBatchIterator.java @@ -1,53 +1,54 @@ package org.roaringbitmap; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.roaringbitmap.buffer.ImmutableRoaringBitmap; import org.roaringbitmap.buffer.MutableRoaringBitmap; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class TestEmptyRoaringBatchIterator { - @Test - public void testEmptyMutableRoaringBitmap(){ - MutableRoaringBitmap mutableRoaringBitmap = new MutableRoaringBitmap(); - BatchIterator iterator = mutableRoaringBitmap.getBatchIterator(); - int[] ints = new int[1024]; - int cnt = iterator.nextBatch(ints); - assertEquals(0, cnt); - - mutableRoaringBitmap.add(1); - iterator = mutableRoaringBitmap.getBatchIterator(); - cnt = iterator.nextBatch(ints); - assertEquals(1, cnt); - } - - @Test - public void testEmptyImmutableRoaringBitmap(){ - MutableRoaringBitmap mutableRoaringBitmap = new MutableRoaringBitmap(); - ImmutableRoaringBitmap immutableRoaringBitmap = mutableRoaringBitmap.toImmutableRoaringBitmap(); - BatchIterator iterator = immutableRoaringBitmap.getBatchIterator(); - int[] ints = new int[1024]; - int cnt = iterator.nextBatch(ints); - assertEquals(0, cnt); - - mutableRoaringBitmap.add(1); - iterator = mutableRoaringBitmap.toImmutableRoaringBitmap().getBatchIterator(); - cnt = iterator.nextBatch(ints); - assertEquals(1, cnt); - } - - @Test - public void testEmptyRoaringBitmap(){ - RoaringBitmap roaringBitmap = new RoaringBitmap(); - BatchIterator iterator = roaringBitmap.getBatchIterator(); - int[] ints = new int[1024]; - int cnt = iterator.nextBatch(ints); - assertEquals(0, cnt); - - roaringBitmap.add(1); - iterator = roaringBitmap.getBatchIterator(); - cnt = iterator.nextBatch(ints); - assertEquals(1, cnt); - } + @Test + public void testEmptyMutableRoaringBitmap() { + MutableRoaringBitmap mutableRoaringBitmap = new MutableRoaringBitmap(); + BatchIterator iterator = mutableRoaringBitmap.getBatchIterator(); + int[] ints = new int[1024]; + int cnt = iterator.nextBatch(ints); + assertEquals(0, cnt); + + mutableRoaringBitmap.add(1); + iterator = mutableRoaringBitmap.getBatchIterator(); + cnt = iterator.nextBatch(ints); + assertEquals(1, cnt); + } + + @Test + public void testEmptyImmutableRoaringBitmap() { + MutableRoaringBitmap mutableRoaringBitmap = new MutableRoaringBitmap(); + ImmutableRoaringBitmap immutableRoaringBitmap = mutableRoaringBitmap.toImmutableRoaringBitmap(); + BatchIterator iterator = immutableRoaringBitmap.getBatchIterator(); + int[] ints = new int[1024]; + int cnt = iterator.nextBatch(ints); + assertEquals(0, cnt); + + mutableRoaringBitmap.add(1); + iterator = mutableRoaringBitmap.toImmutableRoaringBitmap().getBatchIterator(); + cnt = iterator.nextBatch(ints); + assertEquals(1, cnt); + } + + @Test + public void testEmptyRoaringBitmap() { + RoaringBitmap roaringBitmap = new RoaringBitmap(); + BatchIterator iterator = roaringBitmap.getBatchIterator(); + int[] ints = new int[1024]; + int cnt = iterator.nextBatch(ints); + assertEquals(0, cnt); + + roaringBitmap.add(1); + iterator = roaringBitmap.getBatchIterator(); + cnt = iterator.nextBatch(ints); + assertEquals(1, cnt); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java index 07d9b0671..64476ccf6 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestFastAggregation.java @@ -1,5 +1,10 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -11,273 +16,266 @@ import java.util.List; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - - @Execution(ExecutionMode.CONCURRENT) public class TestFastAggregation { - @Test - public void horizontal_or() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); - RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1<<16, 2<<16); - RoaringBitmap result = FastAggregation.horizontal_or(Arrays.asList(rb1, rb2, rb3)); - RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1<<16, 2<<16); - assertEquals(expected, result); - } + @Test + public void horizontal_or() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); + RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1 << 16, 2 << 16); + RoaringBitmap result = FastAggregation.horizontal_or(Arrays.asList(rb1, rb2, rb3)); + RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1 << 16, 2 << 16); + assertEquals(expected, result); + } - @Test - public void or() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); - RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1<<16, 2<<16); - RoaringBitmap result = FastAggregation.or(rb1, rb2, rb3); - RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1<<16, 2<<16); - assertEquals(expected, result); - } + @Test + public void or() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); + RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1 << 16, 2 << 16); + RoaringBitmap result = FastAggregation.or(rb1, rb2, rb3); + RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1 << 16, 2 << 16); + assertEquals(expected, result); + } - @Test - public void horizontal_or2() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); - RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1<<16, 2<<16); - RoaringBitmap result = FastAggregation.horizontal_or(rb1, rb2, rb3); - RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1<<16, 2<<16); - assertEquals(expected, result); - } + @Test + public void horizontal_or2() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); + RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1 << 16, 2 << 16); + RoaringBitmap result = FastAggregation.horizontal_or(rb1, rb2, rb3); + RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1 << 16, 2 << 16); + assertEquals(expected, result); + } - @Test - public void priorityqueue_or() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); - RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1<<16, 2<<16); - RoaringBitmap result = FastAggregation.priorityqueue_or(Arrays.asList(rb1, rb2, rb3).iterator()); - RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1<<16, 2<<16); - assertEquals(expected, result); - } + @Test + public void priorityqueue_or() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); + RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1 << 16, 2 << 16); + RoaringBitmap result = + FastAggregation.priorityqueue_or(Arrays.asList(rb1, rb2, rb3).iterator()); + RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1 << 16, 2 << 16); + assertEquals(expected, result); + } - @Test - public void priorityqueue_or2() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); - RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1<<16, 2<<16); - RoaringBitmap result = FastAggregation.priorityqueue_or(rb1, rb2, rb3); - RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1<<16, 2<<16); - assertEquals(expected, result); - } + @Test + public void priorityqueue_or2() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(0, 1, 2); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(0, 5, 6); + RoaringBitmap rb3 = RoaringBitmap.bitmapOf(1 << 16, 2 << 16); + RoaringBitmap result = FastAggregation.priorityqueue_or(rb1, rb2, rb3); + RoaringBitmap expected = RoaringBitmap.bitmapOf(0, 1, 2, 5, 6, 1 << 16, 2 << 16); + assertEquals(expected, result); + } - private static class ExtendedRoaringBitmap extends RoaringBitmap {} + private static class ExtendedRoaringBitmap extends RoaringBitmap {} + @Test + public void testWorkShyAnd() { + final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2, 0x10001, 0x20001, 0x30001); + final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3, 0x20002, 0x30001); + final RoaringBitmap bResult = FastAggregation.workShyAnd(new long[1024], b1, b2); + assertFalse(bResult.contains(1)); + assertTrue(bResult.contains(2)); + assertFalse(bResult.contains(3)); + } - @Test - public void testWorkShyAnd() { - final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2, 0x10001, 0x20001, 0x30001); - final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3, 0x20002, 0x30001); - final RoaringBitmap bResult = FastAggregation.workShyAnd(new long[1024], b1, b2); - assertFalse(bResult.contains(1)); - assertTrue(bResult.contains(2)); - assertFalse(bResult.contains(3)); - } + @Test + public void testAndWithIterator() { + final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); + final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); + final RoaringBitmap bResult = FastAggregation.and(Arrays.asList(b1, b2).iterator()); + assertFalse(bResult.contains(1)); + assertTrue(bResult.contains(2)); + assertFalse(bResult.contains(3)); - @Test - public void testAndWithIterator() { - final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); - final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); - final RoaringBitmap bResult = FastAggregation.and(Arrays.asList(b1, b2).iterator()); - assertFalse(bResult.contains(1)); - assertTrue(bResult.contains(2)); - assertFalse(bResult.contains(3)); + final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); + eb1.add(1); + eb1.add(2); + final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); + eb2.add(2); + eb2.add(3); + final RoaringBitmap ebResult = FastAggregation.and(Arrays.asList(b1, b2).iterator()); + assertFalse(ebResult.contains(1)); + assertTrue(ebResult.contains(2)); + assertFalse(ebResult.contains(3)); + } - final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); - eb1.add(1); - eb1.add(2); - final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); - eb2.add(2); - eb2.add(3); - final RoaringBitmap ebResult = FastAggregation.and(Arrays.asList(b1, b2).iterator()); - assertFalse(ebResult.contains(1)); - assertTrue(ebResult.contains(2)); - assertFalse(ebResult.contains(3)); - } + @Test + public void testNaiveAndWithIterator() { + final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); + final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); + final RoaringBitmap bResult = FastAggregation.naive_and(Arrays.asList(b1, b2).iterator()); + assertFalse(bResult.contains(1)); + assertTrue(bResult.contains(2)); + assertFalse(bResult.contains(3)); - @Test - public void testNaiveAndWithIterator() { - final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); - final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); - final RoaringBitmap bResult = FastAggregation.naive_and(Arrays.asList(b1, b2).iterator()); - assertFalse(bResult.contains(1)); - assertTrue(bResult.contains(2)); - assertFalse(bResult.contains(3)); + final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); + eb1.add(1); + eb1.add(2); + final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); + eb2.add(2); + eb2.add(3); + final RoaringBitmap ebResult = FastAggregation.naive_and(Arrays.asList(b1, b2).iterator()); + assertFalse(ebResult.contains(1)); + assertTrue(ebResult.contains(2)); + assertFalse(ebResult.contains(3)); + } - final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); - eb1.add(1); - eb1.add(2); - final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); - eb2.add(2); - eb2.add(3); - final RoaringBitmap ebResult = FastAggregation.naive_and(Arrays.asList(b1, b2).iterator()); - assertFalse(ebResult.contains(1)); - assertTrue(ebResult.contains(2)); - assertFalse(ebResult.contains(3)); - } + @Test + public void testOrWithIterator() { + final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); + final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); + final RoaringBitmap bItResult = FastAggregation.or(Arrays.asList(b1, b2).iterator()); + assertTrue(bItResult.contains(1)); + assertTrue(bItResult.contains(2)); + assertTrue(bItResult.contains(3)); - @Test - public void testOrWithIterator() { - final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); - final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); - final RoaringBitmap bItResult = FastAggregation.or(Arrays.asList(b1, b2).iterator()); - assertTrue(bItResult.contains(1)); - assertTrue(bItResult.contains(2)); - assertTrue(bItResult.contains(3)); + final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); + eb1.add(1); + eb1.add(2); + final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); + eb2.add(2); + eb2.add(3); + final RoaringBitmap ebItResult = FastAggregation.or(Arrays.asList(b1, b2).iterator()); + assertTrue(ebItResult.contains(1)); + assertTrue(ebItResult.contains(2)); + assertTrue(ebItResult.contains(3)); + } - final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); - eb1.add(1); - eb1.add(2); - final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); - eb2.add(2); - eb2.add(3); - final RoaringBitmap ebItResult = FastAggregation.or(Arrays.asList(b1, b2).iterator()); - assertTrue(ebItResult.contains(1)); - assertTrue(ebItResult.contains(2)); - assertTrue(ebItResult.contains(3)); - } + @Test + public void testNaiveOrWithIterator() { + final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); + final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); + final RoaringBitmap bResult = FastAggregation.naive_or(Arrays.asList(b1, b2).iterator()); + assertTrue(bResult.contains(1)); + assertTrue(bResult.contains(2)); + assertTrue(bResult.contains(3)); - @Test - public void testNaiveOrWithIterator() { - final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); - final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); - final RoaringBitmap bResult = FastAggregation.naive_or(Arrays.asList(b1, b2).iterator()); - assertTrue(bResult.contains(1)); - assertTrue(bResult.contains(2)); - assertTrue(bResult.contains(3)); - - final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); - eb1.add(1); - eb1.add(2); - final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); - eb2.add(2); - eb2.add(3); - final RoaringBitmap ebResult = FastAggregation.naive_or(Arrays.asList(b1, b2).iterator()); - assertTrue(ebResult.contains(1)); - assertTrue(ebResult.contains(2)); - assertTrue(ebResult.contains(3)); - } + final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); + eb1.add(1); + eb1.add(2); + final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); + eb2.add(2); + eb2.add(3); + final RoaringBitmap ebResult = FastAggregation.naive_or(Arrays.asList(b1, b2).iterator()); + assertTrue(ebResult.contains(1)); + assertTrue(ebResult.contains(2)); + assertTrue(ebResult.contains(3)); + } - @Test - public void testNaiveXorWithIterator() { - final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); - final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); - final RoaringBitmap bResult = FastAggregation.naive_xor(Arrays.asList(b1, b2).iterator()); - assertTrue(bResult.contains(1)); - assertFalse(bResult.contains(2)); - assertTrue(bResult.contains(3)); + @Test + public void testNaiveXorWithIterator() { + final RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2); + final RoaringBitmap b2 = RoaringBitmap.bitmapOf(2, 3); + final RoaringBitmap bResult = FastAggregation.naive_xor(Arrays.asList(b1, b2).iterator()); + assertTrue(bResult.contains(1)); + assertFalse(bResult.contains(2)); + assertTrue(bResult.contains(3)); - final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); - eb1.add(1); - eb1.add(2); - final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); - eb2.add(2); - eb2.add(3); - final RoaringBitmap ebResult = FastAggregation.naive_xor(Arrays.asList(b1, b2).iterator()); - assertTrue(ebResult.contains(1)); - assertFalse(ebResult.contains(2)); - assertTrue(ebResult.contains(3)); - } + final ExtendedRoaringBitmap eb1 = new ExtendedRoaringBitmap(); + eb1.add(1); + eb1.add(2); + final ExtendedRoaringBitmap eb2 = new ExtendedRoaringBitmap(); + eb2.add(2); + eb2.add(3); + final RoaringBitmap ebResult = FastAggregation.naive_xor(Arrays.asList(b1, b2).iterator()); + assertTrue(ebResult.contains(1)); + assertFalse(ebResult.contains(2)); + assertTrue(ebResult.contains(3)); + } - public static Stream bitmaps() { - return Stream.of( - Arguments.of(Arrays.asList( + public static Stream bitmaps() { + return Stream.of( + Arguments.of( + Arrays.asList( testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build(), testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build(), testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build(), - testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build(), testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build(), - testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build(), testCase().withBitmapAt(0).withArrayAt(3).withRunAt(4).build(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withArrayAt(0).withBitmapAt(1).withRunAt(2).build(), testCase().withRunAt(0).withArrayAt(1).withBitmapAt(2).build(), - testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build(), testCase().withBitmapAt(0).withArrayAt(2).withRunAt(4).build(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withArrayAt(0).withArrayAt(1).withArrayAt(2).build(), testCase().withBitmapAt(0).withBitmapAt(2).withBitmapAt(4).build(), - testCase().withRunAt(0).withRunAt(1).withRunAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withRunAt(0).withRunAt(1).withRunAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withArrayAt(0).withArrayAt(1).withArrayAt(2).build(), testCase().withBitmapAt(0).withBitmapAt(2).withArrayAt(4).build(), - testCase().withRunAt(0).withRunAt(1).withArrayAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withRunAt(0).withRunAt(1).withArrayAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withArrayAt(0).withArrayAt(1).withBitmapAt(2).build(), testCase().withBitmapAt(0).withBitmapAt(2).withBitmapAt(4).build(), - testCase().withRunAt(0).withRunAt(1).withBitmapAt(2).build() - )), - Arguments.of(Arrays.asList( + testCase().withRunAt(0).withRunAt(1).withBitmapAt(2).build())), + Arguments.of( + Arrays.asList( testCase().withArrayAt(20).build(), testCase().withBitmapAt(0).withBitmapAt(1).withBitmapAt(4).build(), - testCase().withRunAt(0).withRunAt(1).withBitmapAt(3).build() - )) - ); - } + testCase().withRunAt(0).withRunAt(1).withBitmapAt(3).build()))); + } + @MethodSource("bitmaps") + @ParameterizedTest(name = "testWorkShyAnd") + public void testWorkShyAnd(List list) { + RoaringBitmap[] bitmaps = list.toArray(new RoaringBitmap[0]); + long[] buffer = new long[1024]; + RoaringBitmap result = FastAggregation.and(buffer, bitmaps); + RoaringBitmap expected = FastAggregation.naive_and(bitmaps); + assertEquals(expected, result); + result = FastAggregation.and(bitmaps); + assertEquals(expected, result); + result = FastAggregation.workAndMemoryShyAnd(buffer, bitmaps); + assertEquals(expected, result); + } - @MethodSource("bitmaps") - @ParameterizedTest(name = "testWorkShyAnd") - public void testWorkShyAnd(List list) { - RoaringBitmap[] bitmaps = list.toArray(new RoaringBitmap[0]); - long[] buffer = new long[1024]; - RoaringBitmap result = FastAggregation.and(buffer, bitmaps); - RoaringBitmap expected = FastAggregation.naive_and(bitmaps); - assertEquals(expected, result); - result = FastAggregation.and(bitmaps); - assertEquals(expected, result); - result = FastAggregation.workAndMemoryShyAnd(buffer, bitmaps); - assertEquals(expected, result); + @MethodSource("bitmaps") + @ParameterizedTest(name = "testAndCardinality") + public void testAndCardinality(List list) { + RoaringBitmap[] bitmaps = list.toArray(new RoaringBitmap[0]); + for (int length = 0; length <= bitmaps.length; length++) { + RoaringBitmap[] subset = Arrays.copyOf(bitmaps, length); + RoaringBitmap and = FastAggregation.and(subset); + int andCardinality = FastAggregation.andCardinality(subset); + assertEquals(and.getCardinality(), andCardinality); } + } - @MethodSource("bitmaps") - @ParameterizedTest(name = "testAndCardinality") - public void testAndCardinality(List list) { - RoaringBitmap[] bitmaps = list.toArray(new RoaringBitmap[0]); - for (int length = 0; length <= bitmaps.length; length++) { - RoaringBitmap[] subset = Arrays.copyOf(bitmaps, length); - RoaringBitmap and = FastAggregation.and(subset); - int andCardinality = FastAggregation.andCardinality(subset); - assertEquals(and.getCardinality(), andCardinality); - } + @MethodSource("bitmaps") + @ParameterizedTest(name = "testOrCardinality") + public void testOrCardinality(List list) { + RoaringBitmap[] bitmaps = list.toArray(new RoaringBitmap[0]); + for (int length = 0; length <= bitmaps.length; length++) { + RoaringBitmap[] subset = Arrays.copyOf(bitmaps, length); + RoaringBitmap or = FastAggregation.or(subset); + int orCardinality = FastAggregation.orCardinality(subset); + assertEquals(or.getCardinality(), orCardinality); } - - @MethodSource("bitmaps") - @ParameterizedTest(name = "testOrCardinality") - public void testOrCardinality(List list) { - RoaringBitmap[] bitmaps = list.toArray(new RoaringBitmap[0]); - for (int length = 0; length <= bitmaps.length; length++) { - RoaringBitmap[] subset = Arrays.copyOf(bitmaps, length); - RoaringBitmap or = FastAggregation.or(subset); - int orCardinality = FastAggregation.orCardinality(subset); - assertEquals(or.getCardinality(), orCardinality); - } - } - + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java index 282e37654..ab3efe9e4 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestForAllInRange.java @@ -1,18 +1,18 @@ package org.roaringbitmap; -import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; +import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; + +import org.roaringbitmap.ValidationRangeConsumer.Value; import com.google.common.primitives.UnsignedInteger; -import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.roaringbitmap.ValidationRangeConsumer.Value; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; -import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; +import java.util.Arrays; public class TestForAllInRange { @@ -40,16 +40,14 @@ public void testContinuous(int offset) { bitmap.forAllInRange(uAdd(offset, 10001), 1000, consumer2); assertEquals(1000, consumer2.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new Value[]{ - ABSENT, ABSENT, PRESENT, PRESENT, PRESENT - }); - bitmap.forAllInRange(uAdd(offset,98), 5, consumer3); + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate(new Value[] {ABSENT, ABSENT, PRESENT, PRESENT, PRESENT}); + bitmap.forAllInRange(uAdd(offset, 98), 5, consumer3); assertEquals(5, consumer3.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer4 = ValidationRangeConsumer.validate(new Value[]{ - PRESENT, PRESENT, ABSENT, ABSENT, ABSENT - }); - bitmap.forAllInRange(uAdd(offset,9998), 5, consumer4); + ValidationRangeConsumer consumer4 = + ValidationRangeConsumer.validate(new Value[] {PRESENT, PRESENT, ABSENT, ABSENT, ABSENT}); + bitmap.forAllInRange(uAdd(offset, 9998), 5, consumer4); assertEquals(5, consumer4.getNumberOfValuesConsumed()); bitmap = new RoaringBitmap(); @@ -63,7 +61,7 @@ public void testContinuous(int offset) { consumer6.assertAllPresent(); bitmap = new RoaringBitmap(); - bitmap.add(uAddL(offset, 100), uAddL(offset, 10000)); + bitmap.add(uAddL(offset, 100), uAddL(offset, 10000)); ValidationRangeConsumer consumer7 = ValidationRangeConsumer.ofSize(1000000); bitmap.forAllInRange(uAdd(offset, 10000), 1000000, consumer7); consumer7.assertAllAbsent(); @@ -84,19 +82,20 @@ public void testDense(int offset) { bitmap.forAllInRange(uAdd(offset, 0), 100000, consumer); assertEquals(100000, consumer.getNumberOfValuesConsumed()); - Value[] expectedSubRange = Arrays.copyOfRange(expected,2500, 6000); + Value[] expectedSubRange = Arrays.copyOfRange(expected, 2500, 6000); ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(expectedSubRange); bitmap.forAllInRange(uAdd(offset, 2500), 3500, consumer2); assertEquals(3500, consumer2.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new Value[]{ - expected[99997], expected[99998], expected[99999], ABSENT, ABSENT, ABSENT - }); + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate( + new Value[] { + expected[99997], expected[99998], expected[99999], ABSENT, ABSENT, ABSENT + }); bitmap.forAllInRange(uAdd(offset, 99997), 6, consumer3); assertEquals(6, consumer3.getNumberOfValuesConsumed()); } - @ParameterizedTest @ValueSource(ints = {0, 1, 65531, 65536, 2147483642, 2147483647, -2147483648, -2146958415}) public void testSparse(int offset) { @@ -112,7 +111,7 @@ public void testSparse(int offset) { bitmap.forAllInRange(uAdd(offset, 0), 100000, consumer); assertEquals(100000, consumer.getNumberOfValuesConsumed()); - Value[] expectedSubRange = Arrays.copyOfRange(expected,2500, 6001); + Value[] expectedSubRange = Arrays.copyOfRange(expected, 2500, 6001); ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(expectedSubRange); bitmap.forAllInRange(uAdd(offset, 2500), 3500, consumer2); assertEquals(3500, consumer2.getNumberOfValuesConsumed()); @@ -147,15 +146,18 @@ public void readToEnd() { emptyLastContainerBitmap.forAllInRange(0xFFFFFFFE, 2, consumer3); assertEquals(2, consumer3.getNumberOfValuesConsumed()); } + @Test public void readPastEnd() { final RoaringBitmap bitmap = new RoaringBitmap(); bitmap.add(0xFFFFFFFE); bitmap.add(0xFFFFFFFF); - assertThrows(IllegalArgumentException.class, () -> { - bitmap.forAllInRange(0xFFFFFFFE, 3, ValidationRangeConsumer.ofSize(3)); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + bitmap.forAllInRange(0xFFFFFFFE, 3, ValidationRangeConsumer.ofSize(3)); + }); } @Test diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestForEach.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestForEach.java index 2039f05c9..5b68e1dfc 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestForEach.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestForEach.java @@ -1,10 +1,9 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestForEach { @Test @@ -13,61 +12,60 @@ public void testContinuous() { bitmap.add(100L, 10000L); final MutableInteger cardinality = new MutableInteger(); - bitmap.forEach(new IntConsumer() { - int expected = 100; - - @Override - public void accept(int value) { - cardinality.value++; - assertEquals(value, expected++); - } - }); + bitmap.forEach( + new IntConsumer() { + int expected = 100; + + @Override + public void accept(int value) { + cardinality.value++; + assertEquals(value, expected++); + } + }); assertEquals(cardinality.value, bitmap.getCardinality()); } @Test public void testDense() { RoaringBitmap bitmap = new RoaringBitmap(); - for (int k = 0; k < 100000; k += 3) - bitmap.add(k); + for (int k = 0; k < 100000; k += 3) bitmap.add(k); final MutableInteger cardinality = new MutableInteger(); - bitmap.forEach(new IntConsumer() { - int expected = 0; - - @Override - public void accept(int value) { - cardinality.value++; - assertEquals(value, expected); - expected += 3; - } - }); + bitmap.forEach( + new IntConsumer() { + int expected = 0; + + @Override + public void accept(int value) { + cardinality.value++; + assertEquals(value, expected); + expected += 3; + } + }); assertEquals(cardinality.value, bitmap.getCardinality()); } - @Test public void testSparse() { RoaringBitmap bitmap = new RoaringBitmap(); - for (int k = 0; k < 100000; k += 3000) - bitmap.add(k); + for (int k = 0; k < 100000; k += 3000) bitmap.add(k); final MutableInteger cardinality = new MutableInteger(); - bitmap.forEach(new IntConsumer() { - int expected = 0; - - @Override - public void accept(int value) { - cardinality.value++; - assertEquals(value, expected); - expected += 3000; - } - }); + bitmap.forEach( + new IntConsumer() { + int expected = 0; + + @Override + public void accept(int value) { + cardinality.value++; + assertEquals(value, expected); + expected += 3000; + } + }); assertEquals(cardinality.value, bitmap.getCardinality()); } } - class MutableInteger { public int value = 0; } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java index 323ce4764..29e6a0526 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestImmutableRoaringBitmap.java @@ -1,65 +1,68 @@ package org.roaringbitmap; -import org.junit.jupiter.api.Test; -import org.roaringbitmap.buffer.ImmutableRoaringBitmap; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import org.roaringbitmap.buffer.ImmutableRoaringBitmap; + +import org.junit.jupiter.api.Test; public class TestImmutableRoaringBitmap { - @Test - public void xor() { - ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 73647, 83469); - ImmutableRoaringBitmap b = ImmutableRoaringBitmap.bitmapOf(1, 5, 10<<16); - ImmutableRoaringBitmap xor = ImmutableRoaringBitmap.xor(a, b); - ImmutableRoaringBitmap expected = ImmutableRoaringBitmap.bitmapOf(5, 73647, 83469, 10<<16); - assertEquals(expected, xor); - } + @Test + public void xor() { + ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 73647, 83469); + ImmutableRoaringBitmap b = ImmutableRoaringBitmap.bitmapOf(1, 5, 10 << 16); + ImmutableRoaringBitmap xor = ImmutableRoaringBitmap.xor(a, b); + ImmutableRoaringBitmap expected = ImmutableRoaringBitmap.bitmapOf(5, 73647, 83469, 10 << 16); + assertEquals(expected, xor); + } - @Test - public void or() { - ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 73647, 83469); - ImmutableRoaringBitmap b = ImmutableRoaringBitmap.bitmapOf(1, 5, 10<<16); - ImmutableRoaringBitmap expected = ImmutableRoaringBitmap.bitmapOf(1, 5, 73647, 83469, 10<<16); - assertEquals(expected, ImmutableRoaringBitmap.or(a, b)); - assertEquals(expected, ImmutableRoaringBitmap.or(b, a)); - } + @Test + public void or() { + ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 73647, 83469); + ImmutableRoaringBitmap b = ImmutableRoaringBitmap.bitmapOf(1, 5, 10 << 16); + ImmutableRoaringBitmap expected = ImmutableRoaringBitmap.bitmapOf(1, 5, 73647, 83469, 10 << 16); + assertEquals(expected, ImmutableRoaringBitmap.or(a, b)); + assertEquals(expected, ImmutableRoaringBitmap.or(b, a)); + } - @Test - public void andNot() { - ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1<<16, 2<<16); - ImmutableRoaringBitmap b = ImmutableRoaringBitmap.bitmapOf(11, 12, 13, 2<<16); - ImmutableRoaringBitmap andNot = ImmutableRoaringBitmap.andNot(a, b); - ImmutableRoaringBitmap expected = ImmutableRoaringBitmap.bitmapOf(1<<16); - assertEquals(expected, andNot); - } + @Test + public void andNot() { + ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1 << 16, 2 << 16); + ImmutableRoaringBitmap b = ImmutableRoaringBitmap.bitmapOf(11, 12, 13, 2 << 16); + ImmutableRoaringBitmap andNot = ImmutableRoaringBitmap.andNot(a, b); + ImmutableRoaringBitmap expected = ImmutableRoaringBitmap.bitmapOf(1 << 16); + assertEquals(expected, andNot); + } - @Test - public void flipInvalidRange() { - assertThrows(RuntimeException.class, () -> { - ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 5, 7, 13); - ImmutableRoaringBitmap.flip(a, 7L, 5L); + @Test + public void flipInvalidRange() { + assertThrows( + RuntimeException.class, + () -> { + ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 5, 7, 13); + ImmutableRoaringBitmap.flip(a, 7L, 5L); }); - } + } - @Test - public void flipInvalidRange2() { - assertThrows(IllegalArgumentException.class, () -> { - ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 5, 7, 13); - ImmutableRoaringBitmap.flip(a, 1L << 32, 1L << 33); + @Test + public void flipInvalidRange2() { + assertThrows( + IllegalArgumentException.class, + () -> { + ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 5, 7, 13); + ImmutableRoaringBitmap.flip(a, 1L << 32, 1L << 33); }); - } + } - @Test - public void flipInvalidRange3() { - assertThrows(IllegalArgumentException.class, () -> { - ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 5, 7, 13); - ImmutableRoaringBitmap.flip(a, 1L, 1L << 33); + @Test + public void flipInvalidRange3() { + assertThrows( + IllegalArgumentException.class, + () -> { + ImmutableRoaringBitmap a = ImmutableRoaringBitmap.bitmapOf(1, 5, 7, 13); + ImmutableRoaringBitmap.flip(a, 1L, 1L << 33); }); - } - - - + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java index 466c9f495..b87d1612a 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestIntIteratorFlyweight.java @@ -2,9 +2,11 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.primitives.Ints; @@ -17,9 +19,6 @@ import java.util.List; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - @Execution(ExecutionMode.CONCURRENT) public class TestIntIteratorFlyweight { private static List asList(IntIterator ints) { @@ -43,7 +42,7 @@ private static int[] takeSortedAndDistinct(Random source, int count) { } while (!ints.add(next)); } // we add a range of continuous values - for(int k = 1000; k < 10000; ++k) { + for (int k = 1000; k < 10000; ++k) { ints.add(k); } int[] unboxed = Ints.toArray(ints); @@ -64,8 +63,6 @@ public void testEmptyIteration() { assertFalse(reverseIter.hasNext()); } - - @Test public void testIteration() { final Random source = new Random(0xcb000a2b9b5bdfb6L); @@ -84,16 +81,16 @@ public void testIteration() { IntIteratorFlyweight iter2 = new IntIteratorFlyweight(bitmap); PeekableIntIterator j = bitmap.getIntIterator(); - for(int k = 0; k < data.length; k+=3) { + for (int k = 0; k < data.length; k += 3) { iter2.advanceIfNeeded(data[k]); iter2.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); - assertEquals(j.peekNext(),data[k]); - assertEquals(iter2.peekNext(),data[k]); + assertEquals(j.peekNext(), data[k]); + assertEquals(iter2.peekNext(), data[k]); } new IntIteratorFlyweight(bitmap).advanceIfNeeded(-1); - bitmap.getIntIterator().advanceIfNeeded(-1);// should not crash + bitmap.getIntIterator().advanceIfNeeded(-1); // should not crash ReverseIntIteratorFlyweight reverseIter = new ReverseIntIteratorFlyweight(); reverseIter.wrap(bitmap); @@ -101,7 +98,6 @@ public void testIteration() { final List intIteratorCopy = asList(iter); final List reverseIntIteratorCopy = asList(reverseIter); - assertEquals(bitmap.getCardinality(), intIteratorCopy.size()); assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size()); @@ -123,18 +119,18 @@ public void testIterationFromBitmap() { bitmap.runOptimize(); IntIteratorFlyweight iter = new IntIteratorFlyweight(bitmap); - assertEquals(iter.peekNext(),data[0]); - assertEquals(iter.peekNext(),data[0]); + assertEquals(iter.peekNext(), data[0]); + assertEquals(iter.peekNext(), data[0]); IntIteratorFlyweight iter2 = new IntIteratorFlyweight(bitmap); PeekableIntIterator j = bitmap.getIntIterator(); - for(int k = 0; k < data.length; k+=3) { + for (int k = 0; k < data.length; k += 3) { iter2.advanceIfNeeded(data[k]); iter2.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); - assertEquals(j.peekNext(),data[k]); - assertEquals(iter2.peekNext(),data[k]); + assertEquals(j.peekNext(), data[k]); + assertEquals(iter2.peekNext(), data[k]); } ReverseIntIteratorFlyweight reverseIter = new ReverseIntIteratorFlyweight(bitmap); @@ -142,7 +138,6 @@ public void testIterationFromBitmap() { final List intIteratorCopy = asList(iter); final List reverseIntIteratorCopy = asList(reverseIter); - assertEquals(bitmap.getCardinality(), intIteratorCopy.size()); assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size()); @@ -165,23 +160,27 @@ public void testIterationFromBitmapClone() { IntIteratorFlyweight iter = (IntIteratorFlyweight) new IntIteratorFlyweight(bitmap).clone(); - ReverseIntIteratorFlyweight reverseIter = (ReverseIntIteratorFlyweight) new ReverseIntIteratorFlyweight(bitmap).clone(); + ReverseIntIteratorFlyweight reverseIter = + (ReverseIntIteratorFlyweight) new ReverseIntIteratorFlyweight(bitmap).clone(); final List intIteratorCopy = asList(iter); final List reverseIntIteratorCopy = asList(reverseIter); - assertEquals(bitmap.getCardinality(), intIteratorCopy.size()); assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size()); assertEquals(Ints.asList(data), intIteratorCopy); assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy); } + @Test public void testIterationSmall() { - final int[] data = new int[] {1, 2, 3, 4, 5, 6, 100, 101, 102, 103, 104, 105, 50000, 50001, - 50002, 1000000, 1000005, 1000007}; // runcontainer then arraycontainer + final int[] data = + new int[] { + 1, 2, 3, 4, 5, 6, 100, 101, 102, 103, 104, 105, 50000, 50001, 50002, 1000000, 1000005, + 1000007 + }; // runcontainer then arraycontainer RoaringBitmap bitmap = RoaringBitmap.bitmapOf(data); bitmap.runOptimize(); @@ -194,7 +193,6 @@ public void testIterationSmall() { final List intIteratorCopy = asList(iter); final List reverseIntIteratorCopy = asList(reverseIter); - assertEquals(bitmap.getCardinality(), intIteratorCopy.size()); assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size()); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java index 670cd1b4c..4538783ea 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestIteratorMemory.java @@ -1,5 +1,7 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; @@ -14,9 +16,6 @@ import java.util.Random; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - @Disabled("makes no meaningful assertions") public class TestIteratorMemory { final IntIteratorFlyweight flyweightIterator = new IntIteratorFlyweight(); @@ -27,19 +26,16 @@ public class TestIteratorMemory { final RoaringBitmap bitmap_a; final RoaringBitmap bitmap_b; final RoaringBitmap bitmap_c; - { + { final int[] data = takeSortedAndDistinct(new Random(0xcb000a2b9b5bdfb6L), 100000); bitmap_a = RoaringBitmap.bitmapOf(data); bitmap_b = new RoaringBitmap(); - for (int k = 0; k < (1 << 30); k += 32) - bitmap_b.add(k); + for (int k = 0; k < (1 << 30); k += 32) bitmap_b.add(k); bitmap_c = new RoaringBitmap(); - for (int k = 0; k < (1 << 30); k += 3) - bitmap_c.add(k); - + for (int k = 0; k < (1 << 30); k += 3) bitmap_c.add(k); } private int[] takeSortedAndDistinct(Random source, int count) { @@ -70,13 +66,20 @@ private int[] toArray(LinkedHashSet integers) { protected static final ThreadMXBean THREAD_MBEAN = ManagementFactory.getThreadMXBean(); public static boolean isThreadAllocatedMemorySupported(ThreadMXBean threadMbean) { - if (threadMbean != null && Stream.of(threadMbean.getClass().getInterfaces()) - .anyMatch(c -> c.getName().equals("com.sun.management.ThreadMXBean"))) { + if (threadMbean != null + && Stream.of(threadMbean.getClass().getInterfaces()) + .anyMatch(c -> c.getName().equals("com.sun.management.ThreadMXBean"))) { try { - return (Boolean) Class.forName("com.sun.management.ThreadMXBean") - .getMethod("isThreadAllocatedMemorySupported").invoke(threadMbean); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException - | NoSuchMethodException | SecurityException | ClassNotFoundException e) { + return (Boolean) + Class.forName("com.sun.management.ThreadMXBean") + .getMethod("isThreadAllocatedMemorySupported") + .invoke(threadMbean); + } catch (IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException + | ClassNotFoundException e) { return false; } } else { @@ -87,10 +90,16 @@ public static boolean isThreadAllocatedMemorySupported(ThreadMXBean threadMbean) public static long getThreadAllocatedBytes(ThreadMXBean threadMbean, long l) { if (isThreadAllocatedMemorySupported(threadMbean)) { try { - return (Long) Class.forName("com.sun.management.ThreadMXBean") - .getMethod("getThreadAllocatedBytes", long.class).invoke(threadMbean, l); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException - | NoSuchMethodException | SecurityException | ClassNotFoundException e) { + return (Long) + Class.forName("com.sun.management.ThreadMXBean") + .getMethod("getThreadAllocatedBytes", long.class) + .invoke(threadMbean, l); + } catch (IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException + | ClassNotFoundException e) { return -1L; } } else { @@ -112,7 +121,6 @@ public void measureBoxedIterationAllocation() { long result = 0; while (intIterator.hasNext()) { result += intIterator.next(); - } // A small check for iterator consistency assertEquals(407, result % 1024); @@ -131,7 +139,6 @@ public void measureStandardIterationAllocation() { long result = 0; while (intIterator.hasNext()) { result += intIterator.next(); - } // A small check for iterator consistency assertEquals(407, result % 1024); @@ -152,7 +159,6 @@ public void measureFlyWeightIterationAllocation() { long result = 0; while (intIterator.hasNext()) { result += intIterator.next(); - } // A small check for iterator consistency assertEquals(407, result % 1024); @@ -161,5 +167,4 @@ public void measureFlyWeightIterationAllocation() { System.out.println("FlyWeight Iteration allocated: " + (after - before)); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestIterators.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestIterators.java index 9d6c6fc70..3fada8540 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestIterators.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestIterators.java @@ -2,9 +2,11 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -19,10 +21,6 @@ import java.util.Random; import java.util.stream.Collectors; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - public class TestIterators { private static List asList(IntIterator ints) { int[] values = new int[10]; @@ -37,25 +35,27 @@ private static List asList(IntIterator ints) { } private static List asList(final CharIterator shorts) { - return asList(new IntIterator() { - @Override - public IntIterator clone() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean hasNext() { - return shorts.hasNext(); - } - - @Override - public int next() { - return shorts.next(); - } - }); + return asList( + new IntIterator() { + @Override + public IntIterator clone() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return shorts.hasNext(); + } + + @Override + public int next() { + return shorts.next(); + } + }); } - private static int[] takeSortedAndDistinct(Random source, int count, Comparator comparator) { + private static int[] takeSortedAndDistinct( + Random source, int count, Comparator comparator) { HashSet ints = new HashSet(count); for (int size = 0; size < count; size++) { int next; @@ -101,7 +101,8 @@ public void testIteration() { assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size()); assertEquals(Ints.asList(data), iteratorCopy); assertEquals(Ints.asList(data), intIteratorCopy); - assertEquals(Ints.asList(data).stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy); + assertEquals( + Ints.asList(data).stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy); assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy); } @@ -141,7 +142,7 @@ public void testSkips() { pii.next(); assertEquals(data[i], pii.peekNext()); } - bitmap.getIntIterator().advanceIfNeeded(-1);// should not crash + bitmap.getIntIterator().advanceIfNeeded(-1); // should not crash } @Test @@ -177,10 +178,10 @@ public void testSkipsSignedIterator() { public void testSkipsDense() { RoaringBitmap bitmap = new RoaringBitmap(); int N = 100000; - for(int i = 0; i < N; ++i) { + for (int i = 0; i < N; ++i) { bitmap.add(2 * i); } - for(int i = 0; i < N; ++i) { + for (int i = 0; i < N; ++i) { PeekableIntIterator pii = bitmap.getIntIterator(); pii.advanceIfNeeded(2 * i); assertEquals(pii.peekNext(), 2 * i); @@ -197,18 +198,22 @@ public void testCorruptionInfiniteLoop() { bitmap.add(Integer.MAX_VALUE - 2); // Adding this one leads to the issue bitmap.add(Integer.MAX_VALUE - 3); - bitmap.forEach((org.roaringbitmap.IntConsumer) e -> { - if (!bitmap.contains(e)) { - throw new IllegalStateException("Not expecting to find: " + e); - } - }); + bitmap.forEach( + (org.roaringbitmap.IntConsumer) + e -> { + if (!bitmap.contains(e)) { + throw new IllegalStateException("Not expecting to find: " + e); + } + }); bitmap.runOptimize(); // This is the line causing the issue - bitmap.forEach((org.roaringbitmap.IntConsumer) e -> { - if (!bitmap.contains(e)) { - throw new IllegalStateException("Not expecting to find: " + e); - } - }); + bitmap.forEach( + (org.roaringbitmap.IntConsumer) + e -> { + if (!bitmap.contains(e)) { + throw new IllegalStateException("Not expecting to find: " + e); + } + }); } @Test @@ -216,7 +221,7 @@ public void testSkipsRun() { RoaringBitmap bitmap = new RoaringBitmap(); bitmap.add(4L, 100000L); bitmap.runOptimize(); - for(int i = 4; i < 100000; ++i) { + for (int i = 4; i < 100000; ++i) { PeekableIntIterator pii = bitmap.getIntIterator(); pii.advanceIfNeeded(i); assertEquals(pii.peekNext(), i); @@ -226,15 +231,15 @@ public void testSkipsRun() { @Test public void testIndexIterator4() throws Exception { - RoaringBitmap b = new RoaringBitmap(); - for (int i = 0; i < 4096; i++) { - b.add(i); - } - PeekableIntIterator it = b.getIntIterator(); - it.advanceIfNeeded(4096); - while (it.hasNext()) { - it.next(); - } + RoaringBitmap b = new RoaringBitmap(); + for (int i = 0; i < 4096; i++) { + b.add(i); + } + PeekableIntIterator it = b.getIntIterator(); + it.advanceIfNeeded(4096); + while (it.hasNext()) { + it.next(); + } } @Test @@ -294,7 +299,7 @@ public void testSkipIntoFarAwayGaps() { // advancing to a value not in any range but beyond second range // should go to the first value of third range assertFalse(bitset.contains(4325376 - 5)); // same container - bitIt.advanceIfNeeded( 4325376 - 5); + bitIt.advanceIfNeeded(4325376 - 5); assertEquals(6000000, bitIt.peekNext()); @@ -316,7 +321,7 @@ public void testSkipIntoFarAwayGaps() { // advancing to a value not in any range but beyond second range // should go to the first value of third range assertFalse(bitset.contains(4325376 + 5)); // next container - bitIt.advanceIfNeeded( 4325376 + 5); + bitIt.advanceIfNeeded(4325376 + 5); assertEquals(6000000, bitIt.peekNext()); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestMemory.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestMemory.java index 6123e8ab6..b6b1089cc 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestMemory.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestMemory.java @@ -1,19 +1,22 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestMemory { @Test public void testGCStability() { final int N = 10000; final int M = 5000000; - System.out.println("[testGCStability] testing GC stability with " + N + " bitmaps containing ~" - + M / N + " values each on average"); + System.out.println( + "[testGCStability] testing GC stability with " + + N + + " bitmaps containing ~" + + M / N + + " values each on average"); System.out.println("Universe size = " + M); final RoaringBitmap[] bitmaps = new RoaringBitmap[N]; for (int i = 0; i < N; i++) { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRange.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRange.java index cfbb6e8e6..5fd8588be 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRange.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRange.java @@ -1,5 +1,9 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -7,9 +11,6 @@ import java.util.List; import java.util.Random; -import static org.junit.jupiter.api.Assertions.*; - - public class TestRange { @Test public void flip64() { @@ -22,8 +23,8 @@ public void flip64() { assertFalse(i.hasNext()); } - private static int fillWithRandomBits(final RoaringBitmap bitmap, final BitSet bitset, - final int bits) { + private static int fillWithRandomBits( + final RoaringBitmap bitmap, final BitSet bitset, final int bits) { int added = 0; Random r = new Random(1011); for (int j = 0; j < bits; j++) { @@ -36,7 +37,6 @@ private static int fillWithRandomBits(final RoaringBitmap bitmap, final BitSet b return added; } - @Test public void doubleadd() { RoaringBitmap rb = new RoaringBitmap(); @@ -49,7 +49,6 @@ public void doubleadd() { assertEquals(0, rb.getCardinality()); } - @Test public void rangeAddRemoveBig() { final int numCases = 5000; @@ -68,7 +67,7 @@ public void rangeAddRemoveBig() { } rbinplace.add(start, end); rbstatic = RoaringBitmap.add(rbstatic, start, end); - bs.set((int)start, (int)end); + bs.set((int) start, (int) end); // start = r.nextInt(65536 * 20); @@ -80,7 +79,7 @@ public void rangeAddRemoveBig() { } rbinplace.remove(start, end); rbstatic = RoaringBitmap.remove(rbstatic, start, end); - bs.clear((int)start, (int)end); + bs.clear((int) start, (int) end); // start = r.nextInt(20) * 65536; @@ -92,7 +91,7 @@ public void rangeAddRemoveBig() { } rbinplace.add(start, end); rbstatic = RoaringBitmap.add(rbstatic, start, end); - bs.set((int)start, (int)end); + bs.set((int) start, (int) end); // start = r.nextInt(65536 * 20); @@ -104,7 +103,7 @@ public void rangeAddRemoveBig() { } rbinplace.add(start, end); rbstatic = RoaringBitmap.add(rbstatic, start, end); - bs.set((int)start, (int)end); + bs.set((int) start, (int) end); // start = r.nextInt(20) * 65536; end = r.nextInt(65536 * 20); @@ -115,7 +114,7 @@ public void rangeAddRemoveBig() { } rbinplace.remove(start, end); rbstatic = RoaringBitmap.remove(rbstatic, start, end); - bs.clear((int)start, (int)end); + bs.clear((int) start, (int) end); // start = r.nextInt(65536 * 20); @@ -127,7 +126,7 @@ public void rangeAddRemoveBig() { } rbinplace.remove(start, end); rbstatic = RoaringBitmap.remove(rbstatic, start, end); - bs.clear((int)start, (int)end); + bs.clear((int) start, (int) end); } assertTrue(TestRoaringBitmap.equals(bs, rbstatic)); assertTrue(TestRoaringBitmap.equals(bs, rbinplace)); @@ -188,7 +187,6 @@ public void setTest1A() { assertTrue(TestRoaringBitmap.equals(bs, rb1)); } - @Test public void setTest2() { final RoaringBitmap rb = new RoaringBitmap(); @@ -216,7 +214,6 @@ public void setTest2A() { assertTrue(TestRoaringBitmap.equals(bs, rb)); } - @Test public void setTest3() { final RoaringBitmap rb = new RoaringBitmap(); @@ -234,7 +231,6 @@ public void setTest3() { assertTrue(TestRoaringBitmap.equals(bs, rb)); } - @Test public void setTest3A() { final RoaringBitmap rb = new RoaringBitmap(); @@ -254,7 +250,6 @@ public void setTest3A() { assertTrue(TestRoaringBitmap.equals(bs, rb2)); } - @Test public void setTest4() { final RoaringBitmap rb = new RoaringBitmap(); @@ -429,7 +424,6 @@ public void setTest7A() { assertEquals(rb2, rb3); assertTrue(TestRoaringBitmap.equals(bs, rb3)); - rb3 = RoaringBitmap.add(rb3, 65536L * 3 + 195, 65536L * 3 + 245); bs.set(65536 * 3 + 195, 65536 * 3 + 245); rb2.add(65536L * 3 + 195, 65536L * 3 + 245); @@ -442,7 +436,6 @@ public void setTest7A() { // now removing - rb3 = RoaringBitmap.remove(rb3, 65536L * 3 + 195, 65536L * 3 + 245); bs.clear(65536 * 3 + 195, 65536 * 3 + 245); rb2.remove(65536L * 3 + 195, 65536L * 3 + 245); @@ -464,14 +457,11 @@ public void setTest7A() { assertEquals(rb2, rb3); assertTrue(TestRoaringBitmap.equals(bs, rb3)); - rb2 = RoaringBitmap.remove(rb1, 130L, 185L); bs.clear(130, 185); rb.remove(130L, 185L); assertEquals(rb2, rb); assertTrue(TestRoaringBitmap.equals(bs, rb2)); - - } @Test @@ -569,7 +559,7 @@ public void setTestSinglePonitsA() { public void testClearRanges() { long N = 16; for (long end = 1; end < N; ++end) { - for (long start = 0; start < end; ++start) { + for (long start = 0; start < end; ++start) { RoaringBitmap bs1 = new RoaringBitmap(); bs1.add(0L, N); for (int k = (int) start; k < end; ++k) { @@ -708,7 +698,7 @@ public void testSetRanges() { for (long end = 1; end < N; ++end) { for (long start = 0; start < end; ++start) { RoaringBitmap bs1 = new RoaringBitmap(); - for (int k = (int)start; k < end; ++k) { + for (int k = (int) start; k < end; ++k) { bs1.add(k); } RoaringBitmap bs2 = new RoaringBitmap(); @@ -736,7 +726,6 @@ public void testStaticClearRanges() { } } - @Test public void testStaticSetRanges() { int N = 256; @@ -753,219 +742,204 @@ public void testStaticSetRanges() { } } - /* nb on 20 April 2016, all unit tests above [then] were switched from - * the original int-range functions to the wrapper int-range functions - * without test errors. Then all code above switched use longs for - * range endpoints, again without test errors. - * - * Below, check the deprecated versions for undocumented behaviours that - * hopefully don't rely on...but might have - */ - + /* nb on 20 April 2016, all unit tests above [then] were switched from + * the original int-range functions to the wrapper int-range functions + * without test errors. Then all code above switched use longs for + * range endpoints, again without test errors. + * + * Below, check the deprecated versions for undocumented behaviours that + * hopefully don't rely on...but might have + */ @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedStaticAdd() { RoaringBitmap rb1 = RoaringBitmap.add(new RoaringBitmap(), 300000, 500000); RoaringBitmap rb2 = RoaringBitmap.add(new RoaringBitmap(), 300000L, 500000L); assertEquals(rb1, rb2); - rb1 = RoaringBitmap.add( rb1, Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2 = RoaringBitmap.add( rb2, Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1 = RoaringBitmap.add(rb1, Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2 = RoaringBitmap.add(rb2, Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedStaticFlip() { RoaringBitmap rb1 = RoaringBitmap.flip(new RoaringBitmap(), 300000, 500000); RoaringBitmap rb2 = RoaringBitmap.flip(new RoaringBitmap(), 300000L, 500000L); assertEquals(rb1, rb2); - rb1 = RoaringBitmap.flip(rb1, Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2 = RoaringBitmap.flip(rb2, Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1 = RoaringBitmap.flip(rb1, Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2 = RoaringBitmap.flip(rb2, Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedMemberFlip() { RoaringBitmap rb1 = new RoaringBitmap(); rb1.flip(300000, 500000); RoaringBitmap rb2 = new RoaringBitmap(); rb2.flip(300000L, 500000L); assertEquals(rb1, rb2); - rb1.flip(Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2.flip(Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1.flip(Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2.flip(Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedStaticRemove() { - RoaringBitmap rb1 = RoaringBitmap.add(new RoaringBitmap(), 200000L, 400000L); - rb1 = RoaringBitmap.remove(rb1, 300000, 500000); - RoaringBitmap rb2 = RoaringBitmap.add(new RoaringBitmap(), 200000L, 400000L); - rb2 = RoaringBitmap.remove(rb2,300000L, 500000L); + RoaringBitmap rb1 = RoaringBitmap.add(new RoaringBitmap(), 200000L, 400000L); + rb1 = RoaringBitmap.remove(rb1, 300000, 500000); + RoaringBitmap rb2 = RoaringBitmap.add(new RoaringBitmap(), 200000L, 400000L); + rb2 = RoaringBitmap.remove(rb2, 300000L, 500000L); assertEquals(rb1, rb2); - rb1 = RoaringBitmap.add(rb1, Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - rb2 = RoaringBitmap.add(rb2, Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - rb1 = RoaringBitmap.remove(rb1, Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2 = RoaringBitmap.remove(rb2, Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1 = RoaringBitmap.add(rb1, Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + rb2 = RoaringBitmap.add(rb2, Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + rb1 = RoaringBitmap.remove(rb1, Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2 = RoaringBitmap.remove(rb2, Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedAdd() { - RoaringBitmap rb1 = new RoaringBitmap(); - rb1.add(300000, 500000); - RoaringBitmap rb2 = new RoaringBitmap(); - rb2.add(300000L, 500000L); + RoaringBitmap rb1 = new RoaringBitmap(); + rb1.add(300000, 500000); + RoaringBitmap rb2 = new RoaringBitmap(); + rb2.add(300000L, 500000L); assertEquals(rb1, rb2); - rb1.add( Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2.add( Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1.add(Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2.add(Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedRemove() { - RoaringBitmap rb1 = new RoaringBitmap(); - rb1.add(200000L, 400000L); - rb1.remove(300000, 500000); - RoaringBitmap rb2 = new RoaringBitmap(); - rb2.add(200000L, 400000L); - rb2.remove(300000L, 500000L); + RoaringBitmap rb1 = new RoaringBitmap(); + rb1.add(200000L, 400000L); + rb1.remove(300000, 500000); + RoaringBitmap rb2 = new RoaringBitmap(); + rb2.add(200000L, 400000L); + rb2.remove(300000L, 500000L); assertEquals(rb1, rb2); - rb1.add(Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - rb2.add(Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - rb1.remove(Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2.remove(Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1.add(Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + rb2.add(Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + rb1.remove(Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2.remove(Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } - - - // the other tests for ranged AND are in TestRoaringBitmap; the - // range-with-longs is assumed to be okay and only lightly checked here + // the other tests for ranged AND are in TestRoaringBitmap; the + // range-with-longs is assumed to be okay and only lightly checked here @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorAnd() { - RoaringBitmap rb1 = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); + RoaringBitmap rb1 = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full overlap is on 300000 to 399999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full overlap is on 300000 to 399999 - RoaringBitmap result = RoaringBitmap.and(list.iterator(), 350000L, 450000L); - RoaringBitmap resultInt = RoaringBitmap.and(list.iterator(), 350000, 450000); + RoaringBitmap result = RoaringBitmap.and(list.iterator(), 350000L, 450000L); + RoaringBitmap resultInt = RoaringBitmap.and(list.iterator(), 350000, 450000); assertEquals(result, resultInt); - assertEquals(50000, result.getCardinality()); - + assertEquals(50000, result.getCardinality()); - // empty ranges get empty result - resultInt = RoaringBitmap.and(list.iterator(), 300000, 200000); - result = RoaringBitmap.and(list.iterator(), 300000L, 200000L); + // empty ranges get empty result + resultInt = RoaringBitmap.and(list.iterator(), 300000, 200000); + result = RoaringBitmap.and(list.iterator(), 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorOr() { - RoaringBitmap rb1 = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); + RoaringBitmap rb1 = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full union is 200000 to 499999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full union is 200000 to 499999 - RoaringBitmap result = RoaringBitmap.or(list.iterator(), 250000L, 550000L); - RoaringBitmap resultInt = RoaringBitmap.or(list.iterator(), 250000, 550000); + RoaringBitmap result = RoaringBitmap.or(list.iterator(), 250000L, 550000L); + RoaringBitmap resultInt = RoaringBitmap.or(list.iterator(), 250000, 550000); assertEquals(result, resultInt); - assertEquals(250000, result.getCardinality()); + assertEquals(250000, result.getCardinality()); - - // empty ranges get empty result - resultInt = RoaringBitmap.or(list.iterator(), 300000, 200000); - result = RoaringBitmap.or(list.iterator(), 300000L, 200000L); + // empty ranges get empty result + resultInt = RoaringBitmap.or(list.iterator(), 300000, 200000); + result = RoaringBitmap.or(list.iterator(), 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorAndNot() { - RoaringBitmap rb1 = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); + RoaringBitmap rb1 = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full andNOToverlap is on 200000 to 299999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full andNOToverlap is on 200000 to 299999 - RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, 250000L, 450000L); - RoaringBitmap resultInt = RoaringBitmap.andNot(rb1, rb2, 250000, 450000); + RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, 250000L, 450000L); + RoaringBitmap resultInt = RoaringBitmap.andNot(rb1, rb2, 250000, 450000); assertEquals(result, resultInt); - assertEquals(50000, result.getCardinality()); - + assertEquals(50000, result.getCardinality()); - // empty ranges get empty result - resultInt = RoaringBitmap.andNot(rb1, rb2, 300000, 200000); - result = RoaringBitmap.andNot(rb1, rb2, 300000L, 200000L); + // empty ranges get empty result + resultInt = RoaringBitmap.andNot(rb1, rb2, 300000, 200000); + result = RoaringBitmap.andNot(rb1, rb2, 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorXor() { - RoaringBitmap rb1 = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); + RoaringBitmap rb1 = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full XOR is 200000 to 299999, 400000-4999999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full XOR is 200000 to 299999, 400000-4999999 - RoaringBitmap result = RoaringBitmap.xor(list.iterator(), 250000L, 450000L); - RoaringBitmap resultInt = RoaringBitmap.xor(list.iterator(), 250000, 450000); + RoaringBitmap result = RoaringBitmap.xor(list.iterator(), 250000L, 450000L); + RoaringBitmap resultInt = RoaringBitmap.xor(list.iterator(), 250000, 450000); assertEquals(result, resultInt); - assertEquals(100000, result.getCardinality()); + assertEquals(100000, result.getCardinality()); - - // empty ranges get empty result - resultInt = RoaringBitmap.xor(list.iterator(), 300000, 200000); - result = RoaringBitmap.xor(list.iterator(), 300000L, 200000L); + // empty ranges get empty result + resultInt = RoaringBitmap.xor(list.iterator(), 300000, 200000); + result = RoaringBitmap.xor(list.iterator(), 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - - - - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java index a09463834..c9dcb6ada 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRangeCardinality.java @@ -1,5 +1,6 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -7,30 +8,28 @@ import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestRangeCardinality { - public static Stream data() { - return Stream.of( - Arguments.of(new int[]{1, 3, 5, 7, 9}, 3, 8, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 2, 8, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 3, 7, 2), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 0, 7, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 0, 6, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9, Short.MAX_VALUE}, 0, Short.MAX_VALUE + 1, 6), - Arguments.of(new int[]{1, 10000, 25000, Short.MAX_VALUE - 1}, 0, Short.MAX_VALUE, 4), - Arguments.of(new int[]{1 << 3, 1 << 8, 511,512,513, 1 << 12, 1 << 14}, 0, Short.MAX_VALUE, 7) - ); - } + public static Stream data() { + return Stream.of( + Arguments.of(new int[] {1, 3, 5, 7, 9}, 3, 8, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 2, 8, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 3, 7, 2), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 0, 7, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 0, 6, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9, Short.MAX_VALUE}, 0, Short.MAX_VALUE + 1, 6), + Arguments.of(new int[] {1, 10000, 25000, Short.MAX_VALUE - 1}, 0, Short.MAX_VALUE, 4), + Arguments.of( + new int[] {1 << 3, 1 << 8, 511, 512, 513, 1 << 12, 1 << 14}, 0, Short.MAX_VALUE, 7)); + } - @ParameterizedTest - @MethodSource("data") - public void testCardinalityInBitmapWordRange(int[] elements, int begin, int end, int expected) { - BitmapContainer bc = new BitmapContainer(); - for (int e : elements) { - bc.add((char) e); - } - assertEquals(expected, Util.cardinalityInBitmapRange(bc.bitmap, begin, end)); + @ParameterizedTest + @MethodSource("data") + public void testCardinalityInBitmapWordRange(int[] elements, int begin, int end, int expected) { + BitmapContainer bc = new BitmapContainer(); + for (int e : elements) { + bc.add((char) e); } + assertEquals(expected, Util.cardinalityInBitmapRange(bc.bitmap, begin, end)); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIterator.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIterator.java index 3ed4b7990..ab036051a 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIterator.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIterator.java @@ -1,5 +1,10 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.RoaringBitmapWriter.writer; +import static org.roaringbitmap.SeededTestData.randomBitmap; + import com.google.common.collect.Lists; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -14,11 +19,6 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.roaringbitmap.RoaringBitmapWriter.writer; -import static org.roaringbitmap.SeededTestData.randomBitmap; - @Execution(ExecutionMode.CONCURRENT) public class TestRankIterator { @@ -29,8 +29,8 @@ public static Stream parameters() throws CloneNotSupportedException { withFull.add(0L, 262144L); assertTrue(fast.isCacheDismissed()); - return Lists.cartesianProduct(Arrays.asList(fast, withFull), computeAdvances()) - .stream().map(list -> Arguments.of(list.get(0), list.get(1))); + return Lists.cartesianProduct(Arrays.asList(fast, withFull), computeAdvances()).stream() + .map(list -> Arguments.of(list.get(0), list.get(1))); } @ParameterizedTest(name = "{1}") @@ -78,15 +78,15 @@ private void testBitmapRanksOnAdvance(FastRankRoaringBitmap bm, int advance) { private static List computeAdvances() { return IntStream.of(0, 1, 3, 5, 7, 11) - .flatMap(i -> IntStream.range(0, 18).map(j -> i * (1 << j))) - .boxed() - .distinct() - .collect(Collectors.toList()); + .flatMap(i -> IntStream.range(0, 18).map(j -> i * (1 << j))) + .boxed() + .distinct() + .collect(Collectors.toList()); } private static FastRankRoaringBitmap getBitmap() { - FastRankRoaringBitmap bitmap = randomBitmap(50, - writer().fastRank().initialCapacity(50).constantMemory().get()); + FastRankRoaringBitmap bitmap = + randomBitmap(50, writer().fastRank().initialCapacity(50).constantMemory().get()); assertTrue(bitmap.isCacheDismissed()); return bitmap; } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java index 293217364..4212bf52a 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRankIteratorsOfContainers.java @@ -1,13 +1,12 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; import org.junit.jupiter.api.Test; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; - public class TestRankIteratorsOfContainers { private void testContainerRanksOnNext(Container c) { PeekableCharRankIterator iterator = c.getCharRankIterator(); @@ -82,7 +81,7 @@ private void fillRandom(Container container, Random rnd) { container.add((char) (16384 + rnd.nextInt(1 << 10))); } - assertSame(empty, container,"bad test -- container was changed"); + assertSame(empty, container, "bad test -- container was changed"); } private void fillRange(Container container, int begin, int end) { @@ -120,7 +119,6 @@ public void testBitmapContainer3() { testContainerIterators(container); } - @Test public void testBitmapContainer4() { BitmapContainer container = new BitmapContainer(); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java index 40b347b13..a80a48af3 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestReverseIteratorsOfContainers.java @@ -1,21 +1,20 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.common.primitives.Chars; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; -import com.google.common.primitives.Chars; - import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Random; import java.util.function.Function; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestReverseIteratorsOfContainers { @ParameterizedTest @@ -43,7 +42,7 @@ public void testSkips(Converter converter) { pii.next(); assertEquals(data[i], pii.peekNext()); } - container.getCharIterator().advanceIfNeeded((char) -1);// should not crash + container.getCharIterator().advanceIfNeeded((char) -1); // should not crash } @ParameterizedTest @@ -115,7 +114,7 @@ public void testSkipsReverse(Converter converter) { pii.next(); assertEquals(data[i], pii.peekNext()); } - container.getReverseCharIterator().advanceIfNeeded((char) -1);// should not crash + container.getReverseCharIterator().advanceIfNeeded((char) -1); // should not crash } @ParameterizedTest @@ -153,7 +152,6 @@ public void testSkipsRunReverse(Converter converter) { assertEquals(pii.peekNext(), i); assertEquals(pii.next(), i); } - } @ParameterizedTest @@ -178,9 +176,7 @@ private static char[] takeSortedAndDistinct(Random source, int count) { return unboxed; } - static interface Converter extends Function { - - } + static interface Converter extends Function {} static class ArrayContainerConverter implements Converter { @@ -201,7 +197,6 @@ public Container apply(Container container) { public String toString() { return "ArrayContainer"; } - } static class BitmapContainerConverter implements Converter { @@ -219,7 +214,6 @@ public Container apply(Container container) { public String toString() { return "BitmapContainer"; } - } static class RunContainerConverter implements Converter { @@ -241,17 +235,19 @@ public Container apply(Container container) { public String toString() { return "RunContainer"; } - } static class ContainerProvider implements ArgumentsProvider { - Stream streams = Stream.of(new ArrayContainerConverter(), new BitmapContainerConverter(), new RunContainerConverter()); + Stream streams = + Stream.of( + new ArrayContainerConverter(), + new BitmapContainerConverter(), + new RunContainerConverter()); @Override public Stream provideArguments(ExtensionContext context) { return streams.map(f -> Arguments.of(f)); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java index bfff5c652..04f1c544f 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java @@ -3,6 +3,15 @@ */ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.RoaringBitmapWriter.writer; + import com.google.common.base.Predicate; import com.google.common.collect.ContiguousSet; import com.google.common.collect.DiscreteDomain; @@ -15,5576 +24,5860 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.nio.ByteBuffer; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; +import java.util.TreeSet; +import java.util.Vector; import java.util.stream.IntStream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.RoaringBitmapWriter.writer; - /** * Generic testing of the roaring bitmaps */ @SuppressWarnings({"static-method"}) @Execution(ExecutionMode.CONCURRENT) public class TestRoaringBitmap { - @Test - public void intersectBitmapWithRangeHighBits() { - Container[] values = new Container[1]; - RoaringArray ra = new RoaringArray(new char[1], values, 1); - long[] bitmap = new long[1024]; - Arrays.fill(bitmap, 0, 512, 0xAAAAAAAAAAAAAAAAL); - values[0] = new BitmapContainer(bitmap, 512 * Long.bitCount(0xAAAAAAAAAAAAAAAAL)); - RoaringBitmap rr1 = new RoaringBitmap(ra); - assertFalse(rr1.intersects((1 << 15), 0xFFFF)); - } - - @Test - public void testRangeCardinality() { - RoaringBitmap r = new RoaringBitmap(); - long Min = 0L; - long Max = 1000000L; - r.add(Min, Max); - for (long s = Min; s <= Max; s += 100) { - for (long e = s; e <= Max; e += 100) { - assertEquals(e - s, r.rangeCardinality(s, e)); - } - } + @Test + public void intersectBitmapWithRangeHighBits() { + Container[] values = new Container[1]; + RoaringArray ra = new RoaringArray(new char[1], values, 1); + long[] bitmap = new long[1024]; + Arrays.fill(bitmap, 0, 512, 0xAAAAAAAAAAAAAAAAL); + values[0] = new BitmapContainer(bitmap, 512 * Long.bitCount(0xAAAAAAAAAAAAAAAAL)); + RoaringBitmap rr1 = new RoaringBitmap(ra); + assertFalse(rr1.intersects((1 << 15), 0xFFFF)); + } + + @Test + public void testRangeCardinality() { + RoaringBitmap r = new RoaringBitmap(); + long Min = 0L; + long Max = 1000000L; + r.add(Min, Max); + for (long s = Min; s <= Max; s += 100) { + for (long e = s; e <= Max; e += 100) { + assertEquals(e - s, r.rangeCardinality(s, e)); + } + } + } + + @Test + public void testRangeCardinality2() { + RoaringBitmap r = new RoaringBitmap(); + long Min = 1L << 16; + long Max = 1L << 18; + r.add(Min, Max); + for (long s = Min; s <= Max; s += 1024) { + for (long e = s; e <= Max; e += 1024) { + assertEquals(e - s, r.rangeCardinality(s, e)); + } + } + } + + @Test + public void testMultipleAdd() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(1); + bitmap.add(1, 2, 3); + bitmap.add(0xFFFFFFFF); + bitmap.add(0xFFFFFFFEL, 0xFFFFFFFFL); + assertEquals("{1,2,3,4294967294,4294967295}", bitmap.toString()); + } + + @Test + public void testAddN() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.addN(new int[] {1, 2, 3, 4, 5}, 1, 3); + assertEquals("{2,3,4}", bitmap.toString()); + } + + @Test + public void testStringer() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(1); + bitmap.add(2); + bitmap.add(3); + bitmap.add(0xFFFFFFFF); + assertEquals("{1,2,3,4294967295}", bitmap.toString()); + } + + @Test + public void report128() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(59798854); + bitmap.add(91274955); + bitmap.add(97569495); + bitmap.add(101993170); + PeekableIntIterator it = bitmap.getIntIterator(); + it.advanceIfNeeded(100620278); + assertTrue(it.hasNext()); + assertEquals(101993170, it.next()); + assertFalse(it.hasNext()); + } + + @Test + public void report128_fly() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(59798854); + bitmap.add(91274955); + bitmap.add(97569495); + bitmap.add(101993170); + IntIteratorFlyweight it = new IntIteratorFlyweight(); + it.wrap(bitmap); + it.advanceIfNeeded(100620278); + assertTrue(it.hasNext()); + assertEquals(101993170, it.next()); + assertFalse(it.hasNext()); + } + + @Test + public void limitBug2() { + class MyConsumer implements IntConsumer { + public int count = 0; + + @Override + public void accept(int value) { + count++; + } + } + + RoaringBitmap r = new RoaringBitmap(); + int count = 0; + for (int i = 0; i < 500; i++) { + for (int j = 0; j < 9943; j++) { + if (i % 2 == 0) r.add(count); + count++; + } + } + RoaringBitmap limited = r.limit(1000000); + assertEquals(1000000, limited.getCardinality()); + MyConsumer c = new MyConsumer(); + limited.forEach(c); + assertEquals(1000000, c.count); + assertEquals(1000000, limited.toArray().length); + } + + @Test + public void limitTest() { + RoaringBitmap r = new RoaringBitmap(); + r.add(0l, 10000000l); + assertEquals(1, r.limit(1).getCardinality()); + assertEquals(10, r.limit(10).getCardinality()); + assertEquals(100, r.limit(100).getCardinality()); + assertEquals(1000, r.limit(1000).getCardinality()); + assertEquals(10000, r.limit(10000).getCardinality()); + assertEquals(100000, r.limit(100000).getCardinality()); + assertEquals(1000000, r.limit(1000000).getCardinality()); + } + + @Test + public void pointerContainerTest() { + RoaringBitmap rb = new RoaringBitmap(); + for (int i = 0; i < (1 << 16); i += 2) { + rb.add(i); + } + for (int i = (1 << 16); i < 2 * ((1 << 16)); i += 512) { + rb.add(i); + } + for (int i = 2 * (1 << 16); i < 3 * ((1 << 16)); i++) { + rb.add(i); + } + rb.runOptimize(); + ContainerPointer cp = rb.getContainerPointer(); + ContainerPointer cpo = (ContainerPointer) cp.clone(); + assertNotEquals(cp.getContainer(), null); + assertNotEquals(cpo.getContainer(), null); + + assertEquals(cp.compareTo(cpo), 0); + + assertEquals(cp.getCardinality(), (1 << 16) / 2); + assertTrue(cp.isBitmapContainer()); + assertFalse(cp.isRunContainer()); + + cp.advance(); + assertTrue(cp.compareTo(cpo) > 0); + assertNotEquals(cp.getContainer(), null); + assertEquals(cp.getCardinality(), (1 << 16) / 512); + assertFalse(cp.isBitmapContainer()); + assertFalse(cp.isRunContainer()); + + cp.advance(); + assertTrue(cp.compareTo(cpo) > 0); + assertNotEquals(cp.getContainer(), null); + assertEquals(cp.getCardinality(), (1 << 16)); + assertFalse(cp.isBitmapContainer()); + assertTrue(cp.isRunContainer()); + + cpo.advance(); + assertTrue(cp.compareTo(cpo) > 0); + cpo.advance(); + assertEquals(0, cp.compareTo(cpo)); + + cp.advance(); + + assertNull(cp.getContainer()); + } + + public static int[][] randomlists = { + { + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, + 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, + 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, + 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, + 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, + 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, + 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, + 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, + 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, + 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, + 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, + 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, + 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, + 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, + 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, + 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, + 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, + 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, + 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, + 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, + 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, + 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, + 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, + 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, + 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, + 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, + 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, + 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, + 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, + 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, + 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, + 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, + 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, + 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, + 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, + 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, + 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, + 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, + 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, + 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, + 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, + 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, + 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, + 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, + 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, + 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, + 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, + 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, + 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, + 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, + 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, + 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, + 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, + 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, + 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, + 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, + 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, + 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, + 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, + 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, + 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, + 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, + 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, + 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, + 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, + 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, + 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, + 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, + 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, + 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, + 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, + 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, + 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, + 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, + 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, + 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, + 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, + 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, + 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, + 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, + 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, + 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, + 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, + 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, + 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, + 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, + 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, + 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, + 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, + 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, + 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, + 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, + 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, + 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, + 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, + 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, + 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, + 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, + 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, + 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, + 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, + 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, + 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, + 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, + 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, + 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, + 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, + 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, + 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, + 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, + 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, + 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, + 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, + 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, + 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, + 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 2423, 2424, + 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, + 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, + 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, + 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, + 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, + 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, + 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528, 2529, + 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, + 2545, 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, + 2560, 2561, 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, + 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587, 2588, 2589, + 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, 2604, + 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, + 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, + 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, + 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, + 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678, 2679, + 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, + 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, + 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, + 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 2739, + 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, + 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, + 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, + 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, + 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, + 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, + 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, + 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, + 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, + 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 2889, + 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, + 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, + 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, + 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, + 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964, + 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, + 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, + 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, + 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, + 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, + 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, + 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, + 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, 3079, 3080, 3081, 3082, 3083, 3084, + 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096, 3097, 3098, 3099, + 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, 3114, + 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, + 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, + 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, + 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, + 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, + 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, + 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, + 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, + 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248, 3249, + 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, + 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, + 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, + 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309, + 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, + 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, + 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, + 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368, 3369, + 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, + 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, + 3400, 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, + 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, + 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, + 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, + 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, + 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488, 3489, + 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, + 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, + 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534, + 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, + 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564, + 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, + 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, + 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, + 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, + 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, + 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, + 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, + 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 3684, + 3685, 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, + 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713, 3714, + 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, + 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, + 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, + 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, + 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, + 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, + 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, + 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, + 3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, + 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, + 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, + 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, + 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, + 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 3924, + 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, + 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951, 3952, 3953, 3954, + 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, + 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, + 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, + 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4014, + 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, 4029, + 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, + 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, + 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, + 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, + 4090, 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, 4100, 4101, 4102, 4103, 4104, + 4105, 4106, 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4117, 4118, 4119, + 4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, + 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, + 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, 4161, 4162, 4163, 4164, + 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4175, 4176, 4177, 4178, 4179, + 4180, 4181, 4182, 4183, 4184, 4185, 4186, 4187, 4188, 4189, 4190, 4191, 4192, 4193, 4194, + 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, + 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218, 4219, 4220, 4221, 4222, 4223, 4224, + 4225, 4226, 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, + 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, 4253, 4254, + 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, + 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, + 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4293, 4294, 4295, 4296, 4297, 4298, 4299, + 4300, 4301, 4302, 4303, 4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314, + 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, + 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, + 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, 4355, 4356, 4357, 4358, 4359, + 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371, 4372, 4373, 4374, + 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, + 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4401, 4402, 4403, 4404, + 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4418, 4419, + 4420, 4421, 4422, 4423, 4424, 4425, 4426, 4427, 4428, 4429, 4430, 4431, 4432, 4433, 4434, + 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442, 4443, 4444, 4445, 4446, 4447, 4448, 4449, + 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464, + 4465, 4466, 4467, 4468, 4469, 4470, 4471, 4472, 4473, 4474, 4475, 4476, 4477, 4478, 4479, + 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493, 4494, + 4495, 4496, 4497, 4498, 4499, 4500, 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4521, 4522, 4523, 4524, + 4525, 4526, 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, 4535, 4536, 4537, 4538, 4539, + 4540, 4541, 4542, 4543, 4544, 4545, 4546, 4547, 4548, 4549, 4550, 4551, 4552, 4553, 4554, + 4555, 4556, 4557, 4558, 4559, 4560, 4561, 4562, 4563, 4564, 4565, 4566, 4567, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 4575, 4576, 4577, 4578, 4579, 4580, 4581, 4582, 4583, 4584, + 4585, 4586, 4587, 4588, 4589, 4590, 4591, 4592, 4593, 4594, 4595, 4596, 4597, 4598, 4599, + 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, 4609, 4610, 4611, 4612, 4613, 4614, + 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, 4628, 4629, + 4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, + 4645, 4646, 4647, 4648, 4649, 4650, 4651, 4652, 4653, 4654, 4655, 4656, 4657, 4658, 4659, + 4660, 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, + 4675, 4676, 4677, 4678, 4679, 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 4689, + 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, 4704, + 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, + 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4731, 4732, 4733, 4734, + 4735, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, + 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, 4759, 4760, 4761, 4762, 4763, 4764, + 4765, 4766, 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, 4776, 4777, 4778, 4779, + 4780, 4781, 4782, 4783, 4784, 4785, 4786, 4787, 4788, 4789, 4790, 4791, 4792, 4793, 4794, + 4795, 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, + 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, 4818, 4819, 4820, 4821, 4822, 4823, 4824, + 4825, 4826, 4827, 4828, 4829, 4830, 4831, 4832, 4833, 4834, 4835, 4836, 4837, 4838, 4839, + 4840, 4841, 4842, 4843, 4844, 4845, 4846, 4847, 4848, 4849, 4850, 4851, 4852, 4853, 4854, + 4855, 4856, 4857, 4858, 4859, 4860, 4861, 4862, 4863, 4864, 4865, 4866, 4867, 4868, 4869, + 4870, 4871, 4872, 4873, 4874, 4875, 4876, 4877, 4878, 4879, 4880, 4881, 4882, 4883, 4884, + 4885, 4886, 4887, 4888, 4889, 4890, 4891, 4892, 4893, 4894, 4895, 4896, 4897, 4898, 4899, + 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, + 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 4925, 4926, 4927, 4928, 4929, + 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, + 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, + 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, + 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985, 4986, 4987, 4988, 4989, + 4990, 4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998, 4999, 5000, 5001, 5002, 5003, 5004, + 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5020, 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034, + 5035, 5036, 5037, 5038, 5039, 5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, 5048, 5049, + 5050, 5051, 5052, 5053, 5054, 5055, 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5074, 5075, 5076, 5077, 5078, 5079, + 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, 5089, 5090, 5091, 5092, 5093, 5094, + 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108, 5109, + 5110, 5111, 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, 5120, 5121, 5122, 5123, 5124, + 5125, 5126, 5127, 5128, 5129, 5130, 5131, 5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139, + 5140, 5141, 5142, 5143, 5144, 5145, 5146, 5147, 5148, 5149, 5150, 5151, 5152, 5153, 5154, + 5155, 5156, 5157, 5158, 5159, 5160, 5161, 5162, 5163, 5164, 5165, 5166, 5167, 5168, 5169, + 5170, 5171, 5172, 5173, 5174, 5175, 5176, 5177, 5178, 5179, 5180, 5181, 5182, 5183, 5184, + 5185, 5186, 5187, 5188, 5189, 5190, 5191, 5192, 5193, 5194, 5195, 5196, 5197, 5198, 5199, + 5200, 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, 5209, 5210, 5211, 5212, 5213, 5214, + 5215, 5216, 5217, 5218, 5219, 5220, 5221, 5222, 5223, 5224, 5225, 5226, 5227, 5228, 5229, + 5230, 5231, 5232, 5233, 5234, 5235, 5236, 5237, 5238, 5239, 5240, 5241, 5242, 5243, 5244, + 5245, 5246, 5247, 5248, 5249, 5250, 5251, 5252, 5253, 5254, 5255, 5256, 5257, 5258, 5259, + 5260, 5261, 5262, 5263, 5264, 5265, 5266, 5267, 5268, 5269, 5270, 5271, 5272, 5273, 5274, + 5275, 5276, 5277, 5278, 5279, 5280, 5281, 5282, 5283, 5284, 5285, 5286, 5287, 5288, 5289, + 5290, 5291, 5292, 5293, 5294, 5295, 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303, 5304, + 5305, 5306, 5307, 5308, 5309, 5310, 5311, 5312, 5313, 5314, 5315, 5316, 5317, 5318, 5319, + 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, 5328, 5329, 5330, 5331, 5332, 5333, 5334, + 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 5349, + 5350, 5351, 5352, 5353, 5354, 5355, 5356, 5357, 5358, 5359, 5360, 5361, 5362, 5363, 5364, + 5365, 5366, 5367, 5368, 5369, 5370, 5371, 5372, 5373, 5374, 5375, 5376, 5377, 5378, 5379, + 5380, 5381, 5382, 5383, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 5391, 5392, 5393, 5394, + 5395, 5396, 5397, 5398, 5399, 5400, 5401, 5402, 5403, 5404, 5405, 5406, 5407, 5408, 5409, + 5410, 5411, 5412, 5413, 5414, 5415, 5416, 5417, 5418, 5419, 5420, 5421, 5422, 5423, 5424, + 5425, 5426, 5427, 5428, 5429, 5430, 5431, 5432, 5433, 5434, 5435, 5436, 5437, 5438, 5439, + 5440, 5441, 5442, 5443, 5444, 5445, 5446, 5447, 5448, 5449, 5450, 5451, 5452, 5453, 5454, + 5455, 5456, 5457, 5458, 5459, 5460, 5461, 5462, 5463, 5464, 5465, 5466, 5467, 5468, 5469, + 5470, 5471, 5472, 5473, 5474, 5475, 5476, 5477, 5478, 5479, 5480, 5481, 5482, 5483, 5484, + 5485, 5486, 5487, 5488, 5489, 5490, 5491, 5492, 5493, 5494, 5495, 5496, 5497, 5498, 5499, + 5500, 5501, 5502, 5503, 5504, 5505, 5506, 5507, 5508, 5509, 5510, 5511, 5512, 5513, 5514, + 5515, 5516, 5517, 5518, 5519, 5520, 5521, 5522, 5523, 5524, 5525, 5526, 5527, 5528, 5529, + 5530, 5531, 5532, 5533, 5534, 5535, 5536, 5537, 5538, 5539, 5540, 5541, 5542, 5543, 5544, + 5545, 5546, 5547, 5548, 5549, 5550, 5551, 5552, 5553, 5554, 5555, 5556, 5557, 5558, 5559, + 5560, 5561, 5562, 5563, 5564, 5565, 5566, 5567, 5568, 5569, 5570, 5571, 5572, 5573, 5574, + 5575, 5576, 5577, 5578, 5579, 5580, 5581, 5582, 5583, 5584, 5585, 5586, 5587, 5588, 5589, + 5590, 5591, 5592, 5593, 5594, 5595, 5596, 5597, 5598, 5599, 5600, 5601, 5602, 5603, 5604, + 5605, 5606, 5607, 5608, 5609, 5610, 5611, 5612, 5613, 5614, 5615, 5616, 5617, 5618, 5619, + 5620, 5621, 5622, 5623, 5624, 5625, 5626, 5627, 5628, 5629, 5630, 5631, 5632, 5633, 5634, + 5635, 5636, 5637, 5638, 5639, 5640, 5641, 5642, 5643, 5644, 5645, 5646, 5647, 5648, 5649, + 5650, 5651, 5652, 5653, 5654, 5655, 5656, 5657, 5658, 5659, 5660, 5661, 5662, 5663, 5664, + 5665, 5666, 5667, 5668, 5669, 5670, 5671, 5672, 5673, 5674, 5675, 5676, 5677, 5678, 5679, + 5680, 5681, 5682, 5683, 5684, 5685, 5686, 5687, 5688, 5689, 5690, 5691, 5692, 5693, 5694, + 5695, 5696, 5697, 5698, 5699, 5700, 5701, 5702, 5703, 5704, 5705, 5706, 5707, 5708, 5709, + 5710, 5711, 5712, 5713, 5714, 5715, 5716, 5717, 5718, 5719, 5720, 5721, 5722, 5723, 5724, + 5725, 5726, 5727, 5728, 5729, 5730, 5731, 5732, 5733, 5734, 5735, 5736, 5737, 5738, 5739, + 5740, 5741, 5742, 5743, 5744, 5745, 5746, 5747, 5748, 5749, 5750, 5751, 5752, 5753, 5754, + 5755, 5756, 5757, 5758, 5759, 5760, 5761, 5762, 5763, 5764, 5765, 5766, 5767, 5768, 5769, + 5770, 5771, 5772, 5773, 5774, 5775, 5776, 5777, 5778, 5779, 5780, 5781, 5782, 5783, 5784, + 5785, 5786, 5787, 5788, 5789, 5790, 5791, 5792, 5793, 5794, 5795, 5796, 5797, 5798, 5799, + 5800, 5801, 5802, 5803, 5804, 5805, 5806, 5807, 5808, 5809, 5810, 5811, 5812, 5813, 5814, + 5815, 5816, 5817, 5818, 5819, 5820, 5821, 5822, 5823, 5824, 5825, 5826, 5827, 5828, 5829, + 5830, 5831, 5832, 5833, 5834, 5835, 5836, 5837, 5838, 5839, 5840, 5841, 5842, 5843, 5844, + 5845, 5846, 5847, 5848, 5849, 5850, 5851, 5852, 5853, 5854, 5855, 5856, 5857, 5858, 5859, + 5860, 5861, 5862, 5863, 5864, 5865, 5866, 5867, 5868, 5869, 5870, 5871, 5872, 5873, 5874, + 5875, 5876, 5877, 5878, 5879, 5880, 5881, 5882, 5883, 5884, 5885, 5886, 5887, 5888, 5889, + 5890, 5891, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5900, 5901, 5902, 5903, 5904, + 5905, 5906, 5907, 5908, 5909, 5910, 5911, 5912, 5913, 5914, 5915, 5916, 5917, 5918, 5919, + 5920, 5921, 5922, 5923, 5924, 5925, 5926, 5927, 5928, 5929, 5930, 5931, 5932, 5933, 5934, + 5935, 5936, 5937, 5938, 5939, 5940, 5941, 5942, 5943, 5944, 5945, 5946, 5947, 5948, 5949, + 5950, 5951, 5952, 5953, 5954, 5955, 5956, 5957, 5958, 5959, 5960, 5961, 5962, 5963, 5964, + 5965, 5966, 5967, 5968, 5969, 5970, 5971, 5972, 5973, 5974, 5975, 5976, 5977, 5978, 5979, + 5980, 5981, 5982, 5983, 5984, 5985, 5986, 5987, 5988, 5989, 5990, 5991, 5992, 5993, 5994, + 5995, 5996, 5997, 5998, 5999, 6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009, + 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, + 6025, 6026, 6027, 6028, 6029, 6030, 6031, 6032, 6033, 6034, 6035, 6036, 6037, 6038, 6039, + 6040, 6041, 6042, 6043, 6044, 6045, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6053, 6054, + 6055, 6056, 6057, 6058, 6059, 6060, 6061, 6062, 6063, 6064, 6065, 6066, 6067, 6068, 6069, + 6070, 6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 6079, 6080, 6081, 6082, 6083, 6084, + 6085, 6086, 6087, 6088, 6089, 6090, 6091, 6092, 6093, 6094, 6095, 6096, 6097, 6098, 6099, + 6100, 6101, 6102, 6103, 6104, 6105, 6106, 6107, 6108, 6109, 6110, 6111, 6112, 6113, 6114, + 6115, 6116, 6117, 6118, 6119, 6120, 6121, 6122, 6123, 6124, 6125, 6126, 6127, 6128, 6129, + 6130, 6131, 6132, 6133, 6134, 6135, 6136, 6137, 6138, 6139, 6140, 6141, 6142, 6143, 6144, + 6145, 6146, 6147, 6148, 6149, 6150, 6151, 6152, 6153, 6154, 6155, 6156, 6157, 6158, 6159, + 6160, 6161, 6162, 6163, 6164, 6165, 6166, 6167, 6168, 6169, 6170, 6171, 6172, 6173, 6174, + 6175, 6176, 6177, 6178, 6179, 6180, 6181, 6182, 6183, 6184, 6185, 6186, 6187, 6188, 6189, + 6190, 6191, 6192, 6193, 6194, 6195, 6196, 6197, 6198, 6199, 6200, 6201, 6202, 6203, 6204, + 6205, 6206, 6207, 6208, 6209, 6210, 6211, 6212, 6213, 6214, 6215, 6216, 6217, 6218, 6219, + 6220, 6221, 6222, 6223, 6224, 6225, 6226, 6227, 6228, 6229, 6230, 6231, 6232, 6233, 6234, + 6235, 6236, 6237, 6238, 6239, 6240, 6241, 6242, 6243, 6244, 6245, 6246, 6247, 6248, 6249, + 6250, 6251, 6252, 6253, 6254, 6255, 6256, 6257, 6258, 6259, 6260, 6261, 6262, 6263, 6264, + 6265, 6266, 6267, 6268, 6269, 6270, 6271, 6272, 6273, 6274, 6275, 6276, 6277, 6278, 6279, + 6280, 6281, 6282, 6283, 6284, 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, + 6295, 6296, 6297, 6298, 6299, 6300, 6301, 6302, 6303, 6304, 6305, 6306, 6307, 6308, 6309, + 6310, 6311, 6312, 6313, 6314, 6315, 6316, 6317, 6318, 6319, 6320, 6321, 6322, 6323, 6324, + 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, 6333, 6334, 6335, 6336, 6337, 6338, 6339, + 6340, 6341, 6342, 6343, 6344, 6345, 6346, 6347, 6348, 6349, 6350, 6351, 6352, 6353, 6354, + 6355, 6356, 6357, 6358, 6359, 6360, 6361, 6362, 6363, 6364, 6365, 6366, 6367, 6368, 6369, + 6370, 6371, 6372, 6373, 6374, 6375, 6376, 6377, 6378, 6379, 6380, 6381, 6382, 6383, 6384, + 6385, 6386, 6387, 6388, 6389, 6390, 6391, 6392, 6393, 6394, 6395, 6396, 6397, 6398, 6399, + 6400, 6401, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, 6410, 6411, 6412, 6413, 6414, + 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, 6423, 6424, 6425, 6426, 6427, 6428, 6429, + 6430, 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6444, + 6445, 6446, 6447, 6448, 6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, + 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, 6468, 6469, 6470, 6471, 6472, 6473, 6474, + 6475, 6476, 6477, 6478, 6479, 6480, 6481, 6482, 6483, 6484, 6485, 6486, 6487, 6488, 6489, + 6490, 6491, 6492, 6493, 6494, 6495, 6496, 6497, 6498, 6499, 6500, 6501, 6502, 6503, 6504, + 6505, 6506, 6507, 6508, 6509, 6510, 6511, 6512, 6513, 6514, 6515, 6516, 6517, 6518, 6519, + 6520, 6521, 6522, 6523, 6524, 6525, 6526, 6527, 6528, 6529, 6530, 6531, 6532, 6533, 6534, + 6535, 6536, 6537, 6538, 6539, 6540, 6541, 6542, 6543, 6544, 6545, 6546, 6547, 6548, 6549, + 6550, 6551, 6552, 6553, 6554, 6555, 6556, 6557, 6558, 6559, 6560, 6561, 6562, 6563, 6564, + 6565, 6566, 6567, 6568, 6569, 6570, 6571, 6572, 6573, 6574, 6575, 6576, 6577, 6578, 6579, + 6580, 6581, 6582, 6583, 6584, 6585, 6586, 6587, 6588, 6589, 6590, 6591, 6592, 6593, 6594, + 6595, 6596, 6597, 6598, 6599, 6600, 6601, 6602, 6603, 6604, 6605, 6606, 6607, 6608, 6609, + 6610, 6611, 6612, 6613, 6614, 6615, 6616, 6617, 6618, 6619, 6620, 6621, 6622, 6623, 6624, + 6625, 6626, 6627, 6628, 6629, 6630, 6631, 6632, 6633, 6634, 6635, 6636, 6637, 6638, 6639, + 6640, 6641, 6642, 6643, 6644, 6645, 6646, 6647, 6648, 6649, 6650, 6651, 6652, 6653, 6654, + 6655, 6656, 6657, 6658, 6659, 6660, 6661, 6662, 6663, 6664, 6665, 6666, 6667, 6668, 6669, + 6670, 6671, 6672, 6673, 6674, 6675, 6676, 6677, 6678, 6679, 6680, 6681, 6682, 6683, 6684, + 6685, 6686, 6687, 6688, 6689, 6690, 6691, 6692, 6693, 6694, 6695, 6696, 6697, 6698, 6699, + 6700, 6701, 6702, 6703, 6704, 6705, 6706, 6707, 6708, 6709, 6710, 6711, 6712, 6713, 6714, + 6715, 6716, 6717, 6718, 6719, 6720, 6721, 6722, 6723, 6724, 6725, 6726, 6727, 6728, 6729, + 6730, 6731, 6732, 6733, 6734, 6735, 6736, 6737, 6738, 6739, 6740, 6741, 6742, 6743, 6744, + 6745, 6746, 6747, 6748, 6749, 6750, 6751, 6752, 6753, 6754, 6755, 6756, 6757, 6758, 6759, + 6760, 6761, 6762, 6763, 6764, 6765, 6766, 6767, 6768, 6769, 6770, 6771, 6772, 6773, 6774, + 6775, 6776, 6777, 6778, 6779, 6780, 6781, 6782, 6783, 6784, 6785, 6786, 6787, 6788, 6789, + 6790, 6791, 6792, 6793, 6794, 6795, 6796, 6797, 6798, 6799, 6800, 6801, 6802, 6803, 6804, + 6805, 6806, 6807, 6808, 6809, 6810, 6811, 6812, 6813, 6814, 6815, 6816, 6817, 6818, 6819, + 6820, 6821, 6822, 6823, 6824, 6825, 6826, 6827, 6828, 6829, 6830, 6831, 6832, 6833, 6834, + 6835, 6836, 6837, 6838, 6839, 6840, 6841, 6842, 6843, 6844, 6845, 6846, 6847, 6848, 6849, + 6850, 6851, 6852, 6853, 6854, 6855, 6856, 6857, 6858, 6859, 6860, 6861, 6862, 6863, 6864, + 6865, 6866, 6867, 6868, 6869, 6870, 6871, 6872, 6873, 6874, 6875, 6876, 6877, 6878, 6879, + 6880, 6881, 6882, 6883, 6884, 6885, 6886, 6887, 6888, 6889, 6890, 6891, 6892, 6893, 6894, + 6895, 6896, 6897, 6898, 6899, 6900, 6901, 6902, 6903, 6904, 6905, 6906, 6907, 6908, 6909, + 6910, 6911, 6912, 6913, 6914, 6915, 6916, 6917, 6918, 6919, 6920, 6921, 6922, 6923, 6924, + 6925, 6926, 6927, 6928, 6929, 6930, 6931, 6932, 6933, 6934, 6935, 6936, 6937, 6938, 6939, + 6940, 6941, 6942, 6943, 6944, 6945, 6946, 6947, 6948, 6949, 6950, 6951, 6952, 6953, 6954, + 6955, 6956, 6957, 6958, 6959, 6960, 6961, 6962, 6963, 6964, 6965, 6966, 6967, 6968, 6969, + 6970, 6971, 6972, 6973, 6974, 6975, 6976, 6977, 6978, 6979, 6980, 6981, 6982, 6983, 6984, + 6985, 6986, 6987, 6988, 6989, 6990, 6991, 6992, 6993, 6994, 6995, 6996, 6997, 6998, 6999, + 7000, 7001, 7002, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7011, 7012, 7013, 7014, + 7015, 7016, 7017, 7018, 7019, 7020, 7021, 7022, 7023, 7024, 7025, 7026, 7027, 7028, 7029, + 7030, 7031, 7032, 7033, 7034, 7035, 7036, 7037, 7038, 7039, 7040, 7041, 7042, 7043, 7044, + 7045, 7046, 7047, 7048, 7049, 7050, 7051, 7052, 7053, 7054, 7055, 7056, 7057, 7058, 7059, + 7060, 7061, 7062, 7063, 7064, 7065, 7066, 7067, 7068, 7069, 7070, 7071, 7072, 7073, 7074, + 7075, 7076, 7077, 7078, 7079, 7080, 7081, 7082, 7083, 7084, 7085, 7086, 7087, 7088, 7089, + 7090, 7091, 7092, 7093, 7094, 7095, 7096, 7097, 7098, 7099, 7100, 7101, 7102, 7103, 7104, + 7105, 7106, 7107, 7108, 7109, 7110, 7111, 7112, 7113, 7114, 7115, 7116, 7117, 7118, 7119, + 7120, 7121, 7122, 7123, 7124, 7125, 7126, 7127, 7128, 7129, 7130, 7131, 7132, 7133, 7134, + 7135, 7136, 7137, 7138, 7139, 7140, 7141, 7142, 7143, 7144, 7145, 7146, 7147, 7148, 7149, + 7150, 7151, 7152, 7153, 7154, 7155, 7156, 7157, 7158, 7159, 7160, 7161, 7162, 7163, 7164, + 7165, 7166, 7167, 7168, 7169, 7170, 7171, 7172, 7173, 7174, 7175, 7176, 7177, 7178, 7179, + 7180, 7181, 7182, 7183, 7184, 7185, 7186, 7187, 7188, 7189, 7190, 7191, 7192, 7193, 7194, + 7195, 7196, 7197, 7198, 7199, 7200, 7201, 7202, 7203, 7204, 7205, 7206, 7207, 7208, 7209, + 7210, 7211, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, 7220, 7221, 7222, 7223, 7224, + 7225, 7226, 7227, 7228, 7229, 7230, 7231, 7232, 7233, 7234, 7235, 7236, 7237, 7238, 7239, + 7240, 7241, 7242, 7243, 7244, 7245, 7246, 7247, 7248, 7249, 7250, 7251, 7252, 7253, 7254, + 7255, 7256, 7257, 7258, 7259, 7260, 7261, 7262, 7263, 7264, 7265, 7266, 7267, 7268, 7269, + 7270, 7271, 7272, 7273, 7274, 7275, 7276, 7277, 7278, 7279, 7280, 7281, 7282, 7283, 7284, + 7285, 7286, 7287, 7288, 7289, 7290, 7291, 7292, 7293, 7294, 7295, 7296, 7297, 7298, 7299, + 7300, 7301, 7302, 7303, 7304, 7305, 7306, 7307, 7308, 7309, 7310, 7311, 7312, 7313, 7314, + 7315, 7316, 7317, 7318, 7319, 7320, 7321, 7322, 7323, 7324, 7325, 7326, 7327, 7328, 7329, + 7330, 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, 7340, 7341, 7342, 7343, 7344, + 7345, 7346, 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, 7355, 7356, 7357, 7358, 7359, + 7360, 7361, 7362, 7363, 7364, 7365, 7366, 7367, 7368, 7369, 7370, 7371, 7372, 7373, 7374, + 7375, 7376, 7377, 7378, 7379, 7380, 7381, 7382, 7383, 7384, 7385, 7386, 7387, 7388, 7389, + 7390, 7391, 7392, 7393, 7394, 7395, 7396, 7397, 7398, 7399, 7400, 7401, 7402, 7403, 7404, + 7405, 7406, 7407, 7408, 7409, 7410, 7411, 7412, 7413, 7414, 7415, 7416, 7417, 7418, 7419, + 7420, 7421, 7422, 7423, 7424, 7425, 7426, 7427, 7428, 7429, 7430, 7431, 7432, 7433, 7434, + 7435, 7436, 7437, 7438, 7439, 7440, 7441, 7442, 7443, 7444, 7445, 7446, 7447, 7448, 7449, + 7450, 7451, 7452, 7453, 7454, 7455, 7456, 7457, 7458, 7459, 7460, 7461, 7462, 7463, 7464, + 7465, 7466, 7467, 7468, 7469, 7470, 7471, 7472, 7473, 7474, 7475, 7476, 7477, 7478, 7479, + 7480, 7481, 7482, 7483, 7484, 7485, 7486, 7487, 7488, 7489, 7490, 7491, 7492, 7493, 7494, + 7495, 7496, 7497, 7498, 7499, 7500, 7501, 7502, 7503, 7504, 7505, 7506, 7507, 7508, 7509, + 7510, 7511, 7512, 7513, 7514, 7515, 7516, 7517, 7518, 7519, 7520, 7521, 7522, 7523, 7524, + 7525, 7526, 7527, 7528, 7529, 7530, 7531, 7532, 7533, 7534, 7535, 7536, 7537, 7538, 7539, + 7540, 7541, 7542, 7543, 7544, 7545, 7546, 7547, 7548, 7549, 7550, 7551, 7552, 7553, 7554, + 7555, 7556, 7557, 7558, 7559, 7560, 7561, 7562, 7563, 7564, 7565, 7566, 7567, 7568, 7569, + 7570, 7571, 7572, 7573, 7574, 7575, 7576, 7577, 7578, 7579, 7580, 7581, 7582, 7583, 7584, + 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7592, 7593, 7594, 7595, 7596, 7597, 7598, 7599, + 7600, 7601, 7602, 7603, 7604, 7605, 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, + 7615, 7616, 7617, 7618, 7619, 7620, 7621, 7622, 7623, 7624, 7625, 7626, 7627, 7628, 7629, + 7630, 7631, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, 7643, 7644, + 7645, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7654, 7655, 7656, 7657, 7658, 7659, + 7660, 7661, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, + 7675, 7676, 7677, 7678, 7679, 7680, 7681, 7682, 7683, 7684, 7685, 7686, 7687, 7688, 7689, + 7690, 7691, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7702, 7703, 7704, + 7705, 7706, 7707, 7708, 7709, 7710, 7711, 7712, 7713, 7714, 7715, 7716, 7717, 7718, 7719, + 7720, 7721, 7722, 7723, 7724, 7725, 7726, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, + 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7743, 7744, 7745, 7746, 7747, 7748, 7749, + 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, + 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7772, 7773, 7774, 7775, 7776, 7777, 7778, 7779, + 7780, 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7788, 7789, 7790, 7791, 7792, 7793, 7794, + 7795, 7796, 7797, 7798, 7799, 7800, 7801, 7802, 7803, 7804, 7805, 7806, 7807, 7808, 7809, + 7810, 7811, 7812, 7813, 7814, 7815, 7816, 7817, 7818, 7819, 7820, 7821, 7822, 7823, 7824, + 7825, 7826, 7827, 7828, 7829, 7830, 7831, 7832, 7833, 7834, 7835, 7836, 7837, 7838, 7839, + 7840, 7841, 7842, 7843, 7844, 7845, 7846, 7847, 7848, 7849, 7850, 7851, 7852, 7853, 7854, + 7855, 7856, 7857, 7858, 7859, 7860, 7861, 7862, 7863, 7864, 7865, 7866, 7867, 7868, 7869, + 7870, 7871, 7872, 7873, 7874, 7875, 7876, 7877, 7878, 7879, 7880, 7881, 7882, 7883, 7884, + 7885, 7886, 7887, 7888, 7889, 7890, 7891, 7892, 7893, 7894, 7895, 7896, 7897, 7898, 7899, + 7900, 7901, 7902, 7903, 7904, 7905, 7906, 7907, 7908, 7909, 7910, 7911, 7912, 7913, 7914, + 7915, 7916, 7917, 7918, 7919, 7920, 7921, 7922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, + 7930, 7931, 7932, 7933, 7934, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, + 7945, 7946, 7947, 7948, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7958, 7959, + 7960, 7961, 7962, 7963, 7964, 7965, 7966, 7967, 7968, 7969, 7970, 7971, 7972, 7973, 7974, + 7975, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, + 7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999 + }, + { + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126 + } + }; + + public static boolean equals(BitSet bs, RoaringBitmap rr) { + final int[] a = new int[bs.cardinality()]; + int pos = 0; + for (int x = bs.nextSetBit(0); x >= 0; x = bs.nextSetBit(x + 1)) { + a[pos++] = x; + } + return Arrays.equals(rr.toArray(), a); + } + + private static Iterator toIterator(final T[] x) { + return new Iterator() { + int pos = 0; + + @Override + public boolean hasNext() { + return pos < x.length; + } + + @Override + public T next() { + return x[pos++]; + } + + @Override + public void remove() {} + }; + } + + @Test + public void andBigIntsTest() { + RoaringBitmap rb = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); + HashSet hs = new HashSet(); + + for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { + rb.add(i); + } + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + rb.add(i); + } + for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 3) { + rb.add(i); + } + for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 4) { + rb.add(i); + } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { + rb.add(i); + } + + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + hs.add(i); + rb2.add(i); + } + for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 4) { + hs.add(i); + rb2.add(i); + } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { + hs.add(i); + rb2.add(i); + } + for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 7) { + rb2.add(i); + } + + RoaringBitmap rband = RoaringBitmap.and(rb, rb2); + + Object[] correct = hs.toArray(); + Arrays.sort(correct); + Integer[] resand = ArrayUtils.toObject(rband.toArray()); + assertArrayEquals(correct, resand); + } + + @Test + public void andcounttest() { + // This is based on andtest + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr.add(k); + } + rr.add(100000); + rr.add(110000); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(13); + final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); + assertEquals(rrand.getCardinality(), RoaringBitmap.andCardinality(rr, rr2)); + assertEquals(rrand.getCardinality(), RoaringBitmap.andCardinality(rr2, rr)); + rr.and(rr2); + assertEquals(rrand.getCardinality(), RoaringBitmap.andCardinality(rr2, rr)); + } + + @Test + public void andCounttest3() { + // This is based on andtest3 + final int[] arrayand = new int[11256]; + int pos = 0; + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr.add(k); } - - @Test - public void testRangeCardinality2() { - RoaringBitmap r = new RoaringBitmap(); - long Min = 1L << 16; - long Max = 1L << 18; - r.add(Min, Max); - for (long s = Min; s <= Max; s += 1024) { - for (long e = s; e <= Max; e += 1024) { - assertEquals(e - s, r.rangeCardinality(s, e)); - } - } + for (int k = 65536; k < 65536 + 4000; ++k) { + rr.add(k); } - - @Test - public void testMultipleAdd() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(1); - bitmap.add(1, 2, 3); - bitmap.add(0xFFFFFFFF); - bitmap.add(0xFFFFFFFEL, 0xFFFFFFFFL); - assertEquals("{1,2,3,4294967294,4294967295}", bitmap.toString()); - } - - @Test - public void testAddN() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.addN(new int[]{1, 2, 3, 4, 5}, 1, 3); - assertEquals("{2,3,4}", bitmap.toString()); - } - - @Test - public void testStringer() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(1); - bitmap.add(2); - bitmap.add(3); - bitmap.add(0xFFFFFFFF); - assertEquals("{1,2,3,4294967295}", bitmap.toString()); - } - - @Test - public void report128() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(59798854); - bitmap.add(91274955); - bitmap.add(97569495); - bitmap.add(101993170); - PeekableIntIterator it = bitmap.getIntIterator(); - it.advanceIfNeeded(100620278); - assertTrue(it.hasNext()); - assertEquals(101993170, it.next()); - assertFalse(it.hasNext()); - } - - @Test - public void report128_fly() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(59798854); - bitmap.add(91274955); - bitmap.add(97569495); - bitmap.add(101993170); - IntIteratorFlyweight it = new IntIteratorFlyweight(); - it.wrap(bitmap); - it.advanceIfNeeded(100620278); - assertTrue(it.hasNext()); - assertEquals(101993170, it.next()); - assertFalse(it.hasNext()); - } - - @Test - public void limitBug2() { - class MyConsumer implements IntConsumer { - public int count = 0; - - @Override - public void accept(int value) { - count++; - } - } - - RoaringBitmap r = new RoaringBitmap(); - int count = 0; - for (int i = 0; i < 500; i++) { - for (int j = 0; j < 9943; j++) { - if (i % 2 == 0) r.add(count); - count++; - } - } - RoaringBitmap limited = r.limit(1000000); - assertEquals(1000000, limited.getCardinality()); - MyConsumer c = new MyConsumer(); - limited.forEach(c); - assertEquals(1000000, c.count); - assertEquals(1000000, limited.toArray().length); - - } - - @Test - public void limitTest() { - RoaringBitmap r = new RoaringBitmap(); - r.add(0l, 10000000l); - assertEquals(1, r.limit(1).getCardinality()); - assertEquals(10, r.limit(10).getCardinality()); - assertEquals(100, r.limit(100).getCardinality()); - assertEquals(1000, r.limit(1000).getCardinality()); - assertEquals(10000, r.limit(10000).getCardinality()); - assertEquals(100000, r.limit(100000).getCardinality()); - assertEquals(1000000, r.limit(1000000).getCardinality()); - } - - @Test - public void pointerContainerTest() { - RoaringBitmap rb = new RoaringBitmap(); - for (int i = 0; i < (1 << 16); i += 2) { - rb.add(i); - } - for (int i = (1 << 16); i < 2 * ((1 << 16)); i += 512) { - rb.add(i); - } - for (int i = 2 * (1 << 16); i < 3 * ((1 << 16)); i++) { - rb.add(i); - } - rb.runOptimize(); - ContainerPointer cp = rb.getContainerPointer(); - ContainerPointer cpo = (ContainerPointer) cp.clone(); - assertNotEquals(cp.getContainer(), null); - assertNotEquals(cpo.getContainer(), null); - - assertEquals(cp.compareTo(cpo), 0); - - assertEquals(cp.getCardinality(), (1 << 16) / 2); - assertTrue(cp.isBitmapContainer()); - assertFalse(cp.isRunContainer()); - - cp.advance(); - assertTrue(cp.compareTo(cpo) > 0); - assertNotEquals(cp.getContainer(), null); - assertEquals(cp.getCardinality(), (1 << 16) / 512); - assertFalse(cp.isBitmapContainer()); - assertFalse(cp.isRunContainer()); - - cp.advance(); - assertTrue(cp.compareTo(cpo) > 0); - assertNotEquals(cp.getContainer(), null); - assertEquals(cp.getCardinality(), (1 << 16)); - assertFalse(cp.isBitmapContainer()); - assertTrue(cp.isRunContainer()); - - cpo.advance(); - assertTrue(cp.compareTo(cpo) > 0); - cpo.advance(); - assertEquals(0, cp.compareTo(cpo)); - - cp.advance(); - - assertNull(cp.getContainer()); - } - - - public static int[][] randomlists = {{127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, - 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, - 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, - 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, - 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, - 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, - 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, - 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, - 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, - 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, - 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, - 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, - 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, - 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, - 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, - 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, - 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, - 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, - 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, - 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, - 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, - 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, - 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, - 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, - 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, - 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, - 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, - 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, - 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, - 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, - 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, - 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, - 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, - 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, - 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, - 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, - 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, - 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, - 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, - 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, - 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, - 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, - 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, - 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, - 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, - 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, - 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, - 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, - 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, - 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, - 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, - 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, - 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, - 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, - 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, - 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, - 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, - 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, - 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, - 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, - 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, - 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, - 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, - 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, - 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, - 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, - 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, - 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, - 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, - 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, - 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, - 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, - 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, - 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, - 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, - 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, - 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, - 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, - 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, - 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, - 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, - 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, - 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, - 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, - 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, - 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, - 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, - 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, - 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, - 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, - 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, - 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, - 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, - 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, - 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, - 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, - 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, - 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, - 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, - 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, - 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, - 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, - 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, - 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, - 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, - 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, - 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, - 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, - 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, - 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, - 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, - 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, - 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, - 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, - 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, - 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, - 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, - 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, - 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, - 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, - 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, - 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, - 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, - 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, - 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, - 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, 2584, - 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, - 2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, - 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, - 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, - 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, - 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, - 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, - 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, - 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, - 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, - 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, - 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, - 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, - 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, - 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, - 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, - 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, - 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, - 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, - 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, - 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, - 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, - 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, - 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, - 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, - 2960, 2961, 2962, 2963, 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, - 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989, - 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, 3004, - 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, - 3020, 3021, 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, - 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, - 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, 3064, - 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, 3079, - 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, - 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, - 3110, 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, - 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, 3139, - 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153, 3154, - 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, - 3170, 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, - 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, - 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, - 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, - 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, - 3245, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, - 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3273, 3274, - 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, - 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, - 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, - 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, - 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, - 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, - 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, - 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, - 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, - 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, - 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439, - 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, - 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, - 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, - 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, - 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514, - 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, - 3530, 3531, 3532, 3533, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, - 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, 3558, 3559, - 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, - 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, - 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, - 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, - 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, - 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, - 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, - 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, - 3680, 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, - 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3708, 3709, - 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724, - 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, - 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, - 3755, 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, - 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, - 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, - 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, - 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, - 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, - 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, - 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, - 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, - 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, - 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, - 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933, 3934, - 3935, 3936, 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, - 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, - 3965, 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, - 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3992, 3993, 3994, - 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, - 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, - 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, - 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, - 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, - 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, - 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, - 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, - 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, - 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, - 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, - 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, - 4175, 4176, 4177, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4186, 4187, 4188, 4189, - 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 4204, - 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218, 4219, - 4220, 4221, 4222, 4223, 4224, 4225, 4226, 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, - 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, - 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, - 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, - 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4293, 4294, - 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4305, 4306, 4307, 4308, 4309, - 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, - 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, - 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, - 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, - 4370, 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, - 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, - 4400, 4401, 4402, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, - 4415, 4416, 4417, 4418, 4419, 4420, 4421, 4422, 4423, 4424, 4425, 4426, 4427, 4428, 4429, - 4430, 4431, 4432, 4433, 4434, 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442, 4443, 4444, - 4445, 4446, 4447, 4448, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, - 4460, 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, 4470, 4471, 4472, 4473, 4474, - 4475, 4476, 4477, 4478, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, - 4490, 4491, 4492, 4493, 4494, 4495, 4496, 4497, 4498, 4499, 4500, 4501, 4502, 4503, 4504, - 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, - 4520, 4521, 4522, 4523, 4524, 4525, 4526, 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, - 4535, 4536, 4537, 4538, 4539, 4540, 4541, 4542, 4543, 4544, 4545, 4546, 4547, 4548, 4549, - 4550, 4551, 4552, 4553, 4554, 4555, 4556, 4557, 4558, 4559, 4560, 4561, 4562, 4563, 4564, - 4565, 4566, 4567, 4568, 4569, 4570, 4571, 4572, 4573, 4574, 4575, 4576, 4577, 4578, 4579, - 4580, 4581, 4582, 4583, 4584, 4585, 4586, 4587, 4588, 4589, 4590, 4591, 4592, 4593, 4594, - 4595, 4596, 4597, 4598, 4599, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, 4609, - 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, - 4625, 4626, 4627, 4628, 4629, 4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, - 4640, 4641, 4642, 4643, 4644, 4645, 4646, 4647, 4648, 4649, 4650, 4651, 4652, 4653, 4654, - 4655, 4656, 4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, - 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, 4680, 4681, 4682, 4683, 4684, - 4685, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, - 4700, 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, - 4715, 4716, 4717, 4718, 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, - 4730, 4731, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, 4744, - 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, 4759, - 4760, 4761, 4762, 4763, 4764, 4765, 4766, 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, - 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, 4783, 4784, 4785, 4786, 4787, 4788, 4789, - 4790, 4791, 4792, 4793, 4794, 4795, 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803, 4804, - 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, 4818, 4819, - 4820, 4821, 4822, 4823, 4824, 4825, 4826, 4827, 4828, 4829, 4830, 4831, 4832, 4833, 4834, - 4835, 4836, 4837, 4838, 4839, 4840, 4841, 4842, 4843, 4844, 4845, 4846, 4847, 4848, 4849, - 4850, 4851, 4852, 4853, 4854, 4855, 4856, 4857, 4858, 4859, 4860, 4861, 4862, 4863, 4864, - 4865, 4866, 4867, 4868, 4869, 4870, 4871, 4872, 4873, 4874, 4875, 4876, 4877, 4878, 4879, - 4880, 4881, 4882, 4883, 4884, 4885, 4886, 4887, 4888, 4889, 4890, 4891, 4892, 4893, 4894, - 4895, 4896, 4897, 4898, 4899, 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, - 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, - 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, - 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, - 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, - 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, - 4985, 4986, 4987, 4988, 4989, 4990, 4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998, 4999, - 5000, 5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, - 5015, 5016, 5017, 5018, 5019, 5020, 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, 5029, - 5030, 5031, 5032, 5033, 5034, 5035, 5036, 5037, 5038, 5039, 5040, 5041, 5042, 5043, 5044, - 5045, 5046, 5047, 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055, 5056, 5057, 5058, 5059, - 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5074, - 5075, 5076, 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, 5089, - 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 5104, - 5105, 5106, 5107, 5108, 5109, 5110, 5111, 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, - 5120, 5121, 5122, 5123, 5124, 5125, 5126, 5127, 5128, 5129, 5130, 5131, 5132, 5133, 5134, - 5135, 5136, 5137, 5138, 5139, 5140, 5141, 5142, 5143, 5144, 5145, 5146, 5147, 5148, 5149, - 5150, 5151, 5152, 5153, 5154, 5155, 5156, 5157, 5158, 5159, 5160, 5161, 5162, 5163, 5164, - 5165, 5166, 5167, 5168, 5169, 5170, 5171, 5172, 5173, 5174, 5175, 5176, 5177, 5178, 5179, - 5180, 5181, 5182, 5183, 5184, 5185, 5186, 5187, 5188, 5189, 5190, 5191, 5192, 5193, 5194, - 5195, 5196, 5197, 5198, 5199, 5200, 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, 5209, - 5210, 5211, 5212, 5213, 5214, 5215, 5216, 5217, 5218, 5219, 5220, 5221, 5222, 5223, 5224, - 5225, 5226, 5227, 5228, 5229, 5230, 5231, 5232, 5233, 5234, 5235, 5236, 5237, 5238, 5239, - 5240, 5241, 5242, 5243, 5244, 5245, 5246, 5247, 5248, 5249, 5250, 5251, 5252, 5253, 5254, - 5255, 5256, 5257, 5258, 5259, 5260, 5261, 5262, 5263, 5264, 5265, 5266, 5267, 5268, 5269, - 5270, 5271, 5272, 5273, 5274, 5275, 5276, 5277, 5278, 5279, 5280, 5281, 5282, 5283, 5284, - 5285, 5286, 5287, 5288, 5289, 5290, 5291, 5292, 5293, 5294, 5295, 5296, 5297, 5298, 5299, - 5300, 5301, 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311, 5312, 5313, 5314, - 5315, 5316, 5317, 5318, 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, 5328, 5329, - 5330, 5331, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5342, 5343, 5344, - 5345, 5346, 5347, 5348, 5349, 5350, 5351, 5352, 5353, 5354, 5355, 5356, 5357, 5358, 5359, - 5360, 5361, 5362, 5363, 5364, 5365, 5366, 5367, 5368, 5369, 5370, 5371, 5372, 5373, 5374, - 5375, 5376, 5377, 5378, 5379, 5380, 5381, 5382, 5383, 5384, 5385, 5386, 5387, 5388, 5389, - 5390, 5391, 5392, 5393, 5394, 5395, 5396, 5397, 5398, 5399, 5400, 5401, 5402, 5403, 5404, - 5405, 5406, 5407, 5408, 5409, 5410, 5411, 5412, 5413, 5414, 5415, 5416, 5417, 5418, 5419, - 5420, 5421, 5422, 5423, 5424, 5425, 5426, 5427, 5428, 5429, 5430, 5431, 5432, 5433, 5434, - 5435, 5436, 5437, 5438, 5439, 5440, 5441, 5442, 5443, 5444, 5445, 5446, 5447, 5448, 5449, - 5450, 5451, 5452, 5453, 5454, 5455, 5456, 5457, 5458, 5459, 5460, 5461, 5462, 5463, 5464, - 5465, 5466, 5467, 5468, 5469, 5470, 5471, 5472, 5473, 5474, 5475, 5476, 5477, 5478, 5479, - 5480, 5481, 5482, 5483, 5484, 5485, 5486, 5487, 5488, 5489, 5490, 5491, 5492, 5493, 5494, - 5495, 5496, 5497, 5498, 5499, 5500, 5501, 5502, 5503, 5504, 5505, 5506, 5507, 5508, 5509, - 5510, 5511, 5512, 5513, 5514, 5515, 5516, 5517, 5518, 5519, 5520, 5521, 5522, 5523, 5524, - 5525, 5526, 5527, 5528, 5529, 5530, 5531, 5532, 5533, 5534, 5535, 5536, 5537, 5538, 5539, - 5540, 5541, 5542, 5543, 5544, 5545, 5546, 5547, 5548, 5549, 5550, 5551, 5552, 5553, 5554, - 5555, 5556, 5557, 5558, 5559, 5560, 5561, 5562, 5563, 5564, 5565, 5566, 5567, 5568, 5569, - 5570, 5571, 5572, 5573, 5574, 5575, 5576, 5577, 5578, 5579, 5580, 5581, 5582, 5583, 5584, - 5585, 5586, 5587, 5588, 5589, 5590, 5591, 5592, 5593, 5594, 5595, 5596, 5597, 5598, 5599, - 5600, 5601, 5602, 5603, 5604, 5605, 5606, 5607, 5608, 5609, 5610, 5611, 5612, 5613, 5614, - 5615, 5616, 5617, 5618, 5619, 5620, 5621, 5622, 5623, 5624, 5625, 5626, 5627, 5628, 5629, - 5630, 5631, 5632, 5633, 5634, 5635, 5636, 5637, 5638, 5639, 5640, 5641, 5642, 5643, 5644, - 5645, 5646, 5647, 5648, 5649, 5650, 5651, 5652, 5653, 5654, 5655, 5656, 5657, 5658, 5659, - 5660, 5661, 5662, 5663, 5664, 5665, 5666, 5667, 5668, 5669, 5670, 5671, 5672, 5673, 5674, - 5675, 5676, 5677, 5678, 5679, 5680, 5681, 5682, 5683, 5684, 5685, 5686, 5687, 5688, 5689, - 5690, 5691, 5692, 5693, 5694, 5695, 5696, 5697, 5698, 5699, 5700, 5701, 5702, 5703, 5704, - 5705, 5706, 5707, 5708, 5709, 5710, 5711, 5712, 5713, 5714, 5715, 5716, 5717, 5718, 5719, - 5720, 5721, 5722, 5723, 5724, 5725, 5726, 5727, 5728, 5729, 5730, 5731, 5732, 5733, 5734, - 5735, 5736, 5737, 5738, 5739, 5740, 5741, 5742, 5743, 5744, 5745, 5746, 5747, 5748, 5749, - 5750, 5751, 5752, 5753, 5754, 5755, 5756, 5757, 5758, 5759, 5760, 5761, 5762, 5763, 5764, - 5765, 5766, 5767, 5768, 5769, 5770, 5771, 5772, 5773, 5774, 5775, 5776, 5777, 5778, 5779, - 5780, 5781, 5782, 5783, 5784, 5785, 5786, 5787, 5788, 5789, 5790, 5791, 5792, 5793, 5794, - 5795, 5796, 5797, 5798, 5799, 5800, 5801, 5802, 5803, 5804, 5805, 5806, 5807, 5808, 5809, - 5810, 5811, 5812, 5813, 5814, 5815, 5816, 5817, 5818, 5819, 5820, 5821, 5822, 5823, 5824, - 5825, 5826, 5827, 5828, 5829, 5830, 5831, 5832, 5833, 5834, 5835, 5836, 5837, 5838, 5839, - 5840, 5841, 5842, 5843, 5844, 5845, 5846, 5847, 5848, 5849, 5850, 5851, 5852, 5853, 5854, - 5855, 5856, 5857, 5858, 5859, 5860, 5861, 5862, 5863, 5864, 5865, 5866, 5867, 5868, 5869, - 5870, 5871, 5872, 5873, 5874, 5875, 5876, 5877, 5878, 5879, 5880, 5881, 5882, 5883, 5884, - 5885, 5886, 5887, 5888, 5889, 5890, 5891, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, - 5900, 5901, 5902, 5903, 5904, 5905, 5906, 5907, 5908, 5909, 5910, 5911, 5912, 5913, 5914, - 5915, 5916, 5917, 5918, 5919, 5920, 5921, 5922, 5923, 5924, 5925, 5926, 5927, 5928, 5929, - 5930, 5931, 5932, 5933, 5934, 5935, 5936, 5937, 5938, 5939, 5940, 5941, 5942, 5943, 5944, - 5945, 5946, 5947, 5948, 5949, 5950, 5951, 5952, 5953, 5954, 5955, 5956, 5957, 5958, 5959, - 5960, 5961, 5962, 5963, 5964, 5965, 5966, 5967, 5968, 5969, 5970, 5971, 5972, 5973, 5974, - 5975, 5976, 5977, 5978, 5979, 5980, 5981, 5982, 5983, 5984, 5985, 5986, 5987, 5988, 5989, - 5990, 5991, 5992, 5993, 5994, 5995, 5996, 5997, 5998, 5999, 6000, 6001, 6002, 6003, 6004, - 6005, 6006, 6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, - 6020, 6021, 6022, 6023, 6024, 6025, 6026, 6027, 6028, 6029, 6030, 6031, 6032, 6033, 6034, - 6035, 6036, 6037, 6038, 6039, 6040, 6041, 6042, 6043, 6044, 6045, 6046, 6047, 6048, 6049, - 6050, 6051, 6052, 6053, 6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 6062, 6063, 6064, - 6065, 6066, 6067, 6068, 6069, 6070, 6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 6079, - 6080, 6081, 6082, 6083, 6084, 6085, 6086, 6087, 6088, 6089, 6090, 6091, 6092, 6093, 6094, - 6095, 6096, 6097, 6098, 6099, 6100, 6101, 6102, 6103, 6104, 6105, 6106, 6107, 6108, 6109, - 6110, 6111, 6112, 6113, 6114, 6115, 6116, 6117, 6118, 6119, 6120, 6121, 6122, 6123, 6124, - 6125, 6126, 6127, 6128, 6129, 6130, 6131, 6132, 6133, 6134, 6135, 6136, 6137, 6138, 6139, - 6140, 6141, 6142, 6143, 6144, 6145, 6146, 6147, 6148, 6149, 6150, 6151, 6152, 6153, 6154, - 6155, 6156, 6157, 6158, 6159, 6160, 6161, 6162, 6163, 6164, 6165, 6166, 6167, 6168, 6169, - 6170, 6171, 6172, 6173, 6174, 6175, 6176, 6177, 6178, 6179, 6180, 6181, 6182, 6183, 6184, - 6185, 6186, 6187, 6188, 6189, 6190, 6191, 6192, 6193, 6194, 6195, 6196, 6197, 6198, 6199, - 6200, 6201, 6202, 6203, 6204, 6205, 6206, 6207, 6208, 6209, 6210, 6211, 6212, 6213, 6214, - 6215, 6216, 6217, 6218, 6219, 6220, 6221, 6222, 6223, 6224, 6225, 6226, 6227, 6228, 6229, - 6230, 6231, 6232, 6233, 6234, 6235, 6236, 6237, 6238, 6239, 6240, 6241, 6242, 6243, 6244, - 6245, 6246, 6247, 6248, 6249, 6250, 6251, 6252, 6253, 6254, 6255, 6256, 6257, 6258, 6259, - 6260, 6261, 6262, 6263, 6264, 6265, 6266, 6267, 6268, 6269, 6270, 6271, 6272, 6273, 6274, - 6275, 6276, 6277, 6278, 6279, 6280, 6281, 6282, 6283, 6284, 6285, 6286, 6287, 6288, 6289, - 6290, 6291, 6292, 6293, 6294, 6295, 6296, 6297, 6298, 6299, 6300, 6301, 6302, 6303, 6304, - 6305, 6306, 6307, 6308, 6309, 6310, 6311, 6312, 6313, 6314, 6315, 6316, 6317, 6318, 6319, - 6320, 6321, 6322, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, 6333, 6334, - 6335, 6336, 6337, 6338, 6339, 6340, 6341, 6342, 6343, 6344, 6345, 6346, 6347, 6348, 6349, - 6350, 6351, 6352, 6353, 6354, 6355, 6356, 6357, 6358, 6359, 6360, 6361, 6362, 6363, 6364, - 6365, 6366, 6367, 6368, 6369, 6370, 6371, 6372, 6373, 6374, 6375, 6376, 6377, 6378, 6379, - 6380, 6381, 6382, 6383, 6384, 6385, 6386, 6387, 6388, 6389, 6390, 6391, 6392, 6393, 6394, - 6395, 6396, 6397, 6398, 6399, 6400, 6401, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, - 6410, 6411, 6412, 6413, 6414, 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, 6423, 6424, - 6425, 6426, 6427, 6428, 6429, 6430, 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, - 6440, 6441, 6442, 6443, 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, 6452, 6453, 6454, - 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, 6468, 6469, - 6470, 6471, 6472, 6473, 6474, 6475, 6476, 6477, 6478, 6479, 6480, 6481, 6482, 6483, 6484, - 6485, 6486, 6487, 6488, 6489, 6490, 6491, 6492, 6493, 6494, 6495, 6496, 6497, 6498, 6499, - 6500, 6501, 6502, 6503, 6504, 6505, 6506, 6507, 6508, 6509, 6510, 6511, 6512, 6513, 6514, - 6515, 6516, 6517, 6518, 6519, 6520, 6521, 6522, 6523, 6524, 6525, 6526, 6527, 6528, 6529, - 6530, 6531, 6532, 6533, 6534, 6535, 6536, 6537, 6538, 6539, 6540, 6541, 6542, 6543, 6544, - 6545, 6546, 6547, 6548, 6549, 6550, 6551, 6552, 6553, 6554, 6555, 6556, 6557, 6558, 6559, - 6560, 6561, 6562, 6563, 6564, 6565, 6566, 6567, 6568, 6569, 6570, 6571, 6572, 6573, 6574, - 6575, 6576, 6577, 6578, 6579, 6580, 6581, 6582, 6583, 6584, 6585, 6586, 6587, 6588, 6589, - 6590, 6591, 6592, 6593, 6594, 6595, 6596, 6597, 6598, 6599, 6600, 6601, 6602, 6603, 6604, - 6605, 6606, 6607, 6608, 6609, 6610, 6611, 6612, 6613, 6614, 6615, 6616, 6617, 6618, 6619, - 6620, 6621, 6622, 6623, 6624, 6625, 6626, 6627, 6628, 6629, 6630, 6631, 6632, 6633, 6634, - 6635, 6636, 6637, 6638, 6639, 6640, 6641, 6642, 6643, 6644, 6645, 6646, 6647, 6648, 6649, - 6650, 6651, 6652, 6653, 6654, 6655, 6656, 6657, 6658, 6659, 6660, 6661, 6662, 6663, 6664, - 6665, 6666, 6667, 6668, 6669, 6670, 6671, 6672, 6673, 6674, 6675, 6676, 6677, 6678, 6679, - 6680, 6681, 6682, 6683, 6684, 6685, 6686, 6687, 6688, 6689, 6690, 6691, 6692, 6693, 6694, - 6695, 6696, 6697, 6698, 6699, 6700, 6701, 6702, 6703, 6704, 6705, 6706, 6707, 6708, 6709, - 6710, 6711, 6712, 6713, 6714, 6715, 6716, 6717, 6718, 6719, 6720, 6721, 6722, 6723, 6724, - 6725, 6726, 6727, 6728, 6729, 6730, 6731, 6732, 6733, 6734, 6735, 6736, 6737, 6738, 6739, - 6740, 6741, 6742, 6743, 6744, 6745, 6746, 6747, 6748, 6749, 6750, 6751, 6752, 6753, 6754, - 6755, 6756, 6757, 6758, 6759, 6760, 6761, 6762, 6763, 6764, 6765, 6766, 6767, 6768, 6769, - 6770, 6771, 6772, 6773, 6774, 6775, 6776, 6777, 6778, 6779, 6780, 6781, 6782, 6783, 6784, - 6785, 6786, 6787, 6788, 6789, 6790, 6791, 6792, 6793, 6794, 6795, 6796, 6797, 6798, 6799, - 6800, 6801, 6802, 6803, 6804, 6805, 6806, 6807, 6808, 6809, 6810, 6811, 6812, 6813, 6814, - 6815, 6816, 6817, 6818, 6819, 6820, 6821, 6822, 6823, 6824, 6825, 6826, 6827, 6828, 6829, - 6830, 6831, 6832, 6833, 6834, 6835, 6836, 6837, 6838, 6839, 6840, 6841, 6842, 6843, 6844, - 6845, 6846, 6847, 6848, 6849, 6850, 6851, 6852, 6853, 6854, 6855, 6856, 6857, 6858, 6859, - 6860, 6861, 6862, 6863, 6864, 6865, 6866, 6867, 6868, 6869, 6870, 6871, 6872, 6873, 6874, - 6875, 6876, 6877, 6878, 6879, 6880, 6881, 6882, 6883, 6884, 6885, 6886, 6887, 6888, 6889, - 6890, 6891, 6892, 6893, 6894, 6895, 6896, 6897, 6898, 6899, 6900, 6901, 6902, 6903, 6904, - 6905, 6906, 6907, 6908, 6909, 6910, 6911, 6912, 6913, 6914, 6915, 6916, 6917, 6918, 6919, - 6920, 6921, 6922, 6923, 6924, 6925, 6926, 6927, 6928, 6929, 6930, 6931, 6932, 6933, 6934, - 6935, 6936, 6937, 6938, 6939, 6940, 6941, 6942, 6943, 6944, 6945, 6946, 6947, 6948, 6949, - 6950, 6951, 6952, 6953, 6954, 6955, 6956, 6957, 6958, 6959, 6960, 6961, 6962, 6963, 6964, - 6965, 6966, 6967, 6968, 6969, 6970, 6971, 6972, 6973, 6974, 6975, 6976, 6977, 6978, 6979, - 6980, 6981, 6982, 6983, 6984, 6985, 6986, 6987, 6988, 6989, 6990, 6991, 6992, 6993, 6994, - 6995, 6996, 6997, 6998, 6999, 7000, 7001, 7002, 7003, 7004, 7005, 7006, 7007, 7008, 7009, - 7010, 7011, 7012, 7013, 7014, 7015, 7016, 7017, 7018, 7019, 7020, 7021, 7022, 7023, 7024, - 7025, 7026, 7027, 7028, 7029, 7030, 7031, 7032, 7033, 7034, 7035, 7036, 7037, 7038, 7039, - 7040, 7041, 7042, 7043, 7044, 7045, 7046, 7047, 7048, 7049, 7050, 7051, 7052, 7053, 7054, - 7055, 7056, 7057, 7058, 7059, 7060, 7061, 7062, 7063, 7064, 7065, 7066, 7067, 7068, 7069, - 7070, 7071, 7072, 7073, 7074, 7075, 7076, 7077, 7078, 7079, 7080, 7081, 7082, 7083, 7084, - 7085, 7086, 7087, 7088, 7089, 7090, 7091, 7092, 7093, 7094, 7095, 7096, 7097, 7098, 7099, - 7100, 7101, 7102, 7103, 7104, 7105, 7106, 7107, 7108, 7109, 7110, 7111, 7112, 7113, 7114, - 7115, 7116, 7117, 7118, 7119, 7120, 7121, 7122, 7123, 7124, 7125, 7126, 7127, 7128, 7129, - 7130, 7131, 7132, 7133, 7134, 7135, 7136, 7137, 7138, 7139, 7140, 7141, 7142, 7143, 7144, - 7145, 7146, 7147, 7148, 7149, 7150, 7151, 7152, 7153, 7154, 7155, 7156, 7157, 7158, 7159, - 7160, 7161, 7162, 7163, 7164, 7165, 7166, 7167, 7168, 7169, 7170, 7171, 7172, 7173, 7174, - 7175, 7176, 7177, 7178, 7179, 7180, 7181, 7182, 7183, 7184, 7185, 7186, 7187, 7188, 7189, - 7190, 7191, 7192, 7193, 7194, 7195, 7196, 7197, 7198, 7199, 7200, 7201, 7202, 7203, 7204, - 7205, 7206, 7207, 7208, 7209, 7210, 7211, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, - 7220, 7221, 7222, 7223, 7224, 7225, 7226, 7227, 7228, 7229, 7230, 7231, 7232, 7233, 7234, - 7235, 7236, 7237, 7238, 7239, 7240, 7241, 7242, 7243, 7244, 7245, 7246, 7247, 7248, 7249, - 7250, 7251, 7252, 7253, 7254, 7255, 7256, 7257, 7258, 7259, 7260, 7261, 7262, 7263, 7264, - 7265, 7266, 7267, 7268, 7269, 7270, 7271, 7272, 7273, 7274, 7275, 7276, 7277, 7278, 7279, - 7280, 7281, 7282, 7283, 7284, 7285, 7286, 7287, 7288, 7289, 7290, 7291, 7292, 7293, 7294, - 7295, 7296, 7297, 7298, 7299, 7300, 7301, 7302, 7303, 7304, 7305, 7306, 7307, 7308, 7309, - 7310, 7311, 7312, 7313, 7314, 7315, 7316, 7317, 7318, 7319, 7320, 7321, 7322, 7323, 7324, - 7325, 7326, 7327, 7328, 7329, 7330, 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, - 7340, 7341, 7342, 7343, 7344, 7345, 7346, 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, - 7355, 7356, 7357, 7358, 7359, 7360, 7361, 7362, 7363, 7364, 7365, 7366, 7367, 7368, 7369, - 7370, 7371, 7372, 7373, 7374, 7375, 7376, 7377, 7378, 7379, 7380, 7381, 7382, 7383, 7384, - 7385, 7386, 7387, 7388, 7389, 7390, 7391, 7392, 7393, 7394, 7395, 7396, 7397, 7398, 7399, - 7400, 7401, 7402, 7403, 7404, 7405, 7406, 7407, 7408, 7409, 7410, 7411, 7412, 7413, 7414, - 7415, 7416, 7417, 7418, 7419, 7420, 7421, 7422, 7423, 7424, 7425, 7426, 7427, 7428, 7429, - 7430, 7431, 7432, 7433, 7434, 7435, 7436, 7437, 7438, 7439, 7440, 7441, 7442, 7443, 7444, - 7445, 7446, 7447, 7448, 7449, 7450, 7451, 7452, 7453, 7454, 7455, 7456, 7457, 7458, 7459, - 7460, 7461, 7462, 7463, 7464, 7465, 7466, 7467, 7468, 7469, 7470, 7471, 7472, 7473, 7474, - 7475, 7476, 7477, 7478, 7479, 7480, 7481, 7482, 7483, 7484, 7485, 7486, 7487, 7488, 7489, - 7490, 7491, 7492, 7493, 7494, 7495, 7496, 7497, 7498, 7499, 7500, 7501, 7502, 7503, 7504, - 7505, 7506, 7507, 7508, 7509, 7510, 7511, 7512, 7513, 7514, 7515, 7516, 7517, 7518, 7519, - 7520, 7521, 7522, 7523, 7524, 7525, 7526, 7527, 7528, 7529, 7530, 7531, 7532, 7533, 7534, - 7535, 7536, 7537, 7538, 7539, 7540, 7541, 7542, 7543, 7544, 7545, 7546, 7547, 7548, 7549, - 7550, 7551, 7552, 7553, 7554, 7555, 7556, 7557, 7558, 7559, 7560, 7561, 7562, 7563, 7564, - 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7572, 7573, 7574, 7575, 7576, 7577, 7578, 7579, - 7580, 7581, 7582, 7583, 7584, 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7592, 7593, 7594, - 7595, 7596, 7597, 7598, 7599, 7600, 7601, 7602, 7603, 7604, 7605, 7606, 7607, 7608, 7609, - 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7617, 7618, 7619, 7620, 7621, 7622, 7623, 7624, - 7625, 7626, 7627, 7628, 7629, 7630, 7631, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, - 7640, 7641, 7642, 7643, 7644, 7645, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7654, - 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, - 7670, 7671, 7672, 7673, 7674, 7675, 7676, 7677, 7678, 7679, 7680, 7681, 7682, 7683, 7684, - 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, - 7700, 7701, 7702, 7703, 7704, 7705, 7706, 7707, 7708, 7709, 7710, 7711, 7712, 7713, 7714, - 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, 7724, 7725, 7726, 7727, 7728, 7729, - 7730, 7731, 7732, 7733, 7734, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7743, 7744, - 7745, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, - 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7772, 7773, 7774, - 7775, 7776, 7777, 7778, 7779, 7780, 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7788, 7789, - 7790, 7791, 7792, 7793, 7794, 7795, 7796, 7797, 7798, 7799, 7800, 7801, 7802, 7803, 7804, - 7805, 7806, 7807, 7808, 7809, 7810, 7811, 7812, 7813, 7814, 7815, 7816, 7817, 7818, 7819, - 7820, 7821, 7822, 7823, 7824, 7825, 7826, 7827, 7828, 7829, 7830, 7831, 7832, 7833, 7834, - 7835, 7836, 7837, 7838, 7839, 7840, 7841, 7842, 7843, 7844, 7845, 7846, 7847, 7848, 7849, - 7850, 7851, 7852, 7853, 7854, 7855, 7856, 7857, 7858, 7859, 7860, 7861, 7862, 7863, 7864, - 7865, 7866, 7867, 7868, 7869, 7870, 7871, 7872, 7873, 7874, 7875, 7876, 7877, 7878, 7879, - 7880, 7881, 7882, 7883, 7884, 7885, 7886, 7887, 7888, 7889, 7890, 7891, 7892, 7893, 7894, - 7895, 7896, 7897, 7898, 7899, 7900, 7901, 7902, 7903, 7904, 7905, 7906, 7907, 7908, 7909, - 7910, 7911, 7912, 7913, 7914, 7915, 7916, 7917, 7918, 7919, 7920, 7921, 7922, 7923, 7924, - 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936, 7937, 7938, 7939, - 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 7952, 7953, 7954, - 7955, 7956, 7957, 7958, 7959, 7960, 7961, 7962, 7963, 7964, 7965, 7966, 7967, 7968, 7969, - 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 7984, - 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999}, - {95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126}}; - - public static boolean equals(BitSet bs, RoaringBitmap rr) { - final int[] a = new int[bs.cardinality()]; - int pos = 0; - for (int x = bs.nextSetBit(0); x >= 0; x = bs.nextSetBit(x + 1)) { - a[pos++] = x; - } - return Arrays.equals(rr.toArray(), a); + for (int k = 3 * 65536; k < 3 * 65536 + 1000; ++k) { + rr.add(k); } - - private static Iterator toIterator(final T[] x) { - return new Iterator() { - int pos = 0; - - @Override - public boolean hasNext() { - return pos < x.length; - } - - @Override - public T next() { - return x[pos++]; - } - - @Override - public void remove() { - } - }; - + for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { + rr.add(k); } - - - @Test - public void andBigIntsTest() { - RoaringBitmap rb = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); - HashSet hs = new HashSet(); - - for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { - rb.add(i); - } - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - rb.add(i); - } - for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 3) { - rb.add(i); - } - for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 4) { - rb.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { - rb.add(i); - } - - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - hs.add(i); - rb2.add(i); - } - for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 4) { - hs.add(i); - rb2.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { - hs.add(i); - rb2.add(i); - } - for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 7) { - rb2.add(i); - } - - RoaringBitmap rband = RoaringBitmap.and(rb, rb2); - - Object[] correct = hs.toArray(); - Arrays.sort(correct); - Integer[] resand = ArrayUtils.toObject(rband.toArray()); - assertArrayEquals(correct, resand); + for (int k = 3 * 65536 + 7000; k < 3 * 65536 + 9000; ++k) { + rr.add(k); } - - @Test - public void andcounttest() { - // This is based on andtest - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr.add(k); - } - rr.add(100000); - rr.add(110000); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(13); - final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - assertEquals(rrand.getCardinality(), RoaringBitmap.andCardinality(rr, rr2)); - assertEquals(rrand.getCardinality(), RoaringBitmap.andCardinality(rr2, rr)); - rr.and(rr2); - assertEquals(rrand.getCardinality(), RoaringBitmap.andCardinality(rr2, rr)); - } - - @Test - public void andCounttest3() { - // This is based on andtest3 - final int[] arrayand = new int[11256]; - int pos = 0; - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536; k < 3 * 65536 + 1000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536 + 7000; k < 3 * 65536 + 9000; ++k) { - rr.add(k); - } - for (int k = 4 * 65536; k < 4 * 65536 + 7000; ++k) { - rr.add(k); - } - for (int k = 6 * 65536; k < 6 * 65536 + 10000; ++k) { - rr.add(k); - } - for (int k = 8 * 65536; k < 8 * 65536 + 1000; ++k) { - rr.add(k); - } - for (int k = 9 * 65536; k < 9 * 65536 + 30000; ++k) { - rr.add(k); - } - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 6 * 65536; k < 6 * 65536 + 1000; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 7 * 65536; k < 7 * 65536 + 1000; ++k) { - rr2.add(k); - } - for (int k = 10 * 65536; k < 10 * 65536 + 5000; ++k) { - rr2.add(k); - } - - final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - final int rrandCount = RoaringBitmap.andCardinality(rr, rr2); - - assertEquals(rrand.getCardinality(), rrandCount); + for (int k = 4 * 65536; k < 4 * 65536 + 7000; ++k) { + rr.add(k); } - - @Test - public void andNot() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - - rb.add(1); - rb.add(1 << 16); - rb2.add(1 << 16); - rb.add(2 << 16); - rb.add(3 << 16); - rb2.add(3 << 16); - rb.andNot(rb2); - - final IntIterator i = rb.getIntIterator(); - assertTrue(i.hasNext()); - assertEquals(1, i.next()); - assertTrue(i.hasNext()); - assertEquals(2 << 16, i.next()); - assertFalse(i.hasNext()); - } - - @Test - public void andNotBigIntsTest() { - RoaringBitmap rb = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); - HashSet hs = new HashSet(); - - for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { - rb.add(i); - hs.add(i); - } - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - rb.add(i); - } - for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 6 * 65536; i += 3) { - hs.add(i); - rb.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { - rb.add(i); - } - - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - rb2.add(i); - } - for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 4) { - rb2.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { - rb2.add(i); - } - for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 7) { - rb2.add(i); - } - - RoaringBitmap rbandnot = RoaringBitmap.andNot(rb, rb2); - - Object[] correct = hs.toArray(); - Arrays.sort(correct); - Integer[] resandNot = ArrayUtils.toObject(rbandnot.toArray()); - assertArrayEquals(correct, resandNot); + for (int k = 6 * 65536; k < 6 * 65536 + 10000; ++k) { + rr.add(k); } - - @Test - public void ANDNOTtest() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { - rr.add(k); - } - for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { - rr.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { - rr.add(k); - } - for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { - rr.add(k); - } - for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { - rr.add(k); - } - - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr2.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr2.add(k); - } - for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { - rr2.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { - rr2.add(k); - } - final RoaringBitmap correct = RoaringBitmap.andNot(rr, rr2); - rr.andNot(rr2); - assertEquals(correct, rr); + for (int k = 8 * 65536; k < 8 * 65536 + 1000; ++k) { + rr.add(k); } - - @Test - public void andnottest4() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - - for (int i = 0; i < 200000; i += 4) { - rb2.add(i); - } - for (int i = 200000; i < 400000; i += 14) { - rb2.add(i); - } - rb2.getCardinality(); - - // check or against an empty bitmap - final RoaringBitmap andNotresult = RoaringBitmap.andNot(rb, rb2); - final RoaringBitmap off = RoaringBitmap.andNot(rb2, rb); - - assertEquals(rb, andNotresult); - assertEquals(rb2, off); - rb2.andNot(rb); - assertEquals(rb2, off); + for (int k = 9 * 65536; k < 9 * 65536 + 30000; ++k) { + rr.add(k); } - - @Test - public void andtest() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr.add(k); - } - rr.add(100000); - rr.add(110000); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(13); - final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - int[] array = rrand.toArray(); - - assertEquals(array.length, 1); - assertEquals(array[0], 13); - rr.and(rr2); - array = rr.toArray(); - assertEquals(array.length, 1); - assertEquals(array[0], 13); - - } - - @Test - public void ANDtest() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { - rr.add(k); - } - for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { - rr.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { - rr.add(k); - } - for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { - rr.add(k); - } - for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { - rr.add(k); - } - - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr2.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr2.add(k); - } - for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { - rr2.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { - rr2.add(k); - } - final RoaringBitmap correct = RoaringBitmap.and(rr, rr2); - rr.and(rr2); - assertEquals(correct, rr); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr2.add(k); + arrayand[pos++] = k; } - - @Test - public void andtest2() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr.add(k); - } - rr.add(100000); - rr.add(110000); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(13); - final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - - final int[] array = rrand.toArray(); - assertEquals(array.length, 1); - assertEquals(array[0], 13); - } - - @Test - public void andtest3() { - final int[] arrayand = new int[11256]; - int pos = 0; - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536; k < 3 * 65536 + 1000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536 + 7000; k < 3 * 65536 + 9000; ++k) { - rr.add(k); - } - for (int k = 4 * 65536; k < 4 * 65536 + 7000; ++k) { - rr.add(k); - } - for (int k = 6 * 65536; k < 6 * 65536 + 10000; ++k) { - rr.add(k); - } - for (int k = 8 * 65536; k < 8 * 65536 + 1000; ++k) { - rr.add(k); - } - for (int k = 9 * 65536; k < 9 * 65536 + 30000; ++k) { - rr.add(k); - } - - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 6 * 65536; k < 6 * 65536 + 1000; ++k) { - rr2.add(k); - arrayand[pos++] = k; - } - for (int k = 7 * 65536; k < 7 * 65536 + 1000; ++k) { - rr2.add(k); - } - for (int k = 10 * 65536; k < 10 * 65536 + 5000; ++k) { - rr2.add(k); - } - - final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - - final int[] arrayres = rrand.toArray(); - - assertArrayEquals(arrayand, arrayres); - + for (int k = 65536; k < 65536 + 4000; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 6 * 65536; k < 6 * 65536 + 1000; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 7 * 65536; k < 7 * 65536 + 1000; ++k) { + rr2.add(k); + } + for (int k = 10 * 65536; k < 10 * 65536 + 5000; ++k) { + rr2.add(k); } - @Test - public void andtest4() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); + final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); + final int rrandCount = RoaringBitmap.andCardinality(rr, rr2); - for (int i = 0; i < 200000; i += 4) { - rb2.add(i); - } - for (int i = 200000; i < 400000; i += 14) { - rb2.add(i); - } + assertEquals(rrand.getCardinality(), rrandCount); + } - // check or against an empty bitmap - final RoaringBitmap andresult = RoaringBitmap.and(rb, rb2); - final RoaringBitmap off = RoaringBitmap.and(rb2, rb); - assertEquals(andresult, off); + @Test + public void andNot() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); - assertEquals(0, andresult.getCardinality()); + rb.add(1); + rb.add(1 << 16); + rb2.add(1 << 16); + rb.add(2 << 16); + rb.add(3 << 16); + rb2.add(3 << 16); + rb.andNot(rb2); - for (int i = 500000; i < 600000; i += 14) { - rb.add(i); - } - for (int i = 200000; i < 400000; i += 3) { - rb2.add(i); - } - // check or against an empty bitmap - final RoaringBitmap andresult2 = RoaringBitmap.and(rb, rb2); - assertEquals(0, andresult.getCardinality()); + final IntIterator i = rb.getIntIterator(); + assertTrue(i.hasNext()); + assertEquals(1, i.next()); + assertTrue(i.hasNext()); + assertEquals(2 << 16, i.next()); + assertFalse(i.hasNext()); + } - assertEquals(0, andresult2.getCardinality()); - for (int i = 0; i < 200000; i += 4) { - rb.add(i); - } - for (int i = 200000; i < 400000; i += 14) { - rb.add(i); - } - assertEquals(0, andresult.getCardinality()); - final RoaringBitmap rc = RoaringBitmap.and(rb, rb2); - rb.and(rb2); - assertEquals(rc.getCardinality(), rb.getCardinality()); + @Test + public void andNotBigIntsTest() { + RoaringBitmap rb = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); + HashSet hs = new HashSet(); + for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { + rb.add(i); + hs.add(i); } - - @Test - public void ArrayContainerCardinalityTest() { - final ArrayContainer ac = new ArrayContainer(); - for (char k = 0; k < 100; ++k) { - ac.add(k); - assertEquals(ac.getCardinality(), k + 1); - } - for (char k = 0; k < 100; ++k) { - ac.add(k); - assertEquals(ac.getCardinality(), 100); - } + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + rb.add(i); } - - @Test - public void arraytest() { - final ArrayContainer rr = new ArrayContainer(); - rr.add((char) 110); - rr.add((char) 114); - rr.add((char) 115); - final char[] array = new char[3]; - int pos = 0; - for (final char i : rr) { - array[pos++] = i; - } - assertEquals(array[0], (char) 110); - assertEquals(array[1], (char) 114); - assertEquals(array[2], (char) 115); - } - - @Test - public void basictest() { - final RoaringBitmap rr = new RoaringBitmap(); - final int[] a = new int[4002]; - int pos = 0; - for (int k = 0; k < 4000; ++k) { - rr.add(k); - a[pos++] = k; - } - rr.add(100000); - a[pos++] = 100000; - rr.add(110000); - a[pos++] = 110000; - final int[] array = rr.toArray(); - - - assertArrayEquals(array, a); + for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 6 * 65536; i += 3) { + hs.add(i); + rb.add(i); } - - @Test - public void BitmapContainerCardinalityTest() { - final BitmapContainer ac = new BitmapContainer(); - for (char k = 0; k < 100; ++k) { - ac.add(k); - assertEquals(ac.getCardinality(), k + 1); - } - for (char k = 0; k < 100; ++k) { - ac.add(k); - assertEquals(ac.getCardinality(), 100); - } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { + rb.add(i); } - @Test - public void bitmapOfTest() { - int[] cuiRelsArray = new int[1024]; - for (int k = 0; k < cuiRelsArray.length; ++k) { - cuiRelsArray[k] = k; - } - RoaringBitmap rr1 = RoaringBitmap.bitmapOf(cuiRelsArray); - int[] back = rr1.toArray(); - assertArrayEquals(cuiRelsArray, back); - } - - @Test - public void bitmaptest() { - final BitmapContainer rr = new BitmapContainer(); - rr.add((char) 110); - rr.add((char) 114); - rr.add((char) 115); - final char[] array = new char[3]; - int pos = 0; - for (final char i : rr) { - array[pos++] = i; - } - assertEquals(array[0], (char) 110); - assertEquals(array[1], (char) 114); - assertEquals(array[2], (char) 115); - } - - @Test - public void cardinalityTest() { - final int N = 1024; - for (int gap = 7; gap < 100000; gap *= 10) { - for (int offset = 2; offset <= 1024; offset *= 2) { - final RoaringBitmap rb = new RoaringBitmap(); - // check the add of new values - for (int k = 0; k < N; k++) { - rb.add(k * gap); - assertEquals(rb.getCardinality(), k + 1); - } - assertEquals(rb.getCardinality(), N); - // check the add of existing values - for (int k = 0; k < N; k++) { - rb.add(k * gap); - assertEquals(rb.getCardinality(), N); - } - - final RoaringBitmap rb2 = new RoaringBitmap(); - - for (int k = 0; k < N; k++) { - rb2.add(k * gap * offset); - assertEquals(rb2.getCardinality(), k + 1); - } - - assertEquals(rb2.getCardinality(), N); - - for (int k = 0; k < N; k++) { - rb2.add(k * gap * offset); - assertEquals(rb2.getCardinality(), N); - } - assertEquals(RoaringBitmap.and(rb, rb2).getCardinality(), N / offset); - assertEquals(RoaringBitmap.or(rb, rb2).getCardinality(), 2 * N - N / offset); - assertEquals(RoaringBitmap.xor(rb, rb2).getCardinality(), 2 * N - 2 * N / offset); - } - } + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + rb2.add(i); } - - @Test - public void clearTest() { - final RoaringBitmap rb = new RoaringBitmap(); - for (int i = 0; i < 200000; i += 7) { - // dense - rb.add(i); - } - for (int i = 200000; i < 400000; i += 177) { - // sparse - rb.add(i); - } - - final RoaringBitmap rb2 = new RoaringBitmap(); - final RoaringBitmap rb3 = new RoaringBitmap(); - for (int i = 0; i < 200000; i += 4) { - rb2.add(i); - } - for (int i = 200000; i < 400000; i += 14) { - rb2.add(i); - } - - rb.clear(); - assertEquals(0, rb.getCardinality()); - assertTrue(0 != rb2.getCardinality()); - - rb.add(4); - rb3.add(4); - final RoaringBitmap andresult = RoaringBitmap.and(rb, rb2); - final RoaringBitmap orresult = RoaringBitmap.or(rb, rb2); - - assertEquals(1, andresult.getCardinality()); - assertEquals(rb2.getCardinality(), orresult.getCardinality()); - - for (int i = 0; i < 200000; i += 4) { - rb.add(i); - rb3.add(i); - } - for (int i = 200000; i < 400000; i += 114) { - rb.add(i); - rb3.add(i); - } - - final int[] arrayrr = rb.toArray(); - final int[] arrayrr3 = rb3.toArray(); - - assertArrayEquals(arrayrr, arrayrr3); + for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 4) { + rb2.add(i); } - - @Test - public void ContainerFactory() { - BitmapContainer bc1, bc2, bc3; - ArrayContainer ac1, ac2, ac3; - - bc1 = new BitmapContainer(); - bc2 = new BitmapContainer(); - bc3 = new BitmapContainer(); - ac1 = new ArrayContainer(); - ac2 = new ArrayContainer(); - ac3 = new ArrayContainer(); - - for (char i = 0; i < 5000; i++) { - bc1.add((char) (i * 70)); - } - for (char i = 0; i < 5000; i++) { - bc2.add((char) (i * 70)); - } - for (char i = 0; i < 5000; i++) { - bc3.add((char) (i * 70)); - } - - for (char i = 0; i < 4000; i++) { - ac1.add((char) (i * 50)); - } - for (char i = 0; i < 4000; i++) { - ac2.add((char) (i * 50)); - } - for (char i = 0; i < 4000; i++) { - ac3.add((char) (i * 50)); - } - - BitmapContainer rbc; - - rbc = ac1.clone().toBitmapContainer(); - assertTrue(validate(rbc, ac1)); - rbc = ac2.clone().toBitmapContainer(); - assertTrue(validate(rbc, ac2)); - rbc = ac3.clone().toBitmapContainer(); - assertTrue(validate(rbc, ac3)); - } - - @Test - public void containerSharingWithXor() { - RoaringBitmap r1 = new RoaringBitmap(); - r1.flip(131000L, 131001L); - RoaringBitmap r2 = new RoaringBitmap(); - r2.add(220000); - RoaringBitmap r3 = new RoaringBitmap(); - int killingPosition = 66000; - r3.add(killingPosition); - assertFalse(r1.contains(killingPosition)); - r2.xor(r1); - assertTrue(r2.contains(131000)); - assertFalse(r1.contains(killingPosition)); - r2.or(r3); - assertTrue(r2.contains(131000)); - assertTrue(r2.contains(killingPosition)); - assertFalse(r1.contains(killingPosition)); - } - - // From a bug report contributed by Kevin Karpenske - // this had created an array out of bounds error - @Test - public void fliptest_Karpenske() { - long[] array = new long[]{343798, 343799, 343800, 343801, 343803, 343804, 343805, 343807, 343809, - 343811, 343812, 343815, 343816, 343817, 343818, 343819, 343821, 343825, 343827, 343828, - 343830, 343831, 343832, 343833, 343835, 343836, 343837, 343838, 343839, 343840, 343841, - 343842, 343843, 343844, 343845, 343847, 343848, 343849, 343850, 343851, 343853, 343854, - 343855, 343856, 343858, 343859, 343860, 343861, 343862, 343863, 343864, 343865, 343866, - 343868, 343869, 343874, 343875, 343877, 343879, 343880, 343881, 343882, 343883, 343887, - 343889, 343890, 343891, 343894, 343895, 343898, 343899, 343900, 343901, 343902, 343904, - 343906, 343907, 343908, 343909, 343910, 343911, 343912, 343913, 343914, 343915, 343916, - 343917, 343918, 343919, 343921, 343922, 343923, 343924, 343927, 343928, 343929, 343930, - 343931, 343932, 343933, 343934, 343935, 343938, 343939, 343941, 343942, 343943, 343944, - 343945, 343946, 343949, 343951, 343953, 343954, 343955, 343956, 343958, 343959, 343961, - 343962, 343964, 343965, 343966, 343967, 343968, 343969, 343971, 343972, 343973, 343974, - 343976, 343978, 343979, 343981, 343982, 343983, 343985, 343987, 343988, 343989, 343992, - 343993, 343994, 343995, 343996, 343997, 343998, 344000, 344001, 344002, 344003, 344004, - 344006, 344008, 344009, 344011, 344012, 344013, 344015, 344017, 344019, 344020, 344021, - 344023, 344025, 344026, 344027, 344028, 344029, 344030, 344031, 344034, 344035, 344036, - 344037, 344038, 344039, 344040, 344042, 344043, 344046, 344047}; - RoaringBitmap bitmap = new RoaringBitmap(); - long[] indexes = array; - int rangeStart = 0; - for (int rangeEnd = 1; rangeEnd < indexes.length; rangeEnd++) { - if (indexes[rangeEnd - 1] + 1 != indexes[rangeEnd]) { - if (rangeStart == rangeEnd - 1) { - bitmap.add((int) indexes[rangeStart]); - } else { - bitmap.flip(indexes[rangeStart], indexes[rangeEnd - 1] + 1); - } - rangeStart = rangeEnd; - } - } - if (rangeStart == indexes.length - 1) { - bitmap.add((int) indexes[rangeStart]); - } else { - bitmap.flip(indexes[rangeStart], indexes[indexes.length - 1] + 1); - } - assertEquals(182, bitmap.getCardinality()); + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 5) { + rb2.add(i); } - - @Test - public void flipTest1() { - final RoaringBitmap rb = new RoaringBitmap(); - - rb.flip(100000L, 200000L); // in-place on empty bitmap - final int rbcard = rb.getCardinality(); - assertEquals(100000, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 100000; i < 200000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb)); + for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 7) { + rb2.add(i); } - @Test - public void flipTest1A() { - final RoaringBitmap rb = new RoaringBitmap(); + RoaringBitmap rbandnot = RoaringBitmap.andNot(rb, rb2); - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 200000L); - final int rbcard = rb1.getCardinality(); - assertEquals(100000, rbcard); - assertEquals(0, rb.getCardinality()); + Object[] correct = hs.toArray(); + Arrays.sort(correct); + Integer[] resandNot = ArrayUtils.toObject(rbandnot.toArray()); + assertArrayEquals(correct, resandNot); + } - final BitSet bs = new BitSet(); - assertTrue(equals(bs, rb)); // still empty? - for (int i = 100000; i < 200000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb1)); + @Test + public void ANDNOTtest() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr.add(k); } - - @Test - public void flipTest2() { - final RoaringBitmap rb = new RoaringBitmap(); - - rb.flip(100000L, 100000L); - final int rbcard = rb.getCardinality(); - assertEquals(0, rbcard); - - final BitSet bs = new BitSet(); - assertTrue(equals(bs, rb)); + for (int k = 65536; k < 65536 + 4000; ++k) { + rr.add(k); } - - @Test - public void flipTest2A() { - final RoaringBitmap rb = new RoaringBitmap(); - - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 100000L); - rb.add(1); // will not affect rb1 (no shared container) - final int rbcard = rb1.getCardinality(); - assertEquals(0, rbcard); - assertEquals(1, rb.getCardinality()); - - final BitSet bs = new BitSet(); - assertTrue(equals(bs, rb1)); - bs.set(1); - assertTrue(equals(bs, rb)); + for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { + rr.add(k); } - - @Test - public void flipTest3() { - final RoaringBitmap rb = new RoaringBitmap(); - - rb.flip(100000L, 200000L); // got 100k-199999 - rb.flip(100000L, 199991L); // give back 100k-199990 - final int rbcard = rb.getCardinality(); - - assertEquals(9, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 199991; i < 200000; ++i) { - bs.set(i); - } - - assertTrue(equals(bs, rb)); + for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { + rr.add(k); } - - @Test - public void flipTest3A() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 200000L); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 100000L, 199991L); - final int rbcard = rb2.getCardinality(); - - assertEquals(9, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 199991; i < 200000; ++i) { - bs.set(i); - } - - assertTrue(equals(bs, rb2)); + for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { + rr.add(k); } - - @Test - public void flipTest4() { // fits evenly on both ends - final RoaringBitmap rb = new RoaringBitmap(); - rb.flip(100000L, 200000L); // got 100k-199999 - rb.flip(65536L, 4 * 65536L); - final int rbcard = rb.getCardinality(); - - // 65536 to 99999 are 1s - // 200000 to 262143 are 1s: total card - - assertEquals(96608, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 65536; i < 100000; ++i) { - bs.set(i); - } - for (int i = 200000; i < 262144; ++i) { - bs.set(i); - } - - assertTrue(equals(bs, rb)); + for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { + rr.add(k); } - - @Test - public void flipTest4A() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 200000L); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 65536L, 4 * 65536L); - final int rbcard = rb2.getCardinality(); - - assertEquals(96608, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 65536; i < 100000; ++i) { - bs.set(i); - } - for (int i = 200000; i < 262144; ++i) { - bs.set(i); - } - - assertTrue(equals(bs, rb2)); + for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { + rr.add(k); } - @Test - public void flipTest5() { // fits evenly on small end, multiple - // containers - final RoaringBitmap rb = new RoaringBitmap(); - rb.flip(100000L, 132000L); - rb.flip(65536L, 120000L); - final int rbcard = rb.getCardinality(); - - // 65536 to 99999 are 1s - // 120000 to 131999 - - assertEquals(46464, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 65536; i < 100000; ++i) { - bs.set(i); - } - for (int i = 120000; i < 132000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb)); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr2.add(k); } - - @Test - public void flipTest5A() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 132000L); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 65536L, 120000L); - final int rbcard = rb2.getCardinality(); - - assertEquals(46464, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 65536; i < 100000; ++i) { - bs.set(i); - } - for (int i = 120000; i < 132000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb2)); + for (int k = 65536; k < 65536 + 4000; ++k) { + rr2.add(k); } - - @Test - public void flipTest6() { // fits evenly on big end, multiple containers - final RoaringBitmap rb = new RoaringBitmap(); - rb.flip(100000L, 132000L); - rb.flip(99000L, 2 * 65536L); - final int rbcard = rb.getCardinality(); - - // 99000 to 99999 are 1000 1s - // 131072 to 131999 are 928 1s - - assertEquals(1928, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 99000; i < 100000; ++i) { - bs.set(i); - } - for (int i = 2 * 65536; i < 132000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb)); + for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { + rr2.add(k); } - - @Test - public void flipTest6A() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 132000L); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 99000L, 2 * 65536L); - final int rbcard = rb2.getCardinality(); - - assertEquals(1928, rbcard); - - final BitSet bs = new BitSet(); - for (int i = 99000; i < 100000; ++i) { - bs.set(i); - } - for (int i = 2 * 65536; i < 132000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb2)); + for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { + rr2.add(k); } + for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { + rr2.add(k); + } + for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { + rr2.add(k); + } + final RoaringBitmap correct = RoaringBitmap.andNot(rr, rr2); + rr.andNot(rr2); + assertEquals(correct, rr); + } - @Test - public void flipTest7() { // within 1 word, first container - final RoaringBitmap rb = new RoaringBitmap(); - rb.flip(650L, 132000L); - rb.flip(648L, 651L); - final int rbcard = rb.getCardinality(); - - // 648, 649, 651-131999 - - assertEquals(132000 - 651 + 2, rbcard); + @Test + public void andnottest4() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); - final BitSet bs = new BitSet(); - bs.set(648); - bs.set(649); - for (int i = 651; i < 132000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb)); + for (int i = 0; i < 200000; i += 4) { + rb2.add(i); } + for (int i = 200000; i < 400000; i += 14) { + rb2.add(i); + } + rb2.getCardinality(); - @Test - public void flipTest7A() { // within 1 word, first container - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 650L, 132000L); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 648L, 651L); - final int rbcard = rb2.getCardinality(); - - // 648, 649, 651-131999 + // check or against an empty bitmap + final RoaringBitmap andNotresult = RoaringBitmap.andNot(rb, rb2); + final RoaringBitmap off = RoaringBitmap.andNot(rb2, rb); - assertEquals(132000 - 651 + 2, rbcard); + assertEquals(rb, andNotresult); + assertEquals(rb2, off); + rb2.andNot(rb); + assertEquals(rb2, off); + } - final BitSet bs = new BitSet(); - bs.set(648); - bs.set(649); - for (int i = 651; i < 132000; ++i) { - bs.set(i); - } - assertTrue(equals(bs, rb2)); + @Test + public void andtest() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr.add(k); } + rr.add(100000); + rr.add(110000); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(13); + final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); + int[] array = rrand.toArray(); - @Test - public void flipTest8() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(0); - rb.add(2); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb, 0L, 3L); + assertEquals(array.length, 1); + assertEquals(array[0], 13); + rr.and(rr2); + array = rr.toArray(); + assertEquals(array.length, 1); + assertEquals(array[0], 13); + } - final BitSet bs = new BitSet(); - bs.set(1); - assertTrue(equals(bs, rb2)); + @Test + public void ANDtest() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr.add(k); } - - - @Test - public void flipTestBigInt() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(Integer.MAX_VALUE + 100000); - rb.add(Integer.MAX_VALUE + 100002); - final RoaringBitmap rb2 = RoaringBitmap.flip(rb, Integer.MAX_VALUE + 100001L, - Integer.MAX_VALUE + 200000L); - assertEquals(99999, rb2.getCardinality()); - assertTrue(rb2.contains(Integer.MAX_VALUE + 100000)); - assertFalse(rb2.contains(Integer.MAX_VALUE + 100002)); - assertTrue(rb2.contains(Integer.MAX_VALUE + 199999)); + for (int k = 65536; k < 65536 + 4000; ++k) { + rr.add(k); } - - - @Test - public void flipTestBig() { - final int numCases = 1000; - final RoaringBitmap rb = new RoaringBitmap(); - final BitSet bs = new BitSet(); - final Random r = new Random(3333); - int checkTime = 2; - - for (int i = 0; i < numCases; ++i) { - final long start = r.nextInt(65536 * 20); - long end = r.nextInt(65536 * 20); - if (r.nextDouble() < 0.1) { - end = start + r.nextInt(100); - } - rb.flip(start, end); - if (start < end) { - bs.flip((int) start, (int) end); // throws exception - } - // otherwise - // insert some more ANDs to keep things sparser - if (r.nextDouble() < 0.2) { - final RoaringBitmap mask = new RoaringBitmap(); - final BitSet mask1 = new BitSet(); - final long startM = r.nextInt(65536 * 20); - final long endM = startM + 100000; - mask.flip(startM, endM); - mask1.flip((int) startM, (int) endM); - mask.flip(0L, 65536L * 20 + 100000); - mask1.flip(0, 65536 * 20 + 100000); - rb.and(mask); - bs.and(mask1); - } - // see if we can detect incorrectly shared containers - if (r.nextDouble() < 0.1) { - final RoaringBitmap irrelevant = RoaringBitmap.flip(rb, 10L, 100000L); - irrelevant.flip(5L, 200000L); - irrelevant.flip(190000L, 260000L); - } - if (i > checkTime) { - assertTrue(equals(bs, rb)); - checkTime *= 1.5; - } - } + for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { + rr.add(k); } - - @Test - public void flipTestBigA() { - final int numCases = 1000; - final BitSet bs = new BitSet(); - final Random r = new Random(3333); - int checkTime = 2; - RoaringBitmap rb1 = new RoaringBitmap(), rb2 = null; // alternate - // between - // them - for (int i = 0; i < numCases; ++i) { - final int start = r.nextInt(65536 * 20); - int end = r.nextInt(65536 * 20); - if (r.nextDouble() < 0.1) { - end = start + r.nextInt(100); - } - - if ((i & 1) == 0) { - rb2 = RoaringBitmap.flip(rb1, (long) start, (long) end); - // tweak the other, catch bad sharing - long r1 = r.nextInt(65536 * 20); - long r2 = r.nextInt(65536 * 20); - rb1.flip(r1, r2); - } else { - rb1 = RoaringBitmap.flip(rb2, (long) start, (long) end); - long r1 = r.nextInt(65536 * 20); - long r2 = r.nextInt(65536 * 20); - rb2.flip(r1, r2); - } - - if (start < end) { - bs.flip(start, end); // throws exception - // otherwise - } - // insert some more ANDs to keep things sparser - if (r.nextDouble() < 0.2 && (i & 1) == 0) { - final RoaringBitmap mask = new RoaringBitmap(); - final BitSet mask1 = new BitSet(); - final int startM = r.nextInt(65536 * 20); - final int endM = startM + 100000; - mask.flip((long) startM, (long) endM); - mask1.flip(startM, endM); - mask.flip(0L, 65536L * 20 + 100000); - mask1.flip(0, 65536 * 20 + 100000); - rb2.and(mask); - bs.and(mask1); - } - if (i > checkTime) { - final RoaringBitmap rb = (i & 1) == 0 ? rb2 : rb1; - final boolean status = equals(bs, rb); - assertTrue(status); - checkTime *= 1.5; - } - } + for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { + rr.add(k); } - - @Test - public void intersecttest() { - final RoaringBitmap rr1 = new RoaringBitmap(); - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 0; k < 40000; ++k) { - rr1.add(2 * k); - rr2.add(2 * k + 1); - } - assertFalse(RoaringBitmap.intersects(rr1, rr2)); - rr1.add(2 * 500 + 1); - assertTrue(RoaringBitmap.intersects(rr1, rr2)); - final RoaringBitmap rr3 = new RoaringBitmap(); - rr3.add(2 * 501 + 1); - assertTrue(RoaringBitmap.intersects(rr3, rr2)); - assertFalse(RoaringBitmap.intersects(rr3, rr1)); - for (int k = 0; k < 40000; ++k) { - rr1.add(2 * k + 1); - } - rr1.runOptimize(); - assertTrue(RoaringBitmap.intersects(rr1, rr2)); - } - - @Test - public void intersecttestWithRange() { - RoaringBitmap rr1 = new RoaringBitmap(); - RoaringBitmap rr2 = new RoaringBitmap(); - RoaringBitmap rr3 = new RoaringBitmap(); - - // This bitmap containers will be Run Containers - rr1.add(1L, 4L); - rr1.add(6L, 10L); - - - // This one will be Array Containers - rr2.add(0); - rr2.add(2); - - rr2.add(6); - rr2.add(7); - rr2.add(9); - - assertFalse(rr1.intersects(0, 1)); - assertTrue(rr1.intersects(0, 3)); - assertTrue(rr1.intersects(0, 11)); - assertFalse(rr1.intersects(12, 14)); - assertFalse(rr1.intersects(4, 5)); - assertTrue(rr1.intersects(2, 3)); - assertTrue(rr1.intersects(4, 8)); - assertTrue(rr1.intersects(8, 12)); - - assertTrue(rr2.intersects(0, 11)); - assertFalse(rr2.intersects(12, 14)); - assertFalse(rr2.intersects(4, 5)); - assertTrue(rr2.intersects(2, 3)); - assertTrue(rr2.intersects(4, 8)); - assertTrue(rr2.intersects(8, 12)); - - rr3.add(5L, 10L); - assertTrue(rr3.intersects(5, 10)); - } - - - @Test - public void shouldNotIntersectWithDisjointRangeBelowBitmapFirst() { - char[] keys = new char[1]; - Container[] values = new Container[1]; - RoaringBitmap bitmap = new RoaringBitmap(new RoaringArray(keys, values, 1)); - keys[0] = (char) (1 << 15); - long[] bits = new long[1024]; - long word = 1789303257167203747L; - Arrays.fill(bits, word); - values[0] = new BitmapContainer(bits, 1024 * Long.bitCount(word)); - assertFalse(bitmap.intersects(0, bitmap.first() & 0xFFFFFFFFL)); - } - - @Test - public void shouldIntersectWithFirstWhenBitmapAtStart() { - char[] keys = new char[1]; - Container[] values = new Container[1]; - RoaringBitmap bitmap = new RoaringBitmap(new RoaringArray(keys, values, 1)); - keys[0] = (char) (1 << 15); - long[] bits = new long[1024]; - long word = 2697219678014362575L; - Arrays.fill(bits, word); - values[0] = new BitmapContainer(bits, 1024 * Long.bitCount(word)); - long first = (bitmap.first() & 0xFFFFFFFFL); - assertTrue(bitmap.intersects(first - 1, first + 1)); - assertTrue(bitmap.intersects(first, first + 1)); - assertFalse(bitmap.intersects(first - 1, first)); - } - - @Test - public void orBigIntsTest() { - RoaringBitmap rb = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); - HashSet hs = new HashSet(); - - for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { - rb.add(i); - hs.add(i); - } - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - hs.add(i); - rb.add(i); - } - for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 5) { - hs.add(i); - rb.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 3) { - hs.add(i); - rb.add(i); - } - - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 5) { - hs.add(i); - rb2.add(i); - } - for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 3) { - hs.add(i); - rb2.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 11 * 65536; i += 5) { - hs.add(i); - rb2.add(i); - } - for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 7) { - hs.add(i); - rb2.add(i); - } - - RoaringBitmap rbor = RoaringBitmap.or(rb, rb2); - - Object[] correct = hs.toArray(); - Arrays.sort(correct); - Integer[] resor = ArrayUtils.toObject(rbor.toArray()); - assertArrayEquals(correct, resor); + for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { + rr.add(k); } - - @Test - public void orcount() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr.add(k); - } - rr.add(100000); - rr.add(110000); - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr2.add(k); - } - - final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); - assertEquals(rror.getCardinality(), RoaringBitmap.orCardinality(rr, rr2)); - + for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { + rr.add(k); } - - @Test - public void testXorCardinality() { - final RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rb.add(k); - } - rb.add(100000); - rb.add(110000); - rb.add(1L << 20, 1L << 21); - rb.flip((1 << 20) | (1 << 19)); - final RoaringBitmap rb2 = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rb2.add(k); - } - RoaringBitmap xor = RoaringBitmap.xor(rb, rb2); - assertEquals(xor.getCardinality(), RoaringBitmap.xorCardinality(rb, rb2)); + for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { + rr.add(k); } - @Test - public void testAndNotCardinality() { - final RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rb.add(k); - } - rb.add(100000); - rb.add(110000); - rb.add(1L << 20, 1L << 21); - rb.flip((1 << 20) | (1 << 19)); - final RoaringBitmap rb2 = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rb2.add(k); - } - RoaringBitmap andNot = RoaringBitmap.andNot(rb, rb2); - assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(rb, rb2)); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr2.add(k); } - - @Test - public void testAndNotCardinalityBigVsSmall() { - RoaringBitmap small = RoaringBitmap.bitmapOf(1, 2, 3); - RoaringBitmap big = new RoaringBitmap(); - for (int i = 0; i < 4000; ++i) { - big.add(1 + i * 0x1000); - } - RoaringBitmap andNot = RoaringBitmap.andNot(big, small); - assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(big, small)); + for (int k = 65536; k < 65536 + 4000; ++k) { + rr2.add(k); } - - @Test - public void testAndNotCardinalitySmallVsBig() { - RoaringBitmap small = RoaringBitmap.bitmapOf(1, 2, 3); - RoaringBitmap big = new RoaringBitmap(); - for (int i = 0; i < 4000; ++i) { - big.add(1 + i * 0x1000); - } - RoaringBitmap andNot = RoaringBitmap.andNot(small, big); - assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(small, big)); + for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { + rr2.add(k); } - - @Test - public void testAndNotCardinality_646() { - RoaringBitmap rb = RoaringBitmap.bitmapOf(-587409880, 605467000); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(-587409880, 347844183); - - RoaringBitmap andNot = RoaringBitmap.andNot(rb, rb2); - assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(rb, rb2)); + for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { + rr2.add(k); } - - @Test - public void testAndNotCardinality_648() { - RoaringBitmap s1 = RoaringBitmap.bitmapOf(-1388308580, 236217409, -805382570, 612285977, 1389629939, 851442526, 375756307, 61533603, 1908301308, 2097309572, 204769050, 703198559, -545810986, 2090296816, -87319453, 158018332, -685188145, -566739002, -1446363859, -372441875, -957637004, -1144076256, -1248859542, -160225853, 14707613, 866274329, 1550526350, 877999004, -1784269953, 1274953255, 1490490469, -1340013077, 2067958239, 51232349, 2060711699, -1802459974, 2039829040, -2079650027, -278950425, 1145674649, 298101576, 1687655442, 1209489632, -762136131, 399832491, 1077638711, -635674559, -1643781464, -1067907341, 144525399, 651571848, 1893053071, -2058528151, 1592871441, 84583235, 374119809, -867104416, -1941224259, 787356209, 1972857336, -720703901, -1310021857, -1831922816, 181898740, 600942551, -1745822849, -856908487, 2060184086, -1217485514, -1680395029, 1539735915, 2042390564, -1539856946, 1824974207, 1695025297, 1908431629, -395090370, -1688185468, 570601902, -701368853, -1211735380, -825285093, 788089714, -857723909, 1400502194, 285106906, -1450842998, -2125215206, 1451519492, -1559357910, 1157633452, -387704829, 2036134025, 1051239778, -1542956455, 357879569, 1962230155, -1994777800, 672516512, 174507423, -299175291, 821891018, 1062886766, -1313955904, 1732661804, -767116537, 1352149580, 2001322279, 1698147357, 40451458, 996819026, 1904959950, 2058544757, 1514282221, 234242255, -1364505429, 1498471146, 1134429786, -918860049, 1430732385, 644983298, 793600316, -1726956640, -538511147, -1945670935, 291567421, 1033590420, -1831809482, 985031287, -773476240, 1724734191, -1364525376, 1208307142, -2126741265, -1851759120, 1083333467, 185208087, -375950074, 48210573, -843304856, -295266615, -843941360, -524390895, -102924717, 836117637, 683196001, -1824825594, -1470017798, -1554712054, 291236023, -907874606, 2068945326, -899352179, -1488751007, -449279886, -1085935420, -2094131785, -474243782, 1306756671, 1353254318, 86944198, 1148225154, 487252515, -229770314, -1484325603, 109043190, -252122045, 1431750974, 1667547537, -1775516477, -512978266, -216545450, -486550865, -1193721685, -1108677522, -628326149, -1568065979, -675571394); - RoaringBitmap s2 = RoaringBitmap.bitmapOf(2060184086, 704452713, 1236293943, -178539376, 2037977331, -78910667, -587409880, 204769050, -854426111, 90628341, -1411939301, -927754519, -211274987, 998450197, -1515133464, -1652963250, 499001553, 383696025, -2019580769, 1583380373, -79264832, 1065614902, 1243463658, 424214238, 1124141647, 271662535, 1415634429, 1893053071, -1624960757, -1933550809, -1170233109, -542340662, -1681838238, 292656484, 1587781520, -1463647396, -124042559, -162307067, 1411905814, -1524651941, 1935844108, 1992426746, 422443777, 679395872, -764857187, -401706366, -2007177999, 1044794027, -1561188953, 1627034126, -401273669, -123973748, -694963705, 838892817, -1640102435, 852253834, -23120023, -2072644924, 1140820264, -550227319, -1692730465, 1491150291, 1607642920, -1015774573, -1801713682, -752796152, -439281693, -792361100, -188208805, 808883165, -1364525376, 896915854, -1672522244, -1718572341); - RoaringBitmap s3 = RoaringBitmap.bitmapOf(-30718004, -1652963250, -762136131, -1552606582, -1933550809, -1230616126, 736584428, -2136360654, 1097548480, 192408815, -295266615); - RoaringBitmap s1AndS2 = RoaringBitmap.and(s1, s2); - assertEquals(RoaringBitmap.andNot(s1AndS2, s3).getCardinality(), RoaringBitmap.andNotCardinality(s1AndS2, s3)); + for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { + rr2.add(k); } - - @Test - public void ortest() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr.add(k); - } - rr.add(100000); - rr.add(110000); - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr2.add(k); - } - - final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); - - final int[] array = rror.toArray(); - final int[] arrayrr = rr.toArray(); - - assertArrayEquals(array, arrayrr); - - rr.or(rr2); - final int[] arrayirr = rr.toArray(); - assertArrayEquals(array, arrayirr); - + for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { + rr2.add(k); } + final RoaringBitmap correct = RoaringBitmap.and(rr, rr2); + rr.and(rr2); + assertEquals(correct, rr); + } - @Test - public void ORtest() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { - rr.add(k); - } - for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { - rr.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { - rr.add(k); - } - for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { - rr.add(k); - } - for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { - rr.add(k); - } - - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr2.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr2.add(k); - } - for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { - rr2.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { - rr2.add(k); - } - final RoaringBitmap correct = RoaringBitmap.or(rr, rr2); - rr.or(rr2); - assertEquals(correct, rr); - } - - @Test - public void ortest2() { - final int[] arrayrr = new int[4000 + 4000 + 2]; - int pos = 0; - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rr.add(k); - arrayrr[pos++] = k; - } - rr.add(100000); - rr.add(110000); - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 8000; ++k) { - rr2.add(k); - arrayrr[pos++] = k; - } - - arrayrr[pos++] = 100000; - arrayrr[pos++] = 110000; - - final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); - - final int[] arrayor = rror.toArray(); - - assertArrayEquals(arrayor, arrayrr); + @Test + public void andtest2() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr.add(k); } + rr.add(100000); + rr.add(110000); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(13); + final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - @Test - public void ortest3() { - final HashSet V1 = new HashSet(); - final HashSet V2 = new HashSet(); + final int[] array = rrand.toArray(); + assertEquals(array.length, 1); + assertEquals(array[0], 13); + } - final RoaringBitmap rr = new RoaringBitmap(); - final RoaringBitmap rr2 = new RoaringBitmap(); - // For the first 65536: rr2 has a bitmap container, and rr has - // an array container. - // We will check the union between a BitmapCintainer and an - // arrayContainer - for (int k = 0; k < 4000; ++k) { - rr2.add(k); - V1.add(k); - } - for (int k = 3500; k < 4500; ++k) { - rr.add(k); - V1.add(k); - } - for (int k = 4000; k < 65000; ++k) { - rr2.add(k); - V1.add(k); - } - - // In the second node of each roaring bitmap, we have two bitmap - // containers. - // So, we will check the union between two BitmapContainers - for (int k = 65536; k < 65536 + 10000; ++k) { - rr.add(k); - V1.add(k); - } - - for (int k = 65536; k < 65536 + 14000; ++k) { - rr2.add(k); - V1.add(k); - } - - // In the 3rd node of each Roaring Bitmap, we have an - // ArrayContainer, so, we will try the union between two - // ArrayContainers. - for (int k = 4 * 65535; k < 4 * 65535 + 1000; ++k) { - rr.add(k); - V1.add(k); - } - - for (int k = 4 * 65535; k < 4 * 65535 + 800; ++k) { - rr2.add(k); - V1.add(k); - } - - // For the rest, we will check if the union will take them in - // the result - for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { - rr.add(k); - V1.add(k); - } + @Test + public void andtest3() { + final int[] arrayand = new int[11256]; + int pos = 0; + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr.add(k); + } + for (int k = 65536; k < 65536 + 4000; ++k) { + rr.add(k); + } + for (int k = 3 * 65536; k < 3 * 65536 + 1000; ++k) { + rr.add(k); + } + for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { + rr.add(k); + } + for (int k = 3 * 65536 + 7000; k < 3 * 65536 + 9000; ++k) { + rr.add(k); + } + for (int k = 4 * 65536; k < 4 * 65536 + 7000; ++k) { + rr.add(k); + } + for (int k = 6 * 65536; k < 6 * 65536 + 10000; ++k) { + rr.add(k); + } + for (int k = 8 * 65536; k < 8 * 65536 + 1000; ++k) { + rr.add(k); + } + for (int k = 9 * 65536; k < 9 * 65536 + 30000; ++k) { + rr.add(k); + } - for (int k = 7 * 65535; k < 7 * 65535 + 2000; ++k) { - rr2.add(k); - V1.add(k); - } + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 65536; k < 65536 + 4000; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 3 * 65536 + 1000; k < 3 * 65536 + 7000; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 6 * 65536; k < 6 * 65536 + 1000; ++k) { + rr2.add(k); + arrayand[pos++] = k; + } + for (int k = 7 * 65536; k < 7 * 65536 + 1000; ++k) { + rr2.add(k); + } + for (int k = 10 * 65536; k < 10 * 65536 + 5000; ++k) { + rr2.add(k); + } - final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); - boolean valide = true; + final RoaringBitmap rrand = RoaringBitmap.and(rr, rr2); - // Si tous les elements de rror sont dans V1 et que tous les - // elements de - // V1 sont dans rror(V2) - // alors V1 == rror + final int[] arrayres = rrand.toArray(); - final Object[] tab = V1.toArray(); - final Vector vector = new Vector(); - for (Object aTab : tab) { - vector.add((Integer) aTab); - } + assertArrayEquals(arrayand, arrayres); + } - for (final int i : rror.toArray()) { - if (!vector.contains(i)) { - valide = false; - } - V2.add(i); - } - for (int i = 0; i < V1.size(); i++) { - if (!V2.contains(vector.elementAt(i))) { - valide = false; - } - } + @Test + public void andtest4() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); - assertTrue(valide); + for (int i = 0; i < 200000; i += 4) { + rb2.add(i); } - - @Test - public void ortest4() { + for (int i = 200000; i < 400000; i += 14) { + rb2.add(i); + } + + // check or against an empty bitmap + final RoaringBitmap andresult = RoaringBitmap.and(rb, rb2); + final RoaringBitmap off = RoaringBitmap.and(rb2, rb); + assertEquals(andresult, off); + + assertEquals(0, andresult.getCardinality()); + + for (int i = 500000; i < 600000; i += 14) { + rb.add(i); + } + for (int i = 200000; i < 400000; i += 3) { + rb2.add(i); + } + // check or against an empty bitmap + final RoaringBitmap andresult2 = RoaringBitmap.and(rb, rb2); + assertEquals(0, andresult.getCardinality()); + + assertEquals(0, andresult2.getCardinality()); + for (int i = 0; i < 200000; i += 4) { + rb.add(i); + } + for (int i = 200000; i < 400000; i += 14) { + rb.add(i); + } + assertEquals(0, andresult.getCardinality()); + final RoaringBitmap rc = RoaringBitmap.and(rb, rb2); + rb.and(rb2); + assertEquals(rc.getCardinality(), rb.getCardinality()); + } + + @Test + public void ArrayContainerCardinalityTest() { + final ArrayContainer ac = new ArrayContainer(); + for (char k = 0; k < 100; ++k) { + ac.add(k); + assertEquals(ac.getCardinality(), k + 1); + } + for (char k = 0; k < 100; ++k) { + ac.add(k); + assertEquals(ac.getCardinality(), 100); + } + } + + @Test + public void arraytest() { + final ArrayContainer rr = new ArrayContainer(); + rr.add((char) 110); + rr.add((char) 114); + rr.add((char) 115); + final char[] array = new char[3]; + int pos = 0; + for (final char i : rr) { + array[pos++] = i; + } + assertEquals(array[0], (char) 110); + assertEquals(array[1], (char) 114); + assertEquals(array[2], (char) 115); + } + + @Test + public void basictest() { + final RoaringBitmap rr = new RoaringBitmap(); + final int[] a = new int[4002]; + int pos = 0; + for (int k = 0; k < 4000; ++k) { + rr.add(k); + a[pos++] = k; + } + rr.add(100000); + a[pos++] = 100000; + rr.add(110000); + a[pos++] = 110000; + final int[] array = rr.toArray(); + + assertArrayEquals(array, a); + } + + @Test + public void BitmapContainerCardinalityTest() { + final BitmapContainer ac = new BitmapContainer(); + for (char k = 0; k < 100; ++k) { + ac.add(k); + assertEquals(ac.getCardinality(), k + 1); + } + for (char k = 0; k < 100; ++k) { + ac.add(k); + assertEquals(ac.getCardinality(), 100); + } + } + + @Test + public void bitmapOfTest() { + int[] cuiRelsArray = new int[1024]; + for (int k = 0; k < cuiRelsArray.length; ++k) { + cuiRelsArray[k] = k; + } + RoaringBitmap rr1 = RoaringBitmap.bitmapOf(cuiRelsArray); + int[] back = rr1.toArray(); + assertArrayEquals(cuiRelsArray, back); + } + + @Test + public void bitmaptest() { + final BitmapContainer rr = new BitmapContainer(); + rr.add((char) 110); + rr.add((char) 114); + rr.add((char) 115); + final char[] array = new char[3]; + int pos = 0; + for (final char i : rr) { + array[pos++] = i; + } + assertEquals(array[0], (char) 110); + assertEquals(array[1], (char) 114); + assertEquals(array[2], (char) 115); + } + + @Test + public void cardinalityTest() { + final int N = 1024; + for (int gap = 7; gap < 100000; gap *= 10) { + for (int offset = 2; offset <= 1024; offset *= 2) { final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - - for (int i = 0; i < 200000; i += 4) { - rb2.add(i); - } - for (int i = 200000; i < 400000; i += 14) { - rb2.add(i); - } - final int rb2card = rb2.getCardinality(); - - // check or against an empty bitmap - final RoaringBitmap orresult = RoaringBitmap.or(rb, rb2); - final RoaringBitmap off = RoaringBitmap.or(rb2, rb); - assertEquals(orresult, off); - - assertEquals(rb2card, orresult.getCardinality()); - - for (int i = 500000; i < 600000; i += 14) { - rb.add(i); + // check the add of new values + for (int k = 0; k < N; k++) { + rb.add(k * gap); + assertEquals(rb.getCardinality(), k + 1); } - for (int i = 200000; i < 400000; i += 3) { - rb2.add(i); + assertEquals(rb.getCardinality(), N); + // check the add of existing values + for (int k = 0; k < N; k++) { + rb.add(k * gap); + assertEquals(rb.getCardinality(), N); } - // check or against an empty bitmap - final RoaringBitmap orresult2 = RoaringBitmap.or(rb, rb2); - assertEquals(rb2card, orresult.getCardinality()); - - assertEquals(rb2.getCardinality() + rb.getCardinality(), orresult2.getCardinality()); - rb.or(rb2); - assertEquals(rb, orresult2); - } - - @Test - public void orNot() { - final RoaringBitmap rb = new RoaringBitmap(); final RoaringBitmap rb2 = new RoaringBitmap(); - rb.add(2); - rb.add(1); - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 - - rb2.add(1 << 16);// 65536 - rb2.add(3 << 16);//196608 - - rb.orNot(rb2, (4 << 16) - 1); - - assertEquals((4 << 16) - 1, rb.getCardinality()); + for (int k = 0; k < N; k++) { + rb2.add(k * gap * offset); + assertEquals(rb2.getCardinality(), k + 1); + } - final IntIterator iterator = rb.getIntIterator(); + assertEquals(rb2.getCardinality(), N); - for (int i = 0; i < (4 << 16) - 1; ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next()); + for (int k = 0; k < N; k++) { + rb2.add(k * gap * offset); + assertEquals(rb2.getCardinality(), N); } - assertFalse(iterator.hasNext()); + assertEquals(RoaringBitmap.and(rb, rb2).getCardinality(), N / offset); + assertEquals(RoaringBitmap.or(rb, rb2).getCardinality(), 2 * N - N / offset); + assertEquals(RoaringBitmap.xor(rb, rb2).getCardinality(), 2 * N - 2 * N / offset); + } } + } - - @Test - public void orNotRegressionTest() { - long len = 3L; - long orLen = 3L; - - RoaringBitmap one = new RoaringBitmap(); - RoaringBitmap other = new RoaringBitmap(); - other.add(0L, len); - - one.orNot(other, orLen); + @Test + public void clearTest() { + final RoaringBitmap rb = new RoaringBitmap(); + for (int i = 0; i < 200000; i += 7) { + // dense + rb.add(i); + } + for (int i = 200000; i < 400000; i += 177) { + // sparse + rb.add(i); } - @Test - public void orNotZeroRangeEndPreservesBitmap() { - RoaringBitmap one = new RoaringBitmap(); - one.add(32); - - RoaringBitmap other = new RoaringBitmap(); - other.add(0L, 100); - - one.orNot(other, 0); - assertEquals(one, RoaringBitmap.bitmapOf(32)); + final RoaringBitmap rb2 = new RoaringBitmap(); + final RoaringBitmap rb3 = new RoaringBitmap(); + for (int i = 0; i < 200000; i += 4) { + rb2.add(i); + } + for (int i = 200000; i < 400000; i += 14) { + rb2.add(i); + } + + rb.clear(); + assertEquals(0, rb.getCardinality()); + assertTrue(0 != rb2.getCardinality()); + + rb.add(4); + rb3.add(4); + final RoaringBitmap andresult = RoaringBitmap.and(rb, rb2); + final RoaringBitmap orresult = RoaringBitmap.or(rb, rb2); + + assertEquals(1, andresult.getCardinality()); + assertEquals(rb2.getCardinality(), orresult.getCardinality()); + + for (int i = 0; i < 200000; i += 4) { + rb.add(i); + rb3.add(i); + } + for (int i = 200000; i < 400000; i += 114) { + rb.add(i); + rb3.add(i); + } + + final int[] arrayrr = rb.toArray(); + final int[] arrayrr3 = rb3.toArray(); + + assertArrayEquals(arrayrr, arrayrr3); + } + + @Test + public void ContainerFactory() { + BitmapContainer bc1, bc2, bc3; + ArrayContainer ac1, ac2, ac3; + + bc1 = new BitmapContainer(); + bc2 = new BitmapContainer(); + bc3 = new BitmapContainer(); + ac1 = new ArrayContainer(); + ac2 = new ArrayContainer(); + ac3 = new ArrayContainer(); + + for (char i = 0; i < 5000; i++) { + bc1.add((char) (i * 70)); + } + for (char i = 0; i < 5000; i++) { + bc2.add((char) (i * 70)); + } + for (char i = 0; i < 5000; i++) { + bc3.add((char) (i * 70)); + } + + for (char i = 0; i < 4000; i++) { + ac1.add((char) (i * 50)); + } + for (char i = 0; i < 4000; i++) { + ac2.add((char) (i * 50)); + } + for (char i = 0; i < 4000; i++) { + ac3.add((char) (i * 50)); + } + + BitmapContainer rbc; + + rbc = ac1.clone().toBitmapContainer(); + assertTrue(validate(rbc, ac1)); + rbc = ac2.clone().toBitmapContainer(); + assertTrue(validate(rbc, ac2)); + rbc = ac3.clone().toBitmapContainer(); + assertTrue(validate(rbc, ac3)); + } + + @Test + public void containerSharingWithXor() { + RoaringBitmap r1 = new RoaringBitmap(); + r1.flip(131000L, 131001L); + RoaringBitmap r2 = new RoaringBitmap(); + r2.add(220000); + RoaringBitmap r3 = new RoaringBitmap(); + int killingPosition = 66000; + r3.add(killingPosition); + assertFalse(r1.contains(killingPosition)); + r2.xor(r1); + assertTrue(r2.contains(131000)); + assertFalse(r1.contains(killingPosition)); + r2.or(r3); + assertTrue(r2.contains(131000)); + assertTrue(r2.contains(killingPosition)); + assertFalse(r1.contains(killingPosition)); + } + + // From a bug report contributed by Kevin Karpenske + // this had created an array out of bounds error + @Test + public void fliptest_Karpenske() { + long[] array = + new long[] { + 343798, 343799, 343800, 343801, 343803, 343804, 343805, 343807, 343809, 343811, 343812, + 343815, 343816, 343817, 343818, 343819, 343821, 343825, 343827, 343828, 343830, 343831, + 343832, 343833, 343835, 343836, 343837, 343838, 343839, 343840, 343841, 343842, 343843, + 343844, 343845, 343847, 343848, 343849, 343850, 343851, 343853, 343854, 343855, 343856, + 343858, 343859, 343860, 343861, 343862, 343863, 343864, 343865, 343866, 343868, 343869, + 343874, 343875, 343877, 343879, 343880, 343881, 343882, 343883, 343887, 343889, 343890, + 343891, 343894, 343895, 343898, 343899, 343900, 343901, 343902, 343904, 343906, 343907, + 343908, 343909, 343910, 343911, 343912, 343913, 343914, 343915, 343916, 343917, 343918, + 343919, 343921, 343922, 343923, 343924, 343927, 343928, 343929, 343930, 343931, 343932, + 343933, 343934, 343935, 343938, 343939, 343941, 343942, 343943, 343944, 343945, 343946, + 343949, 343951, 343953, 343954, 343955, 343956, 343958, 343959, 343961, 343962, 343964, + 343965, 343966, 343967, 343968, 343969, 343971, 343972, 343973, 343974, 343976, 343978, + 343979, 343981, 343982, 343983, 343985, 343987, 343988, 343989, 343992, 343993, 343994, + 343995, 343996, 343997, 343998, 344000, 344001, 344002, 344003, 344004, 344006, 344008, + 344009, 344011, 344012, 344013, 344015, 344017, 344019, 344020, 344021, 344023, 344025, + 344026, 344027, 344028, 344029, 344030, 344031, 344034, 344035, 344036, 344037, 344038, + 344039, 344040, 344042, 344043, 344046, 344047 + }; + RoaringBitmap bitmap = new RoaringBitmap(); + long[] indexes = array; + int rangeStart = 0; + for (int rangeEnd = 1; rangeEnd < indexes.length; rangeEnd++) { + if (indexes[rangeEnd - 1] + 1 != indexes[rangeEnd]) { + if (rangeStart == rangeEnd - 1) { + bitmap.add((int) indexes[rangeStart]); + } else { + bitmap.flip(indexes[rangeStart], indexes[rangeEnd - 1] + 1); + } + rangeStart = rangeEnd; + } + } + if (rangeStart == indexes.length - 1) { + bitmap.add((int) indexes[rangeStart]); + } else { + bitmap.flip(indexes[rangeStart], indexes[indexes.length - 1] + 1); } + assertEquals(182, bitmap.getCardinality()); + } - @Test - public void orNotLimitLowerThanFirstPreservesBitmap() { - RoaringBitmap one = new RoaringBitmap(); - one.add(32); + @Test + public void flipTest1() { + final RoaringBitmap rb = new RoaringBitmap(); - RoaringBitmap other = new RoaringBitmap(); - other.add(0L, 100); + rb.flip(100000L, 200000L); // in-place on empty bitmap + final int rbcard = rb.getCardinality(); + assertEquals(100000, rbcard); - one.orNot(other, 10); - assertEquals(one, RoaringBitmap.bitmapOf(32)); + final BitSet bs = new BitSet(); + for (int i = 100000; i < 200000; ++i) { + bs.set(i); } + assertTrue(equals(bs, rb)); + } + @Test + public void flipTest1A() { + final RoaringBitmap rb = new RoaringBitmap(); - @Test - public void orNotLimitHigherThanFirstBitPreservesBitmap() { - RoaringBitmap one = new RoaringBitmap(); - one.add(32); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 200000L); + final int rbcard = rb1.getCardinality(); + assertEquals(100000, rbcard); + assertEquals(0, rb.getCardinality()); - RoaringBitmap other = new RoaringBitmap(); - other.add(0L, 100); - - one.orNot(other, 35); - assertEquals(one, RoaringBitmap.bitmapOf(32)); + final BitSet bs = new BitSet(); + assertTrue(equals(bs, rb)); // still empty? + for (int i = 100000; i < 200000; ++i) { + bs.set(i); } + assertTrue(equals(bs, rb1)); + } - @Test - public void orNotWithSparseBitmaps() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); + @Test + public void flipTest2() { + final RoaringBitmap rb = new RoaringBitmap(); - rb.add(0); - rb.add(1 << 16); // 65536 - rb.add(3 << 16); //196608 + rb.flip(100000L, 100000L); + final int rbcard = rb.getCardinality(); + assertEquals(0, rbcard); - rb2.add((4 << 16) - 1); //262143 + final BitSet bs = new BitSet(); + assertTrue(equals(bs, rb)); + } - rb.orNot(rb2, 4 << 16); + @Test + public void flipTest2A() { + final RoaringBitmap rb = new RoaringBitmap(); - assertEquals((4 << 16) - 1, rb.getCardinality()); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 100000L); + rb.add(1); // will not affect rb1 (no shared container) + final int rbcard = rb1.getCardinality(); + assertEquals(0, rbcard); + assertEquals(1, rb.getCardinality()); - final IntIterator iterator = rb.getIntIterator(); + final BitSet bs = new BitSet(); + assertTrue(equals(bs, rb1)); + bs.set(1); + assertTrue(equals(bs, rb)); + } - for (int i = 0; i < (4 << 16) - 1; ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next()); - } - assertFalse(iterator.hasNext()); - } + @Test + public void flipTest3() { + final RoaringBitmap rb = new RoaringBitmap(); - @Test - public void orNotWithOtherBiggerThanOriginal() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(1); + rb.flip(100000L, 200000L); // got 100k-199999 + rb.flip(100000L, 199991L); // give back 100k-199990 + final int rbcard = rb.getCardinality(); - final RoaringBitmap rb2 = new RoaringBitmap(); - rb2.add(1 << 14); //16384 - rb2.add(3 << 16); //196608 - - rb.orNot(rb2, (5 << 16)); - assertEquals((5 << 16) - 2, rb.getCardinality()); - - final IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (5 << 16); ++i) { - if ((i != (1 << 14)) && (i != (3 << 16))) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - } - assertFalse(iterator.hasNext()); + assertEquals(9, rbcard); + + final BitSet bs = new BitSet(); + for (int i = 199991; i < 200000; ++i) { + bs.set(i); } - @Test - public void orNotWithOtherBiggerThanOriginalAndEndRange() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(1); + assertTrue(equals(bs, rb)); + } - final RoaringBitmap rb2 = new RoaringBitmap(); - rb2.add(3 << 16); //196608 + @Test + public void flipTest3A() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 200000L); + final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 100000L, 199991L); + final int rbcard = rb2.getCardinality(); - rb.orNot(rb2, (2 << 16) + (2 << 14)); //131072 + 32768 = 163840 - assertEquals((2 << 16) + (2 << 14), rb.getCardinality()); + assertEquals(9, rbcard); - final IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (2 << 16) + (2 << 14); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - assertFalse(iterator.hasNext()); + final BitSet bs = new BitSet(); + for (int i = 199991; i < 200000; ++i) { + bs.set(i); } - @Test - public void orNotWithOriginalBiggerThanOther() { - final RoaringBitmap rb = new RoaringBitmap(); + assertTrue(equals(bs, rb2)); + } - rb.add(1); - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + @Test + public void flipTest4() { // fits evenly on both ends + final RoaringBitmap rb = new RoaringBitmap(); + rb.flip(100000L, 200000L); // got 100k-199999 + rb.flip(65536L, 4 * 65536L); + final int rbcard = rb.getCardinality(); - final RoaringBitmap rb2 = new RoaringBitmap(); + // 65536 to 99999 are 1s + // 200000 to 262143 are 1s: total card - rb.orNot(rb2, (5 << 16)); - assertEquals((5 << 16), rb.getCardinality()); + assertEquals(96608, rbcard); - final IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (5 << 16); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - assertFalse(iterator.hasNext()); + final BitSet bs = new BitSet(); + for (int i = 65536; i < 100000; ++i) { + bs.set(i); + } + for (int i = 200000; i < 262144; ++i) { + bs.set(i); } - @Test - public void orNotWithOriginalBiggerThanOther2() { - final RoaringBitmap rb = new RoaringBitmap(); - - rb.add(1); - rb.add((1 << 16) - 1); // 65535 - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 - - final RoaringBitmap rb2 = new RoaringBitmap(); - - rb.orNot(rb2, (1 << 14)); + assertTrue(equals(bs, rb)); + } - // {[0, 2^14], 65535, 65536, 131072, 196608} - assertEquals((1 << 14) + 4, rb.getCardinality()); + @Test + public void flipTest4A() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 200000L); + final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 65536L, 4 * 65536L); + final int rbcard = rb2.getCardinality(); - final IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (1 << 14); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } + assertEquals(96608, rbcard); - assertTrue(iterator.hasNext()); - assertEquals((1 << 16) - 1, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(1 << 16, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(2 << 16, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(3 << 16, iterator.next()); - - assertFalse(iterator.hasNext()); - } - - @Test - public void randomTest() { - rTest(15); - rTest(1024); - rTest(4096); - rTest(65536); - rTest(65536 * 16); - } - - public void rTest(final int N) { - for (int gap = 1; gap <= 65536; gap *= 2) { - final BitSet bs1 = new BitSet(); - final RoaringBitmap rb1 = new RoaringBitmap(); - for (int x = 0; x <= N; x += gap) { - bs1.set(x); - rb1.add(x); - } - if (bs1.cardinality() != rb1.getCardinality()) { - throw new RuntimeException("different card"); - } - if (!equals(bs1, rb1)) { - throw new RuntimeException("basic bug"); - } - for (int offset = 1; offset <= gap; offset *= 2) { - final BitSet bs2 = new BitSet(); - final RoaringBitmap rb2 = new RoaringBitmap(); - for (int x = 0; x <= N; x += gap) { - bs2.set(x + offset); - rb2.add(x + offset); - } - if (bs2.cardinality() != rb2.getCardinality()) { - throw new RuntimeException("different card"); - } - if (!equals(bs2, rb2)) { - throw new RuntimeException("basic bug"); - } - - BitSet clonebs1; - // testing AND - clonebs1 = (BitSet) bs1.clone(); - clonebs1.and(bs2); - if (!equals(clonebs1, RoaringBitmap.and(rb1, rb2))) { - throw new RuntimeException("bug and"); - } - { - final RoaringBitmap t = rb1.clone(); - t.and(rb2); - if (!equals(clonebs1, t)) { - throw new RuntimeException("bug inplace and"); - } - if (!t.equals(RoaringBitmap.and(rb1, rb2))) { - System.out - .println(t.highLowContainer.getContainerAtIndex(0).getClass().getCanonicalName()); - System.out.println(RoaringBitmap.and(rb1, rb2).highLowContainer.getContainerAtIndex(0) - .getClass().getCanonicalName()); - - throw new RuntimeException("bug inplace and"); - } - } - - // testing OR - clonebs1 = (BitSet) bs1.clone(); - clonebs1.or(bs2); - - if (!equals(clonebs1, RoaringBitmap.or(rb1, rb2))) { - throw new RuntimeException("bug or"); - } - { - final RoaringBitmap t = rb1.clone(); - t.or(rb2); - if (!equals(clonebs1, t)) { - throw new RuntimeException("bug or"); - } - if (!t.equals(RoaringBitmap.or(rb1, rb2))) { - throw new RuntimeException("bug or"); - } - if (!t.toString().equals(RoaringBitmap.or(rb1, rb2).toString())) { - throw new RuntimeException("bug or"); - } - - } - // testing XOR - clonebs1 = (BitSet) bs1.clone(); - clonebs1.xor(bs2); - if (!equals(clonebs1, RoaringBitmap.xor(rb1, rb2))) { - throw new RuntimeException("bug xor"); - } - { - final RoaringBitmap t = rb1.clone(); - t.xor(rb2); - if (!equals(clonebs1, t)) { - throw new RuntimeException("bug xor"); - } - if (!t.equals(RoaringBitmap.xor(rb1, rb2))) { - throw new RuntimeException("bug xor"); - } - } - // testing NOTAND - clonebs1 = (BitSet) bs1.clone(); - clonebs1.andNot(bs2); - if (!equals(clonebs1, RoaringBitmap.andNot(rb1, rb2))) { - throw new RuntimeException("bug andnot"); - } - clonebs1 = (BitSet) bs2.clone(); - clonebs1.andNot(bs1); - if (!equals(clonebs1, RoaringBitmap.andNot(rb2, rb1))) { - throw new RuntimeException("bug andnot"); - } - { - final RoaringBitmap t = rb2.clone(); - t.andNot(rb1); - if (!equals(clonebs1, t)) { - throw new RuntimeException("bug inplace andnot"); - } - final RoaringBitmap g = RoaringBitmap.andNot(rb2, rb1); - if (!equals(clonebs1, g)) { - throw new RuntimeException("bug andnot"); - } - if (!t.equals(g)) { - throw new RuntimeException("bug"); - } - } - clonebs1 = (BitSet) bs1.clone(); - clonebs1.andNot(bs2); - if (!equals(clonebs1, RoaringBitmap.andNot(rb1, rb2))) { - throw new RuntimeException("bug andnot"); - } - { - final RoaringBitmap t = rb1.clone(); - t.andNot(rb2); - if (!equals(clonebs1, t)) { - throw new RuntimeException("bug andnot"); - } - final RoaringBitmap g = RoaringBitmap.andNot(rb1, rb2); - if (!equals(clonebs1, g)) { - throw new RuntimeException("bug andnot"); - } - if (!t.equals(g)) { - throw new RuntimeException("bug"); - } - } - } - } + final BitSet bs = new BitSet(); + for (int i = 65536; i < 100000; ++i) { + bs.set(i); } - - @Test - public void sillytestHighBits() { - RoaringBitmap rb = RoaringBitmap.bitmapOf(-1, 0); - int[] array = rb.toArray(); - assertEquals(0, array[0]); - assertEquals(array[1], -1); + for (int i = 200000; i < 262144; ++i) { + bs.set(i); } - @Test - public void simplecardinalityTest() { - final int N = 512; - final int gap = 70; + assertTrue(equals(bs, rb2)); + } - final RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < N; k++) { - rb.add(k * gap); - assertEquals(rb.getCardinality(), k + 1); - } - assertEquals(rb.getCardinality(), N); - for (int k = 0; k < N; k++) { - rb.add(k * gap); - assertEquals(rb.getCardinality(), N); - } - - } + @Test + public void flipTest5() { // fits evenly on small end, multiple + // containers + final RoaringBitmap rb = new RoaringBitmap(); + rb.flip(100000L, 132000L); + rb.flip(65536L, 120000L); + final int rbcard = rb.getCardinality(); - @Test - public void sparseAnd() { - final RoaringBitmap rr1 = new RoaringBitmap(); - rr1.add(1); - rr1.add(1 << 31); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(1 << 31); - RoaringBitmap and = RoaringBitmap.and(rr1, rr2); - assertEquals(1, and.getCardinality()); - assertTrue(and.contains(1 << 31)); - rr1.and(rr2); - assertEquals(1, rr1.getCardinality()); - assertTrue(and.contains(1 << 31)); - } - - @Test - public void sparseAndNot() { - final RoaringBitmap rr1 = new RoaringBitmap(); - rr1.add(1); - rr1.add(1 << 31); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(1 << 31); - RoaringBitmap andNot = RoaringBitmap.andNot(rr1, rr2); - assertEquals(1, andNot.getCardinality()); - assertTrue(andNot.contains(1)); - rr1.andNot(rr2); - assertEquals(1, rr1.getCardinality()); - assertTrue(andNot.contains(1)); - } - - @Test - public void sparseOr() { - final RoaringBitmap rr1 = new RoaringBitmap(); - rr1.add(1); - rr1.add(1 << 31); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(1 << 31); - RoaringBitmap or = RoaringBitmap.or(rr1, rr2); - assertEquals(2, or.getCardinality()); - assertTrue(or.contains(1)); - assertTrue(or.contains(1 << 31)); - rr1.or(rr2); - assertEquals(2, rr1.getCardinality()); - assertTrue(or.contains(1)); - assertTrue(or.contains(1 << 31)); - } - - - @Test - public void sparseXor() { - final RoaringBitmap rr1 = new RoaringBitmap(); - rr1.add(1); - rr1.add(1 << 31); - final RoaringBitmap rr2 = new RoaringBitmap(); - rr2.add(1 << 31); - RoaringBitmap xor = RoaringBitmap.xor(rr1, rr2); - assertEquals(1, xor.getCardinality()); - assertTrue(xor.contains(1)); - rr1.xor(rr2); - assertEquals(1, rr1.getCardinality()); - assertTrue(xor.contains(1)); - } - - @Test - public void testAndNot() { - int[] array1 = {39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, - 39184, 39185, 39186, 39187, 39188}; - int[] array2 = {14205}; - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(array1); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(array2); - RoaringBitmap answer = RoaringBitmap.andNot(rb1, rb2); - assertEquals(answer.getCardinality(), array1.length); - } - - @Test - public void testAstesana() { - RoaringBitmap r1 = new RoaringBitmap(); - // Strange thing: Replace this line by r1.add(131000) and the bug vanishes! - r1.flip(131000L, 131001L); - RoaringBitmap r2 = new RoaringBitmap(); - r2.add(220000); - RoaringBitmap r3 = new RoaringBitmap(); - int killingPosition = 66000; - r3.add(killingPosition); - assertFalse(r1.contains(killingPosition)); // ok - r2.or(r1); - assertFalse(r1.contains(killingPosition)); // ok - r2.or(r3); - assertFalse(r1.contains(killingPosition)); // ko - } - - @Test - public void testCheckedAdd() { - RoaringBitmap rb = new RoaringBitmap(); - // checking if the true value is well returned - // when adding new ints - for (int i = 0; i < 2 * (1 << 16); i += 2) { - assertTrue(rb.checkedAdd(i)); - } - for (int i = 1; i < 2 * (1 << 16); i += 2) { - assertTrue(rb.checkedAdd(i)); - } - // Checking if the false value is well returned - // when adding already existing ints - for (int i = 0; i < 2 * (1 << 16); i += 2) { - assertFalse(rb.checkedAdd(i)); - } - for (int i = 1; i < 2 * (1 << 16) + 1; i += 2) { - assertFalse(rb.checkedAdd(i)); - } - } + // 65536 to 99999 are 1s + // 120000 to 131999 - @Test - public void testCheckedRemove() { - RoaringBitmap rb = new RoaringBitmap(); - // checking if the true value is well returned - // when adding new ints - for (int i = 0; i < 2 * (1 << 16); i++) { - rb.add(i); - } - for (int i = 0; i < 2 * (1 << 16); i += 2) { - assertTrue(rb.checkedRemove(i)); - } - for (int i = 0; i < 2 * (1 << 16); i += 2) { - assertFalse(rb.checkedRemove(i)); - } - for (int i = 1; i < 2 * (1 << 16); i += 2) { - assertTrue(rb.checkedRemove(i)); - } - for (int i = 1; i < 2 * (1 << 16) + 1; i += 2) { - assertFalse(rb.checkedRemove(i)); - } - } + assertEquals(46464, rbcard); - @Test - public void testContains() throws IOException { - RoaringBitmap rbm1 = new RoaringBitmap(); - for (int k = 0; k < 1000; ++k) { - rbm1.add(17 * k); - } - for (int k = 0; k < 17 * 1000; ++k) { - assertEquals(rbm1.contains(k), (k / 17 * 17 == k)); - } + final BitSet bs = new BitSet(); + for (int i = 65536; i < 100000; ++i) { + bs.set(i); } - - @Test - public void testEqual() { - RoaringBitmap rr1 = RoaringBitmap.bitmapOf(1, 2, 100000); - RoaringBitmap rr2 = RoaringBitmap.bitmapOf(3, 4, 100001); - RoaringBitmap rr3 = RoaringBitmap.bitmapOf(1, 2, 100000); - assertEquals(rr1, rr3); - assertNotEquals(rr1, rr2); - assertNotEquals(rr3, rr2); + for (int i = 120000; i < 132000; ++i) { + bs.set(i); } + assertTrue(equals(bs, rb)); + } - // tests for how range falls on container boundaries + @Test + public void flipTest5A() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 132000L); + final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 65536L, 120000L); + final int rbcard = rb2.getCardinality(); - @Test - public void testFlip() { - RoaringBitmap rb = new RoaringBitmap(); - for (int i = 0; i < 1 << 20; ++i) { - rb.flip(i); - assertEquals(rb.getCardinality(), i + 1); - } - for (int i = (1 << 20) - 1; i >= 0; --i) { - rb.flip(i); - assertEquals(rb.getCardinality(), i); - } - } + assertEquals(46464, rbcard); - @Test - public void testFlipBigInts() { - RoaringBitmap rb = new RoaringBitmap(); - for (int i = 0; i < 1 << 20; ++i) { - rb.flip((1 << 31) + i); - assertEquals(rb.getCardinality(), i + 1); - } - for (int i = (1 << 20) - 1; i >= 0; --i) { - rb.flip((1 << 31) + i); - assertEquals(rb.getCardinality(), i); - } + final BitSet bs = new BitSet(); + for (int i = 65536; i < 100000; ++i) { + bs.set(i); } - - - @Test - public void testFlipOnEmpty() { - RoaringBitmap r1 = new RoaringBitmap(); - r1.flip(0L, 10L); - assertEquals(10, r1.getCardinality()); - } - - @Test - public void testHash() { - RoaringBitmap rbm1 = new RoaringBitmap(); - rbm1.add(17); - RoaringBitmap rbm2 = new RoaringBitmap(); - rbm2.add(17); - assertEquals(rbm1.hashCode(), rbm2.hashCode()); - rbm2 = rbm1.clone(); - assertEquals(rbm1.hashCode(), rbm2.hashCode()); - } - - @Test - public void testHighBits() { - for (int offset = 1 << 14; offset < 1 << 18; offset *= 2) { - RoaringBitmap rb = new RoaringBitmap(); - for (long k = Integer.MIN_VALUE; k < Integer.MAX_VALUE; k += offset) { - rb.add((int) k); - } - int cardinality = 0; - for (long k = Integer.MIN_VALUE; k < Integer.MAX_VALUE; k += offset) { - assertTrue(rb.contains((int) k)); - ++cardinality; - } - int[] array = rb.toArray(); - assertEquals(array.length, cardinality); - for (int k = 0; k < array.length - 1; ++k) { - assertTrue((0xFFFFFFFFL & array[k]) <= (0xFFFFFFFFL & array[k + 1])); - } - } + for (int i = 120000; i < 132000; ++i) { + bs.set(i); } + assertTrue(equals(bs, rb2)); + } - @Test - public void testHorizontalOrCardinality() { - int[] vals = {65535, 131071, 196607, 262143, 327679, 393215, 458751, 524287}; - final RoaringBitmap[] b = new RoaringBitmap[2]; - b[0] = RoaringBitmap.bitmapOf(vals); - b[1] = RoaringBitmap.bitmapOf(vals); - RoaringBitmap a = FastAggregation.or(new Iterator() { - int k = 0; + @Test + public void flipTest6() { // fits evenly on big end, multiple containers + final RoaringBitmap rb = new RoaringBitmap(); + rb.flip(100000L, 132000L); + rb.flip(99000L, 2 * 65536L); + final int rbcard = rb.getCardinality(); - @Override - public boolean hasNext() { - return k < b.length; - } + // 99000 to 99999 are 1000 1s + // 131072 to 131999 are 928 1s - @Override - public RoaringBitmap next() { - return b[k++]; - } + assertEquals(1928, rbcard); - @Override - public void remove() { - } - }); - assertEquals(8, a.getCardinality()); + final BitSet bs = new BitSet(); + for (int i = 99000; i < 100000; ++i) { + bs.set(i); + } + for (int i = 2 * 65536; i < 132000; ++i) { + bs.set(i); + } + assertTrue(equals(bs, rb)); + } + + @Test + public void flipTest6A() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 100000L, 132000L); + final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 99000L, 2 * 65536L); + final int rbcard = rb2.getCardinality(); + + assertEquals(1928, rbcard); + + final BitSet bs = new BitSet(); + for (int i = 99000; i < 100000; ++i) { + bs.set(i); + } + for (int i = 2 * 65536; i < 132000; ++i) { + bs.set(i); + } + assertTrue(equals(bs, rb2)); + } + + @Test + public void flipTest7() { // within 1 word, first container + final RoaringBitmap rb = new RoaringBitmap(); + rb.flip(650L, 132000L); + rb.flip(648L, 651L); + final int rbcard = rb.getCardinality(); + + // 648, 649, 651-131999 + + assertEquals(132000 - 651 + 2, rbcard); + + final BitSet bs = new BitSet(); + bs.set(648); + bs.set(649); + for (int i = 651; i < 132000; ++i) { + bs.set(i); + } + assertTrue(equals(bs, rb)); + } + + @Test + public void flipTest7A() { // within 1 word, first container + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb1 = RoaringBitmap.flip(rb, 650L, 132000L); + final RoaringBitmap rb2 = RoaringBitmap.flip(rb1, 648L, 651L); + final int rbcard = rb2.getCardinality(); + + // 648, 649, 651-131999 + + assertEquals(132000 - 651 + 2, rbcard); + + final BitSet bs = new BitSet(); + bs.set(648); + bs.set(649); + for (int i = 651; i < 132000; ++i) { + bs.set(i); + } + assertTrue(equals(bs, rb2)); + } + + @Test + public void flipTest8() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(0); + rb.add(2); + final RoaringBitmap rb2 = RoaringBitmap.flip(rb, 0L, 3L); + + final BitSet bs = new BitSet(); + bs.set(1); + assertTrue(equals(bs, rb2)); + } + + @Test + public void flipTestBigInt() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(Integer.MAX_VALUE + 100000); + rb.add(Integer.MAX_VALUE + 100002); + final RoaringBitmap rb2 = + RoaringBitmap.flip(rb, Integer.MAX_VALUE + 100001L, Integer.MAX_VALUE + 200000L); + assertEquals(99999, rb2.getCardinality()); + assertTrue(rb2.contains(Integer.MAX_VALUE + 100000)); + assertFalse(rb2.contains(Integer.MAX_VALUE + 100002)); + assertTrue(rb2.contains(Integer.MAX_VALUE + 199999)); + } + + @Test + public void flipTestBig() { + final int numCases = 1000; + final RoaringBitmap rb = new RoaringBitmap(); + final BitSet bs = new BitSet(); + final Random r = new Random(3333); + int checkTime = 2; + + for (int i = 0; i < numCases; ++i) { + final long start = r.nextInt(65536 * 20); + long end = r.nextInt(65536 * 20); + if (r.nextDouble() < 0.1) { + end = start + r.nextInt(100); + } + rb.flip(start, end); + if (start < end) { + bs.flip((int) start, (int) end); // throws exception + } + // otherwise + // insert some more ANDs to keep things sparser + if (r.nextDouble() < 0.2) { + final RoaringBitmap mask = new RoaringBitmap(); + final BitSet mask1 = new BitSet(); + final long startM = r.nextInt(65536 * 20); + final long endM = startM + 100000; + mask.flip(startM, endM); + mask1.flip((int) startM, (int) endM); + mask.flip(0L, 65536L * 20 + 100000); + mask1.flip(0, 65536 * 20 + 100000); + rb.and(mask); + bs.and(mask1); + } + // see if we can detect incorrectly shared containers + if (r.nextDouble() < 0.1) { + final RoaringBitmap irrelevant = RoaringBitmap.flip(rb, 10L, 100000L); + irrelevant.flip(5L, 200000L); + irrelevant.flip(190000L, 260000L); + } + if (i > checkTime) { + assertTrue(equals(bs, rb)); + checkTime *= 1.5; + } + } + } + + @Test + public void flipTestBigA() { + final int numCases = 1000; + final BitSet bs = new BitSet(); + final Random r = new Random(3333); + int checkTime = 2; + RoaringBitmap rb1 = new RoaringBitmap(), rb2 = null; // alternate + // between + // them + for (int i = 0; i < numCases; ++i) { + final int start = r.nextInt(65536 * 20); + int end = r.nextInt(65536 * 20); + if (r.nextDouble() < 0.1) { + end = start + r.nextInt(100); + } + + if ((i & 1) == 0) { + rb2 = RoaringBitmap.flip(rb1, (long) start, (long) end); + // tweak the other, catch bad sharing + long r1 = r.nextInt(65536 * 20); + long r2 = r.nextInt(65536 * 20); + rb1.flip(r1, r2); + } else { + rb1 = RoaringBitmap.flip(rb2, (long) start, (long) end); + long r1 = r.nextInt(65536 * 20); + long r2 = r.nextInt(65536 * 20); + rb2.flip(r1, r2); + } + + if (start < end) { + bs.flip(start, end); // throws exception + // otherwise + } + // insert some more ANDs to keep things sparser + if (r.nextDouble() < 0.2 && (i & 1) == 0) { + final RoaringBitmap mask = new RoaringBitmap(); + final BitSet mask1 = new BitSet(); + final int startM = r.nextInt(65536 * 20); + final int endM = startM + 100000; + mask.flip((long) startM, (long) endM); + mask1.flip(startM, endM); + mask.flip(0L, 65536L * 20 + 100000); + mask1.flip(0, 65536 * 20 + 100000); + rb2.and(mask); + bs.and(mask1); + } + if (i > checkTime) { + final RoaringBitmap rb = (i & 1) == 0 ? rb2 : rb1; + final boolean status = equals(bs, rb); + assertTrue(status); + checkTime *= 1.5; + } + } + } + + @Test + public void intersecttest() { + final RoaringBitmap rr1 = new RoaringBitmap(); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 0; k < 40000; ++k) { + rr1.add(2 * k); + rr2.add(2 * k + 1); + } + assertFalse(RoaringBitmap.intersects(rr1, rr2)); + rr1.add(2 * 500 + 1); + assertTrue(RoaringBitmap.intersects(rr1, rr2)); + final RoaringBitmap rr3 = new RoaringBitmap(); + rr3.add(2 * 501 + 1); + assertTrue(RoaringBitmap.intersects(rr3, rr2)); + assertFalse(RoaringBitmap.intersects(rr3, rr1)); + for (int k = 0; k < 40000; ++k) { + rr1.add(2 * k + 1); + } + rr1.runOptimize(); + assertTrue(RoaringBitmap.intersects(rr1, rr2)); + } + + @Test + public void intersecttestWithRange() { + RoaringBitmap rr1 = new RoaringBitmap(); + RoaringBitmap rr2 = new RoaringBitmap(); + RoaringBitmap rr3 = new RoaringBitmap(); + + // This bitmap containers will be Run Containers + rr1.add(1L, 4L); + rr1.add(6L, 10L); + + // This one will be Array Containers + rr2.add(0); + rr2.add(2); + + rr2.add(6); + rr2.add(7); + rr2.add(9); + + assertFalse(rr1.intersects(0, 1)); + assertTrue(rr1.intersects(0, 3)); + assertTrue(rr1.intersects(0, 11)); + assertFalse(rr1.intersects(12, 14)); + assertFalse(rr1.intersects(4, 5)); + assertTrue(rr1.intersects(2, 3)); + assertTrue(rr1.intersects(4, 8)); + assertTrue(rr1.intersects(8, 12)); + + assertTrue(rr2.intersects(0, 11)); + assertFalse(rr2.intersects(12, 14)); + assertFalse(rr2.intersects(4, 5)); + assertTrue(rr2.intersects(2, 3)); + assertTrue(rr2.intersects(4, 8)); + assertTrue(rr2.intersects(8, 12)); + + rr3.add(5L, 10L); + assertTrue(rr3.intersects(5, 10)); + } + + @Test + public void shouldNotIntersectWithDisjointRangeBelowBitmapFirst() { + char[] keys = new char[1]; + Container[] values = new Container[1]; + RoaringBitmap bitmap = new RoaringBitmap(new RoaringArray(keys, values, 1)); + keys[0] = (char) (1 << 15); + long[] bits = new long[1024]; + long word = 1789303257167203747L; + Arrays.fill(bits, word); + values[0] = new BitmapContainer(bits, 1024 * Long.bitCount(word)); + assertFalse(bitmap.intersects(0, bitmap.first() & 0xFFFFFFFFL)); + } + + @Test + public void shouldIntersectWithFirstWhenBitmapAtStart() { + char[] keys = new char[1]; + Container[] values = new Container[1]; + RoaringBitmap bitmap = new RoaringBitmap(new RoaringArray(keys, values, 1)); + keys[0] = (char) (1 << 15); + long[] bits = new long[1024]; + long word = 2697219678014362575L; + Arrays.fill(bits, word); + values[0] = new BitmapContainer(bits, 1024 * Long.bitCount(word)); + long first = (bitmap.first() & 0xFFFFFFFFL); + assertTrue(bitmap.intersects(first - 1, first + 1)); + assertTrue(bitmap.intersects(first, first + 1)); + assertFalse(bitmap.intersects(first - 1, first)); + } + + @Test + public void orBigIntsTest() { + RoaringBitmap rb = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); + HashSet hs = new HashSet(); + + for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { + rb.add(i); + hs.add(i); + } + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + hs.add(i); + rb.add(i); + } + for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 5) { + hs.add(i); + rb.add(i); + } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 3) { + hs.add(i); + rb.add(i); + } + + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 5) { + hs.add(i); + rb2.add(i); + } + for (int i = (1 << 31) + 6 * 65536; i < (1 << 31) + 7 * 65536; i += 3) { + hs.add(i); + rb2.add(i); + } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 11 * 65536; i += 5) { + hs.add(i); + rb2.add(i); + } + for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 7) { + hs.add(i); + rb2.add(i); + } + + RoaringBitmap rbor = RoaringBitmap.or(rb, rb2); + + Object[] correct = hs.toArray(); + Arrays.sort(correct); + Integer[] resor = ArrayUtils.toObject(rbor.toArray()); + assertArrayEquals(correct, resor); + } + + @Test + public void orcount() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr.add(k); + } + rr.add(100000); + rr.add(110000); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr2.add(k); + } + + final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); + assertEquals(rror.getCardinality(), RoaringBitmap.orCardinality(rr, rr2)); + } + + @Test + public void testXorCardinality() { + final RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rb.add(k); + } + rb.add(100000); + rb.add(110000); + rb.add(1L << 20, 1L << 21); + rb.flip((1 << 20) | (1 << 19)); + final RoaringBitmap rb2 = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rb2.add(k); + } + RoaringBitmap xor = RoaringBitmap.xor(rb, rb2); + assertEquals(xor.getCardinality(), RoaringBitmap.xorCardinality(rb, rb2)); + } + + @Test + public void testAndNotCardinality() { + final RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rb.add(k); + } + rb.add(100000); + rb.add(110000); + rb.add(1L << 20, 1L << 21); + rb.flip((1 << 20) | (1 << 19)); + final RoaringBitmap rb2 = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rb2.add(k); + } + RoaringBitmap andNot = RoaringBitmap.andNot(rb, rb2); + assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(rb, rb2)); + } + + @Test + public void testAndNotCardinalityBigVsSmall() { + RoaringBitmap small = RoaringBitmap.bitmapOf(1, 2, 3); + RoaringBitmap big = new RoaringBitmap(); + for (int i = 0; i < 4000; ++i) { + big.add(1 + i * 0x1000); + } + RoaringBitmap andNot = RoaringBitmap.andNot(big, small); + assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(big, small)); + } + + @Test + public void testAndNotCardinalitySmallVsBig() { + RoaringBitmap small = RoaringBitmap.bitmapOf(1, 2, 3); + RoaringBitmap big = new RoaringBitmap(); + for (int i = 0; i < 4000; ++i) { + big.add(1 + i * 0x1000); + } + RoaringBitmap andNot = RoaringBitmap.andNot(small, big); + assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(small, big)); + } + + @Test + public void testAndNotCardinality_646() { + RoaringBitmap rb = RoaringBitmap.bitmapOf(-587409880, 605467000); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(-587409880, 347844183); + + RoaringBitmap andNot = RoaringBitmap.andNot(rb, rb2); + assertEquals(andNot.getCardinality(), RoaringBitmap.andNotCardinality(rb, rb2)); + } + + @Test + public void testAndNotCardinality_648() { + RoaringBitmap s1 = + RoaringBitmap.bitmapOf( + -1388308580, + 236217409, + -805382570, + 612285977, + 1389629939, + 851442526, + 375756307, + 61533603, + 1908301308, + 2097309572, + 204769050, + 703198559, + -545810986, + 2090296816, + -87319453, + 158018332, + -685188145, + -566739002, + -1446363859, + -372441875, + -957637004, + -1144076256, + -1248859542, + -160225853, + 14707613, + 866274329, + 1550526350, + 877999004, + -1784269953, + 1274953255, + 1490490469, + -1340013077, + 2067958239, + 51232349, + 2060711699, + -1802459974, + 2039829040, + -2079650027, + -278950425, + 1145674649, + 298101576, + 1687655442, + 1209489632, + -762136131, + 399832491, + 1077638711, + -635674559, + -1643781464, + -1067907341, + 144525399, + 651571848, + 1893053071, + -2058528151, + 1592871441, + 84583235, + 374119809, + -867104416, + -1941224259, + 787356209, + 1972857336, + -720703901, + -1310021857, + -1831922816, + 181898740, + 600942551, + -1745822849, + -856908487, + 2060184086, + -1217485514, + -1680395029, + 1539735915, + 2042390564, + -1539856946, + 1824974207, + 1695025297, + 1908431629, + -395090370, + -1688185468, + 570601902, + -701368853, + -1211735380, + -825285093, + 788089714, + -857723909, + 1400502194, + 285106906, + -1450842998, + -2125215206, + 1451519492, + -1559357910, + 1157633452, + -387704829, + 2036134025, + 1051239778, + -1542956455, + 357879569, + 1962230155, + -1994777800, + 672516512, + 174507423, + -299175291, + 821891018, + 1062886766, + -1313955904, + 1732661804, + -767116537, + 1352149580, + 2001322279, + 1698147357, + 40451458, + 996819026, + 1904959950, + 2058544757, + 1514282221, + 234242255, + -1364505429, + 1498471146, + 1134429786, + -918860049, + 1430732385, + 644983298, + 793600316, + -1726956640, + -538511147, + -1945670935, + 291567421, + 1033590420, + -1831809482, + 985031287, + -773476240, + 1724734191, + -1364525376, + 1208307142, + -2126741265, + -1851759120, + 1083333467, + 185208087, + -375950074, + 48210573, + -843304856, + -295266615, + -843941360, + -524390895, + -102924717, + 836117637, + 683196001, + -1824825594, + -1470017798, + -1554712054, + 291236023, + -907874606, + 2068945326, + -899352179, + -1488751007, + -449279886, + -1085935420, + -2094131785, + -474243782, + 1306756671, + 1353254318, + 86944198, + 1148225154, + 487252515, + -229770314, + -1484325603, + 109043190, + -252122045, + 1431750974, + 1667547537, + -1775516477, + -512978266, + -216545450, + -486550865, + -1193721685, + -1108677522, + -628326149, + -1568065979, + -675571394); + RoaringBitmap s2 = + RoaringBitmap.bitmapOf( + 2060184086, + 704452713, + 1236293943, + -178539376, + 2037977331, + -78910667, + -587409880, + 204769050, + -854426111, + 90628341, + -1411939301, + -927754519, + -211274987, + 998450197, + -1515133464, + -1652963250, + 499001553, + 383696025, + -2019580769, + 1583380373, + -79264832, + 1065614902, + 1243463658, + 424214238, + 1124141647, + 271662535, + 1415634429, + 1893053071, + -1624960757, + -1933550809, + -1170233109, + -542340662, + -1681838238, + 292656484, + 1587781520, + -1463647396, + -124042559, + -162307067, + 1411905814, + -1524651941, + 1935844108, + 1992426746, + 422443777, + 679395872, + -764857187, + -401706366, + -2007177999, + 1044794027, + -1561188953, + 1627034126, + -401273669, + -123973748, + -694963705, + 838892817, + -1640102435, + 852253834, + -23120023, + -2072644924, + 1140820264, + -550227319, + -1692730465, + 1491150291, + 1607642920, + -1015774573, + -1801713682, + -752796152, + -439281693, + -792361100, + -188208805, + 808883165, + -1364525376, + 896915854, + -1672522244, + -1718572341); + RoaringBitmap s3 = + RoaringBitmap.bitmapOf( + -30718004, + -1652963250, + -762136131, + -1552606582, + -1933550809, + -1230616126, + 736584428, + -2136360654, + 1097548480, + 192408815, + -295266615); + RoaringBitmap s1AndS2 = RoaringBitmap.and(s1, s2); + assertEquals( + RoaringBitmap.andNot(s1AndS2, s3).getCardinality(), + RoaringBitmap.andNotCardinality(s1AndS2, s3)); + } + + @Test + public void ortest() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr.add(k); + } + rr.add(100000); + rr.add(110000); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr2.add(k); + } + + final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); + + final int[] array = rror.toArray(); + final int[] arrayrr = rr.toArray(); + + assertArrayEquals(array, arrayrr); + + rr.or(rr2); + final int[] arrayirr = rr.toArray(); + assertArrayEquals(array, arrayirr); + } + + @Test + public void ORtest() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr.add(k); + } + for (int k = 65536; k < 65536 + 4000; ++k) { + rr.add(k); + } + for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { + rr.add(k); + } + for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { + rr.add(k); + } + for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { + rr.add(k); + } + for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { + rr.add(k); + } + for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { + rr.add(k); + } + + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr2.add(k); + } + for (int k = 65536; k < 65536 + 4000; ++k) { + rr2.add(k); + } + for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { + rr2.add(k); + } + for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { + rr2.add(k); + } + for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { + rr2.add(k); + } + for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { + rr2.add(k); + } + final RoaringBitmap correct = RoaringBitmap.or(rr, rr2); + rr.or(rr2); + assertEquals(correct, rr); + } + + @Test + public void ortest2() { + final int[] arrayrr = new int[4000 + 4000 + 2]; + int pos = 0; + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rr.add(k); + arrayrr[pos++] = k; + } + rr.add(100000); + rr.add(110000); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 8000; ++k) { + rr2.add(k); + arrayrr[pos++] = k; } + arrayrr[pos++] = 100000; + arrayrr[pos++] = 110000; - @Test - public void testHorizontalOrCardinalityBigInts() { - int[] vals = {(1 << 31) + 65535, (1 << 31) + 131071, (1 << 31) + 196607, (1 << 31) + 262143, (1 << 31) + 327679, (1 << 31) + 393215, (1 << 31) + 458751, (1 << 31) + 524287}; - final RoaringBitmap[] b = new RoaringBitmap[2]; - b[0] = RoaringBitmap.bitmapOf(vals); - b[1] = RoaringBitmap.bitmapOf(vals); - RoaringBitmap a = FastAggregation.or(new Iterator() { - int k = 0; - - @Override - public boolean hasNext() { - return k < b.length; - } + final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); - @Override - public RoaringBitmap next() { - return b[k++]; - } + final int[] arrayor = rror.toArray(); - @Override - public void remove() { - } - }); - assertEquals(8, a.getCardinality()); - } + assertArrayEquals(arrayor, arrayrr); + } + @Test + public void ortest3() { + final HashSet V1 = new HashSet(); + final HashSet V2 = new HashSet(); - @Test - public void testIterator() { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rb.add(k); - } - for (int k = 0; k < 1000; ++k) { - rb.add(k * 100); - } - RoaringBitmap copy1 = new RoaringBitmap(); - for (int x : rb) { - copy1.add(x); - } - assertEquals(copy1, rb); - RoaringBitmap copy2 = new RoaringBitmap(); - IntIterator i = rb.getIntIterator(); - while (i.hasNext()) { - copy2.add(i.next()); - } - assertEquals(copy2, rb); + final RoaringBitmap rr = new RoaringBitmap(); + final RoaringBitmap rr2 = new RoaringBitmap(); + // For the first 65536: rr2 has a bitmap container, and rr has + // an array container. + // We will check the union between a BitmapCintainer and an + // arrayContainer + for (int k = 0; k < 4000; ++k) { + rr2.add(k); + V1.add(k); } - - - @Test - public void testIteratorBigInts() { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 4000; ++k) { - rb.add((1 << 31) + k); - } - for (int k = 0; k < 1000; ++k) { - rb.add((1 << 31) + k * 100); - } - RoaringBitmap copy1 = new RoaringBitmap(); - for (int x : rb) { - copy1.add(x); - } - assertEquals(copy1, rb); - RoaringBitmap copy2 = new RoaringBitmap(); - IntIterator i = rb.getIntIterator(); - while (i.hasNext()) { - copy2.add(i.next()); - } - assertEquals(copy2, rb); - } - - - @Test - public void testLimit() { - for (int gap = 1; gap <= 1024; gap *= 2) { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 100000; k += gap) { - rb.add(k); - } - int thiscard = rb.getCardinality(); - for (int k = 0; k < thiscard; k += 100) { - RoaringBitmap limited = rb.limit(k); - assertEquals(limited.getCardinality(), k); - } - assertEquals(rb.limit(thiscard).getCardinality(), thiscard); - assertEquals(rb.limit(thiscard + 1).getCardinality(), thiscard); - } + for (int k = 3500; k < 4500; ++k) { + rr.add(k); + V1.add(k); } - - - @Test - public void testLimitBigInts() { - for (int gap = 1; gap <= 1024; gap *= 2) { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 100000; k += gap) { - rb.add((1 << 31) + k); - } - int thiscard = rb.getCardinality(); - for (int k = 0; k < thiscard; k += 100) { - RoaringBitmap limited = rb.limit(k); - assertEquals(limited.getCardinality(), k); - } - assertEquals(rb.limit(thiscard).getCardinality(), thiscard); - assertEquals(rb.limit(thiscard + 1).getCardinality(), thiscard); - } + for (int k = 4000; k < 65000; ++k) { + rr2.add(k); + V1.add(k); } - - /** - * Test massive and. - */ - @Test - public void testMassiveAnd() { - RoaringBitmap[] ewah = new RoaringBitmap[1024]; - for (int k = 0; k < ewah.length; ++k) { - ewah[k] = new RoaringBitmap(); - } - int howmany = 1000000; - for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); - } - for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip(13L, (long) howmany / 2); - } - for (int N = 2; N < ewah.length; ++N) { - RoaringBitmap answer = ewah[0]; - for (int k = 1; k < N; ++k) { - RoaringBitmap oldAnswer = answer; - answer = RoaringBitmap.and(oldAnswer, ewah[k]); - assertEquals(answer.getCardinality(), - RoaringBitmap.andCardinality(oldAnswer, ewah[k])); - } - RoaringBitmap answer2 = FastAggregation.and(Arrays.copyOf(ewah, N)); - assertEquals(answer, answer2); - RoaringBitmap answer2b = FastAggregation.and(toIterator(Arrays.copyOf(ewah, N))); - assertEquals(answer, answer2b); - } + // In the second node of each roaring bitmap, we have two bitmap + // containers. + // So, we will check the union between two BitmapContainers + for (int k = 65536; k < 65536 + 10000; ++k) { + rr.add(k); + V1.add(k); } - @Test - public void testMassiveAndBigInts() { - RoaringBitmap[] ewah = new RoaringBitmap[1024]; - for (int k = 0; k < ewah.length; ++k) { - ewah[k] = new RoaringBitmap(); - } - int howmany = 1000000; - for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); - } - for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); - } - for (int N = 2; N < ewah.length; ++N) { - RoaringBitmap answer = ewah[0]; - for (int k = 1; k < N; ++k) { - RoaringBitmap oldAnswer = answer; - answer = RoaringBitmap.and(oldAnswer, ewah[k]); - assertEquals(answer.getCardinality(), - RoaringBitmap.andCardinality(oldAnswer, ewah[k])); - } - RoaringBitmap answer2 = FastAggregation.and(Arrays.copyOf(ewah, N)); - assertEquals(answer, answer2); - RoaringBitmap answer2b = FastAggregation.and(toIterator(Arrays.copyOf(ewah, N))); - assertEquals(answer, answer2b); - } + for (int k = 65536; k < 65536 + 14000; ++k) { + rr2.add(k); + V1.add(k); } - private static class ExtendedRoaringBitmap extends RoaringBitmap { - } - - /** - * Tests that the static #or operation works correctly with an iterator of - * RoaringBitmap extended classes. - */ - @Test - public void testOrWithIterator() { - final RoaringBitmap b1 = new RoaringBitmap(); - b1.add(13); - final RoaringBitmap b2 = new RoaringBitmap(); - b2.add(42); - - final RoaringBitmap result = RoaringBitmap.or(Arrays.asList(b1, b2).iterator()); - assertTrue(result.contains(13)); - assertTrue(result.contains(42)); - } - - /** - * Tests that the static #or operation works correctly with an iterator of - * RoaringBitmap extended classes. - */ - @Test - public void testOrWithIteratorOfExtendedRoaringBitmaps() { - final ExtendedRoaringBitmap b1 = new ExtendedRoaringBitmap(); - b1.add(1); - final ExtendedRoaringBitmap b2 = new ExtendedRoaringBitmap(); - b2.add(2); - - final RoaringBitmap result = RoaringBitmap.or(Arrays.asList(b1, b2).iterator()); - assertTrue(result.contains(1)); - assertTrue(result.contains(2)); - } - - /** - * Test massive or. - */ - @Test - public void testMassiveOr() { - final int N = 128; - for (int howmany = 512; howmany <= 1000000; howmany *= 2) { - RoaringBitmap[] ewah = new RoaringBitmap[N]; - for (int k = 0; k < ewah.length; ++k) { - ewah[k] = new RoaringBitmap(); - } - for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); - } - for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip(13L, (long) howmany / 2); - } - RoaringBitmap answer = ewah[0]; - for (int k = 1; k < ewah.length; ++k) { - answer = RoaringBitmap.or(answer, ewah[k]); - } - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); - List rbl = new ArrayList<>(); - rbl.add(rb1); - rbl.add(rb2); - - ArrayList arrayList = new ArrayList<>(); - arrayList.add(rb1); - arrayList.add(rb2); - Iterator rbi = arrayList.iterator(); - - RoaringBitmap rbor = RoaringBitmap.or(rb1, rb2); - RoaringBitmap answer2 = FastAggregation.or(ewah); - RoaringBitmap answer3 = FastAggregation.horizontal_or(ewah); - RoaringBitmap answer3b = FastAggregation.or(toIterator(ewah)); - assertEquals(answer, answer2); - assertEquals(answer, answer3); - assertEquals(answer, answer3b); - assertEquals(rbor, FastAggregation.horizontal_or(rbl)); - assertEquals(rbor, FastAggregation.priorityqueue_or(rb1, rb2)); - assertEquals(rbor, FastAggregation.priorityqueue_or(rbi)); - } + // In the 3rd node of each Roaring Bitmap, we have an + // ArrayContainer, so, we will try the union between two + // ArrayContainers. + for (int k = 4 * 65535; k < 4 * 65535 + 1000; ++k) { + rr.add(k); + V1.add(k); } - @Test - public void testMassiveOrBigInts() { - final int N = 128; - for (int howmany = 512; howmany <= 1000000; howmany *= 2) { - RoaringBitmap[] ewah = new RoaringBitmap[N]; - for (int k = 0; k < ewah.length; ++k) { - ewah[k] = new RoaringBitmap(); - } - for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); - } - for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); - } - RoaringBitmap answer = ewah[0]; - for (int k = 1; k < ewah.length; ++k) { - answer = RoaringBitmap.or(answer, ewah[k]); - } - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); - List rbl = new ArrayList<>(); - rbl.add(rb1); - rbl.add(rb2); - - ArrayList arrayList = new ArrayList<>(); - arrayList.add(rb1); - arrayList.add(rb2); - Iterator rbi = arrayList.iterator(); - - RoaringBitmap rbor = RoaringBitmap.or(rb1, rb2); - RoaringBitmap answer2 = FastAggregation.or(ewah); - RoaringBitmap answer3 = FastAggregation.horizontal_or(ewah); - RoaringBitmap answer3b = FastAggregation.or(toIterator(ewah)); - assertEquals(answer, answer2); - assertEquals(answer, answer3); - assertEquals(answer, answer3b); - assertEquals(rbor, FastAggregation.horizontal_or(rbl)); - assertEquals(rbor, FastAggregation.priorityqueue_or(rb1, rb2)); - assertEquals(rbor, FastAggregation.priorityqueue_or(rbi)); - } + for (int k = 4 * 65535; k < 4 * 65535 + 800; ++k) { + rr2.add(k); + V1.add(k); } + // For the rest, we will check if the union will take them in + // the result + for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { + rr.add(k); + V1.add(k); + } - /** - * Test massive xor. - */ - @Test - public void testMassiveXOr() { - final int N = 128; - for (int howmany = 512; howmany <= 1000000; howmany *= 2) { - RoaringBitmap[] ewah = new RoaringBitmap[N]; - for (int k = 0; k < ewah.length; ++k) { - ewah[k] = new RoaringBitmap(); - } - for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); - } - for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip(13L, (long) howmany / 2); - } - - RoaringBitmap answer = ewah[0]; - for (int k = 1; k < ewah.length; ++k) { - answer = RoaringBitmap.xor(answer, ewah[k]); - } - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); - RoaringBitmap rxor = FastAggregation.xor(rb1, rb2); - RoaringBitmap answer2 = FastAggregation.xor(ewah); - RoaringBitmap answer3 = FastAggregation.horizontal_xor(ewah); - assertEquals(answer, answer2); - assertEquals(answer, answer3); - assertEquals(rxor, FastAggregation.priorityqueue_xor(rb1, rb2)); - } + for (int k = 7 * 65535; k < 7 * 65535 + 2000; ++k) { + rr2.add(k); + V1.add(k); } + final RoaringBitmap rror = RoaringBitmap.or(rr, rr2); + boolean valide = true; - @Test - public void testMassiveXOrBigInts() { - final int N = 128; - for (int howmany = 512; howmany <= 1000000; howmany *= 2) { - RoaringBitmap[] ewah = new RoaringBitmap[N]; - for (int k = 0; k < ewah.length; ++k) { - ewah[k] = new RoaringBitmap(); - } - for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); - } - for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); - } - - RoaringBitmap answer = ewah[0]; - for (int k = 1; k < ewah.length; ++k) { - answer = RoaringBitmap.xor(answer, ewah[k]); - } - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); - RoaringBitmap rxor = FastAggregation.xor(rb1, rb2); - RoaringBitmap answer2 = FastAggregation.xor(ewah); - RoaringBitmap answer3 = FastAggregation.horizontal_xor(ewah); - assertEquals(answer, answer2); - assertEquals(answer, answer3); - assertEquals(rxor, FastAggregation.priorityqueue_xor(rb1, rb2)); - } - } + // Si tous les elements de rror sont dans V1 et que tous les + // elements de + // V1 sont dans rror(V2) + // alors V1 == rror - @Test - public void testOr001() { - int[] array1 = {22871, 22873, 22876, 22880, 22886, 22889, 22893, 22897, 22901, 22905, 22910, - 22915, 22919, 22927, 22934, 22940, 24750, 38579, 48470, 50533, 53256, 53717, 53752, 53802, - 53938, 54727, 54865, 55202, 55815, 55822, 55940, 56711, 56977, 57122, 59933, 60037, 60402, - 60520, 60853, 61163, 61340, 61549, 61632, 62097, 62373, 62961, 62993, 63031, 63075, 64209, - 64644, 64762, 64893, 64927, 64997, 65117, 65128, 65173, 65201, 65472, 65536, 65622, 66092, - 66162, 66302, 66381, 66551, 103979, 104644, 106866, 117285, 123372, 127548, 132167, 132168, - 136283, 136433, 137661, 138019, 138239, 138380, 138816, 138916, 138933, 139414, 140342, - 140914, 142751, 142994, 143895, 145081, 147331, 147686, 148021, 148375, 148587, 149114, - 149734, 152696, 153608, 154741, 154932, 155263, 157121, 158947, 159444, 161102, 161383, - 162735, 164298, 168043, 169398, 169536, 170419, 170846, 171153, 177016, 177471, 178305, - 178673, 183731, 183936, 184083, 184106, 185663, 188371, 189495, 189531, 196189, 198419, - 198758, 198796, 200645, 201137, 216865, 216936, 217770, 217810, 217836, 217909, 218569, - 218700, 218931, 219363, 220009, 225925, 234706, 241183, 241561, 242140, 242281, 245018, - 245056, 249935, 250442, 250615, 251696, 252825, 254178, 256788, 256906, 257289, 258833, - 260432, 260563, 260930, 262684, 262834, 263128, 265919, 268662, 269542, 270217, 271673, - 273776, 274560, 275649, 305458, 306241, 306550, 307580, 310891, 312701, 313514, 318134, - 319185, 320757, 321280, 322046, 322743, 323211, 324667, 325382, 326450, 327159, 328836, - 329075, 331179, 332836, 332997, 333071, 333205, 333488, 333595, 335045, 335803, 336417, - 336610, 338487, 339827, 339992, 346123, 348858, 351257, 351957, 353896, 354559, 357142, - 358253, 366662, 378768, 391984, 392282, 415077, 429446, 429449, 429452, 429453, 429476, - 429480, 429486, 429492, 429497, 429501, 429504, 429505, 429510, 429515, 429519, 429524, - 429530, 429533, 429541, 429546, 429553, 429554, 429564, 429572, 429577, 429579, 429586, - 429589, 429596, 429604, 429606, 429612, 429615, 429616, 429624, 429632, 429639, 429642, - 429646, 429651, 429656, 429664, 429670, 429674, 429678, 429681, 429686, 429695, 429701, - 429706, 429717, 429721, 429725, 429733, 429736, 429739, 429743, 429748, 429754, 429761, - 429767, 429772, 429780, 429791, 429792, 429793, 429794, 429795, 429817, 429822, 429823, - 429831, 429836, 429842, 429849, 429855, 429859, 429863, 429866, 429873, 429876, 429882, - 429885, 429900, 429903, 429913, 429921, 429923, 429927, 429932, 429939, 429947, 429950, - 429955, 429964, 429968, 429974, 429982, 429987, 429993, 429999, 430003, 430011, 430015, - 430023, 430028, 430033, 430039, 430044, 430048, 430053, 430057, 430059, 430063, 430068, - 430073, 430077, 430082, 430086, 430093, 430098, 430101, 430114, 430120, 430126, 430131, - 430135, 430139, 430144, 430149, 430155, 430157, 430167, 430175, 430181, 430186, 430194, - 430195, 430196, 430214, 430223, 430228, 430236, 430253, 430258, 430263, 430269, 430277, - 430284, 430288, 430293, 430297, 430303, 430309, 430316, 430321, 430332, 430338, 430343, - 430346, 430348, 430355, 430358, 430369, 430375, 430384, 430391, 430397, 430410, 430415, - 430420, 430424, 430430, 430435, 430437, 430445, 430449, 430461, 430467, 430473, 430482, - 430486, 430490, 430496, 430500, 430506, 430511, 430515, 430535, 430539, 430550, 430568, - 430575, 430581, 430588, 430591, 430596, 430605, 430612, 430617, 430625, 430629, 430633, - 430638, 430643, 430649, 430656, 430663, 430666, 430672, 430679, 430684, 430692, 430696, - 430700, 430707, 430716, 430723, 430728, 430733, 430745, 430751, 430755, 430759, 430767, - 430770, 430782, 430787, 430791, 430804, 430810, 430814, 430821, 430825, 430829, 430833, - 430838, 430844, 430849, 430852, 430859, 430864, 430867, 430870, 430877, 430881, 430887, - 430891, 430896, 430901, 430907, 430912, 430917, 430923, 430927, 430932, 430936, 430944, - 430947, 430953, 430959, 430967, 430971, 430979, 430985, 430989, 430993, 430997, 431003, - 431006, 431015, 431021, 431022, 431033, 431039, 431046, 431050, 431054, 431059, 431065, - 431069, 431074, 431081, 431085, 431092, 431097, 431104, 431110, 431120, 431125, 431133, - 431138, 431142, 431147, 431157, 431164, 431171, 431175, 431180, 431186, 431190, 431195, - 431207, 431213, 431218, 431220, 431224, 431228, 431233, 431235, 431240, 431245, 431251, - 431259, 431264, 431271, 431272, 431280, 431287, 431294, 431299, 431307, 431315, 431319, - 431324, 431330, 431334, 431339, 431345, 431352, 431356, 431363, 431375, 431379, 431383, - 431388, 431393, 431398, 431405, 431409, 431416, 431422, 431426, 431433, 431438, 431444, - 431451, 431455, 431464, 431469, 431472, 431477, 431483, 431490, 431496, 431506, 431513, - 431516, 431521, 431526, 431534, 431536, 431545, 431550, 431559, 431564, 431571, 431573, - 431579, 431584, 431587, 431592, 431604, 431614, 431624, 431629, 431634, 431638, 431645, - 431651, 431659, 431663, 431674, 431678, 431684, 431692, 431696, 431700, 431706, 431712, - 431719, 431723, 431729, 431736, 431741, 431747, 431755, 431758, 431762, 431767, 431777, - 431782, 431787, 431791, 431796, 431799, 431805, 431809, 431814, 431819, 431823, 431828, - 431832, 431838, 431842, 431849, 431853, 431858, 431862, 431866, 431869, 431874, 431881, - 431887, 431894, 431900, 431906, 431912, 431917, 431925, 431931, 431936, 431943, 431948, - 431956, 431958, 431964, 431971, 431976, 431981, 431988, 431994, 431998, 432008, 432012, - 432024, 432029, 432033, 432038, 432045, 432048, 432058, 432062, 432066, 432070, 432076, - 432077, 432087, 432093, 432098, 432104, 432114, 432123, 432128, 432133, 432139, 432145, - 432151, 432161, 432168, 432177, 432181, 432188, 432189, 432203, 432209, 432216, 432222, - 432227, 432232, 432242, 432247, 432256, 432259, 432264, 432269, 432271, 432277, 432286, - 432294, 432297, 432302, 432308, 432313, 432319, 432326, 432331, 432337, 432345, 432349, - 432353, 432356, 432361, 432366, 432370, 432378, 432384, 432390, 432391, 432397, 432400, - 432403, 432408, 432413, 432419, 432422, 432427, 432433, 432440, 432443, 432450, 432455, - 432460, 432466, 432467, 432481, 432489, 432493, 432498, 432504, 432511, 432513, 432517, - 432525, 432531, 432537, 432544, 432546, 432555, 432561, 432565, 432569, 432574, 432579, - 432586, 432590, 432597, 432605, 432611, 432619, 432626, 432630, 432637, 432644, 432646, - 432653, 432654, 432664, 432670, 432674, 432679, 432682, 432687, 432694, 432706, 432711, - 432714, 432721, 432726, 432732, 432741, 432747, 432753, 432755, 432761, 432764, 432768, - 432774, 432779, 432784, 432792, 432798, 432801, 432808, 432815, 432823, 432825, 432833, - 432838, 432842, 432847, 432853, 432861, 432866, 432873, 432879, 432889, 432895, 432901, - 432906, 432913, 432917, 432920, 432926, 432935, 432940, 432949, 432953, 432958, 432960, - 432966, 432967, 432968, 432969, 432970, 432971, 432972, 432996, 432999, 433004, 433010, - 433020, 433026, 433029, 433033, 433042, 433045, 433050, 433054, 433058, 433062, 433065, - 433070, 433076, 433086, 433095, 433101, 433102, 433116, 433122, 433129, 433132, 433140, - 433146, 433151, 433157, 433163, 433169, 433176, 433181, 433188, 433198, 433204, 433219, - 433229, 433236, 433240, 433246, 433250, 433259, 433263, 433274, 433277, 433282, 433286, - 433291, 433295, 433299, 433306, 433316, 433318, 433322, 433327, 433335, 433342, 433348, - 433351, 433359, 433362, 433367, 433371, 433377, 433384, 433393, 433398, 433403, 433407, - 433411, 433425, 433430, 433437, 433441, 433445, 433452, 433453, 433458, 433462, 433469, - 433473, 433478, 433484, 433490, 433495, 433501, 433506, 433514, 433517, 433521, 433527, - 433534, 433544, 433549, 433552, 433561, 433565, 433569, 433576, 433585, 433589, 433594, - 433597, 433600, 433603, 433606, 433613, 433619, 433623, 433627, 433639, 433643, 433648, - 433654, 433658, 433665, 433673, 433678, 433681, 433689, 433696, 433704, 433709, 433716, - 433721, 433725, 433729, 433734, 433738, 433744, 433749, 433755, 433760, 433766, 433771, - 433776, 433781, 433785, 433790, 433798, 433803, 433810, 433814, 433817, 433822, 433828, - 433833, 433837, 433843, 433849, 433852, 433858, 433863, 433871, 433875, 433881, 433883, - 433884, 433897, 433903, 433909, 433913, 433921, 433926, 433932, 433936, 433942, 433946, - 433951, 433959, 433965, 433976, 433981, 433989, 433996, 434004, 434011, 434013, 434019, - 434023, 434029, 434036, 434041, 434048, 434050, 434056, 434060, 434068, 434074, 434079, - 434085, 434091, 434096, 434100, 434105, 434110, 434119, 434123, 434129, 434133, 434139, - 434146, 434150, 434156, 434161, 434168, 434173, 434183, 434188, 434193, 434200, 434208, - 434213, 434219, 434223, 434229, 434235, 434241, 434247, 434258, 434262, 434269, 434275, - 434282, 434287, 434291, 434296, 434303, 434308, 434313, 434316, 434323, 434327, 434335, - 434342, 434349, 434353, 434360, 434366, 434372, 434373, 434381, 434387, 434392, 434397, - 434401, 434403, 434409, 434414, 434420, 434427, 434433, 434440, 434445, 434449, 434454, - 434460, 434467, 434473, 434479, 434481, 434490, 434494, 434501, 434505, 434510, 434517, - 434526, 434537, 434542, 434548, 434553, 434558, 434563, 434569, 434574, 434580, 434586, - 434588, 434595, 434603, 434606, 434617, 434620, 434626, 434630, 434638, 434644, 434647, - 434651, 434658, 434666, 434671, 434679, 434681, 434685, 434692, 434699, 434703, 434708, - 434713, 434720, 434723, 434729, 434734, 434738, 434742, 434746, 434753, 434762, 434766, - 434773, 434781, 434790, 434799, 434805, 434810, 434814, 434823, 434831, 434839, 434845, - 434850, 434856, 434859, 434863, 434869, 434870, 434882, 434890, 434896, 434899, 434906, - 434912, 434917, 434921, 434930, 434935, 434940, 434945, 434949, 434956, 434961, 434967, - 434977, 434982, 434987, 434992, 434995, 435002, 435005, 435009, 435016, 435021, 435025, - 435028, 435034, 435041, 435050, 435055, 435065, 435069, 435075, 435078, 435083, 435091, - 435097, 435102, 435105, 435107, 435113, 435118, 435124, 435131, 435141, 435144, 435150, - 435154, 435159, 435167, 435171, 435177, 435181, 435187, 435192, 435198, 435204, 435211, - 435212, 435221, 435228, 435231, 435237, 435244, 435246, 435254, 435258, 435264, 435275, - 435283, 435289, 435301, 435304, 435312, 435318, 435323, 435329, 435334, 435340, 435343, - 435347, 435351, 435358, 435363, 435368, 435375, 435382, 435388, 435391, 435396, 435399, - 435405, 435412, 435416, 435422, 435425, 435429, 435437, 435444, 435447, 435453, 435458, - 435470, 435477, 435486, 435491, 435497, 435500, 435511, 435516, 435520, 435526, 435533, - 435539, 435545, 435551, 435559, 435564, 435569, 435575, 435579, 435585, 435590, 435597, - 435599, 435600, 435610, 435616, 435618, 435623, 435628, 435636, 435643, 435649, 435654, - 435659, 435663, 435671, 435675, 435678, 435683, 435689, 435702, 435705, 435712, 435718, - 435749, 435755, 435759, 435764, 435771, 435775, 435780, 435785, 435791, 435794, 435802, - 435811, 435816, 435822, 435828, 435833, 435838, 435844, 435851, 435859, 435861, 435866, - 435869, 435876, 435882, 435890, 435897, 435900, 435908, 435913, 435923, 435929, 435934, - 435937, 435942, 435945, 435951, 435953, 435959, 435965, 435969, 435975, 435982, 435987, - 435992, 436000, 436008, 436013, 436017, 436022, 436027, 436033, 436038, 436043, 436048, - 436052, 436062, 436065, 436069, 436073, 436079, 436088, 436092, 436100, 436106, 436116, - 436123, 436127, 436133, 436139, 436147, 436153, 436159, 436165, 436172, 436179, 436184, - 436190, 436194, 436199, 436206, 436210, 436211, 436217, 436223, 436229, 436234, 436240, - 436245, 436253, 436258, 436262, 436268, 436273, 436282, 436287, 436294, 436303, 436306, - 436313, 436316, 436321, 436329, 436337, 436341, 436349, 436353, 436358, 436365, 436368, - 436373, 436378, 436387, 436391, 436396, 436401, 436408, 436412, 436420, 436423, 436428, - 436435, 436441, 436447, 436451, 436461, 436463, 436467, 436471, 436477, 436479, 436485, - 436489, 436494, 436502, 436509, 436512, 436518, 436529, 436538, 436543, 436552, 436553, - 436560, 436564, 436569, 436575, 436580, 436585, 436591, 436597, 436603, 436605, 436610, - 436616, 436619, 436628, 436633, 436637, 436640, 436644, 436649, 436653, 436659, 436666, - 436674, 436681, 436687, 436694, 436700, 436703, 436710, 436720, 436723, 436730, 436735, - 436742, 436748, 436756, 436761, 436766, 436772, 436778, 436783, 436787, 436792, 436799, - 436808, 436810, 436812, 436817, 436823, 436832, 436838, 436845, 436849, 436853, 436859, - 436865, 436872, 436878, 436882, 436885, 436891, 436898, 436903, 436910, 436911, 436922, - 436928, 436932, 436939, 436942, 436948, 436950, 436956, 436963, 436968, 436975, 436984, - 436988, 436994, 437003, 437009, 437013, 437020, 437023, 437028, 437033, 437043, 437053, - 437058, 437063, 437073, 437076, 437079, 437089, 437093, 437095, 437101, 437111, 437119, - 437121, 437127, 437135, 437140, 437147, 437151, 437155, 437160, 437165, 437171, 437173, - 437180, 437186, 437194, 437199, 437205, 437213, 437217, 437223, 437227, 437231, 437243, - 437250, 437256, 437261, 437267, 437271, 437277, 437284, 437289, 437295, 437300, 437304, - 437312, 437322, 437326, 437333, 437338, 437354, 437357, 437362, 437366, 437370, 437374, - 437380, 437386, 437391, 437395, 437399, 437404, 437412, 437416, 437419, 437427, 437432, - 437433, 437451, 437456, 437461, 437467, 437468, 437477, 437485, 437492, 437495, 437501, - 437502, 437506, 437513, 437524, 437526, 437539, 437544, 437552, 437558, 437562, 437568, - 437573, 437578, 437587, 437592, 437596, 437600, 437605, 437610, 437619, 437625, 437630, - 437631, 437639, 437647, 437648, 437655, 437661, 437667, 437672, 437676, 437680, 437687, - 437689, 437693, 437697, 437704, 437707, 437716, 437723, 437730, 437737, 437740, 437741, - 437757, 437763, 437771, 437778, 437784, 437789, 437793, 437800, 437804, 437811, 437812, - 437819, 437823, 437827, 437833, 437841, 437844, 437853, 437857, 437861, 437866, 437874, - 437881, 437886, 437892, 437901, 437902, 437909, 437914, 437922, 437928, 437934, 437939, - 437948, 437951, 437957, 437963, 437965, 437971, 437980, 437985, 437990, 437996, 438002, - 438008, 438013, 438017, 438025, 438030, 438036, 438041, 438052, 438060, 438065, 438072, - 438073, 438079, 438084, 438091, 438097, 438099, 438107, 438111, 438119, 438125, 438136, - 438144, 438148, 438153, 438158, 438164, 438166, 438173, 438176, 438183, 438184, 438192, - 438198, 438204, 438209, 438216, 438228, 438231, 438237, 438243, 438248, 438257, 438267, - 438269, 438274, 438282, 438287, 438295, 438301, 438306, 438313, 438318, 438323, 438328, - 438335, 438339, 438346, 438352, 438357, 438363, 438370, 438374, 438380, 438384, 438388, - 438394, 438399, 438404, 438409, 438413, 438422, 438428, 438436, 438439, 438444, 438453, - 438461, 438471, 438477, 438483, 438491, 438503, 438505, 438511, 438518, 438527, 438531, - 438541, 438546, 438552, 438556, 438562, 438566, 438570, 438580, 438585, 438593, 438595, - 438603, 438605, 438607, 438614, 438619, 438626, 438631, 438634, 438641, 438646, 438652, - 438657, 438663, 438664, 438665, 438673, 438677, 438682, 438692, 438700, 438706, 438708, - 438715, 438723, 438727, 438737, 438742, 438753, 438760, 438764, 438771, 438775, 438780, - 438783, 438789, 438797, 438806, 438810, 438815, 438832, 438837, 438841, 438845, 438852, - 438860, 438865, 438873, 438883, 438884, 438896, 438908, 438912, 438920, 438924, 438927, - 438934, 438936, 438940, 438946, 438953, 438961, 438968, 438976, 438980, 438985, 438994, - 439006, 439011, 439017, 439021, 439027, 439032, 439036, 439043, 439047, 439055, 439059, - 439065, 439070, 439075, 439083, 439087, 439093, 439099, 439104, 439109, 439114, 439120, - 439123, 439128, 439130, 439134, 439139, 439147, 439157, 439162, 439167, 439172, 439178, - 439183, 439187, 439194, 439201, 439205, 439210, 439216, 439222, 439225, 439231, 439235, - 439245, 439251, 439255, 439261, 439277, 439282, 439288, 439295, 439302, 439308, 439309, - 439314, 439320, 439328, 439332, 439339, 439345, 439350, 439354, 439359, 439365, 439372, - 439377, 439379, 439386, 439391, 439404, 439410, 439416, 439419, 439425, 439430, 439434, - 439438, 439455, 439461, 439465, 439472, 439476, 439482, 439488, 439493, 439496, 439506, - 439510, 439516, 439521, 439527, 439536, 439543, 439551, 439554, 439557, 439564, 439569, - 439574, 439577, 439584, 439588, 439593, 439597, 439602, 439607, 439613, 439618, 439624, - 439625, 439633, 439638, 439641, 439645, 439650, 439655, 439659, 439669, 439670, 439671, - 439682, 439692, 439696, 439701, 439709, 439718, 439725, 439730, 439733, 439739, 439745, - 439757, 439764, 439768, 439771, 439778, 439783, 439788, 439796, 439805, 439811, 439815, - 439820, 439827, 439830, 439840, 439846, 439850, 439854, 439865, 439873, 439879, 439886, - 439891, 439898, 439903, 439909, 439917, 439925, 439928, 439933, 439938, 439944, 439948, - 439955, 439959, 439965, 439969, 439974, 439988, 439989, 440005, 440008, 440011, 440015, - 440020, 440026, 440030, 440035, 440043, 440044, 440055, 440060, 440078, 440091, 440096, - 440101, 440106, 440111, 440116, 440120, 440134, 440139, 440143, 440149, 440157, 440163, - 440167, 440171, 440179, 440187, 440191, 440196, 440201, 440207, 440213, 440218, 440223, - 440228, 440233, 440239, 440244, 440249, 440256, 440262, 440268, 440274, 440277, 440282, - 440289, 440295, 440307, 440311, 440315, 440321, 440327, 440331, 440336, 440341, 440346, - 440355, 440361, 440368, 440375, 440379, 440388, 440394, 440399, 440402, 440410, 440413, - 440421, 440427, 440431, 440435, 440440, 440446, 440454, 440461, 440467, 440476, 440481, - 440486, 440490, 440495, 440500, 440506, 440512, 440523, 440529, 440533, 440539, 440546, - 440552, 440560, 440568, 440578, 440584, 440590, 440594, 440598, 440606, 440612, 440620, - 440623, 440629, 440634, 440641, 440647, 440651, 440655, 440663, 440669, 440674, 440682, - 440689, 440694, 440698, 440702, 440706, 440713, 440719, 440727, 440733, 440737, 440743, - 440747, 440753, 440760, 440767, 440772, 440779, 440783, 440789, 440792, 440798, 440806, - 440808, 440812, 440819, 440823, 440826, 440830, 440835, 440840, 440845, 440853, 440856, - 440861, 440867, 440872, 440876, 440882, 440888, 440893, 440903, 440910, 440915, 440921, - 440927, 440933, 440938, 440945, 440950, 440958, 440966, 440969, 440973, 440977, 440983, - 440987, 440992, 440996, 441005, 441008, 441013, 441028, 441035, 441042, 441047, 441052, - 441056, 441061, 441068, 441075, 441080, 441087, 441094, 441097, 441106, 441111, 441115, - 441121, 441125, 441132, 441136, 441143, 441150, 441157, 441161, 441167, 441171, 441175, - 441179, 441185, 441193, 441196, 441200, 441204, 441210, 441216, 441223, 441226, 441234, - 441238, 441243, 441253, 441260, 441268, 441276, 441287, 441294, 441297, 441306, 441313, - 441315, 441323, 441332, 441339, 441346, 441353, 441358, 441362, 441368, 441373, 441378, - 441382, 441390, 441394, 441399, 441404, 441411, 441416, 441420, 441427, 441432, 441440, - 441445, 441448, 441453, 441456, 441461, 441467, 441473, 441479, 441484, 441491, 441497, - 441506, 441509, 441515, 441521, 441526, 441531, 441535, 441542, 441547, 441551, 441555, - 441559, 441565, 441569, 441574, 441579, 441596, 441599, 441605, 441610, 441617, 441619, - 441623, 441628, 441630, 441636, 441637, 441651, 441652, 441662, 441664, 441667, 441671, - 441681, 441684, 441689, 441693, 441701, 441705, 441710, 441718, 441720, 441726, 441740, - 441746, 441757, 441759, 441766, 441773, 441775, 441780, 441793, 441794, 441799, 441807, - 441817, 441822, 441828, 441831, 441834, 441838, 441845, 441853, 441857, 441863, 441866, - 441872, 441880, 441883, 441886, 441891, 441895, 441900, 441910, 441915, 441921, 441928, - 441934, 441939, 441945, 441947, 441952, 441957, 441964, 441971, 441974, 441980, 441985, - 441990, 441994, 441998, 442002, 442007, 442010, 442017, 442019, 442027, 442043, 442046, - 442054, 442060, 442067, 442074, 442076, 442081, 442086, 442093, 442099, 442103, 442108, - 442112, 442120, 442131, 442135, 442139, 442144, 442148, 442156, 442161, 442165, 442170, - 442181, 442186, 442192, 442197, 442203, 442220, 442226, 442233, 442239, 442245, 442249, - 442254, 442259, 442267, 442275, 442281, 442284, 442287, 442292, 442299, 442308, 442314, - 442318, 442325, 442332, 442333, 442334, 442346, 442351, 442354, 442358, 442364, 442370, - 442372, 442377, 442381, 442389, 442397, 442402, 442409, 442415, 442419, 442424, 442430, - 442438, 442443, 442451, 442459, 442470, 442473, 442482, 442490, 442496, 442501, 442506, - 442514, 442520, 442524, 442530, 442534, 442541, 442546, 442549, 442554, 442558, 442563, - 442573, 442586, 442591, 442595, 442600, 442607, 442613, 442618, 442624, 442628, 442632, - 442640, 442647, 442651, 442657, 442666, 442674, 442679, 442682, 442686, 442692, 442699, - 442705, 442714, 442718, 442722, 442729, 442734, 442739, 442748, 442751, 442754, 442757, - 442765, 442770, 442778, 442783, 442792, 442798, 442802, 442813, 442820, 442829, 442833, - 442841, 442845, 442851, 442857, 442860, 442865, 442871, 442877, 442882, 442886, 442892, - 442898, 442904, 442906, 442911, 442915, 442922, 442929, 442934, 442940, 442944, 442946, - 442952, 442956, 442963, 442971, 442973, 442979, 442985, 442997, 443001, 443006, 443017, - 443019, 443024, 443027, 443036, 443046, 443050, 443057, 443066, 443069, 443078, 443083, - 443089, 443093, 443100, 443104, 443109, 443118, 443126, 443134, 443141, 443146, 443151, - 443158, 443164, 443169, 443174, 443179, 443182, 443189, 443195, 443198, 443206, 443211, - 443213, 443214, 443222, 443224, 443228, 443235, 443240, 443246, 443255, 443259, 443269, - 443270, 443277, 443285, 443291, 443299, 443303, 443311, 443313, 443319, 443322, 443328, - 443338, 443342, 443350, 443351, 443356, 443362, 443365, 443368, 443371, 443375, 443378, - 443384, 443388, 443391, 443397, 443404, 443412, 443416, 443421, 443424, 443428, 443433, - 443438, 443442, 443449, 443462, 443463, 443470, 443474, 443482, 443490, 443495, 443499, - 443506, 443519, 443523, 443527, 443533, 443540, 443548, 443550, 443556, 443559, 443564, - 443568, 443574, 443582, 443589, 443594, 443596, 443602, 443610, 443612, 443616, 443620, - 443625, 443631, 443638, 443643, 443649, 443656, 443660, 443669, 443672, 443680, 443691, - 443695, 443699, 443706, 443710, 443714, 443718, 443721, 443726, 443734, 443739, 443745, - 443752, 443758, 443765, 443771, 443774, 443781, 443786, 443789, 443793, 443797, 443802, - 443811, 443812, 443820, 443829, 443832, 443838, 443847, 443851, 443856, 443857, 443864, - 443871, 443877, 443886, 443892, 443896, 443903, 443909, 443913, 443920, 443925, 443930, - 443935, 443942, 443946, 443954, 443963, 443966, 443969, 443975, 443979, 443982, 443988, - 443996, 443999, 444003, 444007, 444012, 444019, 444026, 444030, 444040, 444049, 444056, - 444060, 444064, 444069, 444073, 444075, 444078, 444083, 444091, 444098, 444103, 444111, - 444121, 444124, 444130, 444136, 444140, 444145, 444150, 444156, 444162, 444168, 444172, - 444179, 444182, 444186, 444189, 444193, 444198, 444203, 444208, 444212, 444218, 444225, - 444231, 444234, 444240, 444246, 444258, 444265, 444273, 444277, 444281, 444288, 444292, - 444298, 444301, 444309, 444314, 444319, 444327, 444332, 444338, 444349, 444354, 444359, - 444364, 444374, 444377, 444381, 444386, 444388, 444394, 444401, 444406, 444417, 444422, - 444429, 444438, 444439, 444448, 444449, 444456, 444461, 444467, 444473, 444480, 444486, - 444490, 444495, 444500, 444503, 444508, 444514, 444518, 444525, 444528, 444535, 444540, - 444544, 444550, 444556, 444563, 444570, 444576, 444580, 444583, 444587, 444591, 444599, - 444605, 444608, 444612, 444619, 444629, 444635, 444643, 444646, 444652, 444660, 444671, - 444676, 444681, 444686, 444690, 444696, 444703, 444710, 444711, 444720, 444723, 444734, - 444742, 444752, 444758, 444763, 444767, 444770, 444774, 444786, 444789, 444794, 444800, - 444809, 444818, 444822, 444830, 444836, 444841, 444846, 444853, 444859, 444866, 444873, - 444878, 444885, 444890, 444896, 444904, 444907, 444914, 444922, 444924, 444931, 446357, - 488475, 495304, 496119, 497438, 498593, 498603, 498917, 499048, 499713, 500776, 501348, - 503424, 508844, 518359, 519305, 519446, 523627, 523776, 523878, 523902, 524135, 524329, - 524515, 524611, 524686, 524798, 524852, 525209, 525700, 525913, 525954, 526158, 526332, - 526356, 536810, 537279, 563933, 578719, 579248, 579791, 584191, 591485, 592871, 613176, - 615012, 616428, 619153, 636103, 640708, 643141, 645080, 646349, 647043, 649345, 651085, - 652849, 653092, 653169, 653227, 653586, 655241, 656093, 658355, 658564, 659381, 659518, - 690513, 693218, 693746, 694340, 694842, 695155, 695563, 695776, 696380, 697608, 697797, - 698222, 698835, 699307, 700154, 700203, 700235, 700404, 700806, 700900, 701796, 702155, - 702956, 702998, 705105, 705377, 705631, 708650, 709265, 709787, 725122, 735376, 737115, - 737174, 738005, 741377, 741986, 746045, 746404, 746590, 748212, 753574, 754379, 764728, - 765776, 766863, 769126, 782626, 782723, 783529, 786875, 787544, 807281, 811132, 821933, - 822194, 829768, 830997, 831095, 832481, 834082, 844664, 845574, 845764, 846820, 849481, - 855607, 857775, 872350, 876126, 902029, 903509, 904449, 904469, 905915, 910463, 911856, - 924365, 928664, 929314, 929606, 929983, 930478, 933195, 933819, 935628, 935911, 935922, - 936002, 937668, 941895, 942677, 943721, 944661, 944980, 945121, 945268, 945360, 950756, - 951007, 959993, 960787, 961048, 961084, 961238, 961589, 962000, 962797, 962827, 962910, - 963788, 964272, 964343, 964431, 964573, 964949, 965017, 965036, 965041, 965598, 965674, - 965957, 966014, 966032, 966092, 966144, 966226, 966234, 966265, 966291, 978103, 980858, - 987212, 987458, 987498, 988368, 988513, 988939, 990571, 993183, 1005493, 1007972, 1008230, - 1009675, 1010075, 1010685, 1011441, 1011828, 1012269, 1012310, 1013612, 1013907, 1014379, - 1018659, 1018923, 1022035, 1024567, 1024568, 1025024, 1026699, 1027212, 1027840, 1029108, - 1031846, 1032670, 1032970, 1034016, 1039255, 1040626, 1040796, 1043457, 1043632, 1051053, - 1052581, 1091611, 1092316, 1092564, 1092634, 1096386, 1096820, 1098606, 1104201, 1107101, - 1110019, 1111384, 1111707, 1128990, 1129111, 1129147, 1129160, 1129367, 1129408, 1129508, - 1129577, 1129699, 1129750, 1129840, 1129951, 1129988, 1130041, 1130139, 1130177, 1130241, - 1130248, 1130268, 1130276, 1130367, 1130540, 1130562, 1130636, 1130637, 1130662, 1130716, - 1131139, 1131218, 1131250, 1131454, 1131541, 1131775, 1132208, 1132280, 1132901, 1133264, - 1133474, 1133475, 1133764, 1133841, 1133988, 1134290, 1134533, 1134553, 1134614, 1134667, - 1134710, 1134861, 1134896, 1135008, 1135178, 1135544, 1135551, 1135573, 1136260, 1136385, - 1136458, 1136782, 1136960, 1137342, 1137713, 1137824, 1138160, 1138291, 1138340, 1138457, - 1138468, 1138516, 1138526, 1138610, 1138648, 1138700, 1138801, 1138869, 1138999, 1139010, - 1139102, 1139114, 1139145, 1139302, 1139322, 1139417, 1139496, 1139581, 1139668, 1139852, - 1139930, 1139958, 1140325, 1140616, 1140811, 1140861, 1141056, 1141197, 1141311, 1141346, - 1141551, 1141666, 1141735, 1141786, 1141895, 1142017, 1142228, 1142242, 1142415, 1142484, - 1142579, 1142599, 1142867, 1142929, 1143057, 1143132, 1143191, 1143203, 1143293, 1143476, - 1143860, 1143997, 1144044, 1144321, 1144338, 1144459, 1144548, 1144564, 1144588, 1144592, - 1144606, 1144623, 1144718, 1144792, 1144906, 1144997, 1145007, 1145082, 1145274, 1145380, - 1145430, 1145584, 1145731, 1145778, 1145869, 1145914, 1145925, 1146025, 1146158, 1146212, - 1146223, 1146448, 1146594, 1146663, 1146761, 1146803, 1146826, 1146833, 1146898, 1147078, - 1147099, 1147330, 1147382, 1147424, 1147431, 1147472, 1147545, 1147592, 1147627, 1147657, - 1147742, 1148005, 1148699, 1155013, 1155166, 1155915, 1178902, 1179255, 1180871, 1184802, - 1187587, 1190670, 1198632, 1198646, 1198832, 1199211, 1199259, 1199330, 1200318, 1200824, - 1200959, 1201200, 1202513, 1210077, 1210208, 1210296, 1211774, 1211775, 1211776, 1211777, - 1212528, 1212529, 1212843, 1216377, 1219904, 1220650, 1232492, 1235492, 1243381, 1243807, - 1267467, 1267561, 1267615, 1267691, 1267708, 1267731, 1267797, 1273165, 1278015, 1278076, - 1278615, 1279032, 1279185, 1279756, 1281009, 1281074, 1282368, 1284002, 1284572, 1285041, - 1285278, 1285788, 1285969, 1286573, 1286679, 1287001, 1287466, 1287714, 1287819, 1288542, - 1288897, 1289486, 1290086, 1290286, 1291047, 1291363, 1291498, 1291749, 1291853, 1292129, - 1292571, 1292828, 1292855, 1292859, 1292892, 1292893, 1292909, 1292910, 1292956, 1292957, - 1292985, 1293133, 1293185, 1293926, 1294446, 1294490, 1294571, 1294966, 1295003, 1295395, - 1295491, 1296604, 1298327, 1298527, 1298685, 1300235, 1300501, 1301193, 1301345, 1301536, - 1301908, 1301969, 1301988, 1302146, 1302158, 1302810, 1303060, 1303244, 1303275, 1303487, - 1303721, 1303831, 1303943, 1304875, 1305210, 1305677, 1305687, 1306397, 1306865, 1307044, - 1307745, 1307926, 1308080, 1308680, 1309204, 1309475, 1310596, 1312574, 1313313, 1313764, - 1313792, 1313963, 1314093, 1314284, 1314743, 1315154, 1315292, 1315503, 1315994, 1316517, - 1316872, 1316909, 1317089, 1317327, 1318223, 1319657, 1321070, 1321083, 1321495, 1321517, - 1322195, 1322221, 1322293, 1322330, 1322471, 1322496, 1322569, 1322634, 1322716, 1322859, - 1323066, 1323356, 1323530, 1323539, 1323614, 1323868, 1323925, 1328650, 1329210, 1332937, - 1333431, 1335482, 1338092, 1342268, 1345890, 1346245, 1346532, 1346613, 1346783, 1347371, - 1347858, 1348077, 1348468, 1349166, 1349298, 1349335, 1350775, 1350809, 1351329, 1352877}; - int[] array2 = {14402, 14403, 14404, 14405, 14406, 14407, 23246, 23247, 23248, 23249, 23250, - 23936, 23937, 23938, 23939, 23940, 23941, 23942, 29721, 29722, 29723, 29724, 29725, 30226, - 30227, 30228, 30229, 30230, 32141, 32142, 32143, 47737, 47738, 47739, 47740, 47741, 47742, - 47743, 47744, 47745, 47746, 47747, 47748, 47749, 47750, 47751, 47752, 68770, 68771, 68772, - 68773, 68774, 68775, 68776, 68777, 68778, 68779, 68780, 72301, 72302, 83071, 83072, 83073, - 83074, 85302, 85303, 85304, 85305, 85306, 85307, 85308, 85309, 85310, 85311, 85312, 85313, - 85314, 85315, 85316, 97108, 97109, 97110, 97111, 103442, 103443, 103444, 103445, 103446, - 103447, 103448, 103449, 103450, 103451, 103452, 103453, 103454, 103455, 103456, 103457, - 103458, 103459, 103460, 103461, 103462, 103463, 103464, 103465, 103466, 103467, 103468, - 103469, 128488, 128489, 128490, 128491, 128492, 128493, 135003, 135004, 135005, 135006, - 135007, 135008, 135009, 135010, 135011, 135012, 135013, 135014, 140363, 140364, 140365, - 140366, 140367, 140368, 140369, 140370, 140371, 140372, 149844, 149845, 149846, 149847, - 149848, 149849, 149850, 149851, 149852, 149853, 149854, 149855, 149856, 149857, 149858, - 149859, 149860, 149861, 149862, 149863, 149864, 172805, 172806, 172807, 172808, 172809, - 172810, 172811, 172812, 172813, 172814, 172815, 172816, 172817, 172818, 172819, 172820, - 172821, 172822, 172823, 172824, 172825, 172826, 172827, 172828, 172829, 172830, 172831, - 172832, 172833, 172834, 172835, 172836, 172837, 172838, 172839, 172840, 172841, 172842, - 172843, 172844, 172845, 172846, 172847, 172848, 172849, 172850, 172851, 172852, 172853, - 172854, 172855, 172856, 172857, 172858, 172859, 172860, 172861, 172862, 172863, 172864, - 172865, 172866, 172867, 172868, 172869, 172870, 172871, 202530, 202531, 202532, 209488, - 209489, 209490, 209491, 209492, 209493, 209494, 209495, 209496, 209497, 209498, 209499, - 209500, 209501, 209502, 209503, 209504, 209505, 209506, 225554, 225555, 225556, 225557, - 225558, 225559, 225560, 225561, 225562, 225563, 225564, 225565, 225566, 225567, 225568, - 225569, 225570, 225571, 225572, 225573, 225574, 225575, 225576, 225577, 225578, 225579, - 225580, 225581, 227917, 227918, 227919, 227920, 227921, 227922, 227923, 227924, 227925, - 227926, 227927, 227928, 227929, 227930, 227931, 227932, 227933, 227934, 227935, 227936, - 227937, 227938, 227939, 252773, 252774, 252775, 252776, 252777, 252778, 252779, 252780, - 252781, 252782, 252783, 252784, 252785, 252786, 252787, 252788, 252789, 252790, 252791, - 252792, 252793, 252794, 278695, 278696, 278697, 278698, 278699, 301237, 301238, 301239, - 301240, 301241, 301242, 301243, 301244, 301245, 301246, 301247, 301248, 301249, 301250, - 301251, 301252, 301253, 301254, 301255, 301256, 301257, 301258, 301259, 301260, 301261, - 301262, 301263, 301264, 301265, 320515, 320516, 320517, 320518, 320519, 320520, 320521, - 320522, 320523, 320524, 320525, 320526, 320527, 320528, 320529, 320530, 320531, 320532, - 320533, 320534, 320535, 320536, 320537, 320538, 320539, 320540, 320541, 320542, 320543, - 320544, 320545, 320546, 320547, 320548, 329641, 329642, 329643, 329644, 329645, 329646, - 329647, 329648, 329649, 329650, 329651, 329652, 329653, 329654, 329655, 329656, 329657, - 329658, 329659, 342703, 342704, 342705, 342706, 349520, 349521, 349522, 349523, 349524, - 349525, 349526, 349527, 349528, 349529, 349530, 362716, 362717, 362718, 362719, 362720, - 362721, 362722, 362723, 362724, 362725, 362726, 362727, 378643, 378644, 378645, 378646, - 390154, 390155, 390156, 390157, 390158, 390159, 390160, 390161, 390162, 390163, 390164, - 390165, 390166, 390167, 390168, 390169, 395108, 395109, 395110, 395111, 395112, 395113, - 395114, 395115, 403260, 403261, 403262, 403263, 403264, 403265, 403266, 403267, 403268, - 403269, 403270, 403271, 417315, 417316, 417317, 417318, 417319, 417320, 432653, 432654, - 432655, 432656, 432657, 432658, 432659, 432660, 432661, 432662, 432663, 432664, 432665, - 432666, 432667, 432668, 432669, 432670, 432671, 432672, 432673, 432674, 432675, 432676, - 432677, 432678, 449394, 449395, 449396, 449397, 449398, 459961, 459962, 459963, 459964, - 474537, 474538, 474539, 474540, 474541, 474542, 474543, 474544, 474545, 474546, 474547, - 474548, 474549, 474550, 474551, 474552, 474553, 474554, 474555, 474556, 474557, 474558, - 474559, 474560, 474561, 474562, 474563, 474564, 474565, 474566, 474567, 474568, 474569, - 474570, 474571, 474572, 474573, 474574, 474575, 474576, 474577, 474578, 474579, 474580, - 474581, 474582, 474583, 474584, 474585, 474586, 474587, 474588, 474589, 474590, 474591, - 474592, 474593, 474594, 474595, 474596, 474597, 483571, 483572, 483573, 483574, 483575, - 483576, 489641, 489642, 489643, 489644, 489645, 489646, 489647, 489648, 489649, 489650, - 489651, 491296, 491297, 491298, 495868, 495869, 495870, 502769, 502770, 502771, 502772, - 502773, 502774, 502775, 502776, 502777, 502778, 502779, 502780, 502781, 502782, 502783, - 513810, 513811, 513812, 513813, 513814, 513815, 513816, 513817, 513818, 513819, 513820, - 513821, 513822, 513823, 513824, 513825, 513826, 513827, 513828, 513829, 513830, 513831, - 513832, 517220, 517221, 517222, 517223, 517224, 517225, 517226, 517227, 519778, 519779, - 519780, 519781, 519782, 519783, 519784, 519785, 524240, 524241, 524242, 524243, 524244, - 524245, 524246, 524247, 524248, 524249, 527255, 527256, 527257, 527258, 527259, 533697, - 533698, 533699, 533700, 533701, 533702, 533703, 533704, 533705, 533706, 533707, 533708, - 533709, 539237, 539238, 539239, 539240, 539241, 539242, 539243, 562203, 562204, 562205, - 562206, 569773, 569774, 569775, 569776, 569777, 569778, 569779, 569780, 569781, 569782, - 569783, 569784, 569785, 569786, 569787, 569788, 569789, 569790, 569791, 569792, 569793, - 569794, 569795, 569796, 569797, 569798, 569799, 569800, 569801, 569802, 569803, 569804, - 569805, 569806, 569807, 569808, 569809, 569810, 569811, 569812, 569813, 569814, 569815, - 569816, 569817, 569818, 569819, 569820, 569821, 580161, 580162, 580163, 580164, 580165, - 580166, 580167, 580168, 580169, 580170, 580171, 580172, 580173, 580174, 580175, 580176, - 588299, 588300, 588301, 588302, 588303, 588304, 588305, 588306, 588307, 588308, 588309, - 588310, 588311, 588312, 588313, 588314, 588315, 588316, 588317, 588318, 588319, 588320, - 588321, 588322, 588323, 588324, 588325, 588326, 588327, 588328, 588329, 588330, 588331, - 588332, 588333, 588334, 588335, 608580, 608581, 608582, 608583, 608584, 608585, 608586, - 608587, 608588, 608589, 608590, 608591, 608592, 608593, 608594, 608595, 608596, 608597, - 608598, 608599, 608600, 608601, 608602, 608603, 608604, 608605, 618326, 618327, 618328, - 618329, 618330, 618331, 618332, 618333, 618334, 618335, 618336, 618337, 618338, 618339, - 618340, 618341, 618342, 618343, 618344, 618345, 618346, 618347, 618348, 618349, 626895, - 626896, 626897, 626898, 626899, 626900, 635313, 635314, 635315, 635316, 635317, 635318, - 635319, 635320, 635321, 635322, 635323, 635324, 635325, 635326, 635327, 635328, 635329, - 635330, 635331, 635332, 635333, 635334, 635335, 635336, 635337, 635338, 635339, 635340, - 635341, 635342, 635343, 635344, 635345, 635346, 635347, 635348, 635349, 635350, 635351, - 635352, 635353, 635354, 635355, 648087, 648088, 648089, 648090, 648091, 648092, 648093, - 648094, 648095, 648096, 648097, 648098, 648099, 648100, 648101, 648102, 648103, 648104, - 648105, 648106, 648107, 648108, 648109, 648110, 661574, 661575, 661576, 661577, 674566, - 674567, 674568, 674569, 674570, 674571, 674572, 674573, 674574, 674575, 674576, 674577, - 674578, 674579, 674580, 674581, 674582, 674583, 674584, 674585, 689328, 689329, 689330, - 689331, 689332, 689333, 689334, 689335, 689336, 689337, 697978, 697979, 697980, 697981, - 697982, 697983, 697984, 697985, 697986, 697987, 697988, 697989, 697990, 697991, 697992, - 697993, 697994, 726676, 726677, 726678, 726679, 726680, 726681, 782220, 782221, 782222, - 782223, 782224, 782225, 782226, 782227, 782228, 782229, 782230, 782231, 782232, 782233, - 782234, 782235, 782236, 782237, 782238, 782239, 797574, 797575, 797576, 797577, 797578, - 797579, 797580, 797581, 797582, 804283, 804284, 804285, 822332, 822333, 822334, 822335, - 822336, 831020, 831021, 831022, 831023, 831024, 831025, 831026, 831027, 831028, 831029, - 831030, 831031, 831032, 831033, 831034, 831035, 831036, 831037, 831038, 831039, 831040, - 847227, 847228, 847229, 847230, 847231, 847232, 847233, 847234, 847235, 847236, 847237, - 847238, 847239, 847240, 847241, 847242, 847243, 847244, 847245, 857616, 857617, 857618, - 857619, 857620, 857621, 857622, 857623, 857624, 857625, 867324, 867325, 867326, 867327, - 867328, 867329, 867330, 867331, 867332, 867333, 867334, 867335, 867336, 867337, 867338, - 867339, 877587, 877588, 877589, 877590, 877591, 877592, 877593, 877594, 877595, 877596, - 877597, 877598, 877599, 877600, 877601, 877602, 877603, 877604, 877605, 877606, 877607, - 877608, 877609, 877610, 877611, 877612, 877613, 877614, 877615, 896235, 896236, 896237, - 896238, 896239, 896240, 916629, 916630, 916631, 916632, 929361, 929362, 929363, 929364, - 929365, 929366, 929367, 929368, 929369, 929370, 929371, 948695, 948696, 948697, 948698, - 948699, 948700, 948701, 948702, 949573, 949574, 957768, 957769, 957770, 957771, 957772, - 957773, 957774, 957775, 961032, 961033, 961034, 961035, 987440, 987441, 987442, 987443, - 1001434, 1001435, 1001436, 1001437, 1001438, 1001439, 1001440, 1001441, 1001442, 1001443, - 1001444, 1001445, 1001446, 1001447, 1001448, 1001449, 1001450, 1001451, 1001452, 1001453, - 1001454, 1001455, 1001456, 1001457, 1001458, 1001459, 1001460, 1009985, 1009986, 1009987, - 1009988, 1009989, 1037191, 1037192, 1037193, 1037194, 1037195, 1037196, 1037197, 1037198, - 1037199, 1037200, 1037201, 1037202, 1037203, 1037204, 1053198, 1053199, 1053200, 1053201, - 1053202, 1053203, 1053204, 1053205, 1053206, 1053207, 1053208, 1053209, 1053210, 1053211, - 1053212, 1053213, 1053214, 1053215, 1053216, 1053217, 1053218, 1053219, 1053220, 1053221, - 1053222, 1053223, 1053224, 1084019, 1084020, 1084021, 1084022, 1084023, 1084024, 1084025, - 1088361, 1088362, 1088363, 1088364, 1088365, 1088366, 1089312, 1089313, 1089314, 1089315, - 1089316, 1089317, 1089318, 1092235, 1092236, 1092237, 1092238, 1092239, 1092240, 1092241, - 1092242, 1092243, 1092244, 1102836, 1102837, 1102838, 1102839, 1102840, 1102841, 1102842, - 1102843, 1102844, 1102845, 1102846, 1102847, 1108575, 1108576, 1108577, 1108578, 1108579, - 1108580, 1108581, 1108582, 1108583, 1108584, 1108585, 1108586, 1108587, 1108588, 1108589, - 1108590, 1108591, 1108592, 1108593, 1108594, 1108595, 1108596, 1108597, 1108598, 1134091, - 1134092, 1134093, 1134094, 1134095, 1134096, 1134097, 1134098, 1134099, 1134100, 1134101, - 1134102, 1134103, 1134104, 1134105, 1134106, 1134107, 1134108, 1134109, 1134110, 1134111, - 1134112, 1134113, 1134114, 1134115, 1134116, 1134117, 1134118, 1134119, 1134120, 1134121, - 1134122, 1134123, 1134124, 1134125, 1134126, 1134127, 1134128, 1134129, 1151732, 1151733, - 1151734, 1151735, 1151736, 1151737, 1151738, 1151739, 1151740, 1151741, 1151742, 1151743, - 1151744, 1151745, 1151746, 1151747, 1199223, 1199224, 1199225, 1199226, 1203252, 1203253, - 1203254, 1203255, 1203256, 1203257, 1203258, 1203259, 1203260, 1217223, 1217224, 1217225, - 1217226, 1226505, 1226506, 1226507, 1226508, 1226509, 1226510, 1226511, 1226512, 1231411, - 1231412, 1231413, 1231414, 1231415, 1231416, 1231417, 1231418, 1231419, 1231420, 1231421, - 1231422, 1231423, 1243464, 1243465, 1243466, 1243467, 1243468, 1243469, 1243470, 1247919, - 1247920, 1247921, 1255972, 1255973, 1255974, 1255975, 1255976, 1255977, 1255978, 1255979, - 1255980, 1263675, 1263676, 1263677, 1263678, 1263679, 1277693, 1277694, 1277695, 1277696, - 1277697, 1277698, 1277699, 1277700, 1283492, 1283493, 1283494, 1283495, 1283496, 1283497, - 1283498, 1283499, 1283500, 1283501, 1283502, 1283503, 1283504, 1283505, 1283506, 1283507, - 1283508, 1283509, 1283510, 1283511, 1283512, 1283513, 1283514, 1325789, 1325790, 1325791, - 1325792, 1325793, 1325794, 1325795, 1325796, 1325797, 1325798, 1325799}; - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(array1); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(array2); - RoaringBitmap rrb1 = rb1.clone(); - RoaringBitmap rrb2 = rb2.clone(); - rrb1.runOptimize(); - rrb2.runOptimize(); - assertEquals(RoaringBitmap.or(rb1, rb2), RoaringBitmap.or(rrb1, rrb2)); - } - - @Test - public void testRandomLists() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); - RoaringBitmap rbor = RoaringBitmap.or(rb1, rb2); - assertEquals(rbor, FastAggregation.horizontal_or(rb1, rb2)); - } - - @Test - public void testRank() { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 100000; k += 7) { - rb.add(k); - } - for (int k = 100000; k < 200000; k += 1000) { - rb.add(k); - } - for (int k = 0; k < 100000; ++k) { - assertEquals(1 + k / 7, rb.rank(k)); - } - for (int k = 100000; k < 200000; ++k) { - assertEquals(1 + 100000 / 7 + 1 + (k - 100000) / 1000, rb.rank(k)); - } + final Object[] tab = V1.toArray(); + final Vector vector = new Vector(); + for (Object aTab : tab) { + vector.add((Integer) aTab); } - @Test - public void testRankBigInts() { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 100000; k += 7) { - rb.add((1 << 31) + k); - } - for (int k = 100000; k < 200000; k += 1000) { - rb.add((1 << 31) + k); - } - for (int k = 0; k < 100000; ++k) { - assertEquals(1 + k / 7, rb.rank((1 << 31) + k)); - } - for (int k = 100000; k < 200000; ++k) { - assertEquals(1 + 100000 / 7 + 1 + (k - 100000) / 1000, rb.rank((1 << 31) + k)); - } + for (final int i : rror.toArray()) { + if (!vector.contains(i)) { + valide = false; + } + V2.add(i); } - - - @Test - public void testSelect() { - long w = ~0l; - for (int k = 0; k < 64; ++k) { - assertEquals(k, Util.select(w, k)); - } - for (int k = 0; k < 64; ++k) { - assertEquals(k, Util.select(1l << k, 0)); - } - for (int k = 1; k < 64; ++k) { - assertEquals(k, Util.select((1l << k) + 1, 1)); - } - assertEquals(0, Util.select(1, 0)); - assertEquals(0, Util.select(5, 0)); - assertEquals(2, Util.select(5, 1)); - for (int gap = 1; gap <= 1024; gap *= 2) { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 100000; k += gap) { - rb.add(k); - } - for (int k = 0; k < 100000 / gap; ++k) { - assertEquals(k * gap, rb.select(k)); - } - } + for (int i = 0; i < V1.size(); i++) { + if (!V2.contains(vector.elementAt(i))) { + valide = false; + } } + assertTrue(valide); + } - @Test - public void testSelectBigInts() { - for (int gap = 1; gap <= 1024; gap *= 2) { - RoaringBitmap rb = new RoaringBitmap(); - for (int k = 0; k < 100000; k += gap) { - rb.add((1 << 31) + k); - } - for (int k = 0; k < 100000 / gap; ++k) { - assertEquals((1 << 31) + k * gap, rb.select(k)); - } - } - } - + @Test + public void ortest4() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); - @Test - public void testSerialization() throws IOException, ClassNotFoundException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - final ObjectOutputStream oo = new ObjectOutputStream(bos); - rr.writeExternal(oo); - oo.close(); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - rrback.readExternal(new ObjectInputStream(bis)); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerializationBigInts() throws IOException, ClassNotFoundException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add((1 << 31) + k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - final ObjectOutputStream oo = new ObjectOutputStream(bos); - rr.writeExternal(oo); - oo.close(); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - rrback.readExternal(new ObjectInputStream(bis)); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerialization2() throws IOException, ClassNotFoundException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 200; k < 400; ++k) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - final ObjectOutputStream oo = new ObjectOutputStream(bos); - rr.writeExternal(oo); - oo.close(); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - rrback.readExternal(new ObjectInputStream(bis)); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerialization3() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add(k); - } - rr.add(1444000); - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray()))); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - // Deserialize DataInput with a buffer - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerialization4() throws IOException, ClassNotFoundException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 1; k <= 10000000; k += 10) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray()))); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - // Deserialize DataInput with a buffer - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerializationDataInputWithBuffer() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerializationDataInputWithBufferBigInts() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add((1 << 31) + k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerializationDataInputWithBuffer2() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 200; k < 400; ++k) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerializationDataInputWithBuffer3() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add(k); - } - rr.add(1444000); - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerializationDataInputWithBuffer4() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 1; k <= 10000000; k += 10) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerializationByteBuffer() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); - rrback.deserialize(buf); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerializationByteBufferBigInts() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add((1 << 31) + k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); - rrback.deserialize(buf); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - - @Test - public void testSerializationByteBuffer2() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 200; k < 400; ++k) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); - rrback.deserialize(buf); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerializationByteBuffer3() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 65000; k < 2 * 65000; ++k) { - rr.add(k); - } - rr.add(1444000); - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); - rrback.deserialize(buf); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSerializationByteBuffer4() throws IOException { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 1; k <= 10000000; k += 10) { - rr.add(k); - } - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Note: you could use a file output steam instead of - // ByteArrayOutputStream - int howmuch = rr.serializedSizeInBytes(); - final DataOutputStream oo = new DataOutputStream(bos); - rr.serialize(oo); - oo.close(); - assertEquals(howmuch, bos.toByteArray().length); - final RoaringBitmap rrback = new RoaringBitmap(); - final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); - rrback.deserialize(buf); - assertEquals(rr.getCardinality(), rrback.getCardinality()); - assertEquals(rr, rrback); - } - - @Test - public void testSetUtilIntersection() { - char[] data1 = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}; - char[] data2 = {0, 3, 6, 9, 12, 15, 18}; - char[] result = new char[data1.length + data2.length]; - char[] expectedresult = {0, 6, 12, 18}; - int nl = Util.unsignedLocalIntersect2by2(data1, data1.length, data2, data2.length, result); - result = Arrays.copyOf(result, nl); - assertArrayEquals(expectedresult, result); - } - - @Test - public void testXORSimple() { - RoaringBitmap a = RoaringBitmap.bitmapOf(73647, 83469); - RoaringBitmap b = RoaringBitmap.bitmapOf(1, 2, 3, 5, 6, 8, 9, 10, 11, 13, 14, 16, 17, 18, 19, - 20, 21, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 39, 40, 41, 50, 51, 69, 79, 80, 81, - 88, 89, 172); - RoaringBitmap rxor = RoaringBitmap.xor(a, b); - RoaringBitmap ror = RoaringBitmap.or(a, b); - assertEquals(rxor, ror); - } - - @Test - public void trimArrayContainerCardinalityTest() { - final ArrayContainer ac = new ArrayContainer(); - ac.trim(); - for (char k = 0; k < 100; ++k) { - ac.add(k); - ac.trim(); - assertEquals(ac.getCardinality(), k + 1); - } - for (char k = 0; k < 100; ++k) { - ac.add(k); - ac.trim(); - assertEquals(ac.getCardinality(), 100); - } + for (int i = 0; i < 200000; i += 4) { + rb2.add(i); + } + for (int i = 200000; i < 400000; i += 14) { + rb2.add(i); } + final int rb2card = rb2.getCardinality(); - boolean validate(BitmapContainer bc, ArrayContainer ac) { - // Checking the cardinalities of each container + // check or against an empty bitmap + final RoaringBitmap orresult = RoaringBitmap.or(rb, rb2); + final RoaringBitmap off = RoaringBitmap.or(rb2, rb); + assertEquals(orresult, off); - if (bc.getCardinality() != ac.getCardinality()) { - System.out.println("cardinality differs"); - return false; - } - // Checking that the two containers contain the same values - int counter = 0; - - int i = bc.nextSetBit(0); - while (i >= 0) { - ++counter; - if (!ac.contains((char) i)) { - System.out.println("content differs"); - System.out.println(bc); - System.out.println(ac); - return false; - } - i = bc.nextSetBit(i + 1); - } + assertEquals(rb2card, orresult.getCardinality()); - // checking the cardinality of the BitmapContainer - return counter == bc.getCardinality(); + for (int i = 500000; i < 600000; i += 14) { + rb.add(i); } + for (int i = 200000; i < 400000; i += 3) { + rb2.add(i); + } + // check or against an empty bitmap + final RoaringBitmap orresult2 = RoaringBitmap.or(rb, rb2); + assertEquals(rb2card, orresult.getCardinality()); - @Test - public void trimTest() { - // with bitmap containing 4k containers - RoaringBitmap rb = new RoaringBitmap(); - for (int i = 0; i < 4000; i++) { - rb.add((1 << 16) * i); - } + assertEquals(rb2.getCardinality() + rb.getCardinality(), orresult2.getCardinality()); + rb.or(rb2); + assertEquals(rb, orresult2); + } - rb.trim(); - - int wastedBytes = 0; - final int javaReferenceSize = 4; // or 8 depending on factors - RoaringArray ra = rb.highLowContainer; - wastedBytes += Short.BYTES * (ra.keys.length - ra.size); - wastedBytes += javaReferenceSize * (ra.values.length - ra.size); - ContainerPointer cp = ra.getContainerPointer(); - while (cp.getContainer() != null) { - if (cp.isBitmapContainer()) { - ; //nothing wasted - } else if (cp.isRunContainer()) { - ; //not able to access information about wasted bytes - } else { - ArrayContainer ac = (ArrayContainer) cp.getContainer(); - wastedBytes += Short.BYTES * (ac.content.length - ac.cardinality); - } - cp.advance(); - } - assertEquals(0, wastedBytes); - } + @Test + public void orNot() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); - @Test - public void xorBigIntsTest() { - RoaringBitmap rb = new RoaringBitmap(); - RoaringBitmap rb2 = new RoaringBitmap(); - HashSet hs = new HashSet(); + rb.add(2); + rb.add(1); + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { - hs.add(i); - rb.add(i); - } - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - rb.add(i); - } - for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 5) { - rb.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 7) { - rb.add(i); - } - for (int i = (1 << 31) + 11 * 65536; i < (1 << 31) + 12 * 65536; i += 6) { - hs.add(i); - rb.add(i); - } + rb2.add(1 << 16); // 65536 + rb2.add(3 << 16); // 196608 - for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { - rb2.add(i); - } - for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 5) { - rb2.add(i); - } - for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 7) { - rb2.add(i); - } - for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 2) { - hs.add(i); - rb2.add(i); - } + rb.orNot(rb2, (4 << 16) - 1); - RoaringBitmap rbxor = RoaringBitmap.xor(rb, rb2); + assertEquals((4 << 16) - 1, rb.getCardinality()); - Object[] correct = hs.toArray(); - Arrays.sort(correct); - Integer[] resxor = ArrayUtils.toObject(rbxor.toArray()); - assertArrayEquals(correct, resxor); - } + final IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (4 << 16) - 1; ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next()); + } + assertFalse(iterator.hasNext()); + } - @Test - public void XORtest() { - final RoaringBitmap rr = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr.add(k); - } - for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { - rr.add(k); - } - for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { - rr.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { - rr.add(k); - } - for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { - rr.add(k); - } - for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { - rr.add(k); - } + @Test + public void orNotRegressionTest() { + long len = 3L; + long orLen = 3L; - final RoaringBitmap rr2 = new RoaringBitmap(); - for (int k = 4000; k < 4256; ++k) { - rr2.add(k); - } - for (int k = 65536; k < 65536 + 4000; ++k) { - rr2.add(k); - } - for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { - rr2.add(k); - } - for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { - rr2.add(k); - } - for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { - rr2.add(k); - } - final RoaringBitmap correct = RoaringBitmap.xor(rr, rr2); - rr.xor(rr2); - assertEquals(correct, rr); - } - - @Test - public void xortest1() { - final HashSet V1 = new HashSet(); - final HashSet V2 = new HashSet(); - - final RoaringBitmap rr = new RoaringBitmap(); - final RoaringBitmap rr2 = new RoaringBitmap(); - // For the first 65536: rr2 has a bitmap container, and rr has - // an array container. - // We will check the union between a BitmapCintainer and an - // arrayContainer - for (int k = 0; k < 4000; ++k) { - rr2.add(k); - if (k < 3500) { - V1.add(k); - } - } - for (int k = 3500; k < 4500; ++k) { - rr.add(k); - } - for (int k = 4000; k < 65000; ++k) { - rr2.add(k); - if (k >= 4500) { - V1.add(k); - } - } + RoaringBitmap one = new RoaringBitmap(); + RoaringBitmap other = new RoaringBitmap(); + other.add(0L, len); - // In the second node of each roaring bitmap, we have two bitmap - // containers. - // So, we will check the union between two BitmapContainers - for (int k = 65536; k < 65536 + 30000; ++k) { - rr.add(k); - } + one.orNot(other, orLen); + } - for (int k = 65536; k < 65536 + 50000; ++k) { - rr2.add(k); - if (k >= 65536 + 30000) { - V1.add(k); - } - } + @Test + public void orNotZeroRangeEndPreservesBitmap() { + RoaringBitmap one = new RoaringBitmap(); + one.add(32); - // In the 3rd node of each Roaring Bitmap, we have an - // ArrayContainer. So, we will try the union between two - // ArrayContainers. - for (int k = 4 * 65535; k < 4 * 65535 + 1000; ++k) { - rr.add(k); - if (k >= 4 * 65535 + 800) { - V1.add(k); - } - } + RoaringBitmap other = new RoaringBitmap(); + other.add(0L, 100); - for (int k = 4 * 65535; k < 4 * 65535 + 800; ++k) { - rr2.add(k); - } + one.orNot(other, 0); + assertEquals(one, RoaringBitmap.bitmapOf(32)); + } - // For the rest, we will check if the union will take them in - // the result - for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { - rr.add(k); - V1.add(k); - } + @Test + public void orNotLimitLowerThanFirstPreservesBitmap() { + RoaringBitmap one = new RoaringBitmap(); + one.add(32); - for (int k = 7 * 65535; k < 7 * 65535 + 2000; ++k) { - rr2.add(k); - V1.add(k); - } + RoaringBitmap other = new RoaringBitmap(); + other.add(0L, 100); - final RoaringBitmap rrxor = RoaringBitmap.xor(rr, rr2); - boolean valide = true; - - // Si tous les elements de rror sont dans V1 et que tous les - // elements de - // V1 sont dans rror(V2) - // alors V1 == rror - final Object[] tab = V1.toArray(); - final Vector vector = new Vector(); - for (Object aTab : tab) { - vector.add((Integer) aTab); - } + one.orNot(other, 10); + assertEquals(one, RoaringBitmap.bitmapOf(32)); + } - for (final int i : rrxor.toArray()) { - if (!vector.contains(i)) { - valide = false; - } - V2.add(i); - } - for (int i = 0; i < V1.size(); i++) { - if (!V2.contains(vector.elementAt(i))) { - valide = false; - } - } + @Test + public void orNotLimitHigherThanFirstBitPreservesBitmap() { + RoaringBitmap one = new RoaringBitmap(); + one.add(32); - assertTrue(valide); - } + RoaringBitmap other = new RoaringBitmap(); + other.add(0L, 100); - @Test - public void xortest4() { - final RoaringBitmap rb = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); + one.orNot(other, 35); + assertEquals(one, RoaringBitmap.bitmapOf(32)); + } - for (int i = 0; i < 200000; i += 4) { - rb2.add(i); - } - for (int i = 200000; i < 400000; i += 14) { - rb2.add(i); - } - final int rb2card = rb2.getCardinality(); + @Test + public void orNotWithSparseBitmaps() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); - // check or against an empty bitmap - final RoaringBitmap xorresult = RoaringBitmap.xor(rb, rb2); - final RoaringBitmap off = RoaringBitmap.or(rb2, rb); - assertEquals(xorresult, off); + rb.add(0); + rb.add(1 << 16); // 65536 + rb.add(3 << 16); // 196608 - assertEquals(rb2card, xorresult.getCardinality()); + rb2.add((4 << 16) - 1); // 262143 - for (int i = 500000; i < 600000; i += 14) { - rb.add(i); - } - for (int i = 200000; i < 400000; i += 3) { - rb2.add(i); - } - // check or against an empty bitmap - final RoaringBitmap xorresult2 = RoaringBitmap.xor(rb, rb2); - assertEquals(rb2card, xorresult.getCardinality()); - - assertEquals(rb2.getCardinality() + rb.getCardinality(), xorresult2.getCardinality()); - rb.xor(rb2); - assertEquals(xorresult2, rb); - - } - - - // is this better in testRange? - @Test - public void testRangedOr() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add(val1); - set1.add(val1); - - rb2.add(val2); - set2.add(val2); - } - Set unionSet = new TreeSet<>(); - unionSet.addAll(set1); - unionSet.addAll(set2); - for (int iter = 0; iter < NUM_ITER; iter++) { - int rangeStart = random.nextInt(length - 1); - // +1 to ensure rangeEnd >rangeStart, may - int rangeLength = random.nextInt(length - rangeStart) + 1; - int rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = rangeStart; i < rangeEnd; i++) { - if (unionSet.contains(i)) { - expectedResultSet.add(i); - } - } - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); - RoaringBitmap result = RoaringBitmap.or(list.iterator(), (long) rangeStart, (long) rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } - } + rb.orNot(rb2, 4 << 16); - @Test - public void testRangedOrBigInts() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add((1 << 31) + val1); - set1.add((1 << 31) + val1); - - rb2.add((1 << 31) + val2); - set2.add((1 << 31) + val2); - } - Set unionSet = new TreeSet<>(); - unionSet.addAll(set1); - unionSet.addAll(set2); - for (int iter = 0; iter < NUM_ITER; iter++) { - long rangeStart1 = random.nextInt(length - 1); - long rangeStart = (1L << 31) + rangeStart1; - long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; - long rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { - if (unionSet.contains(i)) { - expectedResultSet.add(i); - } - } - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); - RoaringBitmap result = RoaringBitmap.or(list.iterator(), rangeStart, rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } - } + assertEquals((4 << 16) - 1, rb.getCardinality()); + final IntIterator iterator = rb.getIntIterator(); - @Test - public void testRangedAnd() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add(val1); - set1.add(val1); - - rb2.add(val2); - set2.add(val2); - } - Set intersectionSet = new TreeSet<>(set1); - intersectionSet.retainAll(set2); - for (int iter = 0; iter < NUM_ITER; iter++) { - int rangeStart = random.nextInt(length - 1); - // +1 to ensure rangeEnd >rangeStart, may - int rangeLength = random.nextInt(length - rangeStart) + 1; - int rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = rangeStart; i < rangeEnd; i++) { - if (intersectionSet.contains(i)) { - expectedResultSet.add(i); - } - } - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); - RoaringBitmap result = RoaringBitmap.and(list.iterator(), (long) rangeStart, (long) rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } + for (int i = 0; i < (4 << 16) - 1; ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next()); } + assertFalse(iterator.hasNext()); + } - @Test - public void testRangedAndBigInts() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add((1 << 31) + val1); - set1.add((1 << 31) + val1); - - rb2.add((1 << 31) + val2); - set2.add((1 << 31) + val2); - } - Set intersectionSet = new TreeSet<>(set1); - intersectionSet.retainAll(set2); - for (int iter = 0; iter < NUM_ITER; iter++) { - long rangeStart1 = random.nextInt(length - 1); - long rangeStart = (1L << 31) + rangeStart1; - long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; - long rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { - if (intersectionSet.contains(i)) { - expectedResultSet.add(i); - } - } - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); - RoaringBitmap result = RoaringBitmap.and(list.iterator(), rangeStart, rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } - } + @Test + public void orNotWithOtherBiggerThanOriginal() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(1); + final RoaringBitmap rb2 = new RoaringBitmap(); + rb2.add(1 << 14); // 16384 + rb2.add(3 << 16); // 196608 - @Test - public void testRangedXor() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add(val1); - set1.add(val1); - - rb2.add(val2); - set2.add(val2); - } - Set xorSet = new TreeSet<>(); - xorSet.addAll(set1); - xorSet.addAll(set2); - Set andSet = new TreeSet<>(set1); - andSet.retainAll(set2); - - xorSet.removeAll(andSet); - for (int iter = 0; iter < NUM_ITER; iter++) { - int rangeStart = random.nextInt(length - 1); - // +1 to ensure rangeEnd >rangeStart, may - int rangeLength = random.nextInt(length - rangeStart) + 1; - int rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = rangeStart; i < rangeEnd; i++) { - if (xorSet.contains(i)) { - expectedResultSet.add(i); - } - } - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); - RoaringBitmap result = RoaringBitmap.xor(list.iterator(), (long) rangeStart, (long) rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } + rb.orNot(rb2, (5 << 16)); + assertEquals((5 << 16) - 2, rb.getCardinality()); + + final IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (5 << 16); ++i) { + if ((i != (1 << 14)) && (i != (3 << 16))) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); + } } + assertFalse(iterator.hasNext()); + } + @Test + public void orNotWithOtherBiggerThanOriginalAndEndRange() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(1); - @Test - public void testRangedXorBigInts() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add((1 << 31) + val1); - set1.add((1 << 31) + val1); - - rb2.add((1 << 31) + val2); - set2.add((1 << 31) + val2); - } - Set xorSet = new TreeSet<>(); - xorSet.addAll(set1); - xorSet.addAll(set2); - Set andSet = new TreeSet<>(set1); - andSet.retainAll(set2); - - xorSet.removeAll(andSet); - for (int iter = 0; iter < NUM_ITER; iter++) { - long rangeStart1 = random.nextInt(length - 1); - long rangeStart = (1L << 31) + rangeStart1; - long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; - long rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { - if (xorSet.contains(i)) { - expectedResultSet.add(i); - } - } - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); - RoaringBitmap result = RoaringBitmap.xor(list.iterator(), rangeStart, rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } - } + final RoaringBitmap rb2 = new RoaringBitmap(); + rb2.add(3 << 16); // 196608 + rb.orNot(rb2, (2 << 16) + (2 << 14)); // 131072 + 32768 = 163840 + assertEquals((2 << 16) + (2 << 14), rb.getCardinality()); - @Test - public void testRangedAndNot() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add(val1); - set1.add(val1); - - rb2.add(val2); - set2.add(val2); - } - Set andNotSet = new TreeSet<>(); - for (int i : set1) { - if (!set2.contains(i)) { - andNotSet.add(i); - } - } - for (int iter = 0; iter < NUM_ITER; iter++) { - int rangeStart = random.nextInt(length - 1); - // +1 to ensure rangeEnd >rangeStart, may - int rangeLength = random.nextInt(length - rangeStart) + 1; - int rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = rangeStart; i < rangeEnd; i++) { - if (andNotSet.contains(i)) { - expectedResultSet.add(i); - } - } - RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, (long) rangeStart, (long) rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } + final IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (2 << 16) + (2 << 14); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } + assertFalse(iterator.hasNext()); + } + @Test + public void orNotWithOriginalBiggerThanOther() { + final RoaringBitmap rb = new RoaringBitmap(); - @Test - public void testRangedAndNotBigInts() { - int length = 1000; - int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests - for (int test = 0; test < 50; ++test) { - final RoaringBitmap rb1 = new RoaringBitmap(); - final RoaringBitmap rb2 = new RoaringBitmap(); - Set set1 = new HashSet<>(); - Set set2 = new HashSet<>(); - int numBitsToSet = length / 2; - for (int i = 0; i < numBitsToSet; i++) { - int val1 = random.nextInt(length); - int val2 = random.nextInt(length); - - rb1.add((1 << 31) + val1); - set1.add((1 << 31) + val1); - - rb2.add((1 << 31) + val2); - set2.add((1 << 31) + val2); - } - Set andNotSet = new TreeSet<>(); - for (int i : set1) { - if (!set2.contains(i)) { - andNotSet.add(i); - } - } - for (int iter = 0; iter < NUM_ITER; iter++) { - long rangeStart1 = random.nextInt(length - 1); - long rangeStart = (1L << 31) + rangeStart1; - long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; - long rangeEnd = rangeStart + rangeLength; - Set expectedResultSet = new TreeSet<>(); - for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { - if (andNotSet.contains(i)) { - expectedResultSet.add(i); - } - } - RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, rangeStart, rangeEnd); - Set actualResultSet = new TreeSet<>(); - IntIterator intIterator = result.getIntIterator(); - while (intIterator.hasNext()) { - actualResultSet.add(intIterator.next()); - } - assertEquals(expectedResultSet, actualResultSet); - } - } - } + rb.add(1); + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 + final RoaringBitmap rb2 = new RoaringBitmap(); - @Test - public void testOr() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(4, 7, 8, 9); - RoaringBitmap rb3 = RoaringBitmap.bitmapOf(12, 13, 15, 19, 21); - RoaringBitmap rb4 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9); - RoaringBitmap rb5 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 12, 13, 15, 19, 21); - assertEquals(rb4, RoaringBitmap.lazyorfromlazyinputs(rb1, rb2)); - assertEquals(rb5, RoaringBitmap.or(rb1, rb2, rb3)); - } + rb.orNot(rb2, (5 << 16)); + assertEquals((5 << 16), rb.getCardinality()); - @Test - public void testLazyOr() { - RoaringBitmap rb1 = RoaringBitmap.bitmapOf(1 << 16, 1 << 18, 1 << 19); - rb1.lazyor(RoaringBitmap.bitmapOf(4, 7, 8, 9)); - rb1.lazyor(RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 1 << 16, 1 << 17, 1 << 20)); - RoaringBitmap rb2 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20); - assertEquals(rb2, rb1); + final IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (5 << 16); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } + assertFalse(iterator.hasNext()); + } - @Test - public void testFirstLast_CreateSparseContainers() { - RoaringBitmap rb = new RoaringBitmap(); - for (int i = 0; i < 20; ++i) { - int x = 1 << i; - rb.add(x); - assertEquals(1, rb.first()); - assertEquals(x, rb.last()); - } - } + @Test + public void orNotWithOriginalBiggerThanOther2() { + final RoaringBitmap rb = new RoaringBitmap(); - @Test - public void testFirstLast_CreateSparseContainersAfterRun() { - RoaringBitmap rb = new RoaringBitmap(); - rb.add(1L, 1 << 14); - for (int i = 18; i < 31; ++i) { - int x = 1 << i; - rb.add(x); - assertEquals(1, rb.first()); - assertEquals(x, rb.last()); - } - } + rb.add(1); + rb.add((1 << 16) - 1); // 65535 + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - @Test - public void testFirstLast_AfterLazyMutation1() { - RoaringBitmap rb = new RoaringBitmap(); - rb.add(1, 3, 5, 7); - assertEquals(1, rb.first()); - assertEquals(7, rb.last()); - RoaringBitmap mutator = new RoaringBitmap(); - mutator.add(0, 2, 4, 6, 8); - rb.lazyor(mutator); - assertEquals(0, rb.first()); - assertEquals(8, rb.last()); - } - - - @Test - public void testFirstLast_AfterLazyMutation2() { - RoaringBitmap rb = new RoaringBitmap(); - Iterable willForceUseOfBitmapContainer = Iterables.filter( - ContiguousSet.create(Range.openClosed(0, 1 << 16), DiscreteDomain.integers()), - new Predicate() { - @Override - public boolean apply(Integer input) { - return input % 3 == 0; - } - } - ); - int max = 0; - for (Integer i : willForceUseOfBitmapContainer) { - rb.add(i); - max = i; - } - assertEquals(3, rb.first()); - assertEquals(max, rb.last()); - RoaringBitmap mutator = new RoaringBitmap(); - mutator.add(0, 2, 4, 6, 8); - rb.lazyor(mutator); - assertEquals(0, rb.first()); - assertEquals(max, rb.last()); - } + final RoaringBitmap rb2 = new RoaringBitmap(); + rb.orNot(rb2, (1 << 14)); - @Test - public void testEmptyFirst() { - assertThrows(NoSuchElementException.class, () -> new RoaringBitmap().first()); - } + // {[0, 2^14], 65535, 65536, 131072, 196608} + assertEquals((1 << 14) + 4, rb.getCardinality()); - @Test - public void testEmptyLast() { - assertThrows(NoSuchElementException.class, () -> new RoaringBitmap().last()); + final IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (1 << 14); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } - @Test - public void testFirstLast() { - RoaringBitmap rb = new RoaringBitmap(); + assertTrue(iterator.hasNext()); + assertEquals((1 << 16) - 1, iterator.next()); - rb.add(2); - rb.add(4); - rb.add(8); - assertEquals(2, rb.first()); - assertEquals(8, rb.last()); + assertTrue(iterator.hasNext()); + assertEquals(1 << 16, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(2 << 16, iterator.next()); + + assertTrue(iterator.hasNext()); + assertEquals(3 << 16, iterator.next()); + + assertFalse(iterator.hasNext()); + } + + @Test + public void randomTest() { + rTest(15); + rTest(1024); + rTest(4096); + rTest(65536); + rTest(65536 * 16); + } + + public void rTest(final int N) { + for (int gap = 1; gap <= 65536; gap *= 2) { + final BitSet bs1 = new BitSet(); + final RoaringBitmap rb1 = new RoaringBitmap(); + for (int x = 0; x <= N; x += gap) { + bs1.set(x); + rb1.add(x); + } + if (bs1.cardinality() != rb1.getCardinality()) { + throw new RuntimeException("different card"); + } + if (!equals(bs1, rb1)) { + throw new RuntimeException("basic bug"); + } + for (int offset = 1; offset <= gap; offset *= 2) { + final BitSet bs2 = new BitSet(); + final RoaringBitmap rb2 = new RoaringBitmap(); + for (int x = 0; x <= N; x += gap) { + bs2.set(x + offset); + rb2.add(x + offset); + } + if (bs2.cardinality() != rb2.getCardinality()) { + throw new RuntimeException("different card"); + } + if (!equals(bs2, rb2)) { + throw new RuntimeException("basic bug"); + } + + BitSet clonebs1; + // testing AND + clonebs1 = (BitSet) bs1.clone(); + clonebs1.and(bs2); + if (!equals(clonebs1, RoaringBitmap.and(rb1, rb2))) { + throw new RuntimeException("bug and"); + } + { + final RoaringBitmap t = rb1.clone(); + t.and(rb2); + if (!equals(clonebs1, t)) { + throw new RuntimeException("bug inplace and"); + } + if (!t.equals(RoaringBitmap.and(rb1, rb2))) { + System.out.println( + t.highLowContainer.getContainerAtIndex(0).getClass().getCanonicalName()); + System.out.println( + RoaringBitmap.and(rb1, rb2) + .highLowContainer + .getContainerAtIndex(0) + .getClass() + .getCanonicalName()); + + throw new RuntimeException("bug inplace and"); + } + } + + // testing OR + clonebs1 = (BitSet) bs1.clone(); + clonebs1.or(bs2); + + if (!equals(clonebs1, RoaringBitmap.or(rb1, rb2))) { + throw new RuntimeException("bug or"); + } + { + final RoaringBitmap t = rb1.clone(); + t.or(rb2); + if (!equals(clonebs1, t)) { + throw new RuntimeException("bug or"); + } + if (!t.equals(RoaringBitmap.or(rb1, rb2))) { + throw new RuntimeException("bug or"); + } + if (!t.toString().equals(RoaringBitmap.or(rb1, rb2).toString())) { + throw new RuntimeException("bug or"); + } + } + // testing XOR + clonebs1 = (BitSet) bs1.clone(); + clonebs1.xor(bs2); + if (!equals(clonebs1, RoaringBitmap.xor(rb1, rb2))) { + throw new RuntimeException("bug xor"); + } + { + final RoaringBitmap t = rb1.clone(); + t.xor(rb2); + if (!equals(clonebs1, t)) { + throw new RuntimeException("bug xor"); + } + if (!t.equals(RoaringBitmap.xor(rb1, rb2))) { + throw new RuntimeException("bug xor"); + } + } + // testing NOTAND + clonebs1 = (BitSet) bs1.clone(); + clonebs1.andNot(bs2); + if (!equals(clonebs1, RoaringBitmap.andNot(rb1, rb2))) { + throw new RuntimeException("bug andnot"); + } + clonebs1 = (BitSet) bs2.clone(); + clonebs1.andNot(bs1); + if (!equals(clonebs1, RoaringBitmap.andNot(rb2, rb1))) { + throw new RuntimeException("bug andnot"); + } + { + final RoaringBitmap t = rb2.clone(); + t.andNot(rb1); + if (!equals(clonebs1, t)) { + throw new RuntimeException("bug inplace andnot"); + } + final RoaringBitmap g = RoaringBitmap.andNot(rb2, rb1); + if (!equals(clonebs1, g)) { + throw new RuntimeException("bug andnot"); + } + if (!t.equals(g)) { + throw new RuntimeException("bug"); + } + } + clonebs1 = (BitSet) bs1.clone(); + clonebs1.andNot(bs2); + if (!equals(clonebs1, RoaringBitmap.andNot(rb1, rb2))) { + throw new RuntimeException("bug andnot"); + } + { + final RoaringBitmap t = rb1.clone(); + t.andNot(rb2); + if (!equals(clonebs1, t)) { + throw new RuntimeException("bug andnot"); + } + final RoaringBitmap g = RoaringBitmap.andNot(rb1, rb2); + if (!equals(clonebs1, g)) { + throw new RuntimeException("bug andnot"); + } + if (!t.equals(g)) { + throw new RuntimeException("bug"); + } + } + } + } + } + + @Test + public void sillytestHighBits() { + RoaringBitmap rb = RoaringBitmap.bitmapOf(-1, 0); + int[] array = rb.toArray(); + assertEquals(0, array[0]); + assertEquals(array[1], -1); + } + + @Test + public void simplecardinalityTest() { + final int N = 512; + final int gap = 70; + + final RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < N; k++) { + rb.add(k * gap); + assertEquals(rb.getCardinality(), k + 1); + } + assertEquals(rb.getCardinality(), N); + for (int k = 0; k < N; k++) { + rb.add(k * gap); + assertEquals(rb.getCardinality(), N); + } + } + + @Test + public void sparseAnd() { + final RoaringBitmap rr1 = new RoaringBitmap(); + rr1.add(1); + rr1.add(1 << 31); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(1 << 31); + RoaringBitmap and = RoaringBitmap.and(rr1, rr2); + assertEquals(1, and.getCardinality()); + assertTrue(and.contains(1 << 31)); + rr1.and(rr2); + assertEquals(1, rr1.getCardinality()); + assertTrue(and.contains(1 << 31)); + } + + @Test + public void sparseAndNot() { + final RoaringBitmap rr1 = new RoaringBitmap(); + rr1.add(1); + rr1.add(1 << 31); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(1 << 31); + RoaringBitmap andNot = RoaringBitmap.andNot(rr1, rr2); + assertEquals(1, andNot.getCardinality()); + assertTrue(andNot.contains(1)); + rr1.andNot(rr2); + assertEquals(1, rr1.getCardinality()); + assertTrue(andNot.contains(1)); + } + + @Test + public void sparseOr() { + final RoaringBitmap rr1 = new RoaringBitmap(); + rr1.add(1); + rr1.add(1 << 31); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(1 << 31); + RoaringBitmap or = RoaringBitmap.or(rr1, rr2); + assertEquals(2, or.getCardinality()); + assertTrue(or.contains(1)); + assertTrue(or.contains(1 << 31)); + rr1.or(rr2); + assertEquals(2, rr1.getCardinality()); + assertTrue(or.contains(1)); + assertTrue(or.contains(1 << 31)); + } + + @Test + public void sparseXor() { + final RoaringBitmap rr1 = new RoaringBitmap(); + rr1.add(1); + rr1.add(1 << 31); + final RoaringBitmap rr2 = new RoaringBitmap(); + rr2.add(1 << 31); + RoaringBitmap xor = RoaringBitmap.xor(rr1, rr2); + assertEquals(1, xor.getCardinality()); + assertTrue(xor.contains(1)); + rr1.xor(rr2); + assertEquals(1, rr1.getCardinality()); + assertTrue(xor.contains(1)); + } + + @Test + public void testAndNot() { + int[] array1 = { + 39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, 39184, 39185, + 39186, 39187, 39188 + }; + int[] array2 = {14205}; + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(array1); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(array2); + RoaringBitmap answer = RoaringBitmap.andNot(rb1, rb2); + assertEquals(answer.getCardinality(), array1.length); + } + + @Test + public void testAstesana() { + RoaringBitmap r1 = new RoaringBitmap(); + // Strange thing: Replace this line by r1.add(131000) and the bug vanishes! + r1.flip(131000L, 131001L); + RoaringBitmap r2 = new RoaringBitmap(); + r2.add(220000); + RoaringBitmap r3 = new RoaringBitmap(); + int killingPosition = 66000; + r3.add(killingPosition); + assertFalse(r1.contains(killingPosition)); // ok + r2.or(r1); + assertFalse(r1.contains(killingPosition)); // ok + r2.or(r3); + assertFalse(r1.contains(killingPosition)); // ko + } + + @Test + public void testCheckedAdd() { + RoaringBitmap rb = new RoaringBitmap(); + // checking if the true value is well returned + // when adding new ints + for (int i = 0; i < 2 * (1 << 16); i += 2) { + assertTrue(rb.checkedAdd(i)); + } + for (int i = 1; i < 2 * (1 << 16); i += 2) { + assertTrue(rb.checkedAdd(i)); + } + // Checking if the false value is well returned + // when adding already existing ints + for (int i = 0; i < 2 * (1 << 16); i += 2) { + assertFalse(rb.checkedAdd(i)); + } + for (int i = 1; i < 2 * (1 << 16) + 1; i += 2) { + assertFalse(rb.checkedAdd(i)); + } + } + + @Test + public void testCheckedRemove() { + RoaringBitmap rb = new RoaringBitmap(); + // checking if the true value is well returned + // when adding new ints + for (int i = 0; i < 2 * (1 << 16); i++) { + rb.add(i); + } + for (int i = 0; i < 2 * (1 << 16); i += 2) { + assertTrue(rb.checkedRemove(i)); + } + for (int i = 0; i < 2 * (1 << 16); i += 2) { + assertFalse(rb.checkedRemove(i)); + } + for (int i = 1; i < 2 * (1 << 16); i += 2) { + assertTrue(rb.checkedRemove(i)); + } + for (int i = 1; i < 2 * (1 << 16) + 1; i += 2) { + assertFalse(rb.checkedRemove(i)); + } + } + + @Test + public void testContains() throws IOException { + RoaringBitmap rbm1 = new RoaringBitmap(); + for (int k = 0; k < 1000; ++k) { + rbm1.add(17 * k); + } + for (int k = 0; k < 17 * 1000; ++k) { + assertEquals(rbm1.contains(k), (k / 17 * 17 == k)); + } + } + + @Test + public void testEqual() { + RoaringBitmap rr1 = RoaringBitmap.bitmapOf(1, 2, 100000); + RoaringBitmap rr2 = RoaringBitmap.bitmapOf(3, 4, 100001); + RoaringBitmap rr3 = RoaringBitmap.bitmapOf(1, 2, 100000); + assertEquals(rr1, rr3); + assertNotEquals(rr1, rr2); + assertNotEquals(rr3, rr2); + } + + // tests for how range falls on container boundaries + + @Test + public void testFlip() { + RoaringBitmap rb = new RoaringBitmap(); + for (int i = 0; i < 1 << 20; ++i) { + rb.flip(i); + assertEquals(rb.getCardinality(), i + 1); + } + for (int i = (1 << 20) - 1; i >= 0; --i) { + rb.flip(i); + assertEquals(rb.getCardinality(), i); + } + } + + @Test + public void testFlipBigInts() { + RoaringBitmap rb = new RoaringBitmap(); + for (int i = 0; i < 1 << 20; ++i) { + rb.flip((1 << 31) + i); + assertEquals(rb.getCardinality(), i + 1); + } + for (int i = (1 << 20) - 1; i >= 0; --i) { + rb.flip((1 << 31) + i); + assertEquals(rb.getCardinality(), i); + } + } + + @Test + public void testFlipOnEmpty() { + RoaringBitmap r1 = new RoaringBitmap(); + r1.flip(0L, 10L); + assertEquals(10, r1.getCardinality()); + } + + @Test + public void testHash() { + RoaringBitmap rbm1 = new RoaringBitmap(); + rbm1.add(17); + RoaringBitmap rbm2 = new RoaringBitmap(); + rbm2.add(17); + assertEquals(rbm1.hashCode(), rbm2.hashCode()); + rbm2 = rbm1.clone(); + assertEquals(rbm1.hashCode(), rbm2.hashCode()); + } + + @Test + public void testHighBits() { + for (int offset = 1 << 14; offset < 1 << 18; offset *= 2) { + RoaringBitmap rb = new RoaringBitmap(); + for (long k = Integer.MIN_VALUE; k < Integer.MAX_VALUE; k += offset) { + rb.add((int) k); + } + int cardinality = 0; + for (long k = Integer.MIN_VALUE; k < Integer.MAX_VALUE; k += offset) { + assertTrue(rb.contains((int) k)); + ++cardinality; + } + int[] array = rb.toArray(); + assertEquals(array.length, cardinality); + for (int k = 0; k < array.length - 1; ++k) { + assertTrue((0xFFFFFFFFL & array[k]) <= (0xFFFFFFFFL & array[k + 1])); + } + } + } + + @Test + public void testHorizontalOrCardinality() { + int[] vals = {65535, 131071, 196607, 262143, 327679, 393215, 458751, 524287}; + final RoaringBitmap[] b = new RoaringBitmap[2]; + b[0] = RoaringBitmap.bitmapOf(vals); + b[1] = RoaringBitmap.bitmapOf(vals); + RoaringBitmap a = + FastAggregation.or( + new Iterator() { + int k = 0; + + @Override + public boolean hasNext() { + return k < b.length; + } - rb.add(1L << 5, 1L << 14); - assertEquals(2, rb.first()); - assertEquals((1 << 14) - 1, rb.last()); + @Override + public RoaringBitmap next() { + return b[k++]; + } + + @Override + public void remove() {} + }); + assertEquals(8, a.getCardinality()); + } + + @Test + public void testHorizontalOrCardinalityBigInts() { + int[] vals = { + (1 << 31) + 65535, + (1 << 31) + 131071, + (1 << 31) + 196607, + (1 << 31) + 262143, + (1 << 31) + 327679, + (1 << 31) + 393215, + (1 << 31) + 458751, + (1 << 31) + 524287 + }; + final RoaringBitmap[] b = new RoaringBitmap[2]; + b[0] = RoaringBitmap.bitmapOf(vals); + b[1] = RoaringBitmap.bitmapOf(vals); + RoaringBitmap a = + FastAggregation.or( + new Iterator() { + int k = 0; + + @Override + public boolean hasNext() { + return k < b.length; + } - rb.add(1L << 15, 1L << 30); - assertEquals(2, rb.first()); - assertEquals((1L << 30) - 1, rb.last()); + @Override + public RoaringBitmap next() { + return b[k++]; + } + + @Override + public void remove() {} + }); + assertEquals(8, a.getCardinality()); + } + + @Test + public void testIterator() { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rb.add(k); + } + for (int k = 0; k < 1000; ++k) { + rb.add(k * 100); + } + RoaringBitmap copy1 = new RoaringBitmap(); + for (int x : rb) { + copy1.add(x); + } + assertEquals(copy1, rb); + RoaringBitmap copy2 = new RoaringBitmap(); + IntIterator i = rb.getIntIterator(); + while (i.hasNext()) { + copy2.add(i.next()); + } + assertEquals(copy2, rb); + } + + @Test + public void testIteratorBigInts() { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 4000; ++k) { + rb.add((1 << 31) + k); + } + for (int k = 0; k < 1000; ++k) { + rb.add((1 << 31) + k * 100); + } + RoaringBitmap copy1 = new RoaringBitmap(); + for (int x : rb) { + copy1.add(x); + } + assertEquals(copy1, rb); + RoaringBitmap copy2 = new RoaringBitmap(); + IntIterator i = rb.getIntIterator(); + while (i.hasNext()) { + copy2.add(i.next()); + } + assertEquals(copy2, rb); + } + + @Test + public void testLimit() { + for (int gap = 1; gap <= 1024; gap *= 2) { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 100000; k += gap) { + rb.add(k); + } + int thiscard = rb.getCardinality(); + for (int k = 0; k < thiscard; k += 100) { + RoaringBitmap limited = rb.limit(k); + assertEquals(limited.getCardinality(), k); + } + assertEquals(rb.limit(thiscard).getCardinality(), thiscard); + assertEquals(rb.limit(thiscard + 1).getCardinality(), thiscard); + } + } + + @Test + public void testLimitBigInts() { + for (int gap = 1; gap <= 1024; gap *= 2) { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 100000; k += gap) { + rb.add((1 << 31) + k); + } + int thiscard = rb.getCardinality(); + for (int k = 0; k < thiscard; k += 100) { + RoaringBitmap limited = rb.limit(k); + assertEquals(limited.getCardinality(), k); + } + assertEquals(rb.limit(thiscard).getCardinality(), thiscard); + assertEquals(rb.limit(thiscard + 1).getCardinality(), thiscard); + } + } + + /** + * Test massive and. + */ + @Test + public void testMassiveAnd() { + RoaringBitmap[] ewah = new RoaringBitmap[1024]; + for (int k = 0; k < ewah.length; ++k) { + ewah[k] = new RoaringBitmap(); + } + int howmany = 1000000; + for (int k = 0; k < howmany; ++k) { + ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); + } + for (int k = 3; k < ewah.length; k += 3) { + ewah[k].flip(13L, (long) howmany / 2); + } + for (int N = 2; N < ewah.length; ++N) { + RoaringBitmap answer = ewah[0]; + for (int k = 1; k < N; ++k) { + RoaringBitmap oldAnswer = answer; + answer = RoaringBitmap.and(oldAnswer, ewah[k]); + assertEquals(answer.getCardinality(), RoaringBitmap.andCardinality(oldAnswer, ewah[k])); + } + RoaringBitmap answer2 = FastAggregation.and(Arrays.copyOf(ewah, N)); + assertEquals(answer, answer2); + RoaringBitmap answer2b = FastAggregation.and(toIterator(Arrays.copyOf(ewah, N))); + assertEquals(answer, answer2b); + } + } + + @Test + public void testMassiveAndBigInts() { + RoaringBitmap[] ewah = new RoaringBitmap[1024]; + for (int k = 0; k < ewah.length; ++k) { + ewah[k] = new RoaringBitmap(); + } + int howmany = 1000000; + for (int k = 0; k < howmany; ++k) { + ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); + } + for (int k = 3; k < ewah.length; k += 3) { + ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); + } + for (int N = 2; N < ewah.length; ++N) { + RoaringBitmap answer = ewah[0]; + for (int k = 1; k < N; ++k) { + RoaringBitmap oldAnswer = answer; + answer = RoaringBitmap.and(oldAnswer, ewah[k]); + assertEquals(answer.getCardinality(), RoaringBitmap.andCardinality(oldAnswer, ewah[k])); + } + RoaringBitmap answer2 = FastAggregation.and(Arrays.copyOf(ewah, N)); + assertEquals(answer, answer2); + RoaringBitmap answer2b = FastAggregation.and(toIterator(Arrays.copyOf(ewah, N))); + assertEquals(answer, answer2b); + } + } + + private static class ExtendedRoaringBitmap extends RoaringBitmap {} + + /** + * Tests that the static #or operation works correctly with an iterator of + * RoaringBitmap extended classes. + */ + @Test + public void testOrWithIterator() { + final RoaringBitmap b1 = new RoaringBitmap(); + b1.add(13); + final RoaringBitmap b2 = new RoaringBitmap(); + b2.add(42); + + final RoaringBitmap result = RoaringBitmap.or(Arrays.asList(b1, b2).iterator()); + assertTrue(result.contains(13)); + assertTrue(result.contains(42)); + } + + /** + * Tests that the static #or operation works correctly with an iterator of + * RoaringBitmap extended classes. + */ + @Test + public void testOrWithIteratorOfExtendedRoaringBitmaps() { + final ExtendedRoaringBitmap b1 = new ExtendedRoaringBitmap(); + b1.add(1); + final ExtendedRoaringBitmap b2 = new ExtendedRoaringBitmap(); + b2.add(2); + + final RoaringBitmap result = + RoaringBitmap.or(Arrays.asList(b1, b2).iterator()); + assertTrue(result.contains(1)); + assertTrue(result.contains(2)); + } + + /** + * Test massive or. + */ + @Test + public void testMassiveOr() { + final int N = 128; + for (int howmany = 512; howmany <= 1000000; howmany *= 2) { + RoaringBitmap[] ewah = new RoaringBitmap[N]; + for (int k = 0; k < ewah.length; ++k) { + ewah[k] = new RoaringBitmap(); + } + for (int k = 0; k < howmany; ++k) { + ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); + } + for (int k = 3; k < ewah.length; k += 3) { + ewah[k].flip(13L, (long) howmany / 2); + } + RoaringBitmap answer = ewah[0]; + for (int k = 1; k < ewah.length; ++k) { + answer = RoaringBitmap.or(answer, ewah[k]); + } + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); + List rbl = new ArrayList<>(); + rbl.add(rb1); + rbl.add(rb2); + + ArrayList arrayList = new ArrayList<>(); + arrayList.add(rb1); + arrayList.add(rb2); + Iterator rbi = arrayList.iterator(); + + RoaringBitmap rbor = RoaringBitmap.or(rb1, rb2); + RoaringBitmap answer2 = FastAggregation.or(ewah); + RoaringBitmap answer3 = FastAggregation.horizontal_or(ewah); + RoaringBitmap answer3b = FastAggregation.or(toIterator(ewah)); + assertEquals(answer, answer2); + assertEquals(answer, answer3); + assertEquals(answer, answer3b); + assertEquals(rbor, FastAggregation.horizontal_or(rbl)); + assertEquals(rbor, FastAggregation.priorityqueue_or(rb1, rb2)); + assertEquals(rbor, FastAggregation.priorityqueue_or(rbi)); + } + } + + @Test + public void testMassiveOrBigInts() { + final int N = 128; + for (int howmany = 512; howmany <= 1000000; howmany *= 2) { + RoaringBitmap[] ewah = new RoaringBitmap[N]; + for (int k = 0; k < ewah.length; ++k) { + ewah[k] = new RoaringBitmap(); + } + for (int k = 0; k < howmany; ++k) { + ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); + } + for (int k = 3; k < ewah.length; k += 3) { + ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); + } + RoaringBitmap answer = ewah[0]; + for (int k = 1; k < ewah.length; ++k) { + answer = RoaringBitmap.or(answer, ewah[k]); + } + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); + List rbl = new ArrayList<>(); + rbl.add(rb1); + rbl.add(rb2); + + ArrayList arrayList = new ArrayList<>(); + arrayList.add(rb1); + arrayList.add(rb2); + Iterator rbi = arrayList.iterator(); + + RoaringBitmap rbor = RoaringBitmap.or(rb1, rb2); + RoaringBitmap answer2 = FastAggregation.or(ewah); + RoaringBitmap answer3 = FastAggregation.horizontal_or(ewah); + RoaringBitmap answer3b = FastAggregation.or(toIterator(ewah)); + assertEquals(answer, answer2); + assertEquals(answer, answer3); + assertEquals(answer, answer3b); + assertEquals(rbor, FastAggregation.horizontal_or(rbl)); + assertEquals(rbor, FastAggregation.priorityqueue_or(rb1, rb2)); + assertEquals(rbor, FastAggregation.priorityqueue_or(rbi)); + } + } + + /** + * Test massive xor. + */ + @Test + public void testMassiveXOr() { + final int N = 128; + for (int howmany = 512; howmany <= 1000000; howmany *= 2) { + RoaringBitmap[] ewah = new RoaringBitmap[N]; + for (int k = 0; k < ewah.length; ++k) { + ewah[k] = new RoaringBitmap(); + } + for (int k = 0; k < howmany; ++k) { + ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); + } + for (int k = 3; k < ewah.length; k += 3) { + ewah[k].flip(13L, (long) howmany / 2); + } + + RoaringBitmap answer = ewah[0]; + for (int k = 1; k < ewah.length; ++k) { + answer = RoaringBitmap.xor(answer, ewah[k]); + } + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); + RoaringBitmap rxor = FastAggregation.xor(rb1, rb2); + RoaringBitmap answer2 = FastAggregation.xor(ewah); + RoaringBitmap answer3 = FastAggregation.horizontal_xor(ewah); + assertEquals(answer, answer2); + assertEquals(answer, answer3); + assertEquals(rxor, FastAggregation.priorityqueue_xor(rb1, rb2)); + } + } + + @Test + public void testMassiveXOrBigInts() { + final int N = 128; + for (int howmany = 512; howmany <= 1000000; howmany *= 2) { + RoaringBitmap[] ewah = new RoaringBitmap[N]; + for (int k = 0; k < ewah.length; ++k) { + ewah[k] = new RoaringBitmap(); + } + for (int k = 0; k < howmany; ++k) { + ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); + } + for (int k = 3; k < ewah.length; k += 3) { + ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); + } + + RoaringBitmap answer = ewah[0]; + for (int k = 1; k < ewah.length; ++k) { + answer = RoaringBitmap.xor(answer, ewah[k]); + } + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); + RoaringBitmap rxor = FastAggregation.xor(rb1, rb2); + RoaringBitmap answer2 = FastAggregation.xor(ewah); + RoaringBitmap answer3 = FastAggregation.horizontal_xor(ewah); + assertEquals(answer, answer2); + assertEquals(answer, answer3); + assertEquals(rxor, FastAggregation.priorityqueue_xor(rb1, rb2)); + } + } + + @Test + public void testOr001() { + int[] array1 = { + 22871, 22873, 22876, 22880, 22886, 22889, 22893, 22897, 22901, 22905, 22910, 22915, 22919, + 22927, 22934, 22940, 24750, 38579, 48470, 50533, 53256, 53717, 53752, 53802, 53938, 54727, + 54865, 55202, 55815, 55822, 55940, 56711, 56977, 57122, 59933, 60037, 60402, 60520, 60853, + 61163, 61340, 61549, 61632, 62097, 62373, 62961, 62993, 63031, 63075, 64209, 64644, 64762, + 64893, 64927, 64997, 65117, 65128, 65173, 65201, 65472, 65536, 65622, 66092, 66162, 66302, + 66381, 66551, 103979, 104644, 106866, 117285, 123372, 127548, 132167, 132168, 136283, 136433, + 137661, 138019, 138239, 138380, 138816, 138916, 138933, 139414, 140342, 140914, 142751, + 142994, 143895, 145081, 147331, 147686, 148021, 148375, 148587, 149114, 149734, 152696, + 153608, 154741, 154932, 155263, 157121, 158947, 159444, 161102, 161383, 162735, 164298, + 168043, 169398, 169536, 170419, 170846, 171153, 177016, 177471, 178305, 178673, 183731, + 183936, 184083, 184106, 185663, 188371, 189495, 189531, 196189, 198419, 198758, 198796, + 200645, 201137, 216865, 216936, 217770, 217810, 217836, 217909, 218569, 218700, 218931, + 219363, 220009, 225925, 234706, 241183, 241561, 242140, 242281, 245018, 245056, 249935, + 250442, 250615, 251696, 252825, 254178, 256788, 256906, 257289, 258833, 260432, 260563, + 260930, 262684, 262834, 263128, 265919, 268662, 269542, 270217, 271673, 273776, 274560, + 275649, 305458, 306241, 306550, 307580, 310891, 312701, 313514, 318134, 319185, 320757, + 321280, 322046, 322743, 323211, 324667, 325382, 326450, 327159, 328836, 329075, 331179, + 332836, 332997, 333071, 333205, 333488, 333595, 335045, 335803, 336417, 336610, 338487, + 339827, 339992, 346123, 348858, 351257, 351957, 353896, 354559, 357142, 358253, 366662, + 378768, 391984, 392282, 415077, 429446, 429449, 429452, 429453, 429476, 429480, 429486, + 429492, 429497, 429501, 429504, 429505, 429510, 429515, 429519, 429524, 429530, 429533, + 429541, 429546, 429553, 429554, 429564, 429572, 429577, 429579, 429586, 429589, 429596, + 429604, 429606, 429612, 429615, 429616, 429624, 429632, 429639, 429642, 429646, 429651, + 429656, 429664, 429670, 429674, 429678, 429681, 429686, 429695, 429701, 429706, 429717, + 429721, 429725, 429733, 429736, 429739, 429743, 429748, 429754, 429761, 429767, 429772, + 429780, 429791, 429792, 429793, 429794, 429795, 429817, 429822, 429823, 429831, 429836, + 429842, 429849, 429855, 429859, 429863, 429866, 429873, 429876, 429882, 429885, 429900, + 429903, 429913, 429921, 429923, 429927, 429932, 429939, 429947, 429950, 429955, 429964, + 429968, 429974, 429982, 429987, 429993, 429999, 430003, 430011, 430015, 430023, 430028, + 430033, 430039, 430044, 430048, 430053, 430057, 430059, 430063, 430068, 430073, 430077, + 430082, 430086, 430093, 430098, 430101, 430114, 430120, 430126, 430131, 430135, 430139, + 430144, 430149, 430155, 430157, 430167, 430175, 430181, 430186, 430194, 430195, 430196, + 430214, 430223, 430228, 430236, 430253, 430258, 430263, 430269, 430277, 430284, 430288, + 430293, 430297, 430303, 430309, 430316, 430321, 430332, 430338, 430343, 430346, 430348, + 430355, 430358, 430369, 430375, 430384, 430391, 430397, 430410, 430415, 430420, 430424, + 430430, 430435, 430437, 430445, 430449, 430461, 430467, 430473, 430482, 430486, 430490, + 430496, 430500, 430506, 430511, 430515, 430535, 430539, 430550, 430568, 430575, 430581, + 430588, 430591, 430596, 430605, 430612, 430617, 430625, 430629, 430633, 430638, 430643, + 430649, 430656, 430663, 430666, 430672, 430679, 430684, 430692, 430696, 430700, 430707, + 430716, 430723, 430728, 430733, 430745, 430751, 430755, 430759, 430767, 430770, 430782, + 430787, 430791, 430804, 430810, 430814, 430821, 430825, 430829, 430833, 430838, 430844, + 430849, 430852, 430859, 430864, 430867, 430870, 430877, 430881, 430887, 430891, 430896, + 430901, 430907, 430912, 430917, 430923, 430927, 430932, 430936, 430944, 430947, 430953, + 430959, 430967, 430971, 430979, 430985, 430989, 430993, 430997, 431003, 431006, 431015, + 431021, 431022, 431033, 431039, 431046, 431050, 431054, 431059, 431065, 431069, 431074, + 431081, 431085, 431092, 431097, 431104, 431110, 431120, 431125, 431133, 431138, 431142, + 431147, 431157, 431164, 431171, 431175, 431180, 431186, 431190, 431195, 431207, 431213, + 431218, 431220, 431224, 431228, 431233, 431235, 431240, 431245, 431251, 431259, 431264, + 431271, 431272, 431280, 431287, 431294, 431299, 431307, 431315, 431319, 431324, 431330, + 431334, 431339, 431345, 431352, 431356, 431363, 431375, 431379, 431383, 431388, 431393, + 431398, 431405, 431409, 431416, 431422, 431426, 431433, 431438, 431444, 431451, 431455, + 431464, 431469, 431472, 431477, 431483, 431490, 431496, 431506, 431513, 431516, 431521, + 431526, 431534, 431536, 431545, 431550, 431559, 431564, 431571, 431573, 431579, 431584, + 431587, 431592, 431604, 431614, 431624, 431629, 431634, 431638, 431645, 431651, 431659, + 431663, 431674, 431678, 431684, 431692, 431696, 431700, 431706, 431712, 431719, 431723, + 431729, 431736, 431741, 431747, 431755, 431758, 431762, 431767, 431777, 431782, 431787, + 431791, 431796, 431799, 431805, 431809, 431814, 431819, 431823, 431828, 431832, 431838, + 431842, 431849, 431853, 431858, 431862, 431866, 431869, 431874, 431881, 431887, 431894, + 431900, 431906, 431912, 431917, 431925, 431931, 431936, 431943, 431948, 431956, 431958, + 431964, 431971, 431976, 431981, 431988, 431994, 431998, 432008, 432012, 432024, 432029, + 432033, 432038, 432045, 432048, 432058, 432062, 432066, 432070, 432076, 432077, 432087, + 432093, 432098, 432104, 432114, 432123, 432128, 432133, 432139, 432145, 432151, 432161, + 432168, 432177, 432181, 432188, 432189, 432203, 432209, 432216, 432222, 432227, 432232, + 432242, 432247, 432256, 432259, 432264, 432269, 432271, 432277, 432286, 432294, 432297, + 432302, 432308, 432313, 432319, 432326, 432331, 432337, 432345, 432349, 432353, 432356, + 432361, 432366, 432370, 432378, 432384, 432390, 432391, 432397, 432400, 432403, 432408, + 432413, 432419, 432422, 432427, 432433, 432440, 432443, 432450, 432455, 432460, 432466, + 432467, 432481, 432489, 432493, 432498, 432504, 432511, 432513, 432517, 432525, 432531, + 432537, 432544, 432546, 432555, 432561, 432565, 432569, 432574, 432579, 432586, 432590, + 432597, 432605, 432611, 432619, 432626, 432630, 432637, 432644, 432646, 432653, 432654, + 432664, 432670, 432674, 432679, 432682, 432687, 432694, 432706, 432711, 432714, 432721, + 432726, 432732, 432741, 432747, 432753, 432755, 432761, 432764, 432768, 432774, 432779, + 432784, 432792, 432798, 432801, 432808, 432815, 432823, 432825, 432833, 432838, 432842, + 432847, 432853, 432861, 432866, 432873, 432879, 432889, 432895, 432901, 432906, 432913, + 432917, 432920, 432926, 432935, 432940, 432949, 432953, 432958, 432960, 432966, 432967, + 432968, 432969, 432970, 432971, 432972, 432996, 432999, 433004, 433010, 433020, 433026, + 433029, 433033, 433042, 433045, 433050, 433054, 433058, 433062, 433065, 433070, 433076, + 433086, 433095, 433101, 433102, 433116, 433122, 433129, 433132, 433140, 433146, 433151, + 433157, 433163, 433169, 433176, 433181, 433188, 433198, 433204, 433219, 433229, 433236, + 433240, 433246, 433250, 433259, 433263, 433274, 433277, 433282, 433286, 433291, 433295, + 433299, 433306, 433316, 433318, 433322, 433327, 433335, 433342, 433348, 433351, 433359, + 433362, 433367, 433371, 433377, 433384, 433393, 433398, 433403, 433407, 433411, 433425, + 433430, 433437, 433441, 433445, 433452, 433453, 433458, 433462, 433469, 433473, 433478, + 433484, 433490, 433495, 433501, 433506, 433514, 433517, 433521, 433527, 433534, 433544, + 433549, 433552, 433561, 433565, 433569, 433576, 433585, 433589, 433594, 433597, 433600, + 433603, 433606, 433613, 433619, 433623, 433627, 433639, 433643, 433648, 433654, 433658, + 433665, 433673, 433678, 433681, 433689, 433696, 433704, 433709, 433716, 433721, 433725, + 433729, 433734, 433738, 433744, 433749, 433755, 433760, 433766, 433771, 433776, 433781, + 433785, 433790, 433798, 433803, 433810, 433814, 433817, 433822, 433828, 433833, 433837, + 433843, 433849, 433852, 433858, 433863, 433871, 433875, 433881, 433883, 433884, 433897, + 433903, 433909, 433913, 433921, 433926, 433932, 433936, 433942, 433946, 433951, 433959, + 433965, 433976, 433981, 433989, 433996, 434004, 434011, 434013, 434019, 434023, 434029, + 434036, 434041, 434048, 434050, 434056, 434060, 434068, 434074, 434079, 434085, 434091, + 434096, 434100, 434105, 434110, 434119, 434123, 434129, 434133, 434139, 434146, 434150, + 434156, 434161, 434168, 434173, 434183, 434188, 434193, 434200, 434208, 434213, 434219, + 434223, 434229, 434235, 434241, 434247, 434258, 434262, 434269, 434275, 434282, 434287, + 434291, 434296, 434303, 434308, 434313, 434316, 434323, 434327, 434335, 434342, 434349, + 434353, 434360, 434366, 434372, 434373, 434381, 434387, 434392, 434397, 434401, 434403, + 434409, 434414, 434420, 434427, 434433, 434440, 434445, 434449, 434454, 434460, 434467, + 434473, 434479, 434481, 434490, 434494, 434501, 434505, 434510, 434517, 434526, 434537, + 434542, 434548, 434553, 434558, 434563, 434569, 434574, 434580, 434586, 434588, 434595, + 434603, 434606, 434617, 434620, 434626, 434630, 434638, 434644, 434647, 434651, 434658, + 434666, 434671, 434679, 434681, 434685, 434692, 434699, 434703, 434708, 434713, 434720, + 434723, 434729, 434734, 434738, 434742, 434746, 434753, 434762, 434766, 434773, 434781, + 434790, 434799, 434805, 434810, 434814, 434823, 434831, 434839, 434845, 434850, 434856, + 434859, 434863, 434869, 434870, 434882, 434890, 434896, 434899, 434906, 434912, 434917, + 434921, 434930, 434935, 434940, 434945, 434949, 434956, 434961, 434967, 434977, 434982, + 434987, 434992, 434995, 435002, 435005, 435009, 435016, 435021, 435025, 435028, 435034, + 435041, 435050, 435055, 435065, 435069, 435075, 435078, 435083, 435091, 435097, 435102, + 435105, 435107, 435113, 435118, 435124, 435131, 435141, 435144, 435150, 435154, 435159, + 435167, 435171, 435177, 435181, 435187, 435192, 435198, 435204, 435211, 435212, 435221, + 435228, 435231, 435237, 435244, 435246, 435254, 435258, 435264, 435275, 435283, 435289, + 435301, 435304, 435312, 435318, 435323, 435329, 435334, 435340, 435343, 435347, 435351, + 435358, 435363, 435368, 435375, 435382, 435388, 435391, 435396, 435399, 435405, 435412, + 435416, 435422, 435425, 435429, 435437, 435444, 435447, 435453, 435458, 435470, 435477, + 435486, 435491, 435497, 435500, 435511, 435516, 435520, 435526, 435533, 435539, 435545, + 435551, 435559, 435564, 435569, 435575, 435579, 435585, 435590, 435597, 435599, 435600, + 435610, 435616, 435618, 435623, 435628, 435636, 435643, 435649, 435654, 435659, 435663, + 435671, 435675, 435678, 435683, 435689, 435702, 435705, 435712, 435718, 435749, 435755, + 435759, 435764, 435771, 435775, 435780, 435785, 435791, 435794, 435802, 435811, 435816, + 435822, 435828, 435833, 435838, 435844, 435851, 435859, 435861, 435866, 435869, 435876, + 435882, 435890, 435897, 435900, 435908, 435913, 435923, 435929, 435934, 435937, 435942, + 435945, 435951, 435953, 435959, 435965, 435969, 435975, 435982, 435987, 435992, 436000, + 436008, 436013, 436017, 436022, 436027, 436033, 436038, 436043, 436048, 436052, 436062, + 436065, 436069, 436073, 436079, 436088, 436092, 436100, 436106, 436116, 436123, 436127, + 436133, 436139, 436147, 436153, 436159, 436165, 436172, 436179, 436184, 436190, 436194, + 436199, 436206, 436210, 436211, 436217, 436223, 436229, 436234, 436240, 436245, 436253, + 436258, 436262, 436268, 436273, 436282, 436287, 436294, 436303, 436306, 436313, 436316, + 436321, 436329, 436337, 436341, 436349, 436353, 436358, 436365, 436368, 436373, 436378, + 436387, 436391, 436396, 436401, 436408, 436412, 436420, 436423, 436428, 436435, 436441, + 436447, 436451, 436461, 436463, 436467, 436471, 436477, 436479, 436485, 436489, 436494, + 436502, 436509, 436512, 436518, 436529, 436538, 436543, 436552, 436553, 436560, 436564, + 436569, 436575, 436580, 436585, 436591, 436597, 436603, 436605, 436610, 436616, 436619, + 436628, 436633, 436637, 436640, 436644, 436649, 436653, 436659, 436666, 436674, 436681, + 436687, 436694, 436700, 436703, 436710, 436720, 436723, 436730, 436735, 436742, 436748, + 436756, 436761, 436766, 436772, 436778, 436783, 436787, 436792, 436799, 436808, 436810, + 436812, 436817, 436823, 436832, 436838, 436845, 436849, 436853, 436859, 436865, 436872, + 436878, 436882, 436885, 436891, 436898, 436903, 436910, 436911, 436922, 436928, 436932, + 436939, 436942, 436948, 436950, 436956, 436963, 436968, 436975, 436984, 436988, 436994, + 437003, 437009, 437013, 437020, 437023, 437028, 437033, 437043, 437053, 437058, 437063, + 437073, 437076, 437079, 437089, 437093, 437095, 437101, 437111, 437119, 437121, 437127, + 437135, 437140, 437147, 437151, 437155, 437160, 437165, 437171, 437173, 437180, 437186, + 437194, 437199, 437205, 437213, 437217, 437223, 437227, 437231, 437243, 437250, 437256, + 437261, 437267, 437271, 437277, 437284, 437289, 437295, 437300, 437304, 437312, 437322, + 437326, 437333, 437338, 437354, 437357, 437362, 437366, 437370, 437374, 437380, 437386, + 437391, 437395, 437399, 437404, 437412, 437416, 437419, 437427, 437432, 437433, 437451, + 437456, 437461, 437467, 437468, 437477, 437485, 437492, 437495, 437501, 437502, 437506, + 437513, 437524, 437526, 437539, 437544, 437552, 437558, 437562, 437568, 437573, 437578, + 437587, 437592, 437596, 437600, 437605, 437610, 437619, 437625, 437630, 437631, 437639, + 437647, 437648, 437655, 437661, 437667, 437672, 437676, 437680, 437687, 437689, 437693, + 437697, 437704, 437707, 437716, 437723, 437730, 437737, 437740, 437741, 437757, 437763, + 437771, 437778, 437784, 437789, 437793, 437800, 437804, 437811, 437812, 437819, 437823, + 437827, 437833, 437841, 437844, 437853, 437857, 437861, 437866, 437874, 437881, 437886, + 437892, 437901, 437902, 437909, 437914, 437922, 437928, 437934, 437939, 437948, 437951, + 437957, 437963, 437965, 437971, 437980, 437985, 437990, 437996, 438002, 438008, 438013, + 438017, 438025, 438030, 438036, 438041, 438052, 438060, 438065, 438072, 438073, 438079, + 438084, 438091, 438097, 438099, 438107, 438111, 438119, 438125, 438136, 438144, 438148, + 438153, 438158, 438164, 438166, 438173, 438176, 438183, 438184, 438192, 438198, 438204, + 438209, 438216, 438228, 438231, 438237, 438243, 438248, 438257, 438267, 438269, 438274, + 438282, 438287, 438295, 438301, 438306, 438313, 438318, 438323, 438328, 438335, 438339, + 438346, 438352, 438357, 438363, 438370, 438374, 438380, 438384, 438388, 438394, 438399, + 438404, 438409, 438413, 438422, 438428, 438436, 438439, 438444, 438453, 438461, 438471, + 438477, 438483, 438491, 438503, 438505, 438511, 438518, 438527, 438531, 438541, 438546, + 438552, 438556, 438562, 438566, 438570, 438580, 438585, 438593, 438595, 438603, 438605, + 438607, 438614, 438619, 438626, 438631, 438634, 438641, 438646, 438652, 438657, 438663, + 438664, 438665, 438673, 438677, 438682, 438692, 438700, 438706, 438708, 438715, 438723, + 438727, 438737, 438742, 438753, 438760, 438764, 438771, 438775, 438780, 438783, 438789, + 438797, 438806, 438810, 438815, 438832, 438837, 438841, 438845, 438852, 438860, 438865, + 438873, 438883, 438884, 438896, 438908, 438912, 438920, 438924, 438927, 438934, 438936, + 438940, 438946, 438953, 438961, 438968, 438976, 438980, 438985, 438994, 439006, 439011, + 439017, 439021, 439027, 439032, 439036, 439043, 439047, 439055, 439059, 439065, 439070, + 439075, 439083, 439087, 439093, 439099, 439104, 439109, 439114, 439120, 439123, 439128, + 439130, 439134, 439139, 439147, 439157, 439162, 439167, 439172, 439178, 439183, 439187, + 439194, 439201, 439205, 439210, 439216, 439222, 439225, 439231, 439235, 439245, 439251, + 439255, 439261, 439277, 439282, 439288, 439295, 439302, 439308, 439309, 439314, 439320, + 439328, 439332, 439339, 439345, 439350, 439354, 439359, 439365, 439372, 439377, 439379, + 439386, 439391, 439404, 439410, 439416, 439419, 439425, 439430, 439434, 439438, 439455, + 439461, 439465, 439472, 439476, 439482, 439488, 439493, 439496, 439506, 439510, 439516, + 439521, 439527, 439536, 439543, 439551, 439554, 439557, 439564, 439569, 439574, 439577, + 439584, 439588, 439593, 439597, 439602, 439607, 439613, 439618, 439624, 439625, 439633, + 439638, 439641, 439645, 439650, 439655, 439659, 439669, 439670, 439671, 439682, 439692, + 439696, 439701, 439709, 439718, 439725, 439730, 439733, 439739, 439745, 439757, 439764, + 439768, 439771, 439778, 439783, 439788, 439796, 439805, 439811, 439815, 439820, 439827, + 439830, 439840, 439846, 439850, 439854, 439865, 439873, 439879, 439886, 439891, 439898, + 439903, 439909, 439917, 439925, 439928, 439933, 439938, 439944, 439948, 439955, 439959, + 439965, 439969, 439974, 439988, 439989, 440005, 440008, 440011, 440015, 440020, 440026, + 440030, 440035, 440043, 440044, 440055, 440060, 440078, 440091, 440096, 440101, 440106, + 440111, 440116, 440120, 440134, 440139, 440143, 440149, 440157, 440163, 440167, 440171, + 440179, 440187, 440191, 440196, 440201, 440207, 440213, 440218, 440223, 440228, 440233, + 440239, 440244, 440249, 440256, 440262, 440268, 440274, 440277, 440282, 440289, 440295, + 440307, 440311, 440315, 440321, 440327, 440331, 440336, 440341, 440346, 440355, 440361, + 440368, 440375, 440379, 440388, 440394, 440399, 440402, 440410, 440413, 440421, 440427, + 440431, 440435, 440440, 440446, 440454, 440461, 440467, 440476, 440481, 440486, 440490, + 440495, 440500, 440506, 440512, 440523, 440529, 440533, 440539, 440546, 440552, 440560, + 440568, 440578, 440584, 440590, 440594, 440598, 440606, 440612, 440620, 440623, 440629, + 440634, 440641, 440647, 440651, 440655, 440663, 440669, 440674, 440682, 440689, 440694, + 440698, 440702, 440706, 440713, 440719, 440727, 440733, 440737, 440743, 440747, 440753, + 440760, 440767, 440772, 440779, 440783, 440789, 440792, 440798, 440806, 440808, 440812, + 440819, 440823, 440826, 440830, 440835, 440840, 440845, 440853, 440856, 440861, 440867, + 440872, 440876, 440882, 440888, 440893, 440903, 440910, 440915, 440921, 440927, 440933, + 440938, 440945, 440950, 440958, 440966, 440969, 440973, 440977, 440983, 440987, 440992, + 440996, 441005, 441008, 441013, 441028, 441035, 441042, 441047, 441052, 441056, 441061, + 441068, 441075, 441080, 441087, 441094, 441097, 441106, 441111, 441115, 441121, 441125, + 441132, 441136, 441143, 441150, 441157, 441161, 441167, 441171, 441175, 441179, 441185, + 441193, 441196, 441200, 441204, 441210, 441216, 441223, 441226, 441234, 441238, 441243, + 441253, 441260, 441268, 441276, 441287, 441294, 441297, 441306, 441313, 441315, 441323, + 441332, 441339, 441346, 441353, 441358, 441362, 441368, 441373, 441378, 441382, 441390, + 441394, 441399, 441404, 441411, 441416, 441420, 441427, 441432, 441440, 441445, 441448, + 441453, 441456, 441461, 441467, 441473, 441479, 441484, 441491, 441497, 441506, 441509, + 441515, 441521, 441526, 441531, 441535, 441542, 441547, 441551, 441555, 441559, 441565, + 441569, 441574, 441579, 441596, 441599, 441605, 441610, 441617, 441619, 441623, 441628, + 441630, 441636, 441637, 441651, 441652, 441662, 441664, 441667, 441671, 441681, 441684, + 441689, 441693, 441701, 441705, 441710, 441718, 441720, 441726, 441740, 441746, 441757, + 441759, 441766, 441773, 441775, 441780, 441793, 441794, 441799, 441807, 441817, 441822, + 441828, 441831, 441834, 441838, 441845, 441853, 441857, 441863, 441866, 441872, 441880, + 441883, 441886, 441891, 441895, 441900, 441910, 441915, 441921, 441928, 441934, 441939, + 441945, 441947, 441952, 441957, 441964, 441971, 441974, 441980, 441985, 441990, 441994, + 441998, 442002, 442007, 442010, 442017, 442019, 442027, 442043, 442046, 442054, 442060, + 442067, 442074, 442076, 442081, 442086, 442093, 442099, 442103, 442108, 442112, 442120, + 442131, 442135, 442139, 442144, 442148, 442156, 442161, 442165, 442170, 442181, 442186, + 442192, 442197, 442203, 442220, 442226, 442233, 442239, 442245, 442249, 442254, 442259, + 442267, 442275, 442281, 442284, 442287, 442292, 442299, 442308, 442314, 442318, 442325, + 442332, 442333, 442334, 442346, 442351, 442354, 442358, 442364, 442370, 442372, 442377, + 442381, 442389, 442397, 442402, 442409, 442415, 442419, 442424, 442430, 442438, 442443, + 442451, 442459, 442470, 442473, 442482, 442490, 442496, 442501, 442506, 442514, 442520, + 442524, 442530, 442534, 442541, 442546, 442549, 442554, 442558, 442563, 442573, 442586, + 442591, 442595, 442600, 442607, 442613, 442618, 442624, 442628, 442632, 442640, 442647, + 442651, 442657, 442666, 442674, 442679, 442682, 442686, 442692, 442699, 442705, 442714, + 442718, 442722, 442729, 442734, 442739, 442748, 442751, 442754, 442757, 442765, 442770, + 442778, 442783, 442792, 442798, 442802, 442813, 442820, 442829, 442833, 442841, 442845, + 442851, 442857, 442860, 442865, 442871, 442877, 442882, 442886, 442892, 442898, 442904, + 442906, 442911, 442915, 442922, 442929, 442934, 442940, 442944, 442946, 442952, 442956, + 442963, 442971, 442973, 442979, 442985, 442997, 443001, 443006, 443017, 443019, 443024, + 443027, 443036, 443046, 443050, 443057, 443066, 443069, 443078, 443083, 443089, 443093, + 443100, 443104, 443109, 443118, 443126, 443134, 443141, 443146, 443151, 443158, 443164, + 443169, 443174, 443179, 443182, 443189, 443195, 443198, 443206, 443211, 443213, 443214, + 443222, 443224, 443228, 443235, 443240, 443246, 443255, 443259, 443269, 443270, 443277, + 443285, 443291, 443299, 443303, 443311, 443313, 443319, 443322, 443328, 443338, 443342, + 443350, 443351, 443356, 443362, 443365, 443368, 443371, 443375, 443378, 443384, 443388, + 443391, 443397, 443404, 443412, 443416, 443421, 443424, 443428, 443433, 443438, 443442, + 443449, 443462, 443463, 443470, 443474, 443482, 443490, 443495, 443499, 443506, 443519, + 443523, 443527, 443533, 443540, 443548, 443550, 443556, 443559, 443564, 443568, 443574, + 443582, 443589, 443594, 443596, 443602, 443610, 443612, 443616, 443620, 443625, 443631, + 443638, 443643, 443649, 443656, 443660, 443669, 443672, 443680, 443691, 443695, 443699, + 443706, 443710, 443714, 443718, 443721, 443726, 443734, 443739, 443745, 443752, 443758, + 443765, 443771, 443774, 443781, 443786, 443789, 443793, 443797, 443802, 443811, 443812, + 443820, 443829, 443832, 443838, 443847, 443851, 443856, 443857, 443864, 443871, 443877, + 443886, 443892, 443896, 443903, 443909, 443913, 443920, 443925, 443930, 443935, 443942, + 443946, 443954, 443963, 443966, 443969, 443975, 443979, 443982, 443988, 443996, 443999, + 444003, 444007, 444012, 444019, 444026, 444030, 444040, 444049, 444056, 444060, 444064, + 444069, 444073, 444075, 444078, 444083, 444091, 444098, 444103, 444111, 444121, 444124, + 444130, 444136, 444140, 444145, 444150, 444156, 444162, 444168, 444172, 444179, 444182, + 444186, 444189, 444193, 444198, 444203, 444208, 444212, 444218, 444225, 444231, 444234, + 444240, 444246, 444258, 444265, 444273, 444277, 444281, 444288, 444292, 444298, 444301, + 444309, 444314, 444319, 444327, 444332, 444338, 444349, 444354, 444359, 444364, 444374, + 444377, 444381, 444386, 444388, 444394, 444401, 444406, 444417, 444422, 444429, 444438, + 444439, 444448, 444449, 444456, 444461, 444467, 444473, 444480, 444486, 444490, 444495, + 444500, 444503, 444508, 444514, 444518, 444525, 444528, 444535, 444540, 444544, 444550, + 444556, 444563, 444570, 444576, 444580, 444583, 444587, 444591, 444599, 444605, 444608, + 444612, 444619, 444629, 444635, 444643, 444646, 444652, 444660, 444671, 444676, 444681, + 444686, 444690, 444696, 444703, 444710, 444711, 444720, 444723, 444734, 444742, 444752, + 444758, 444763, 444767, 444770, 444774, 444786, 444789, 444794, 444800, 444809, 444818, + 444822, 444830, 444836, 444841, 444846, 444853, 444859, 444866, 444873, 444878, 444885, + 444890, 444896, 444904, 444907, 444914, 444922, 444924, 444931, 446357, 488475, 495304, + 496119, 497438, 498593, 498603, 498917, 499048, 499713, 500776, 501348, 503424, 508844, + 518359, 519305, 519446, 523627, 523776, 523878, 523902, 524135, 524329, 524515, 524611, + 524686, 524798, 524852, 525209, 525700, 525913, 525954, 526158, 526332, 526356, 536810, + 537279, 563933, 578719, 579248, 579791, 584191, 591485, 592871, 613176, 615012, 616428, + 619153, 636103, 640708, 643141, 645080, 646349, 647043, 649345, 651085, 652849, 653092, + 653169, 653227, 653586, 655241, 656093, 658355, 658564, 659381, 659518, 690513, 693218, + 693746, 694340, 694842, 695155, 695563, 695776, 696380, 697608, 697797, 698222, 698835, + 699307, 700154, 700203, 700235, 700404, 700806, 700900, 701796, 702155, 702956, 702998, + 705105, 705377, 705631, 708650, 709265, 709787, 725122, 735376, 737115, 737174, 738005, + 741377, 741986, 746045, 746404, 746590, 748212, 753574, 754379, 764728, 765776, 766863, + 769126, 782626, 782723, 783529, 786875, 787544, 807281, 811132, 821933, 822194, 829768, + 830997, 831095, 832481, 834082, 844664, 845574, 845764, 846820, 849481, 855607, 857775, + 872350, 876126, 902029, 903509, 904449, 904469, 905915, 910463, 911856, 924365, 928664, + 929314, 929606, 929983, 930478, 933195, 933819, 935628, 935911, 935922, 936002, 937668, + 941895, 942677, 943721, 944661, 944980, 945121, 945268, 945360, 950756, 951007, 959993, + 960787, 961048, 961084, 961238, 961589, 962000, 962797, 962827, 962910, 963788, 964272, + 964343, 964431, 964573, 964949, 965017, 965036, 965041, 965598, 965674, 965957, 966014, + 966032, 966092, 966144, 966226, 966234, 966265, 966291, 978103, 980858, 987212, 987458, + 987498, 988368, 988513, 988939, 990571, 993183, 1005493, 1007972, 1008230, 1009675, 1010075, + 1010685, 1011441, 1011828, 1012269, 1012310, 1013612, 1013907, 1014379, 1018659, 1018923, + 1022035, 1024567, 1024568, 1025024, 1026699, 1027212, 1027840, 1029108, 1031846, 1032670, + 1032970, 1034016, 1039255, 1040626, 1040796, 1043457, 1043632, 1051053, 1052581, 1091611, + 1092316, 1092564, 1092634, 1096386, 1096820, 1098606, 1104201, 1107101, 1110019, 1111384, + 1111707, 1128990, 1129111, 1129147, 1129160, 1129367, 1129408, 1129508, 1129577, 1129699, + 1129750, 1129840, 1129951, 1129988, 1130041, 1130139, 1130177, 1130241, 1130248, 1130268, + 1130276, 1130367, 1130540, 1130562, 1130636, 1130637, 1130662, 1130716, 1131139, 1131218, + 1131250, 1131454, 1131541, 1131775, 1132208, 1132280, 1132901, 1133264, 1133474, 1133475, + 1133764, 1133841, 1133988, 1134290, 1134533, 1134553, 1134614, 1134667, 1134710, 1134861, + 1134896, 1135008, 1135178, 1135544, 1135551, 1135573, 1136260, 1136385, 1136458, 1136782, + 1136960, 1137342, 1137713, 1137824, 1138160, 1138291, 1138340, 1138457, 1138468, 1138516, + 1138526, 1138610, 1138648, 1138700, 1138801, 1138869, 1138999, 1139010, 1139102, 1139114, + 1139145, 1139302, 1139322, 1139417, 1139496, 1139581, 1139668, 1139852, 1139930, 1139958, + 1140325, 1140616, 1140811, 1140861, 1141056, 1141197, 1141311, 1141346, 1141551, 1141666, + 1141735, 1141786, 1141895, 1142017, 1142228, 1142242, 1142415, 1142484, 1142579, 1142599, + 1142867, 1142929, 1143057, 1143132, 1143191, 1143203, 1143293, 1143476, 1143860, 1143997, + 1144044, 1144321, 1144338, 1144459, 1144548, 1144564, 1144588, 1144592, 1144606, 1144623, + 1144718, 1144792, 1144906, 1144997, 1145007, 1145082, 1145274, 1145380, 1145430, 1145584, + 1145731, 1145778, 1145869, 1145914, 1145925, 1146025, 1146158, 1146212, 1146223, 1146448, + 1146594, 1146663, 1146761, 1146803, 1146826, 1146833, 1146898, 1147078, 1147099, 1147330, + 1147382, 1147424, 1147431, 1147472, 1147545, 1147592, 1147627, 1147657, 1147742, 1148005, + 1148699, 1155013, 1155166, 1155915, 1178902, 1179255, 1180871, 1184802, 1187587, 1190670, + 1198632, 1198646, 1198832, 1199211, 1199259, 1199330, 1200318, 1200824, 1200959, 1201200, + 1202513, 1210077, 1210208, 1210296, 1211774, 1211775, 1211776, 1211777, 1212528, 1212529, + 1212843, 1216377, 1219904, 1220650, 1232492, 1235492, 1243381, 1243807, 1267467, 1267561, + 1267615, 1267691, 1267708, 1267731, 1267797, 1273165, 1278015, 1278076, 1278615, 1279032, + 1279185, 1279756, 1281009, 1281074, 1282368, 1284002, 1284572, 1285041, 1285278, 1285788, + 1285969, 1286573, 1286679, 1287001, 1287466, 1287714, 1287819, 1288542, 1288897, 1289486, + 1290086, 1290286, 1291047, 1291363, 1291498, 1291749, 1291853, 1292129, 1292571, 1292828, + 1292855, 1292859, 1292892, 1292893, 1292909, 1292910, 1292956, 1292957, 1292985, 1293133, + 1293185, 1293926, 1294446, 1294490, 1294571, 1294966, 1295003, 1295395, 1295491, 1296604, + 1298327, 1298527, 1298685, 1300235, 1300501, 1301193, 1301345, 1301536, 1301908, 1301969, + 1301988, 1302146, 1302158, 1302810, 1303060, 1303244, 1303275, 1303487, 1303721, 1303831, + 1303943, 1304875, 1305210, 1305677, 1305687, 1306397, 1306865, 1307044, 1307745, 1307926, + 1308080, 1308680, 1309204, 1309475, 1310596, 1312574, 1313313, 1313764, 1313792, 1313963, + 1314093, 1314284, 1314743, 1315154, 1315292, 1315503, 1315994, 1316517, 1316872, 1316909, + 1317089, 1317327, 1318223, 1319657, 1321070, 1321083, 1321495, 1321517, 1322195, 1322221, + 1322293, 1322330, 1322471, 1322496, 1322569, 1322634, 1322716, 1322859, 1323066, 1323356, + 1323530, 1323539, 1323614, 1323868, 1323925, 1328650, 1329210, 1332937, 1333431, 1335482, + 1338092, 1342268, 1345890, 1346245, 1346532, 1346613, 1346783, 1347371, 1347858, 1348077, + 1348468, 1349166, 1349298, 1349335, 1350775, 1350809, 1351329, 1352877 + }; + int[] array2 = { + 14402, 14403, 14404, 14405, 14406, 14407, 23246, 23247, 23248, 23249, 23250, 23936, 23937, + 23938, 23939, 23940, 23941, 23942, 29721, 29722, 29723, 29724, 29725, 30226, 30227, 30228, + 30229, 30230, 32141, 32142, 32143, 47737, 47738, 47739, 47740, 47741, 47742, 47743, 47744, + 47745, 47746, 47747, 47748, 47749, 47750, 47751, 47752, 68770, 68771, 68772, 68773, 68774, + 68775, 68776, 68777, 68778, 68779, 68780, 72301, 72302, 83071, 83072, 83073, 83074, 85302, + 85303, 85304, 85305, 85306, 85307, 85308, 85309, 85310, 85311, 85312, 85313, 85314, 85315, + 85316, 97108, 97109, 97110, 97111, 103442, 103443, 103444, 103445, 103446, 103447, 103448, + 103449, 103450, 103451, 103452, 103453, 103454, 103455, 103456, 103457, 103458, 103459, + 103460, 103461, 103462, 103463, 103464, 103465, 103466, 103467, 103468, 103469, 128488, + 128489, 128490, 128491, 128492, 128493, 135003, 135004, 135005, 135006, 135007, 135008, + 135009, 135010, 135011, 135012, 135013, 135014, 140363, 140364, 140365, 140366, 140367, + 140368, 140369, 140370, 140371, 140372, 149844, 149845, 149846, 149847, 149848, 149849, + 149850, 149851, 149852, 149853, 149854, 149855, 149856, 149857, 149858, 149859, 149860, + 149861, 149862, 149863, 149864, 172805, 172806, 172807, 172808, 172809, 172810, 172811, + 172812, 172813, 172814, 172815, 172816, 172817, 172818, 172819, 172820, 172821, 172822, + 172823, 172824, 172825, 172826, 172827, 172828, 172829, 172830, 172831, 172832, 172833, + 172834, 172835, 172836, 172837, 172838, 172839, 172840, 172841, 172842, 172843, 172844, + 172845, 172846, 172847, 172848, 172849, 172850, 172851, 172852, 172853, 172854, 172855, + 172856, 172857, 172858, 172859, 172860, 172861, 172862, 172863, 172864, 172865, 172866, + 172867, 172868, 172869, 172870, 172871, 202530, 202531, 202532, 209488, 209489, 209490, + 209491, 209492, 209493, 209494, 209495, 209496, 209497, 209498, 209499, 209500, 209501, + 209502, 209503, 209504, 209505, 209506, 225554, 225555, 225556, 225557, 225558, 225559, + 225560, 225561, 225562, 225563, 225564, 225565, 225566, 225567, 225568, 225569, 225570, + 225571, 225572, 225573, 225574, 225575, 225576, 225577, 225578, 225579, 225580, 225581, + 227917, 227918, 227919, 227920, 227921, 227922, 227923, 227924, 227925, 227926, 227927, + 227928, 227929, 227930, 227931, 227932, 227933, 227934, 227935, 227936, 227937, 227938, + 227939, 252773, 252774, 252775, 252776, 252777, 252778, 252779, 252780, 252781, 252782, + 252783, 252784, 252785, 252786, 252787, 252788, 252789, 252790, 252791, 252792, 252793, + 252794, 278695, 278696, 278697, 278698, 278699, 301237, 301238, 301239, 301240, 301241, + 301242, 301243, 301244, 301245, 301246, 301247, 301248, 301249, 301250, 301251, 301252, + 301253, 301254, 301255, 301256, 301257, 301258, 301259, 301260, 301261, 301262, 301263, + 301264, 301265, 320515, 320516, 320517, 320518, 320519, 320520, 320521, 320522, 320523, + 320524, 320525, 320526, 320527, 320528, 320529, 320530, 320531, 320532, 320533, 320534, + 320535, 320536, 320537, 320538, 320539, 320540, 320541, 320542, 320543, 320544, 320545, + 320546, 320547, 320548, 329641, 329642, 329643, 329644, 329645, 329646, 329647, 329648, + 329649, 329650, 329651, 329652, 329653, 329654, 329655, 329656, 329657, 329658, 329659, + 342703, 342704, 342705, 342706, 349520, 349521, 349522, 349523, 349524, 349525, 349526, + 349527, 349528, 349529, 349530, 362716, 362717, 362718, 362719, 362720, 362721, 362722, + 362723, 362724, 362725, 362726, 362727, 378643, 378644, 378645, 378646, 390154, 390155, + 390156, 390157, 390158, 390159, 390160, 390161, 390162, 390163, 390164, 390165, 390166, + 390167, 390168, 390169, 395108, 395109, 395110, 395111, 395112, 395113, 395114, 395115, + 403260, 403261, 403262, 403263, 403264, 403265, 403266, 403267, 403268, 403269, 403270, + 403271, 417315, 417316, 417317, 417318, 417319, 417320, 432653, 432654, 432655, 432656, + 432657, 432658, 432659, 432660, 432661, 432662, 432663, 432664, 432665, 432666, 432667, + 432668, 432669, 432670, 432671, 432672, 432673, 432674, 432675, 432676, 432677, 432678, + 449394, 449395, 449396, 449397, 449398, 459961, 459962, 459963, 459964, 474537, 474538, + 474539, 474540, 474541, 474542, 474543, 474544, 474545, 474546, 474547, 474548, 474549, + 474550, 474551, 474552, 474553, 474554, 474555, 474556, 474557, 474558, 474559, 474560, + 474561, 474562, 474563, 474564, 474565, 474566, 474567, 474568, 474569, 474570, 474571, + 474572, 474573, 474574, 474575, 474576, 474577, 474578, 474579, 474580, 474581, 474582, + 474583, 474584, 474585, 474586, 474587, 474588, 474589, 474590, 474591, 474592, 474593, + 474594, 474595, 474596, 474597, 483571, 483572, 483573, 483574, 483575, 483576, 489641, + 489642, 489643, 489644, 489645, 489646, 489647, 489648, 489649, 489650, 489651, 491296, + 491297, 491298, 495868, 495869, 495870, 502769, 502770, 502771, 502772, 502773, 502774, + 502775, 502776, 502777, 502778, 502779, 502780, 502781, 502782, 502783, 513810, 513811, + 513812, 513813, 513814, 513815, 513816, 513817, 513818, 513819, 513820, 513821, 513822, + 513823, 513824, 513825, 513826, 513827, 513828, 513829, 513830, 513831, 513832, 517220, + 517221, 517222, 517223, 517224, 517225, 517226, 517227, 519778, 519779, 519780, 519781, + 519782, 519783, 519784, 519785, 524240, 524241, 524242, 524243, 524244, 524245, 524246, + 524247, 524248, 524249, 527255, 527256, 527257, 527258, 527259, 533697, 533698, 533699, + 533700, 533701, 533702, 533703, 533704, 533705, 533706, 533707, 533708, 533709, 539237, + 539238, 539239, 539240, 539241, 539242, 539243, 562203, 562204, 562205, 562206, 569773, + 569774, 569775, 569776, 569777, 569778, 569779, 569780, 569781, 569782, 569783, 569784, + 569785, 569786, 569787, 569788, 569789, 569790, 569791, 569792, 569793, 569794, 569795, + 569796, 569797, 569798, 569799, 569800, 569801, 569802, 569803, 569804, 569805, 569806, + 569807, 569808, 569809, 569810, 569811, 569812, 569813, 569814, 569815, 569816, 569817, + 569818, 569819, 569820, 569821, 580161, 580162, 580163, 580164, 580165, 580166, 580167, + 580168, 580169, 580170, 580171, 580172, 580173, 580174, 580175, 580176, 588299, 588300, + 588301, 588302, 588303, 588304, 588305, 588306, 588307, 588308, 588309, 588310, 588311, + 588312, 588313, 588314, 588315, 588316, 588317, 588318, 588319, 588320, 588321, 588322, + 588323, 588324, 588325, 588326, 588327, 588328, 588329, 588330, 588331, 588332, 588333, + 588334, 588335, 608580, 608581, 608582, 608583, 608584, 608585, 608586, 608587, 608588, + 608589, 608590, 608591, 608592, 608593, 608594, 608595, 608596, 608597, 608598, 608599, + 608600, 608601, 608602, 608603, 608604, 608605, 618326, 618327, 618328, 618329, 618330, + 618331, 618332, 618333, 618334, 618335, 618336, 618337, 618338, 618339, 618340, 618341, + 618342, 618343, 618344, 618345, 618346, 618347, 618348, 618349, 626895, 626896, 626897, + 626898, 626899, 626900, 635313, 635314, 635315, 635316, 635317, 635318, 635319, 635320, + 635321, 635322, 635323, 635324, 635325, 635326, 635327, 635328, 635329, 635330, 635331, + 635332, 635333, 635334, 635335, 635336, 635337, 635338, 635339, 635340, 635341, 635342, + 635343, 635344, 635345, 635346, 635347, 635348, 635349, 635350, 635351, 635352, 635353, + 635354, 635355, 648087, 648088, 648089, 648090, 648091, 648092, 648093, 648094, 648095, + 648096, 648097, 648098, 648099, 648100, 648101, 648102, 648103, 648104, 648105, 648106, + 648107, 648108, 648109, 648110, 661574, 661575, 661576, 661577, 674566, 674567, 674568, + 674569, 674570, 674571, 674572, 674573, 674574, 674575, 674576, 674577, 674578, 674579, + 674580, 674581, 674582, 674583, 674584, 674585, 689328, 689329, 689330, 689331, 689332, + 689333, 689334, 689335, 689336, 689337, 697978, 697979, 697980, 697981, 697982, 697983, + 697984, 697985, 697986, 697987, 697988, 697989, 697990, 697991, 697992, 697993, 697994, + 726676, 726677, 726678, 726679, 726680, 726681, 782220, 782221, 782222, 782223, 782224, + 782225, 782226, 782227, 782228, 782229, 782230, 782231, 782232, 782233, 782234, 782235, + 782236, 782237, 782238, 782239, 797574, 797575, 797576, 797577, 797578, 797579, 797580, + 797581, 797582, 804283, 804284, 804285, 822332, 822333, 822334, 822335, 822336, 831020, + 831021, 831022, 831023, 831024, 831025, 831026, 831027, 831028, 831029, 831030, 831031, + 831032, 831033, 831034, 831035, 831036, 831037, 831038, 831039, 831040, 847227, 847228, + 847229, 847230, 847231, 847232, 847233, 847234, 847235, 847236, 847237, 847238, 847239, + 847240, 847241, 847242, 847243, 847244, 847245, 857616, 857617, 857618, 857619, 857620, + 857621, 857622, 857623, 857624, 857625, 867324, 867325, 867326, 867327, 867328, 867329, + 867330, 867331, 867332, 867333, 867334, 867335, 867336, 867337, 867338, 867339, 877587, + 877588, 877589, 877590, 877591, 877592, 877593, 877594, 877595, 877596, 877597, 877598, + 877599, 877600, 877601, 877602, 877603, 877604, 877605, 877606, 877607, 877608, 877609, + 877610, 877611, 877612, 877613, 877614, 877615, 896235, 896236, 896237, 896238, 896239, + 896240, 916629, 916630, 916631, 916632, 929361, 929362, 929363, 929364, 929365, 929366, + 929367, 929368, 929369, 929370, 929371, 948695, 948696, 948697, 948698, 948699, 948700, + 948701, 948702, 949573, 949574, 957768, 957769, 957770, 957771, 957772, 957773, 957774, + 957775, 961032, 961033, 961034, 961035, 987440, 987441, 987442, 987443, 1001434, 1001435, + 1001436, 1001437, 1001438, 1001439, 1001440, 1001441, 1001442, 1001443, 1001444, 1001445, + 1001446, 1001447, 1001448, 1001449, 1001450, 1001451, 1001452, 1001453, 1001454, 1001455, + 1001456, 1001457, 1001458, 1001459, 1001460, 1009985, 1009986, 1009987, 1009988, 1009989, + 1037191, 1037192, 1037193, 1037194, 1037195, 1037196, 1037197, 1037198, 1037199, 1037200, + 1037201, 1037202, 1037203, 1037204, 1053198, 1053199, 1053200, 1053201, 1053202, 1053203, + 1053204, 1053205, 1053206, 1053207, 1053208, 1053209, 1053210, 1053211, 1053212, 1053213, + 1053214, 1053215, 1053216, 1053217, 1053218, 1053219, 1053220, 1053221, 1053222, 1053223, + 1053224, 1084019, 1084020, 1084021, 1084022, 1084023, 1084024, 1084025, 1088361, 1088362, + 1088363, 1088364, 1088365, 1088366, 1089312, 1089313, 1089314, 1089315, 1089316, 1089317, + 1089318, 1092235, 1092236, 1092237, 1092238, 1092239, 1092240, 1092241, 1092242, 1092243, + 1092244, 1102836, 1102837, 1102838, 1102839, 1102840, 1102841, 1102842, 1102843, 1102844, + 1102845, 1102846, 1102847, 1108575, 1108576, 1108577, 1108578, 1108579, 1108580, 1108581, + 1108582, 1108583, 1108584, 1108585, 1108586, 1108587, 1108588, 1108589, 1108590, 1108591, + 1108592, 1108593, 1108594, 1108595, 1108596, 1108597, 1108598, 1134091, 1134092, 1134093, + 1134094, 1134095, 1134096, 1134097, 1134098, 1134099, 1134100, 1134101, 1134102, 1134103, + 1134104, 1134105, 1134106, 1134107, 1134108, 1134109, 1134110, 1134111, 1134112, 1134113, + 1134114, 1134115, 1134116, 1134117, 1134118, 1134119, 1134120, 1134121, 1134122, 1134123, + 1134124, 1134125, 1134126, 1134127, 1134128, 1134129, 1151732, 1151733, 1151734, 1151735, + 1151736, 1151737, 1151738, 1151739, 1151740, 1151741, 1151742, 1151743, 1151744, 1151745, + 1151746, 1151747, 1199223, 1199224, 1199225, 1199226, 1203252, 1203253, 1203254, 1203255, + 1203256, 1203257, 1203258, 1203259, 1203260, 1217223, 1217224, 1217225, 1217226, 1226505, + 1226506, 1226507, 1226508, 1226509, 1226510, 1226511, 1226512, 1231411, 1231412, 1231413, + 1231414, 1231415, 1231416, 1231417, 1231418, 1231419, 1231420, 1231421, 1231422, 1231423, + 1243464, 1243465, 1243466, 1243467, 1243468, 1243469, 1243470, 1247919, 1247920, 1247921, + 1255972, 1255973, 1255974, 1255975, 1255976, 1255977, 1255978, 1255979, 1255980, 1263675, + 1263676, 1263677, 1263678, 1263679, 1277693, 1277694, 1277695, 1277696, 1277697, 1277698, + 1277699, 1277700, 1283492, 1283493, 1283494, 1283495, 1283496, 1283497, 1283498, 1283499, + 1283500, 1283501, 1283502, 1283503, 1283504, 1283505, 1283506, 1283507, 1283508, 1283509, + 1283510, 1283511, 1283512, 1283513, 1283514, 1325789, 1325790, 1325791, 1325792, 1325793, + 1325794, 1325795, 1325796, 1325797, 1325798, 1325799 + }; + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(array1); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(array2); + RoaringBitmap rrb1 = rb1.clone(); + RoaringBitmap rrb2 = rb2.clone(); + rrb1.runOptimize(); + rrb2.runOptimize(); + assertEquals(RoaringBitmap.or(rb1, rb2), RoaringBitmap.or(rrb1, rrb2)); + } + + @Test + public void testRandomLists() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(randomlists[0]); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(randomlists[1]); + RoaringBitmap rbor = RoaringBitmap.or(rb1, rb2); + assertEquals(rbor, FastAggregation.horizontal_or(rb1, rb2)); + } + + @Test + public void testRank() { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 100000; k += 7) { + rb.add(k); + } + for (int k = 100000; k < 200000; k += 1000) { + rb.add(k); + } + for (int k = 0; k < 100000; ++k) { + assertEquals(1 + k / 7, rb.rank(k)); + } + for (int k = 100000; k < 200000; ++k) { + assertEquals(1 + 100000 / 7 + 1 + (k - 100000) / 1000, rb.rank(k)); + } + } + + @Test + public void testRankBigInts() { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 100000; k += 7) { + rb.add((1 << 31) + k); + } + for (int k = 100000; k < 200000; k += 1000) { + rb.add((1 << 31) + k); + } + for (int k = 0; k < 100000; ++k) { + assertEquals(1 + k / 7, rb.rank((1 << 31) + k)); + } + for (int k = 100000; k < 200000; ++k) { + assertEquals(1 + 100000 / 7 + 1 + (k - 100000) / 1000, rb.rank((1 << 31) + k)); + } + } + + @Test + public void testSelect() { + long w = ~0l; + for (int k = 0; k < 64; ++k) { + assertEquals(k, Util.select(w, k)); + } + for (int k = 0; k < 64; ++k) { + assertEquals(k, Util.select(1l << k, 0)); + } + for (int k = 1; k < 64; ++k) { + assertEquals(k, Util.select((1l << k) + 1, 1)); + } + assertEquals(0, Util.select(1, 0)); + assertEquals(0, Util.select(5, 0)); + assertEquals(2, Util.select(5, 1)); + for (int gap = 1; gap <= 1024; gap *= 2) { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 100000; k += gap) { + rb.add(k); + } + for (int k = 0; k < 100000 / gap; ++k) { + assertEquals(k * gap, rb.select(k)); + } + } + } + + @Test + public void testSelectBigInts() { + for (int gap = 1; gap <= 1024; gap *= 2) { + RoaringBitmap rb = new RoaringBitmap(); + for (int k = 0; k < 100000; k += gap) { + rb.add((1 << 31) + k); + } + for (int k = 0; k < 100000 / gap; ++k) { + assertEquals((1 << 31) + k * gap, rb.select(k)); + } + } + } + + @Test + public void testSerialization() throws IOException, ClassNotFoundException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + final ObjectOutputStream oo = new ObjectOutputStream(bos); + rr.writeExternal(oo); + oo.close(); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + rrback.readExternal(new ObjectInputStream(bis)); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationBigInts() throws IOException, ClassNotFoundException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add((1 << 31) + k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + final ObjectOutputStream oo = new ObjectOutputStream(bos); + rr.writeExternal(oo); + oo.close(); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + rrback.readExternal(new ObjectInputStream(bis)); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerialization2() throws IOException, ClassNotFoundException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 200; k < 400; ++k) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + final ObjectOutputStream oo = new ObjectOutputStream(bos); + rr.writeExternal(oo); + oo.close(); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + rrback.readExternal(new ObjectInputStream(bis)); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerialization3() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add(k); + } + rr.add(1444000); + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray()))); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + // Deserialize DataInput with a buffer + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerialization4() throws IOException, ClassNotFoundException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 1; k <= 10000000; k += 10) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray()))); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + // Deserialize DataInput with a buffer + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationDataInputWithBuffer() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationDataInputWithBufferBigInts() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add((1 << 31) + k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationDataInputWithBuffer2() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 200; k < 400; ++k) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationDataInputWithBuffer3() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add(k); + } + rr.add(1444000); + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationDataInputWithBuffer4() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 1; k <= 10000000; k += 10) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + rrback.deserialize(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())), null); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationByteBuffer() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); + rrback.deserialize(buf); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationByteBufferBigInts() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add((1 << 31) + k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); + rrback.deserialize(buf); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationByteBuffer2() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 200; k < 400; ++k) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); + rrback.deserialize(buf); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationByteBuffer3() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 65000; k < 2 * 65000; ++k) { + rr.add(k); + } + rr.add(1444000); + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); + rrback.deserialize(buf); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSerializationByteBuffer4() throws IOException { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 1; k <= 10000000; k += 10) { + rr.add(k); + } + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // Note: you could use a file output steam instead of + // ByteArrayOutputStream + int howmuch = rr.serializedSizeInBytes(); + final DataOutputStream oo = new DataOutputStream(bos); + rr.serialize(oo); + oo.close(); + assertEquals(howmuch, bos.toByteArray().length); + final RoaringBitmap rrback = new RoaringBitmap(); + final ByteBuffer buf = ByteBuffer.wrap(bos.toByteArray()); + rrback.deserialize(buf); + assertEquals(rr.getCardinality(), rrback.getCardinality()); + assertEquals(rr, rrback); + } + + @Test + public void testSetUtilIntersection() { + char[] data1 = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}; + char[] data2 = {0, 3, 6, 9, 12, 15, 18}; + char[] result = new char[data1.length + data2.length]; + char[] expectedresult = {0, 6, 12, 18}; + int nl = Util.unsignedLocalIntersect2by2(data1, data1.length, data2, data2.length, result); + result = Arrays.copyOf(result, nl); + assertArrayEquals(expectedresult, result); + } + + @Test + public void testXORSimple() { + RoaringBitmap a = RoaringBitmap.bitmapOf(73647, 83469); + RoaringBitmap b = + RoaringBitmap.bitmapOf( + 1, 2, 3, 5, 6, 8, 9, 10, 11, 13, 14, 16, 17, 18, 19, 20, 21, 25, 26, 27, 28, 29, 30, 32, + 33, 34, 35, 36, 37, 39, 40, 41, 50, 51, 69, 79, 80, 81, 88, 89, 172); + RoaringBitmap rxor = RoaringBitmap.xor(a, b); + RoaringBitmap ror = RoaringBitmap.or(a, b); + assertEquals(rxor, ror); + } + + @Test + public void trimArrayContainerCardinalityTest() { + final ArrayContainer ac = new ArrayContainer(); + ac.trim(); + for (char k = 0; k < 100; ++k) { + ac.add(k); + ac.trim(); + assertEquals(ac.getCardinality(), k + 1); + } + for (char k = 0; k < 100; ++k) { + ac.add(k); + ac.trim(); + assertEquals(ac.getCardinality(), 100); + } + } + + boolean validate(BitmapContainer bc, ArrayContainer ac) { + // Checking the cardinalities of each container + + if (bc.getCardinality() != ac.getCardinality()) { + System.out.println("cardinality differs"); + return false; + } + // Checking that the two containers contain the same values + int counter = 0; + + int i = bc.nextSetBit(0); + while (i >= 0) { + ++counter; + if (!ac.contains((char) i)) { + System.out.println("content differs"); + System.out.println(bc); + System.out.println(ac); + return false; + } + i = bc.nextSetBit(i + 1); + } + + // checking the cardinality of the BitmapContainer + return counter == bc.getCardinality(); + } + + @Test + public void trimTest() { + // with bitmap containing 4k containers + RoaringBitmap rb = new RoaringBitmap(); + for (int i = 0; i < 4000; i++) { + rb.add((1 << 16) * i); + } + + rb.trim(); + + int wastedBytes = 0; + final int javaReferenceSize = 4; // or 8 depending on factors + RoaringArray ra = rb.highLowContainer; + wastedBytes += Short.BYTES * (ra.keys.length - ra.size); + wastedBytes += javaReferenceSize * (ra.values.length - ra.size); + ContainerPointer cp = ra.getContainerPointer(); + while (cp.getContainer() != null) { + if (cp.isBitmapContainer()) { + ; // nothing wasted + } else if (cp.isRunContainer()) { + ; // not able to access information about wasted bytes + } else { + ArrayContainer ac = (ArrayContainer) cp.getContainer(); + wastedBytes += Short.BYTES * (ac.content.length - ac.cardinality); + } + cp.advance(); + } + assertEquals(0, wastedBytes); + } + + @Test + public void xorBigIntsTest() { + RoaringBitmap rb = new RoaringBitmap(); + RoaringBitmap rb2 = new RoaringBitmap(); + HashSet hs = new HashSet(); + + for (int i = 1 << 31; i < (1 << 31) + 65536; i += 2) { + hs.add(i); + rb.add(i); + } + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + rb.add(i); + } + for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 5) { + rb.add(i); + } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 7) { + rb.add(i); + } + for (int i = (1 << 31) + 11 * 65536; i < (1 << 31) + 12 * 65536; i += 6) { + hs.add(i); + rb.add(i); + } + + for (int i = (1 << 31) + 3 * 65536; i < (1 << 31) + 4 * 65536; i += 3) { + rb2.add(i); + } + for (int i = (1 << 31) + 5 * 65536; i < (1 << 31) + 7 * 65536; i += 5) { + rb2.add(i); } - - @Test - public void testIsHammingSimilar_AtStart() { - // similar bitmaps in the first container - RoaringBitmap baseline = RoaringBitmap.bitmapOf(2, 4, 8, 1 << 17, 1 << 22); - assertTrue(baseline.isHammingSimilar(baseline, 0)); - RoaringBitmap other = baseline.clone(); - other.flip(0L, 9); - for (int i = 0; i < 9; ++i) { - assertFalse(baseline.isHammingSimilar(other, i)); - } - assertTrue(baseline.isHammingSimilar(other, 9)); - other.add(0L, 9L); - for (int i = 0; i < 6; ++i) { - assertFalse(baseline.isHammingSimilar(other, i)); - } - assertTrue(baseline.isHammingSimilar(other, 6)); - } - - @Test - public void testHammingSimilarity_BigVsSmall() { - RoaringBitmap big = new RoaringBitmap(); - big.add(1, 2, 3, 4); - big.add(1L << 17, 1L << 30); - big.flip((1 << 17) | (1 << 16)); - for (int i = 1 << 18; i < 1 << 19; ++i) { - if (i % 3 == 0) { - big.flip(i); - } - } - RoaringBitmap small = RoaringBitmap.bitmapOf(1, 2, 3, 4); - assertFalse(small.isHammingSimilar(big, 1)); - assertFalse(big.isHammingSimilar(small, 1)); - } - - @Test - public void testHammingSimilarity_Shifted() { - RoaringBitmap baseline = RoaringBitmap.bitmapOf(1, 2, 3, 4); - RoaringBitmap shifted = RoaringBitmap.bitmapOf((1 << 17) + 1, (1 << 17) + 2, (1 << 17) + 3, - (1 << 17) + 4); - assertFalse(baseline.isHammingSimilar(shifted, 0)); - } - - @Test - public void testIsHammingSimilar_AtEnd() { - // reject bitmaps that are identical for many chunks but differ at the end - RoaringBitmap baseline = new RoaringBitmap(); - for (int i = 0; i < 1 << 15; ++i) { - if (i % 3 == 0) { - baseline.add(i); - } - } - baseline.add((1L << 16) + 1, 1L << 18); - baseline.add((1L << 19) + 1, 1L << 20); - baseline.add((1 << 21) + 1); - baseline.add((1 << 21) + 3); - baseline.add((1 << 21) + 5); - assertEquals(baseline.getCardinality(), RoaringBitmap.andCardinality(baseline, baseline)); - assertTrue(baseline.isHammingSimilar(baseline, 0)); - RoaringBitmap other = baseline.clone(); - other.flip((1 << 21) + 1); - assertTrue(baseline.isHammingSimilar(other, 1)); - assertFalse(baseline.isHammingSimilar(other, 0)); - other.add((1 << 21) + 2); - assertTrue(baseline.isHammingSimilar(other, 2)); - assertFalse(baseline.isHammingSimilar(other, 1)); - other.flip((1 << 21) + 3); - assertTrue(baseline.isHammingSimilar(other, 3)); - assertFalse(baseline.isHammingSimilar(other, 2)); - } - - @Test - public void testAndCardinality() { - RoaringBitmap baseline = new RoaringBitmap(); - baseline.add((1L << 16) + 1, 1L << 18); - baseline.add((1L << 19) + 1, 1L << 20); - baseline.add((1 << 21) + 1); - baseline.add((1 << 21) + 3); - baseline.add((1 << 21) + 5); - assertEquals(baseline, RoaringBitmap.and(baseline, baseline)); - assertEquals(baseline.getCardinality(), RoaringBitmap.andCardinality(baseline, baseline)); - } - - - @Test - public void testRankOverflow() { - assertEquals(0, RoaringBitmap.bitmapOf(65537).rank(1)); - assertEquals(1, RoaringBitmap.bitmapOf(65537).rank(65537)); - assertEquals(1, RoaringBitmap.bitmapOf(65537).rank(65538)); - } - - - @Test - public void testNegativeAdd() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(-7); - - assertEquals("{4294967289}", bitmap.toString()); - } - - @Test - public void testNegative_last() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(-7); - bitmap.add(777); - - assertEquals(-7, bitmap.last()); - } - - @Test - public void testFirstLastSigned() { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1_111_111, 3_333_333); - assertEquals(1_111_111, bitmap.firstSigned()); - assertEquals(3_333_333, bitmap.lastSigned()); - - bitmap = RoaringBitmap.bitmapOf(-3_333_333, 3_333_333); - assertEquals(-3_333_333, bitmap.firstSigned()); - assertEquals(3_333_333, bitmap.lastSigned()); - - bitmap = RoaringBitmap.bitmapOf(-3_333_333, -1_111_111); - assertEquals(-3_333_333, bitmap.firstSigned()); - assertEquals(-1_111_111, bitmap.lastSigned()); - - bitmap = RoaringBitmap.bitmapOfRange(0, 1L << 32); - assertEquals(Integer.MIN_VALUE, bitmap.firstSigned()); - assertEquals(Integer.MAX_VALUE, bitmap.lastSigned()); - } - - @ParameterizedTest - @ValueSource(ints = {Integer.MIN_VALUE, -65_536, 0, 65_536, Integer.MAX_VALUE}) - public void testFirstLastSigned_SingleValueBitmap(int value) { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(value); - assertEquals(value, bitmap.firstSigned()); - assertEquals(value, bitmap.lastSigned()); - } - - @Test - public void testContainsRange_ContiguousBitmap() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(0L, 1_000_000L); - assertTrue(bitmap.contains(1L, 999_999L)); - assertFalse(bitmap.contains(1L, 1_000_001L)); - bitmap.flip(500_000); - assertFalse(bitmap.contains(1L, 999_999L)); - bitmap.flip(500_000); - bitmap.flip(500_000L, 600_000L); - assertFalse(bitmap.contains(1L, 999_999L)); - assertTrue(bitmap.contains(0L, 500_000L)); - assertFalse(bitmap.contains(2_000_001L, 10_000_000L)); - } - - @Test - public void testContainsRange_SmallBitmap() { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6); - assertTrue(bitmap.contains(1, 6)); - assertTrue(bitmap.contains(1, 5)); - assertTrue(bitmap.contains(2, 6)); - assertTrue(bitmap.contains(2, 7)); - assertFalse(bitmap.contains(2, 8)); - assertFalse(bitmap.contains(0, 6)); - assertFalse(bitmap.contains(0, 1)); - assertFalse(bitmap.contains(6, 10)); - assertFalse(bitmap.contains(7, 1 << 16)); - assertFalse(bitmap.contains(1 << 17, 1 << 19)); - } - - @Test - public void testContainsRange_DirtyBitmap() { - RoaringBitmapWriter writer = writer().constantMemory().get(); - IntStream.range(0, 1_000_000) - .map(i -> i * 2) - .forEach(writer::add); - writer.flush(); - RoaringBitmap bitmap = writer.getUnderlying(); - assertFalse(bitmap.contains(0L, 2_000_000L)); - assertFalse(bitmap.contains(0L, 2L)); - assertTrue(bitmap.contains(0L, 1L)); - assertTrue(bitmap.contains(1L << 10, 1 | (1L << 10))); - assertFalse(bitmap.contains(1L << 31, 1L << 32)); - } - - @Test - public void addoffset() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(10); - rb.add(0xFFFF); - rb.add(0x010101); - for (int i = 100000; i < 200000; i += 4) { - rb.add(i); - } - rb.add(400000L, 1400000L); - for (int offset = 3; offset < 1000000; offset *= 3) { - RoaringBitmap rboff = RoaringBitmap.addOffset(rb, offset); - IntIterator i = rb.getIntIterator(); - IntIterator j = rboff.getIntIterator(); - while (i.hasNext() && j.hasNext()) { - int val1 = i.next() + offset; - int val2 = j.next(); - assertEquals(val1, val2); - } - assertEquals(i.hasNext(), j.hasNext()); - } - for (int offset = 1024; offset < 1000000; offset *= 2) { - RoaringBitmap rboff = RoaringBitmap.addOffset(rb, offset); - IntIterator i = rb.getIntIterator(); - IntIterator j = rboff.getIntIterator(); - while (i.hasNext() && j.hasNext()) { - assertEquals(i.next() + offset, j.next()); - } - assertEquals(i.hasNext(), j.hasNext()); - } + for (int i = (1 << 31) + 9 * 65536; i < (1 << 31) + 10 * 65536; i += 7) { + rb2.add(i); } - - @Test - public void issue418() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(0); - assertEquals(rb.contains(0), true); - assertEquals(rb.getCardinality(), 1); - long vals[] = { 100, 0xFFFF0000L, 0xFFFF0001L }; - for(long s : vals) { - RoaringBitmap shifted = RoaringBitmap.addOffset(rb, s); - System.out.println("moved "+shifted); - assertEquals(shifted.contains((int)s), true); - assertEquals(shifted.getCardinality(), 1); - System.out.println("moving back by "+(-s)); - - shifted = RoaringBitmap.addOffset(shifted, -s); - System.out.println("back "+shifted); - - assertEquals(shifted.contains(0), true); - assertEquals(shifted.getCardinality(), 1); - } + for (int i = (1 << 31) + 13 * 65536; i < (1 << 31) + 14 * 65536; i += 2) { + hs.add(i); + rb2.add(i); } - @Test - public void addNegativeOffset() { - final RoaringBitmap rb = new RoaringBitmap(); - rb.add(10); - rb.add(0xFFFF); - rb.add(0x010101); - for (int i = 100000; i < 200000; i += 4) { - rb.add(i); - } - rb.add(400000L, 1400000L); - for (int offset = 3; offset < 1000000; offset *= 3) { - RoaringBitmap rboffpos = RoaringBitmap.addOffset(rb, offset); - RoaringBitmap rboff = RoaringBitmap.addOffset(rboffpos, -offset); - - IntIterator i = rb.getIntIterator(); - IntIterator j = rboff.getIntIterator(); - while (i.hasNext() && j.hasNext()) { - int val1 = i.next(); - int val2 = j.next(); - if (val1 != val2) - assertEquals(val1, val2); - } - assertEquals(i.hasNext(), j.hasNext()); - } - for (int offset = 1024; offset < 1000000; offset *= 2) { - RoaringBitmap rboffpos = RoaringBitmap.addOffset(rb, offset); - RoaringBitmap rboff = RoaringBitmap.addOffset(rboffpos, -offset); - IntIterator i = rb.getIntIterator(); - IntIterator j = rboff.getIntIterator(); - while (i.hasNext() && j.hasNext()) { - assertEquals(i.next(), j.next()); - } - assertEquals(i.hasNext(), j.hasNext()); - } - } + RoaringBitmap rbxor = RoaringBitmap.xor(rb, rb2); + Object[] correct = hs.toArray(); + Arrays.sort(correct); + Integer[] resxor = ArrayUtils.toObject(rbxor.toArray()); + assertArrayEquals(correct, resxor); + } - @Test - public void testNextValue() { - RoaringBitmap bitmap = SeededTestData.TestDataSet.testCase() - .withRunAt(0) - .withBitmapAt(1) - .withArrayAt(2) - .withRunAt(3) - .withBitmapAt(4) - .withArrayAt(5) - .build(); - - BitSet bitset = new BitSet(); - bitmap.forEach((IntConsumer) bitset::set); - long b1 = 0; - int b2 = 0; - while (b1 >= 0 && b2 >= 0) { - b1 = bitmap.nextValue((int) b1 + 1); - b2 = bitset.nextSetBit(b2 + 1); - assertEquals(b1, b2); - } + @Test + public void XORtest() { + final RoaringBitmap rr = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr.add(k); } - - @Test - public void testPreviousValueLimit() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(1); - assertEquals(-1l, bitmap.previousValue(0)); - } - - @Test - public void testPreviousAbsentValueLimit() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(0); - assertEquals(-1L, bitmap.previousAbsentValue(0)); - } - - @Test - public void testNextValueLimit() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(0xffffffff-1); - assertEquals(-1L, bitmap.nextValue(0xffffffff)); - } - - @Test - public void testNextAbsentValueLimit() { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.add(-1); - assertEquals(-1L, bitmap.nextAbsentValue(-1)); - } - - @Test - public void testPreviousValue() { - RoaringBitmap bitmap = SeededTestData.TestDataSet.testCase() - .withRunAt(0) - .withBitmapAt(1) - .withArrayAt(2) - .withRunAt(3) - .withBitmapAt(4) - .withArrayAt(5) - .build(); - - BitSet bitset = new BitSet(); - bitmap.forEach((IntConsumer) bitset::set); - long b1 = Util.toUnsignedLong(bitmap.last()); - int b2 = bitset.previousSetBit(Integer.MAX_VALUE); - int i = bitmap.getCardinality(); - while (b1 > 0 && b2 > 0) { - assertEquals(b1, b2); - b1 = bitmap.previousValue((int) (b1 - 1)); - b2 = bitset.previousSetBit(b2 - 1); - assertEquals(b1, b2, "mismatch at " + i + "(bitset=" + b2 + ", rb=" + b1 + ")"); - --i; - } + for (int k = 65536; k < 65536 + 4000; ++k) { + rr.add(k); } - - @Test - public void testPreviousValueRegression() { - // see https://github.com/RoaringBitmap/RoaringBitmap/issues/564 - assertEquals(-1, RoaringBitmap.bitmapOf(27399807).previousValue(403042)); - assertEquals(-1, RoaringBitmap.bitmapOf().previousValue(403042)); + for (int k = 3 * 65536; k < 3 * 65536 + 9000; ++k) { + rr.add(k); } - - @Test - public void testPreviousValue_AbsentTargetContainer() { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(-1, 2, 3, 131072); - assertEquals(3, bitmap.previousValue(65536)); - assertEquals(131072, bitmap.previousValue(Integer.MAX_VALUE)); - assertEquals(131072, bitmap.previousValue(-131072)); - - bitmap = RoaringBitmap.bitmapOf(131072); - assertEquals(-1, bitmap.previousValue(65536)); + for (int k = 4 * 65535; k < 4 * 65535 + 7000; ++k) { + rr.add(k); } - - @Test - public void testPreviousValue_LastReturnedAsUnsignedLong() { - RoaringBitmap bitmap = RoaringBitmap.bitmapOf(-650002, -650001, -650000); - assertEquals(Util.toUnsignedLong(-650000), bitmap.previousValue(-1)); + for (int k = 6 * 65535; k < 6 * 65535 + 10000; ++k) { + rr.add(k); } - - @Test - public void testRangeCardinalityAtBoundary() { - // See https://github.com/RoaringBitmap/RoaringBitmap/issues/285 - RoaringBitmap r = new RoaringBitmap(); - r.add(66236); - assertEquals(1, r.rangeCardinality(60000, 70000)); + for (int k = 8 * 65535; k < 8 * 65535 + 1000; ++k) { + rr.add(k); } - - @Test - public void testNextValueArray() { - RoaringBitmap r = new RoaringBitmap(); - r.add(0, 1, 2, 4, 6); - assertEquals(-1, r.nextValue(7)); + for (int k = 9 * 65535; k < 9 * 65535 + 30000; ++k) { + rr.add(k); } - @Test - public void regressionTestEquals370() { - // see https://github.com/RoaringBitmap/RoaringBitmap/issues/370 - int[] a = {239, 240, 241, 242, 243, 244, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, 413, 420, 421, 422, 509, 510, 511, 512, 513, 514, 539, 540, 541, 542, 543, 544, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 624, 625, 634, 635, 636, 649, 650, 651, 652, 653, 654, 714, 715, 716, 718, 719, 720, 721, 722, 723, 724, 725, 726, 728, 729, 730, 731, 732, 733, 734, 735, 736, 739, 740, 741, 742, 743, 744, 771, 772, 773}; - int[] b = {239, 240, 241, 242, 243, 244, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, 413, 420, 421, 422, 509, 510, 511, 512, 513, 514, 539, 540, 541, 542, 543, 544, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 578, 579, 580, 581, 582, 583, 584, 585, 586, 607, 608, 634, 635, 636, 649, 650, 651, 652, 653, 654, 714, 715, 716, 718, 719, 720, 721, 722, 723, 724, 725, 726, 728, 729, 730, 731, 732, 733, 734, 735, 736, 739, 740, 741, 742, 743, 744, 771, 772, 773}; - - RoaringBitmap rbA = RoaringBitmap.bitmapOf(a); - RoaringBitmap rbB = RoaringBitmap.bitmapOf(b); - - assertNotEquals(rbB, rbA); - rbA.runOptimize(); - assertNotEquals(rbB, rbA); - rbB.runOptimize(); - assertNotEquals(rbB, rbA); + final RoaringBitmap rr2 = new RoaringBitmap(); + for (int k = 4000; k < 4256; ++k) { + rr2.add(k); } - - @Test - public void regressionTestRemove377() { - // https://github.com/RoaringBitmap/RoaringBitmap/issues/377 - RoaringBitmap map = new RoaringBitmap(); - map.add(0L, 64L); - for (int i = 0; i < 64; i++) { - if (i != 30 && i != 32) { - map.remove(i); - } - } - map.remove(0L, 31L); - assertFalse(map.contains(30)); - assertTrue(map.contains(32)); + for (int k = 65536; k < 65536 + 4000; ++k) { + rr2.add(k); } - - @Test - public void invalidCookieBuffer() { - assertThrows(IOException.class, () -> { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.deserialize(ByteBuffer.allocate(4)); - }); + for (int k = 3 * 65536 + 2000; k < 3 * 65536 + 6000; ++k) { + rr2.add(k); } - - @Test - public void invalidCookieDataInput() { - assertThrows(IOException.class, () -> { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.deserialize(new DataInputStream(new ByteArrayInputStream(new byte[4]))); - }); + for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { + rr2.add(k); } - - @Test - public void invalidCookieDataInputWithBuffer() { - assertThrows(IOException.class, () -> { - RoaringBitmap bitmap = new RoaringBitmap(); - bitmap.deserialize(new DataInputStream(new ByteArrayInputStream(new byte[4])), new byte[8]); - }); + for (int k = 7 * 65535; k < 7 * 65535 + 1000; ++k) { + rr2.add(k); } - - @Test - public void testCardinalityExceeds() { - RoaringBitmap bitmap = new RoaringBitmap(); - long runLength = 20_000L; - bitmap.add(0L, runLength); - for (int i = (1 << 16) + 1; i < 1 << 17; i+= 2) { - bitmap.add(i); - } - long bitmapCount = 1 << 15; - bitmap.add((1 << 17) | 1); - bitmap.add((1 << 17) | 2); - bitmap.add((1 << 17) | 3); - long arrayCount = 3; - bitmap.runOptimize(); - assertFalse(bitmap.cardinalityExceeds(Integer.MAX_VALUE)); - assertFalse(bitmap.cardinalityExceeds(runLength + bitmapCount + arrayCount)); - assertTrue(bitmap.cardinalityExceeds(runLength + bitmapCount + 1)); - assertTrue(bitmap.cardinalityExceeds(runLength + bitmapCount - 1)); - assertTrue(bitmap.cardinalityExceeds(runLength - 1)); - } - - - @Test - public void testWithYourself() { - RoaringBitmap b1 = RoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10); - b1.runOptimize(); - b1.or(b1); - assertTrue(b1.equals(RoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10))); - b1.xor(b1); - assertTrue(b1.isEmpty()); - b1 = RoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10); - b1.and(b1); - assertTrue(b1.equals(RoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10))); - b1.andNot(b1); - assertTrue(b1.isEmpty()); - } - - @Test - public void testIssue566() { - RoaringBitmap roaringBitMap = new RoaringBitmap(); - BitSet bitSet = new BitSet(5000); - double prob = 0.001; - Random random = new Random(); - for (int i = 0; i < 5000; i++) { - if (random.nextDouble() < prob) { - bitSet.set(i); - roaringBitMap.add(i); - } - } - long roaringbits = roaringBitMap.getSizeInBytes() * 8; - long bitsetbits = bitSet.size(); - System.out.println("[issue566] cardinality: "+ roaringBitMap.getCardinality()); - System.out.println("[issue566] bitset bits: "+ bitsetbits); - System.out.println("[issue566] bitset bits per entry: " + bitsetbits * 1.0 / bitSet.cardinality()); - System.out.println("[issue566] RoaringBitmap bits: " + roaringbits); - System.out.println("[issue566] RoaringBitmap bits per entry: " + roaringbits * 1.0 / roaringBitMap.getCardinality()); - assertTrue(roaringbits < bitsetbits); - } - - @Test - public void issue623() { - RoaringBitmap r = new RoaringBitmap(); - r.add(65535); - r.add(65535+1); - assertTrue(r.contains(65535)); - assertTrue(r.contains(65535 + 1)); - assertTrue(r.contains(65535L, 65535L + 1)); - for (long i = 1; i <= 10_000_000; i++) { - r.add(i, i + 1); - } - for (long i = 1; i <= 10_000_000; i++) { - assertTrue(r.contains(i, i + 1)); - } + for (int k = 10 * 65535; k < 10 * 65535 + 5000; ++k) { + rr2.add(k); } + final RoaringBitmap correct = RoaringBitmap.xor(rr, rr2); + rr.xor(rr2); + assertEquals(correct, rr); + } - @Test - public void test1235() { - RoaringBitmap r = RoaringBitmap.bitmapOf(1, 2, 3, 5); - r.flip(4); - assertEquals(r, RoaringBitmap.bitmapOf(1, 2, 3, 4, 5)); + @Test + public void xortest1() { + final HashSet V1 = new HashSet(); + final HashSet V2 = new HashSet(); + + final RoaringBitmap rr = new RoaringBitmap(); + final RoaringBitmap rr2 = new RoaringBitmap(); + // For the first 65536: rr2 has a bitmap container, and rr has + // an array container. + // We will check the union between a BitmapCintainer and an + // arrayContainer + for (int k = 0; k < 4000; ++k) { + rr2.add(k); + if (k < 3500) { + V1.add(k); + } + } + for (int k = 3500; k < 4500; ++k) { + rr.add(k); + } + for (int k = 4000; k < 65000; ++k) { + rr2.add(k); + if (k >= 4500) { + V1.add(k); + } } - @Test - public void test2345() { - RoaringBitmap r = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5); - r.flip(1); - assertEquals(r, RoaringBitmap.bitmapOf(2, 3, 4, 5)); + // In the second node of each roaring bitmap, we have two bitmap + // containers. + // So, we will check the union between two BitmapContainers + for (int k = 65536; k < 65536 + 30000; ++k) { + rr.add(k); } + for (int k = 65536; k < 65536 + 50000; ++k) { + rr2.add(k); + if (k >= 65536 + 30000) { + V1.add(k); + } + } - @Test - public void testSelectRange() { - RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 1000000); - for(int i = 1; i <= 1000000; i+= 1000) { - for(int j = i; j <= 1000000; j+= 1000) { - RoaringBitmap rr = r.selectRange(i, j); - assertEquals(rr, RoaringBitmap.bitmapOfRange(i, j)); - } - } + // In the 3rd node of each Roaring Bitmap, we have an + // ArrayContainer. So, we will try the union between two + // ArrayContainers. + for (int k = 4 * 65535; k < 4 * 65535 + 1000; ++k) { + rr.add(k); + if (k >= 4 * 65535 + 800) { + V1.add(k); + } } - @Test - public void testContainerSizeRoaringBitmapMultiple() { - RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 1000000); - assertEquals(16, r.getContainerCount()); + for (int k = 4 * 65535; k < 4 * 65535 + 800; ++k) { + rr2.add(k); } - @Test - public void testContainerSizeRoaringBitmapSingle() { - RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 100); - assertEquals(1, r.getContainerCount()); + + // For the rest, we will check if the union will take them in + // the result + for (int k = 6 * 65535; k < 6 * 65535 + 1000; ++k) { + rr.add(k); + V1.add(k); } + + for (int k = 7 * 65535; k < 7 * 65535 + 2000; ++k) { + rr2.add(k); + V1.add(k); + } + + final RoaringBitmap rrxor = RoaringBitmap.xor(rr, rr2); + boolean valide = true; + + // Si tous les elements de rror sont dans V1 et que tous les + // elements de + // V1 sont dans rror(V2) + // alors V1 == rror + final Object[] tab = V1.toArray(); + final Vector vector = new Vector(); + for (Object aTab : tab) { + vector.add((Integer) aTab); + } + + for (final int i : rrxor.toArray()) { + if (!vector.contains(i)) { + valide = false; + } + V2.add(i); + } + for (int i = 0; i < V1.size(); i++) { + if (!V2.contains(vector.elementAt(i))) { + valide = false; + } + } + + assertTrue(valide); + } + + @Test + public void xortest4() { + final RoaringBitmap rb = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + + for (int i = 0; i < 200000; i += 4) { + rb2.add(i); + } + for (int i = 200000; i < 400000; i += 14) { + rb2.add(i); + } + final int rb2card = rb2.getCardinality(); + + // check or against an empty bitmap + final RoaringBitmap xorresult = RoaringBitmap.xor(rb, rb2); + final RoaringBitmap off = RoaringBitmap.or(rb2, rb); + assertEquals(xorresult, off); + + assertEquals(rb2card, xorresult.getCardinality()); + + for (int i = 500000; i < 600000; i += 14) { + rb.add(i); + } + for (int i = 200000; i < 400000; i += 3) { + rb2.add(i); + } + // check or against an empty bitmap + final RoaringBitmap xorresult2 = RoaringBitmap.xor(rb, rb2); + assertEquals(rb2card, xorresult.getCardinality()); + + assertEquals(rb2.getCardinality() + rb.getCardinality(), xorresult2.getCardinality()); + rb.xor(rb2); + assertEquals(xorresult2, rb); + } + + // is this better in testRange? + @Test + public void testRangedOr() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add(val1); + set1.add(val1); + + rb2.add(val2); + set2.add(val2); + } + Set unionSet = new TreeSet<>(); + unionSet.addAll(set1); + unionSet.addAll(set2); + for (int iter = 0; iter < NUM_ITER; iter++) { + int rangeStart = random.nextInt(length - 1); + // +1 to ensure rangeEnd >rangeStart, may + int rangeLength = random.nextInt(length - rangeStart) + 1; + int rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = rangeStart; i < rangeEnd; i++) { + if (unionSet.contains(i)) { + expectedResultSet.add(i); + } + } + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); + RoaringBitmap result = + RoaringBitmap.or(list.iterator(), (long) rangeStart, (long) rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedOrBigInts() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add((1 << 31) + val1); + set1.add((1 << 31) + val1); + + rb2.add((1 << 31) + val2); + set2.add((1 << 31) + val2); + } + Set unionSet = new TreeSet<>(); + unionSet.addAll(set1); + unionSet.addAll(set2); + for (int iter = 0; iter < NUM_ITER; iter++) { + long rangeStart1 = random.nextInt(length - 1); + long rangeStart = (1L << 31) + rangeStart1; + long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; + long rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { + if (unionSet.contains(i)) { + expectedResultSet.add(i); + } + } + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); + RoaringBitmap result = RoaringBitmap.or(list.iterator(), rangeStart, rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedAnd() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add(val1); + set1.add(val1); + + rb2.add(val2); + set2.add(val2); + } + Set intersectionSet = new TreeSet<>(set1); + intersectionSet.retainAll(set2); + for (int iter = 0; iter < NUM_ITER; iter++) { + int rangeStart = random.nextInt(length - 1); + // +1 to ensure rangeEnd >rangeStart, may + int rangeLength = random.nextInt(length - rangeStart) + 1; + int rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = rangeStart; i < rangeEnd; i++) { + if (intersectionSet.contains(i)) { + expectedResultSet.add(i); + } + } + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); + RoaringBitmap result = + RoaringBitmap.and(list.iterator(), (long) rangeStart, (long) rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedAndBigInts() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add((1 << 31) + val1); + set1.add((1 << 31) + val1); + + rb2.add((1 << 31) + val2); + set2.add((1 << 31) + val2); + } + Set intersectionSet = new TreeSet<>(set1); + intersectionSet.retainAll(set2); + for (int iter = 0; iter < NUM_ITER; iter++) { + long rangeStart1 = random.nextInt(length - 1); + long rangeStart = (1L << 31) + rangeStart1; + long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; + long rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { + if (intersectionSet.contains(i)) { + expectedResultSet.add(i); + } + } + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); + RoaringBitmap result = RoaringBitmap.and(list.iterator(), rangeStart, rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedXor() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add(val1); + set1.add(val1); + + rb2.add(val2); + set2.add(val2); + } + Set xorSet = new TreeSet<>(); + xorSet.addAll(set1); + xorSet.addAll(set2); + Set andSet = new TreeSet<>(set1); + andSet.retainAll(set2); + + xorSet.removeAll(andSet); + for (int iter = 0; iter < NUM_ITER; iter++) { + int rangeStart = random.nextInt(length - 1); + // +1 to ensure rangeEnd >rangeStart, may + int rangeLength = random.nextInt(length - rangeStart) + 1; + int rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = rangeStart; i < rangeEnd; i++) { + if (xorSet.contains(i)) { + expectedResultSet.add(i); + } + } + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); + RoaringBitmap result = + RoaringBitmap.xor(list.iterator(), (long) rangeStart, (long) rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedXorBigInts() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add((1 << 31) + val1); + set1.add((1 << 31) + val1); + + rb2.add((1 << 31) + val2); + set2.add((1 << 31) + val2); + } + Set xorSet = new TreeSet<>(); + xorSet.addAll(set1); + xorSet.addAll(set2); + Set andSet = new TreeSet<>(set1); + andSet.retainAll(set2); + + xorSet.removeAll(andSet); + for (int iter = 0; iter < NUM_ITER; iter++) { + long rangeStart1 = random.nextInt(length - 1); + long rangeStart = (1L << 31) + rangeStart1; + long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; + long rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { + if (xorSet.contains(i)) { + expectedResultSet.add(i); + } + } + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); + RoaringBitmap result = RoaringBitmap.xor(list.iterator(), rangeStart, rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedAndNot() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add(val1); + set1.add(val1); + + rb2.add(val2); + set2.add(val2); + } + Set andNotSet = new TreeSet<>(); + for (int i : set1) { + if (!set2.contains(i)) { + andNotSet.add(i); + } + } + for (int iter = 0; iter < NUM_ITER; iter++) { + int rangeStart = random.nextInt(length - 1); + // +1 to ensure rangeEnd >rangeStart, may + int rangeLength = random.nextInt(length - rangeStart) + 1; + int rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = rangeStart; i < rangeEnd; i++) { + if (andNotSet.contains(i)) { + expectedResultSet.add(i); + } + } + RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, (long) rangeStart, (long) rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testRangedAndNotBigInts() { + int length = 1000; + int NUM_ITER = 10; + Random random = new Random(1234); // please use deterministic tests + for (int test = 0; test < 50; ++test) { + final RoaringBitmap rb1 = new RoaringBitmap(); + final RoaringBitmap rb2 = new RoaringBitmap(); + Set set1 = new HashSet<>(); + Set set2 = new HashSet<>(); + int numBitsToSet = length / 2; + for (int i = 0; i < numBitsToSet; i++) { + int val1 = random.nextInt(length); + int val2 = random.nextInt(length); + + rb1.add((1 << 31) + val1); + set1.add((1 << 31) + val1); + + rb2.add((1 << 31) + val2); + set2.add((1 << 31) + val2); + } + Set andNotSet = new TreeSet<>(); + for (int i : set1) { + if (!set2.contains(i)) { + andNotSet.add(i); + } + } + for (int iter = 0; iter < NUM_ITER; iter++) { + long rangeStart1 = random.nextInt(length - 1); + long rangeStart = (1L << 31) + rangeStart1; + long rangeLength = random.nextInt((int) (length - rangeStart1)) + 1; + long rangeEnd = rangeStart + rangeLength; + Set expectedResultSet = new TreeSet<>(); + for (int i = (int) rangeStart; i < (int) rangeEnd; i++) { + if (andNotSet.contains(i)) { + expectedResultSet.add(i); + } + } + RoaringBitmap result = RoaringBitmap.andNot(rb1, rb2, rangeStart, rangeEnd); + Set actualResultSet = new TreeSet<>(); + IntIterator intIterator = result.getIntIterator(); + while (intIterator.hasNext()) { + actualResultSet.add(intIterator.next()); + } + assertEquals(expectedResultSet, actualResultSet); + } + } + } + + @Test + public void testOr() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5); + RoaringBitmap rb2 = RoaringBitmap.bitmapOf(4, 7, 8, 9); + RoaringBitmap rb3 = RoaringBitmap.bitmapOf(12, 13, 15, 19, 21); + RoaringBitmap rb4 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9); + RoaringBitmap rb5 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 12, 13, 15, 19, 21); + assertEquals(rb4, RoaringBitmap.lazyorfromlazyinputs(rb1, rb2)); + assertEquals(rb5, RoaringBitmap.or(rb1, rb2, rb3)); + } + + @Test + public void testLazyOr() { + RoaringBitmap rb1 = RoaringBitmap.bitmapOf(1 << 16, 1 << 18, 1 << 19); + rb1.lazyor(RoaringBitmap.bitmapOf(4, 7, 8, 9)); + rb1.lazyor(RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 1 << 16, 1 << 17, 1 << 20)); + RoaringBitmap rb2 = + RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20); + assertEquals(rb2, rb1); + } + + @Test + public void testFirstLast_CreateSparseContainers() { + RoaringBitmap rb = new RoaringBitmap(); + for (int i = 0; i < 20; ++i) { + int x = 1 << i; + rb.add(x); + assertEquals(1, rb.first()); + assertEquals(x, rb.last()); + } + } + + @Test + public void testFirstLast_CreateSparseContainersAfterRun() { + RoaringBitmap rb = new RoaringBitmap(); + rb.add(1L, 1 << 14); + for (int i = 18; i < 31; ++i) { + int x = 1 << i; + rb.add(x); + assertEquals(1, rb.first()); + assertEquals(x, rb.last()); + } + } + + @Test + public void testFirstLast_AfterLazyMutation1() { + RoaringBitmap rb = new RoaringBitmap(); + rb.add(1, 3, 5, 7); + assertEquals(1, rb.first()); + assertEquals(7, rb.last()); + RoaringBitmap mutator = new RoaringBitmap(); + mutator.add(0, 2, 4, 6, 8); + rb.lazyor(mutator); + assertEquals(0, rb.first()); + assertEquals(8, rb.last()); + } + + @Test + public void testFirstLast_AfterLazyMutation2() { + RoaringBitmap rb = new RoaringBitmap(); + Iterable willForceUseOfBitmapContainer = + Iterables.filter( + ContiguousSet.create(Range.openClosed(0, 1 << 16), DiscreteDomain.integers()), + new Predicate() { + @Override + public boolean apply(Integer input) { + return input % 3 == 0; + } + }); + int max = 0; + for (Integer i : willForceUseOfBitmapContainer) { + rb.add(i); + max = i; + } + assertEquals(3, rb.first()); + assertEquals(max, rb.last()); + RoaringBitmap mutator = new RoaringBitmap(); + mutator.add(0, 2, 4, 6, 8); + rb.lazyor(mutator); + assertEquals(0, rb.first()); + assertEquals(max, rb.last()); + } + + @Test + public void testEmptyFirst() { + assertThrows(NoSuchElementException.class, () -> new RoaringBitmap().first()); + } + + @Test + public void testEmptyLast() { + assertThrows(NoSuchElementException.class, () -> new RoaringBitmap().last()); + } + + @Test + public void testFirstLast() { + RoaringBitmap rb = new RoaringBitmap(); + + rb.add(2); + rb.add(4); + rb.add(8); + assertEquals(2, rb.first()); + assertEquals(8, rb.last()); + + rb.add(1L << 5, 1L << 14); + assertEquals(2, rb.first()); + assertEquals((1 << 14) - 1, rb.last()); + + rb.add(1L << 15, 1L << 30); + assertEquals(2, rb.first()); + assertEquals((1L << 30) - 1, rb.last()); + } + + @Test + public void testIsHammingSimilar_AtStart() { + // similar bitmaps in the first container + RoaringBitmap baseline = RoaringBitmap.bitmapOf(2, 4, 8, 1 << 17, 1 << 22); + assertTrue(baseline.isHammingSimilar(baseline, 0)); + RoaringBitmap other = baseline.clone(); + other.flip(0L, 9); + for (int i = 0; i < 9; ++i) { + assertFalse(baseline.isHammingSimilar(other, i)); + } + assertTrue(baseline.isHammingSimilar(other, 9)); + other.add(0L, 9L); + for (int i = 0; i < 6; ++i) { + assertFalse(baseline.isHammingSimilar(other, i)); + } + assertTrue(baseline.isHammingSimilar(other, 6)); + } + + @Test + public void testHammingSimilarity_BigVsSmall() { + RoaringBitmap big = new RoaringBitmap(); + big.add(1, 2, 3, 4); + big.add(1L << 17, 1L << 30); + big.flip((1 << 17) | (1 << 16)); + for (int i = 1 << 18; i < 1 << 19; ++i) { + if (i % 3 == 0) { + big.flip(i); + } + } + RoaringBitmap small = RoaringBitmap.bitmapOf(1, 2, 3, 4); + assertFalse(small.isHammingSimilar(big, 1)); + assertFalse(big.isHammingSimilar(small, 1)); + } + + @Test + public void testHammingSimilarity_Shifted() { + RoaringBitmap baseline = RoaringBitmap.bitmapOf(1, 2, 3, 4); + RoaringBitmap shifted = + RoaringBitmap.bitmapOf((1 << 17) + 1, (1 << 17) + 2, (1 << 17) + 3, (1 << 17) + 4); + assertFalse(baseline.isHammingSimilar(shifted, 0)); + } + + @Test + public void testIsHammingSimilar_AtEnd() { + // reject bitmaps that are identical for many chunks but differ at the end + RoaringBitmap baseline = new RoaringBitmap(); + for (int i = 0; i < 1 << 15; ++i) { + if (i % 3 == 0) { + baseline.add(i); + } + } + baseline.add((1L << 16) + 1, 1L << 18); + baseline.add((1L << 19) + 1, 1L << 20); + baseline.add((1 << 21) + 1); + baseline.add((1 << 21) + 3); + baseline.add((1 << 21) + 5); + assertEquals(baseline.getCardinality(), RoaringBitmap.andCardinality(baseline, baseline)); + assertTrue(baseline.isHammingSimilar(baseline, 0)); + RoaringBitmap other = baseline.clone(); + other.flip((1 << 21) + 1); + assertTrue(baseline.isHammingSimilar(other, 1)); + assertFalse(baseline.isHammingSimilar(other, 0)); + other.add((1 << 21) + 2); + assertTrue(baseline.isHammingSimilar(other, 2)); + assertFalse(baseline.isHammingSimilar(other, 1)); + other.flip((1 << 21) + 3); + assertTrue(baseline.isHammingSimilar(other, 3)); + assertFalse(baseline.isHammingSimilar(other, 2)); + } + + @Test + public void testAndCardinality() { + RoaringBitmap baseline = new RoaringBitmap(); + baseline.add((1L << 16) + 1, 1L << 18); + baseline.add((1L << 19) + 1, 1L << 20); + baseline.add((1 << 21) + 1); + baseline.add((1 << 21) + 3); + baseline.add((1 << 21) + 5); + assertEquals(baseline, RoaringBitmap.and(baseline, baseline)); + assertEquals(baseline.getCardinality(), RoaringBitmap.andCardinality(baseline, baseline)); + } + + @Test + public void testRankOverflow() { + assertEquals(0, RoaringBitmap.bitmapOf(65537).rank(1)); + assertEquals(1, RoaringBitmap.bitmapOf(65537).rank(65537)); + assertEquals(1, RoaringBitmap.bitmapOf(65537).rank(65538)); + } + + @Test + public void testNegativeAdd() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(-7); + + assertEquals("{4294967289}", bitmap.toString()); + } + + @Test + public void testNegative_last() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(-7); + bitmap.add(777); + + assertEquals(-7, bitmap.last()); + } + + @Test + public void testFirstLastSigned() { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1_111_111, 3_333_333); + assertEquals(1_111_111, bitmap.firstSigned()); + assertEquals(3_333_333, bitmap.lastSigned()); + + bitmap = RoaringBitmap.bitmapOf(-3_333_333, 3_333_333); + assertEquals(-3_333_333, bitmap.firstSigned()); + assertEquals(3_333_333, bitmap.lastSigned()); + + bitmap = RoaringBitmap.bitmapOf(-3_333_333, -1_111_111); + assertEquals(-3_333_333, bitmap.firstSigned()); + assertEquals(-1_111_111, bitmap.lastSigned()); + + bitmap = RoaringBitmap.bitmapOfRange(0, 1L << 32); + assertEquals(Integer.MIN_VALUE, bitmap.firstSigned()); + assertEquals(Integer.MAX_VALUE, bitmap.lastSigned()); + } + + @ParameterizedTest + @ValueSource(ints = {Integer.MIN_VALUE, -65_536, 0, 65_536, Integer.MAX_VALUE}) + public void testFirstLastSigned_SingleValueBitmap(int value) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(value); + assertEquals(value, bitmap.firstSigned()); + assertEquals(value, bitmap.lastSigned()); + } + + @Test + public void testContainsRange_ContiguousBitmap() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(0L, 1_000_000L); + assertTrue(bitmap.contains(1L, 999_999L)); + assertFalse(bitmap.contains(1L, 1_000_001L)); + bitmap.flip(500_000); + assertFalse(bitmap.contains(1L, 999_999L)); + bitmap.flip(500_000); + bitmap.flip(500_000L, 600_000L); + assertFalse(bitmap.contains(1L, 999_999L)); + assertTrue(bitmap.contains(0L, 500_000L)); + assertFalse(bitmap.contains(2_000_001L, 10_000_000L)); + } + + @Test + public void testContainsRange_SmallBitmap() { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6); + assertTrue(bitmap.contains(1, 6)); + assertTrue(bitmap.contains(1, 5)); + assertTrue(bitmap.contains(2, 6)); + assertTrue(bitmap.contains(2, 7)); + assertFalse(bitmap.contains(2, 8)); + assertFalse(bitmap.contains(0, 6)); + assertFalse(bitmap.contains(0, 1)); + assertFalse(bitmap.contains(6, 10)); + assertFalse(bitmap.contains(7, 1 << 16)); + assertFalse(bitmap.contains(1 << 17, 1 << 19)); + } + + @Test + public void testContainsRange_DirtyBitmap() { + RoaringBitmapWriter writer = writer().constantMemory().get(); + IntStream.range(0, 1_000_000).map(i -> i * 2).forEach(writer::add); + writer.flush(); + RoaringBitmap bitmap = writer.getUnderlying(); + assertFalse(bitmap.contains(0L, 2_000_000L)); + assertFalse(bitmap.contains(0L, 2L)); + assertTrue(bitmap.contains(0L, 1L)); + assertTrue(bitmap.contains(1L << 10, 1 | (1L << 10))); + assertFalse(bitmap.contains(1L << 31, 1L << 32)); + } + + @Test + public void addoffset() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(10); + rb.add(0xFFFF); + rb.add(0x010101); + for (int i = 100000; i < 200000; i += 4) { + rb.add(i); + } + rb.add(400000L, 1400000L); + for (int offset = 3; offset < 1000000; offset *= 3) { + RoaringBitmap rboff = RoaringBitmap.addOffset(rb, offset); + IntIterator i = rb.getIntIterator(); + IntIterator j = rboff.getIntIterator(); + while (i.hasNext() && j.hasNext()) { + int val1 = i.next() + offset; + int val2 = j.next(); + assertEquals(val1, val2); + } + assertEquals(i.hasNext(), j.hasNext()); + } + for (int offset = 1024; offset < 1000000; offset *= 2) { + RoaringBitmap rboff = RoaringBitmap.addOffset(rb, offset); + IntIterator i = rb.getIntIterator(); + IntIterator j = rboff.getIntIterator(); + while (i.hasNext() && j.hasNext()) { + assertEquals(i.next() + offset, j.next()); + } + assertEquals(i.hasNext(), j.hasNext()); + } + } + + @Test + public void issue418() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(0); + assertEquals(rb.contains(0), true); + assertEquals(rb.getCardinality(), 1); + long vals[] = {100, 0xFFFF0000L, 0xFFFF0001L}; + for (long s : vals) { + RoaringBitmap shifted = RoaringBitmap.addOffset(rb, s); + System.out.println("moved " + shifted); + assertEquals(shifted.contains((int) s), true); + assertEquals(shifted.getCardinality(), 1); + System.out.println("moving back by " + (-s)); + + shifted = RoaringBitmap.addOffset(shifted, -s); + System.out.println("back " + shifted); + + assertEquals(shifted.contains(0), true); + assertEquals(shifted.getCardinality(), 1); + } + } + + @Test + public void addNegativeOffset() { + final RoaringBitmap rb = new RoaringBitmap(); + rb.add(10); + rb.add(0xFFFF); + rb.add(0x010101); + for (int i = 100000; i < 200000; i += 4) { + rb.add(i); + } + rb.add(400000L, 1400000L); + for (int offset = 3; offset < 1000000; offset *= 3) { + RoaringBitmap rboffpos = RoaringBitmap.addOffset(rb, offset); + RoaringBitmap rboff = RoaringBitmap.addOffset(rboffpos, -offset); + + IntIterator i = rb.getIntIterator(); + IntIterator j = rboff.getIntIterator(); + while (i.hasNext() && j.hasNext()) { + int val1 = i.next(); + int val2 = j.next(); + if (val1 != val2) assertEquals(val1, val2); + } + assertEquals(i.hasNext(), j.hasNext()); + } + for (int offset = 1024; offset < 1000000; offset *= 2) { + RoaringBitmap rboffpos = RoaringBitmap.addOffset(rb, offset); + RoaringBitmap rboff = RoaringBitmap.addOffset(rboffpos, -offset); + IntIterator i = rb.getIntIterator(); + IntIterator j = rboff.getIntIterator(); + while (i.hasNext() && j.hasNext()) { + assertEquals(i.next(), j.next()); + } + assertEquals(i.hasNext(), j.hasNext()); + } + } + + @Test + public void testNextValue() { + RoaringBitmap bitmap = + SeededTestData.TestDataSet.testCase() + .withRunAt(0) + .withBitmapAt(1) + .withArrayAt(2) + .withRunAt(3) + .withBitmapAt(4) + .withArrayAt(5) + .build(); + + BitSet bitset = new BitSet(); + bitmap.forEach((IntConsumer) bitset::set); + long b1 = 0; + int b2 = 0; + while (b1 >= 0 && b2 >= 0) { + b1 = bitmap.nextValue((int) b1 + 1); + b2 = bitset.nextSetBit(b2 + 1); + assertEquals(b1, b2); + } + } + + @Test + public void testPreviousValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(1); + assertEquals(-1l, bitmap.previousValue(0)); + } + + @Test + public void testPreviousAbsentValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(0); + assertEquals(-1L, bitmap.previousAbsentValue(0)); + } + + @Test + public void testNextValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(0xffffffff - 1); + assertEquals(-1L, bitmap.nextValue(0xffffffff)); + } + + @Test + public void testNextAbsentValueLimit() { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.add(-1); + assertEquals(-1L, bitmap.nextAbsentValue(-1)); + } + + @Test + public void testPreviousValue() { + RoaringBitmap bitmap = + SeededTestData.TestDataSet.testCase() + .withRunAt(0) + .withBitmapAt(1) + .withArrayAt(2) + .withRunAt(3) + .withBitmapAt(4) + .withArrayAt(5) + .build(); + + BitSet bitset = new BitSet(); + bitmap.forEach((IntConsumer) bitset::set); + long b1 = Util.toUnsignedLong(bitmap.last()); + int b2 = bitset.previousSetBit(Integer.MAX_VALUE); + int i = bitmap.getCardinality(); + while (b1 > 0 && b2 > 0) { + assertEquals(b1, b2); + b1 = bitmap.previousValue((int) (b1 - 1)); + b2 = bitset.previousSetBit(b2 - 1); + assertEquals(b1, b2, "mismatch at " + i + "(bitset=" + b2 + ", rb=" + b1 + ")"); + --i; + } + } + + @Test + public void testPreviousValueRegression() { + // see https://github.com/RoaringBitmap/RoaringBitmap/issues/564 + assertEquals(-1, RoaringBitmap.bitmapOf(27399807).previousValue(403042)); + assertEquals(-1, RoaringBitmap.bitmapOf().previousValue(403042)); + } + + @Test + public void testPreviousValue_AbsentTargetContainer() { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(-1, 2, 3, 131072); + assertEquals(3, bitmap.previousValue(65536)); + assertEquals(131072, bitmap.previousValue(Integer.MAX_VALUE)); + assertEquals(131072, bitmap.previousValue(-131072)); + + bitmap = RoaringBitmap.bitmapOf(131072); + assertEquals(-1, bitmap.previousValue(65536)); + } + + @Test + public void testPreviousValue_LastReturnedAsUnsignedLong() { + RoaringBitmap bitmap = RoaringBitmap.bitmapOf(-650002, -650001, -650000); + assertEquals(Util.toUnsignedLong(-650000), bitmap.previousValue(-1)); + } + + @Test + public void testRangeCardinalityAtBoundary() { + // See https://github.com/RoaringBitmap/RoaringBitmap/issues/285 + RoaringBitmap r = new RoaringBitmap(); + r.add(66236); + assertEquals(1, r.rangeCardinality(60000, 70000)); + } + + @Test + public void testNextValueArray() { + RoaringBitmap r = new RoaringBitmap(); + r.add(0, 1, 2, 4, 6); + assertEquals(-1, r.nextValue(7)); + } + + @Test + public void regressionTestEquals370() { + // see https://github.com/RoaringBitmap/RoaringBitmap/issues/370 + int[] a = { + 239, 240, 241, 242, 243, 244, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 273, + 274, 275, 276, 277, 278, 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, + 413, 420, 421, 422, 509, 510, 511, 512, 513, 514, 539, 540, 541, 542, 543, 544, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, + 588, 589, 590, 591, 592, 593, 594, 595, 624, 625, 634, 635, 636, 649, 650, 651, 652, 653, 654, + 714, 715, 716, 718, 719, 720, 721, 722, 723, 724, 725, 726, 728, 729, 730, 731, 732, 733, 734, + 735, 736, 739, 740, 741, 742, 743, 744, 771, 772, 773 + }; + int[] b = { + 239, 240, 241, 242, 243, 244, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 273, + 274, 275, 276, 277, 278, 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, + 413, 420, 421, 422, 509, 510, 511, 512, 513, 514, 539, 540, 541, 542, 543, 544, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 578, 579, 580, 581, 582, 583, 584, 585, 586, 607, + 608, 634, 635, 636, 649, 650, 651, 652, 653, 654, 714, 715, 716, 718, 719, 720, 721, 722, 723, + 724, 725, 726, 728, 729, 730, 731, 732, 733, 734, 735, 736, 739, 740, 741, 742, 743, 744, 771, + 772, 773 + }; + + RoaringBitmap rbA = RoaringBitmap.bitmapOf(a); + RoaringBitmap rbB = RoaringBitmap.bitmapOf(b); + + assertNotEquals(rbB, rbA); + rbA.runOptimize(); + assertNotEquals(rbB, rbA); + rbB.runOptimize(); + assertNotEquals(rbB, rbA); + } + + @Test + public void regressionTestRemove377() { + // https://github.com/RoaringBitmap/RoaringBitmap/issues/377 + RoaringBitmap map = new RoaringBitmap(); + map.add(0L, 64L); + for (int i = 0; i < 64; i++) { + if (i != 30 && i != 32) { + map.remove(i); + } + } + map.remove(0L, 31L); + assertFalse(map.contains(30)); + assertTrue(map.contains(32)); + } + + @Test + public void invalidCookieBuffer() { + assertThrows( + IOException.class, + () -> { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.deserialize(ByteBuffer.allocate(4)); + }); + } + + @Test + public void invalidCookieDataInput() { + assertThrows( + IOException.class, + () -> { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.deserialize(new DataInputStream(new ByteArrayInputStream(new byte[4]))); + }); + } + + @Test + public void invalidCookieDataInputWithBuffer() { + assertThrows( + IOException.class, + () -> { + RoaringBitmap bitmap = new RoaringBitmap(); + bitmap.deserialize( + new DataInputStream(new ByteArrayInputStream(new byte[4])), new byte[8]); + }); + } + + @Test + public void testCardinalityExceeds() { + RoaringBitmap bitmap = new RoaringBitmap(); + long runLength = 20_000L; + bitmap.add(0L, runLength); + for (int i = (1 << 16) + 1; i < 1 << 17; i += 2) { + bitmap.add(i); + } + long bitmapCount = 1 << 15; + bitmap.add((1 << 17) | 1); + bitmap.add((1 << 17) | 2); + bitmap.add((1 << 17) | 3); + long arrayCount = 3; + bitmap.runOptimize(); + assertFalse(bitmap.cardinalityExceeds(Integer.MAX_VALUE)); + assertFalse(bitmap.cardinalityExceeds(runLength + bitmapCount + arrayCount)); + assertTrue(bitmap.cardinalityExceeds(runLength + bitmapCount + 1)); + assertTrue(bitmap.cardinalityExceeds(runLength + bitmapCount - 1)); + assertTrue(bitmap.cardinalityExceeds(runLength - 1)); + } + + @Test + public void testWithYourself() { + RoaringBitmap b1 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + b1.runOptimize(); + b1.or(b1); + assertTrue(b1.equals(RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))); + b1.xor(b1); + assertTrue(b1.isEmpty()); + b1 = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + b1.and(b1); + assertTrue(b1.equals(RoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))); + b1.andNot(b1); + assertTrue(b1.isEmpty()); + } + + @Test + public void testIssue566() { + RoaringBitmap roaringBitMap = new RoaringBitmap(); + BitSet bitSet = new BitSet(5000); + double prob = 0.001; + Random random = new Random(); + for (int i = 0; i < 5000; i++) { + if (random.nextDouble() < prob) { + bitSet.set(i); + roaringBitMap.add(i); + } + } + long roaringbits = roaringBitMap.getSizeInBytes() * 8; + long bitsetbits = bitSet.size(); + System.out.println("[issue566] cardinality: " + roaringBitMap.getCardinality()); + System.out.println("[issue566] bitset bits: " + bitsetbits); + System.out.println( + "[issue566] bitset bits per entry: " + bitsetbits * 1.0 / bitSet.cardinality()); + System.out.println("[issue566] RoaringBitmap bits: " + roaringbits); + System.out.println( + "[issue566] RoaringBitmap bits per entry: " + + roaringbits * 1.0 / roaringBitMap.getCardinality()); + assertTrue(roaringbits < bitsetbits); + } + + @Test + public void issue623() { + RoaringBitmap r = new RoaringBitmap(); + r.add(65535); + r.add(65535 + 1); + assertTrue(r.contains(65535)); + assertTrue(r.contains(65535 + 1)); + assertTrue(r.contains(65535L, 65535L + 1)); + for (long i = 1; i <= 10_000_000; i++) { + r.add(i, i + 1); + } + for (long i = 1; i <= 10_000_000; i++) { + assertTrue(r.contains(i, i + 1)); + } + } + + @Test + public void test1235() { + RoaringBitmap r = RoaringBitmap.bitmapOf(1, 2, 3, 5); + r.flip(4); + assertEquals(r, RoaringBitmap.bitmapOf(1, 2, 3, 4, 5)); + } + + @Test + public void test2345() { + RoaringBitmap r = RoaringBitmap.bitmapOf(1, 2, 3, 4, 5); + r.flip(1); + assertEquals(r, RoaringBitmap.bitmapOf(2, 3, 4, 5)); + } + + @Test + public void testSelectRange() { + RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 1000000); + for (int i = 1; i <= 1000000; i += 1000) { + for (int j = i; j <= 1000000; j += 1000) { + RoaringBitmap rr = r.selectRange(i, j); + assertEquals(rr, RoaringBitmap.bitmapOfRange(i, j)); + } + } + } + + @Test + public void testContainerSizeRoaringBitmapMultiple() { + RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 1000000); + assertEquals(16, r.getContainerCount()); + } + + @Test + public void testContainerSizeRoaringBitmapSingle() { + RoaringBitmap r = RoaringBitmap.bitmapOfRange(1, 100); + assertEquals(1, r.getContainerCount()); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java index 0d40306d2..8d70239d9 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapOrNot.java @@ -3,6 +3,11 @@ */ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.Util.toUnsignedLong; + import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -16,9 +21,6 @@ import java.util.List; import java.util.Map; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.Util.toUnsignedLong; - @Execution(ExecutionMode.CONCURRENT) public class TestRoaringBitmapOrNot { @@ -30,11 +32,11 @@ public void orNot1() { rb.add(2); rb.add(1); rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - rb2.add(1 << 16);// 65536 - rb2.add(3 << 16);//196608 + rb2.add(1 << 16); // 65536 + rb2.add(3 << 16); // 196608 rb.orNot(rb2, (4 << 16) - 1); @@ -56,9 +58,9 @@ public void orNot2() { rb.add(0); rb.add(1 << 16); // 65536 - rb.add(3 << 16); //196608 + rb.add(3 << 16); // 196608 - rb2.add((4 << 16) - 1); //262143 + rb2.add((4 << 16) - 1); // 262143 rb.orNot(rb2, 4 << 16); @@ -79,8 +81,8 @@ public void orNot3() { rb.add(2 << 16); final RoaringBitmap rb2 = new RoaringBitmap(); - rb2.add(1 << 14); //16384 - rb2.add(3 << 16); //196608 + rb2.add(1 << 14); // 16384 + rb2.add(3 << 16); // 196608 rb.orNot(rb2, (5 << 16)); assertEquals((5 << 16) - 2, rb.getCardinality()); @@ -101,9 +103,9 @@ public void orNot4() { rb.add(1); final RoaringBitmap rb2 = new RoaringBitmap(); - rb2.add(3 << 16); //196608 + rb2.add(3 << 16); // 196608 - rb.orNot(rb2, (2 << 16) + (2 << 14)); //131072 + 32768 = 163840 + rb.orNot(rb2, (2 << 16) + (2 << 14)); // 131072 + 32768 = 163840 assertEquals((2 << 16) + (2 << 14), rb.getCardinality()); final IntIterator iterator = rb.getIntIterator(); @@ -120,8 +122,8 @@ public void orNot5() { rb.add(1); rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 final RoaringBitmap rb2 = new RoaringBitmap(); @@ -143,8 +145,8 @@ public void orNot6() { rb.add(1); rb.add((1 << 16) - 1); // 65535 rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 final RoaringBitmap rb2 = new RoaringBitmap(); @@ -179,8 +181,8 @@ public void orNot7() { final RoaringBitmap rb = new RoaringBitmap(); rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 final RoaringBitmap rb2 = new RoaringBitmap(); @@ -195,7 +197,6 @@ public void orNot7() { assertEquals(i, iterator.next(), "Error on iteration " + i); } - assertTrue(iterator.hasNext()); assertEquals(1 << 16, iterator.next()); @@ -208,16 +209,13 @@ public void orNot7() { assertFalse(iterator.hasNext()); } - - @Test public void orNot9() { final RoaringBitmap rb1 = new RoaringBitmap(); rb1.add(1 << 16); // 65536 - rb1.add(2 << 16); //131072 - rb1.add(3 << 16); //196608 - + rb1.add(2 << 16); // 131072 + rb1.add(3 << 16); // 196608 { final RoaringBitmap rb2 = new RoaringBitmap(); @@ -251,7 +249,6 @@ public void orNot9() { assertEquals(196608, iterator.next()); } - { final RoaringBitmap rb2 = new RoaringBitmap(); rb2.add((1 << 16) + (1 << 13)); @@ -264,7 +261,9 @@ public void orNot9() { final IntIterator iterator = answer.getIntIterator(); for (int i = 0; i < (2 << 16) + 1; ++i) { - if ((i != (1 << 16) + (1 << 13)) && (i != (1 << 16) + (1 << 14)) && (i != (1 << 16) + (1 << 15))) { + if ((i != (1 << 16) + (1 << 13)) + && (i != (1 << 16) + (1 << 14)) + && (i != (1 << 16) + (1 << 15))) { assertTrue(iterator.hasNext(), "Error on iteration " + i); assertEquals(i, iterator.next(), "Error on iteration " + i); } @@ -338,7 +337,7 @@ public void orNot11() { RoaringBitmap rb3 = RoaringBitmap.orNot(rb, rb2, 65535L * 65536L + 65524); - assertEquals((int)(65535L * 65536L + 65523), rb3.last()); + assertEquals((int) (65535L * 65536L + 65523), rb3.last()); } @Test @@ -354,7 +353,7 @@ public void orNotAgainstFullBitmap() { public void orNotNonEmptyAgainstFullBitmap() { RoaringBitmap rb = RoaringBitmap.bitmapOf(1, 0x10001, 0x20001); RoaringBitmap full = new RoaringBitmap(); - full.add((long)0, (long)0x40000); + full.add((long) 0, (long) 0x40000); rb.orNot(full, 0x30000); assertEquals(RoaringBitmap.bitmapOf(1, 0x10001, 0x20001), rb); } @@ -373,15 +372,17 @@ public void orNotNonEmptyAgainstFullBitmapStatic() { RoaringBitmap rb = RoaringBitmap.bitmapOf(1, 0x10001, 0x20001); RoaringBitmap full = new RoaringBitmap(); full.add(0, 0x40000L); - assertEquals(RoaringBitmap.bitmapOf(1, 0x10001, 0x20001), RoaringBitmap.orNot(rb, full, 0x30000L)); + assertEquals( + RoaringBitmap.bitmapOf(1, 0x10001, 0x20001), RoaringBitmap.orNot(rb, full, 0x30000L)); } @Test @SuppressWarnings("unchecked") public void testBigOrNot() throws IOException { - byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); + byte[] bytes = + Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); Map info = new ObjectMapper().readerFor(Map.class).readValue(bytes); - List base64Bitmaps = (List)info.get("bitmaps"); + List base64Bitmaps = (List) info.get("bitmaps"); ByteBuffer lBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(0))); ByteBuffer rBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(1))); RoaringBitmap l = new RoaringBitmap(); @@ -400,13 +401,13 @@ public void testBigOrNot() throws IOException { assertEquals(expected, actual); } - @Test @SuppressWarnings("unchecked") public void testBigOrNotStatic() throws IOException { - byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); + byte[] bytes = + Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); Map info = new ObjectMapper().readerFor(Map.class).readValue(bytes); - List base64Bitmaps = (List)info.get("bitmaps"); + List base64Bitmaps = (List) info.get("bitmaps"); ByteBuffer lBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(0))); ByteBuffer rBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(1))); RoaringBitmap l = new RoaringBitmap(); @@ -423,5 +424,4 @@ public void testBigOrNotStatic() throws IOException { RoaringBitmap actual = RoaringBitmap.orNot(l, r, limit); assertEquals(expected, actual); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java index 0250bfae6..205947168 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriter.java @@ -1,5 +1,12 @@ package org.roaringbitmap; +import static java.lang.Integer.MAX_VALUE; +import static java.lang.Integer.MIN_VALUE; +import static java.lang.Integer.toUnsignedLong; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.RoaringBitmapWriter.bufferWriter; +import static org.roaringbitmap.RoaringBitmapWriter.writer; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -10,129 +17,237 @@ import java.util.function.Supplier; import java.util.stream.Stream; -import static java.lang.Integer.*; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.roaringbitmap.RoaringBitmapWriter.bufferWriter; -import static org.roaringbitmap.RoaringBitmapWriter.writer; - @Execution(ExecutionMode.CONCURRENT) public class TestRoaringBitmapWriter { public static Stream params() { return Stream.of( - Arguments.of(writer().optimiseForArrays()), - Arguments.of(writer().optimiseForRuns()), - Arguments.of(writer().constantMemory()), - Arguments.of(writer().optimiseForArrays().fastRank()), - Arguments.of(writer().optimiseForRuns().fastRank()), - Arguments.of(writer().constantMemory().fastRank()), - Arguments.of(writer().expectedDensity(0.001)), - Arguments.of(writer().expectedDensity(0.01)), - Arguments.of(writer().expectedDensity(0.1)), - Arguments.of(writer().expectedDensity(0.6)), - Arguments.of(writer().expectedDensity(0.001).fastRank()), - Arguments.of(writer().expectedDensity(0.01).fastRank()), - Arguments.of(writer().expectedDensity(0.1).fastRank()), - Arguments.of(writer().expectedDensity(0.6).fastRank()), - Arguments.of(writer().initialCapacity(1)), - Arguments.of(writer().initialCapacity(8)), - Arguments.of(writer().initialCapacity(8192)), - Arguments.of(writer().initialCapacity(1).fastRank()), - Arguments.of(writer().initialCapacity(8).fastRank()), - Arguments.of(writer().initialCapacity(8192).fastRank()), - Arguments.of(writer().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank()), - Arguments.of(writer().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank()), - Arguments.of(writer().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank()), - Arguments.of(writer().optimiseForArrays().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().optimiseForRuns().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().constantMemory().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().optimiseForArrays().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).fastRank()), - Arguments.of(writer().optimiseForRuns().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).fastRank()), - Arguments.of(writer().constantMemory().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).fastRank()), - Arguments.of(bufferWriter().optimiseForArrays()), - Arguments.of(bufferWriter().optimiseForRuns()), - Arguments.of(bufferWriter().constantMemory()), - Arguments.of(bufferWriter().expectedDensity(0.001)), - Arguments.of(bufferWriter().expectedDensity(0.01)), - Arguments.of(bufferWriter().expectedDensity(0.1)), - Arguments.of(bufferWriter().expectedDensity(0.6)), - Arguments.of(bufferWriter().initialCapacity(1)), - Arguments.of(bufferWriter().initialCapacity(8)), - Arguments.of(bufferWriter().initialCapacity(8192)), - Arguments.of(bufferWriter().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE))), - Arguments.of(bufferWriter().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE))), - Arguments.of(bufferWriter().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE))), - Arguments.of(bufferWriter().optimiseForArrays().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), - Arguments.of(bufferWriter().optimiseForRuns().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), - Arguments.of(bufferWriter().constantMemory().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), - Arguments.of(writer().optimiseForArrays().runCompress(false)), - Arguments.of(writer().optimiseForRuns().runCompress(false)), - Arguments.of(writer().constantMemory().runCompress(false)), - Arguments.of(writer().optimiseForArrays().fastRank().runCompress(false)), - Arguments.of(writer().optimiseForRuns().fastRank().runCompress(false)), - Arguments.of(writer().constantMemory().fastRank().runCompress(false)), - Arguments.of(writer().expectedDensity(0.001).runCompress(false)), - Arguments.of(writer().expectedDensity(0.01).runCompress(false)), - Arguments.of(writer().expectedDensity(0.1).runCompress(false)), - Arguments.of(writer().expectedDensity(0.6).runCompress(false)), - Arguments.of(writer().expectedDensity(0.001).fastRank().runCompress(false)), - Arguments.of(writer().expectedDensity(0.01).fastRank().runCompress(false)), - Arguments.of(writer().expectedDensity(0.1).fastRank().runCompress(false)), - Arguments.of(writer().expectedDensity(0.6).fastRank().runCompress(false)), - Arguments.of(writer().initialCapacity(1).runCompress(false)), - Arguments.of(writer().initialCapacity(8).runCompress(false)), - Arguments.of(writer().initialCapacity(8192).runCompress(false)), - Arguments.of(writer().initialCapacity(1).fastRank().runCompress(false)), - Arguments.of(writer().initialCapacity(8).fastRank().runCompress(false)), - Arguments.of(writer().initialCapacity(8192).fastRank().runCompress(false)), - Arguments.of(writer().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(writer().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(writer().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(writer().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank().runCompress(false)), - Arguments.of(writer().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank().runCompress(false)), - Arguments.of(writer().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank().runCompress(false)), - Arguments.of(writer().optimiseForArrays().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(writer().optimiseForRuns().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(writer().constantMemory().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(writer().optimiseForArrays().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).fastRank().runCompress(false)), - Arguments.of(writer().optimiseForRuns().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).fastRank().runCompress(false)), - Arguments.of(writer().constantMemory().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).fastRank().runCompress(false)), - Arguments.of(bufferWriter().optimiseForArrays().runCompress(false)), - Arguments.of(bufferWriter().optimiseForRuns().runCompress(false)), - Arguments.of(bufferWriter().constantMemory().runCompress(false)), - Arguments.of(bufferWriter().expectedDensity(0.001).runCompress(false)), - Arguments.of(bufferWriter().expectedDensity(0.01).runCompress(false)), - Arguments.of(bufferWriter().expectedDensity(0.1).runCompress(false)), - Arguments.of(bufferWriter().expectedDensity(0.6).runCompress(false)), - Arguments.of(bufferWriter().initialCapacity(1).runCompress(false)), - Arguments.of(bufferWriter().initialCapacity(8).runCompress(false)), - Arguments.of(bufferWriter().initialCapacity(8192).runCompress(false)), - Arguments.of(bufferWriter().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(bufferWriter().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(bufferWriter().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(bufferWriter().optimiseForArrays().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(bufferWriter().optimiseForRuns().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).runCompress(false)), - Arguments.of(bufferWriter().constantMemory().expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)).runCompress(false)) - ); + Arguments.of(writer().optimiseForArrays()), + Arguments.of(writer().optimiseForRuns()), + Arguments.of(writer().constantMemory()), + Arguments.of(writer().optimiseForArrays().fastRank()), + Arguments.of(writer().optimiseForRuns().fastRank()), + Arguments.of(writer().constantMemory().fastRank()), + Arguments.of(writer().expectedDensity(0.001)), + Arguments.of(writer().expectedDensity(0.01)), + Arguments.of(writer().expectedDensity(0.1)), + Arguments.of(writer().expectedDensity(0.6)), + Arguments.of(writer().expectedDensity(0.001).fastRank()), + Arguments.of(writer().expectedDensity(0.01).fastRank()), + Arguments.of(writer().expectedDensity(0.1).fastRank()), + Arguments.of(writer().expectedDensity(0.6).fastRank()), + Arguments.of(writer().initialCapacity(1)), + Arguments.of(writer().initialCapacity(8)), + Arguments.of(writer().initialCapacity(8192)), + Arguments.of(writer().initialCapacity(1).fastRank()), + Arguments.of(writer().initialCapacity(8).fastRank()), + Arguments.of(writer().initialCapacity(8192).fastRank()), + Arguments.of(writer().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE))), + Arguments.of(writer().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE))), + Arguments.of(writer().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE))), + Arguments.of( + writer().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank()), + Arguments.of( + writer().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank()), + Arguments.of( + writer().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE)).fastRank()), + Arguments.of( + writer() + .optimiseForArrays() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), + Arguments.of( + writer() + .optimiseForRuns() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), + Arguments.of( + writer() + .constantMemory() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), + Arguments.of( + writer() + .optimiseForArrays() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .fastRank()), + Arguments.of( + writer() + .optimiseForRuns() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .fastRank()), + Arguments.of( + writer() + .constantMemory() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .fastRank()), + Arguments.of(bufferWriter().optimiseForArrays()), + Arguments.of(bufferWriter().optimiseForRuns()), + Arguments.of(bufferWriter().constantMemory()), + Arguments.of(bufferWriter().expectedDensity(0.001)), + Arguments.of(bufferWriter().expectedDensity(0.01)), + Arguments.of(bufferWriter().expectedDensity(0.1)), + Arguments.of(bufferWriter().expectedDensity(0.6)), + Arguments.of(bufferWriter().initialCapacity(1)), + Arguments.of(bufferWriter().initialCapacity(8)), + Arguments.of(bufferWriter().initialCapacity(8192)), + Arguments.of( + bufferWriter().optimiseForArrays().expectedRange(0, toUnsignedLong(MIN_VALUE))), + Arguments.of(bufferWriter().optimiseForRuns().expectedRange(0, toUnsignedLong(MIN_VALUE))), + Arguments.of(bufferWriter().constantMemory().expectedRange(0, toUnsignedLong(MIN_VALUE))), + Arguments.of( + bufferWriter() + .optimiseForArrays() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), + Arguments.of( + bufferWriter() + .optimiseForRuns() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), + Arguments.of( + bufferWriter() + .constantMemory() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE))), + Arguments.of(writer().optimiseForArrays().runCompress(false)), + Arguments.of(writer().optimiseForRuns().runCompress(false)), + Arguments.of(writer().constantMemory().runCompress(false)), + Arguments.of(writer().optimiseForArrays().fastRank().runCompress(false)), + Arguments.of(writer().optimiseForRuns().fastRank().runCompress(false)), + Arguments.of(writer().constantMemory().fastRank().runCompress(false)), + Arguments.of(writer().expectedDensity(0.001).runCompress(false)), + Arguments.of(writer().expectedDensity(0.01).runCompress(false)), + Arguments.of(writer().expectedDensity(0.1).runCompress(false)), + Arguments.of(writer().expectedDensity(0.6).runCompress(false)), + Arguments.of(writer().expectedDensity(0.001).fastRank().runCompress(false)), + Arguments.of(writer().expectedDensity(0.01).fastRank().runCompress(false)), + Arguments.of(writer().expectedDensity(0.1).fastRank().runCompress(false)), + Arguments.of(writer().expectedDensity(0.6).fastRank().runCompress(false)), + Arguments.of(writer().initialCapacity(1).runCompress(false)), + Arguments.of(writer().initialCapacity(8).runCompress(false)), + Arguments.of(writer().initialCapacity(8192).runCompress(false)), + Arguments.of(writer().initialCapacity(1).fastRank().runCompress(false)), + Arguments.of(writer().initialCapacity(8).fastRank().runCompress(false)), + Arguments.of(writer().initialCapacity(8192).fastRank().runCompress(false)), + Arguments.of( + writer() + .optimiseForArrays() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + writer() + .optimiseForRuns() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + writer() + .constantMemory() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + writer() + .optimiseForArrays() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .fastRank() + .runCompress(false)), + Arguments.of( + writer() + .optimiseForRuns() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .fastRank() + .runCompress(false)), + Arguments.of( + writer() + .constantMemory() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .fastRank() + .runCompress(false)), + Arguments.of( + writer() + .optimiseForArrays() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + writer() + .optimiseForRuns() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + writer() + .constantMemory() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + writer() + .optimiseForArrays() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .fastRank() + .runCompress(false)), + Arguments.of( + writer() + .optimiseForRuns() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .fastRank() + .runCompress(false)), + Arguments.of( + writer() + .constantMemory() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .fastRank() + .runCompress(false)), + Arguments.of(bufferWriter().optimiseForArrays().runCompress(false)), + Arguments.of(bufferWriter().optimiseForRuns().runCompress(false)), + Arguments.of(bufferWriter().constantMemory().runCompress(false)), + Arguments.of(bufferWriter().expectedDensity(0.001).runCompress(false)), + Arguments.of(bufferWriter().expectedDensity(0.01).runCompress(false)), + Arguments.of(bufferWriter().expectedDensity(0.1).runCompress(false)), + Arguments.of(bufferWriter().expectedDensity(0.6).runCompress(false)), + Arguments.of(bufferWriter().initialCapacity(1).runCompress(false)), + Arguments.of(bufferWriter().initialCapacity(8).runCompress(false)), + Arguments.of(bufferWriter().initialCapacity(8192).runCompress(false)), + Arguments.of( + bufferWriter() + .optimiseForArrays() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + bufferWriter() + .optimiseForRuns() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + bufferWriter() + .constantMemory() + .expectedRange(0, toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + bufferWriter() + .optimiseForArrays() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + bufferWriter() + .optimiseForRuns() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .runCompress(false)), + Arguments.of( + bufferWriter() + .constantMemory() + .expectedRange(toUnsignedLong(MAX_VALUE), toUnsignedLong(MIN_VALUE)) + .runCompress(false))); } @ParameterizedTest @MethodSource("params") - public void addInReverseOrder(Supplier> supplier) { + public void addInReverseOrder( + Supplier> supplier) { RoaringBitmapWriter writer = supplier.get(); writer.add(1 << 17); writer.add(0); writer.flush(); - assertArrayEquals(RoaringBitmap.bitmapOf(0, 1 << 17).toArray(), writer.getUnderlying().toArray()); + assertArrayEquals( + RoaringBitmap.bitmapOf(0, 1 << 17).toArray(), writer.getUnderlying().toArray()); } @ParameterizedTest @MethodSource("params") - public void bitmapShouldContainAllValuesAfterFlush(Supplier> supplier) { + public void bitmapShouldContainAllValuesAfterFlush( + Supplier> supplier) { RoaringBitmapWriter writer = supplier.get(); writer.add(0); writer.add(1 << 17); @@ -141,10 +256,10 @@ public void bitmapShouldContainAllValuesAfterFlush(Supplier> supplier) { + public void newKeyShouldTriggerFlush( + Supplier> supplier) { RoaringBitmapWriter writer = supplier.get(); writer.add(0); writer.add(1 << 17); @@ -155,7 +270,8 @@ public void newKeyShouldTriggerFlush(Supplier> supplier) { + public void writeSameKeyAfterManualFlush( + Supplier> supplier) { RoaringBitmapWriter writer = supplier.get(); writer.add(0); writer.flush(); @@ -164,7 +280,6 @@ public void writeSameKeyAfterManualFlush(Supplier> supplier) { @@ -181,7 +296,8 @@ public void writeRange(Supplier> supplier) { + public void testWriteToMaxKeyAfterFlush( + Supplier> supplier) { RoaringBitmapWriter writer = supplier.get(); writer.add(0); writer.add(-2); @@ -191,17 +307,17 @@ public void testWriteToMaxKeyAfterFlush(Supplier> supplier) { + public void testWriteBitmapAfterReset( + Supplier> supplier) { RoaringBitmapWriter writer = supplier.get(); writer.add(0); writer.add(-2); - assertArrayEquals(new int[]{0, -2}, writer.get().toArray()); + assertArrayEquals(new int[] {0, -2}, writer.get().toArray()); writer.reset(); writer.add(100); writer.addMany(4, 5, 6); - assertArrayEquals(new int[]{4, 5, 6, 100}, writer.get().toArray()); + assertArrayEquals(new int[] {4, 5, 6, 100}, writer.get().toArray()); } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java index 6110d471c..e31a4f342 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmapWriterWizard.java @@ -1,11 +1,14 @@ package org.roaringbitmap; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.roaringbitmap.RoaringBitmapWriter.bufferWriter; import static org.roaringbitmap.RoaringBitmapWriter.writer; +import org.junit.jupiter.api.Test; + public class TestRoaringBitmapWriterWizard { @Test @@ -20,13 +23,13 @@ public void whenFastRankIsSelectedWizardCreatesFastRankRoaringBitmap() { @Test public void whenFastRankIsSelectedBufferWizardThrows() { - assertThrows(IllegalStateException.class, - () -> bufferWriter().fastRank().get().getUnderlying()); + assertThrows( + IllegalStateException.class, () -> bufferWriter().fastRank().get().getUnderlying()); } @Test public void shouldRespectProvidedStorageSizeHint() { - assertEquals(20, writer().initialCapacity(20).get().getUnderlying().highLowContainer.keys.length); + assertEquals( + 20, writer().initialCapacity(20).get().getUnderlying().highLowContainer.keys.length); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java index 84f61c59b..95138d6b8 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap_FastRank.java @@ -3,6 +3,10 @@ */ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -10,9 +14,6 @@ import java.util.Random; -import static org.junit.jupiter.api.Assertions.*; - - /** * Check FastRankRoaringBitmap dismiss the caches cardinalities when necessary */ @@ -131,7 +132,6 @@ public void addSmallAddNegativeRemoveSmall() { assertEquals(1, b.rank(-234 + 1)); } - @Test public void addSmallAddNegativeRemoveNegative() { FastRankRoaringBitmap b = new FastRankRoaringBitmap(); @@ -185,7 +185,6 @@ public void addManyRandomlyThenRemoveAllRandomly() { for (int i = 0; i < nbReallyAdded; i++) { int selected = b.select(r.nextInt(nbReallyAdded - i)); b.remove(selected); - } assertEquals(0, b.getLongCardinality()); } @@ -236,10 +235,12 @@ public void rankOnEmpty() { @Test public void selectOnEmpty() { - assertThrows(IllegalArgumentException.class, () -> { - FastRankRoaringBitmap b = new FastRankRoaringBitmap(); - b.select(0); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + FastRankRoaringBitmap b = new FastRankRoaringBitmap(); + b.select(0); + }); } @Test @@ -265,8 +266,8 @@ public void performanceTest_MixedAddRemove_LargeInts() { long timeNormal = System.currentTimeMillis() - startNormal; // Mixed workload: "fast" is expected slower as it recomputer cardinality regularly - System.out - .println("AddSelectRemoveAreMixed LargeInts FastRankRoaringBitmap=" + timeFast + "ms"); + System.out.println( + "AddSelectRemoveAreMixed LargeInts FastRankRoaringBitmap=" + timeFast + "ms"); System.out.println("AddSelectRemoveAreMixed LargeInts RoaringBitmap=" + timeNormal + "ms"); } @@ -293,8 +294,8 @@ public void performanceTest_MixedAddRemove_SmallInts() { long timeNormal = System.currentTimeMillis() - startNormal; // Mixed workload: "fast" is expected slower as it recomputes cardinality regularly - System.out - .println("AddSelectRemoveAreMixed SmallInts FastRankRoaringBitmap=" + timeFast + "ms"); + System.out.println( + "AddSelectRemoveAreMixed SmallInts FastRankRoaringBitmap=" + timeFast + "ms"); System.out.println("AddSelectRemoveAreMixed SmallInts RoaringBitmap=" + timeNormal + "ms"); } @@ -341,8 +342,6 @@ public void performanceTest_AddManyThenSelectMany() { System.out.println("AddOnlyThenSelectOnly RoaringBitmap=" + timeNormal + "ms"); } - - private FastRankRoaringBitmap prepareFastWithComputedCache() { FastRankRoaringBitmap fast = new FastRankRoaringBitmap(); @@ -529,15 +528,22 @@ public void testSelectExceptionOutOfBounds() { roaringBitmap.add(3); roaringBitmap.add(5); assertEquals(5, roaringBitmap.select(roaringBitmap.getCardinality() - 1)); - assertThrows(IllegalArgumentException.class, () -> roaringBitmap.select(roaringBitmap.getCardinality())); - assertThrows(IllegalArgumentException.class, () -> roaringBitmap.select(roaringBitmap.getCardinality() + 1)); + assertThrows( + IllegalArgumentException.class, () -> roaringBitmap.select(roaringBitmap.getCardinality())); + assertThrows( + IllegalArgumentException.class, + () -> roaringBitmap.select(roaringBitmap.getCardinality() + 1)); // FastRankRoaringBitmap behavior has to be identical FastRankRoaringBitmap rankRoaringBitmap = new FastRankRoaringBitmap(); rankRoaringBitmap.add(3); rankRoaringBitmap.add(5); assertEquals(5, rankRoaringBitmap.select(rankRoaringBitmap.getCardinality() - 1)); - assertThrows(IllegalArgumentException.class, () -> rankRoaringBitmap.select(rankRoaringBitmap.getCardinality())); - assertThrows(IllegalArgumentException.class, () -> rankRoaringBitmap.select(rankRoaringBitmap.getCardinality() + 1)); + assertThrows( + IllegalArgumentException.class, + () -> rankRoaringBitmap.select(rankRoaringBitmap.getCardinality())); + assertThrows( + IllegalArgumentException.class, + () -> rankRoaringBitmap.select(rankRoaringBitmap.getCardinality() + 1)); } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestRunContainer.java index c5e156f0f..ab346c43d 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestRunContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestRunContainer.java @@ -1,5 +1,16 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.ArrayContainer.DEFAULT_MAX_SIZE; +import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; +import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -8,30 +19,32 @@ import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.ArrayContainer.DEFAULT_MAX_SIZE; -import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; -import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; @Execution(ExecutionMode.CONCURRENT) public class TestRunContainer { @Test public void testRunOpti() { RoaringBitmap mrb = new RoaringBitmap(); - for(int r = 0; r< 100000; r+=3 ) { + for (int r = 0; r < 100000; r += 3) { mrb.add(r); } mrb.add(1000000); - for(int r = 2000000; r < 3000000; ++r) { + for (int r = 2000000; r < 3000000; ++r) { mrb.add(r); } RoaringBitmap m2 = mrb.clone(); m2.runOptimize(); IntIterator x = m2.getReverseIntIterator(); int count = 0; - while(x.hasNext()) { + while (x.hasNext()) { x.next(); count++; } @@ -78,8 +91,8 @@ static int[] generateUniformHash(Random rand, int N, int Max) { return ans; } - private static void getSetOfRunContainers(ArrayList set, - ArrayList setb) { + private static void getSetOfRunContainers( + ArrayList set, ArrayList setb) { RunContainer r1 = new RunContainer(); r1 = (RunContainer) r1.iadd(0, (1 << 16)); Container b1 = new ArrayContainer(); @@ -139,7 +152,6 @@ private static void getSetOfRunContainers(ArrayList set, set.add(r6); setb.add(b6); - RunContainer r7 = new RunContainer(); Container b7 = new ArrayContainer(); for (int k = 0; k + 1 < 65536; k += 11) { @@ -149,7 +161,6 @@ private static void getSetOfRunContainers(ArrayList set, assertEquals(r7, b7); set.add(r7); setb.add(b7); - } /** @@ -578,7 +589,6 @@ public void equalTest2() { assertEquals(ac, ar); } - @Test public void fillLeastSignificantBits() { Container rc = new RunContainer(); @@ -593,8 +603,6 @@ public void fillLeastSignificantBits() { assertEquals(12, array[3]); } - - @Test public void flip() { RunContainer rc = new RunContainer(); @@ -604,23 +612,24 @@ public void flip() { assertFalse(rc.contains((char) 1)); } - @Test public void iaddInvalidRange1() { - assertThrows(IllegalArgumentException.class, () -> { - Container rc = new RunContainer(); - rc.iadd(10, 9); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container rc = new RunContainer(); + rc.iadd(10, 9); + }); } - - @Test public void iaddInvalidRange2() { - assertThrows(IllegalArgumentException.class, () -> { - Container rc = new RunContainer(); - rc.iadd(0, 1 << 20); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container rc = new RunContainer(); + rc.iadd(0, 1 << 20); + }); } @Test @@ -878,7 +887,6 @@ public void iaddRange7() { assertEquals(16, rc.getSizeInBytes()); } - @Test public void iaddRange8() { Container rc = new RunContainer(); @@ -902,8 +910,6 @@ public void iaddRange8() { assertEquals(12, rc.getSizeInBytes()); } - - @Test public void iaddRangeAndFuseWithPreviousValueLength() { RunContainer container = new RunContainer(); @@ -918,7 +924,6 @@ public void iaddRangeAndFuseWithPreviousValueLength() { assertEquals(8, container.getSizeInBytes()); } - @Test public void iaddRangeOnNonEmptyContainerAndFuse() { RunContainer container = new RunContainer(); @@ -935,7 +940,6 @@ public void iaddRangeOnNonEmptyContainerAndFuse() { } } - @Test public void iaddRangeWithinSetBounds() { RunContainer container = new RunContainer(); @@ -1042,8 +1046,6 @@ public void inot12A() { } } - - @Test public void inot13() { RunContainer container = new RunContainer(); @@ -1099,7 +1101,6 @@ private void inot14once(int num, int rangeSize) { for (int i = 0; i < 65536; ++i) { assertFalse(result.contains((char) i) ^ checker.get(i)); } - } @Test @@ -1146,8 +1147,6 @@ public void inot3() { } } - - @Test public void inot4() { RunContainer container = new RunContainer(); @@ -1165,7 +1164,6 @@ public void inot4() { } } - @Test public void inot5() { RunContainer container = new RunContainer(); @@ -1199,7 +1197,6 @@ public void inot6() { } } - @Test public void inot7() { RunContainer container = new RunContainer(); @@ -1210,7 +1207,6 @@ public void inot7() { container.add((char) 504); container.add((char) 505); - // one run, spans the range Container result = container.inot(502, 504); @@ -1334,6 +1330,7 @@ public void ior2() { rc.ior(ac); assertEquals(512, rc.getCardinality()); } + @Test public void iorNot() { Container rc1 = new RunContainer(); @@ -1482,7 +1479,6 @@ public void orNot() { assertFalse(iterator.hasNext()); } - } @Test @@ -1750,18 +1746,22 @@ public void iremove9() { @Test public void iremoveInvalidRange1() { - assertThrows(IllegalArgumentException.class, () -> { - Container rc = new RunContainer(); - rc.iremove(10, 9); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container rc = new RunContainer(); + rc.iremove(10, 9); + }); } @Test public void iremoveInvalidRange2() { - assertThrows(IllegalArgumentException.class, () -> { - Container rc = new RunContainer(); - rc.remove(0, 1 << 20); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Container rc = new RunContainer(); + rc.remove(0, 1 << 20); + }); } @Test @@ -1802,7 +1802,7 @@ public void iremoveRange() { public void iremoveEmptyRange() { RunContainer container = new RunContainer(); assertEquals(0, container.getCardinality()); - container.iremove(0,0); + container.iremove(0, 0); assertEquals(0, container.getCardinality()); } @@ -1941,7 +1941,6 @@ public void not11() { } } - @Test public void not12() { RunContainer container = new RunContainer(); @@ -1965,7 +1964,6 @@ public void not12() { } } - @Test public void not12A() { RunContainer container = new RunContainer(); @@ -1999,7 +1997,6 @@ public void not13() { } } - @Test public void not14() { not14once(10, 1); @@ -2014,7 +2011,6 @@ public void not14() { } } - private void not14once(int num, int rangeSize) { RunContainer container = new RunContainer(); BitSet checker = new BitSet(); @@ -2037,10 +2033,8 @@ private void not14once(int num, int rangeSize) { for (int i = 0; i < 65536; ++i) { assertFalse(result.contains((char) i) ^ checker.get(i)); } - } - @Test public void not15() { RunContainer container = new RunContainer(); @@ -2058,7 +2052,6 @@ public void not15() { assertTrue(result instanceof RunContainer); } - @Test public void not2() { RunContainer container = new RunContainer(); @@ -2075,7 +2068,6 @@ public void not2() { } } - @Test public void not3() { RunContainer container = new RunContainer(); @@ -2104,7 +2096,6 @@ public void not4() { } } - @Test public void not5() { RunContainer container = new RunContainer(); @@ -2122,8 +2113,6 @@ public void not5() { } } - - @Test public void not6() { RunContainer container = new RunContainer(); @@ -2150,7 +2139,6 @@ public void not7() { container.add((char) 504); container.add((char) 505); - // one run, spans the range Container result = container.not(502, 504); @@ -2160,8 +2148,6 @@ public void not7() { } } - - @Test public void not8() { RunContainer container = new RunContainer(); @@ -2182,8 +2168,6 @@ public void not8() { } } - - @Test public void not9() { RunContainer container = new RunContainer(); @@ -2203,8 +2187,6 @@ public void not9() { } } - - @Test public void randomFun() { final int bitsetperword1 = 32; @@ -2217,7 +2199,6 @@ public void randomFun() { int[] values1 = generateUniformHash(rand, bitsetperword1 * howmanywords, max); int[] values2 = generateUniformHash(rand, bitsetperword2 * howmanywords, max); - rc1 = new RunContainer(); rc1 = fillMeUp(rc1, values1); @@ -2253,7 +2234,6 @@ public void randomFun() { if (!rc1.xor(rc2).equals(ac1.xor(ac2))) { throw new RuntimeException("xors do not match"); } - } @Test @@ -2280,7 +2260,6 @@ public void charRangeRank() { assertEquals(16, container.rank((char) 32)); } - @Test public void remove() { Container rc = new RunContainer(); @@ -2289,8 +2268,6 @@ public void remove() { assertEquals(0, newContainer.getCardinality()); } - - @Test public void RunContainerArg_ArrayAND() { boolean atLeastOneArray = false; @@ -2315,8 +2292,6 @@ public void RunContainerArg_ArrayAND() { assertTrue(atLeastOneArray); } - - @Test public void RunContainerArg_ArrayANDNOT() { boolean atLeastOneArray = false; @@ -2345,22 +2320,24 @@ public void RunContainerArg_ArrayANDNOT() { @Test public void RunContainerArg_ArrayANDNOT2() { - ArrayContainer ac = new ArrayContainer(12, new char[]{0, 2, 4, 8, 10, 15, 16, 48, 50, 61, 80, (char)-2}); - RunContainer rc = new RunContainer(new char[]{7, 3, 17, 2, 20, 3, 30, 3, 36, 6, 60, 5, (char)-3, 2}, 7); - assertEquals(new ArrayContainer(8, new char[]{0, 2, 4, 15, 16, 48, 50, 80}), ac.andNot(rc)); + ArrayContainer ac = + new ArrayContainer(12, new char[] {0, 2, 4, 8, 10, 15, 16, 48, 50, 61, 80, (char) -2}); + RunContainer rc = + new RunContainer(new char[] {7, 3, 17, 2, 20, 3, 30, 3, 36, 6, 60, 5, (char) -3, 2}, 7); + assertEquals(new ArrayContainer(8, new char[] {0, 2, 4, 15, 16, 48, 50, 80}), ac.andNot(rc)); } @Test public void FullRunContainerArg_ArrayANDNOT2() { - ArrayContainer ac = new ArrayContainer(1, new char[]{3}); + ArrayContainer ac = new ArrayContainer(1, new char[] {3}); Container rc = RunContainer.full(); assertEquals(new ArrayContainer(), ac.andNot(rc)); } @Test public void RunContainerArg_ArrayANDNOT3() { - ArrayContainer ac = new ArrayContainer(1, new char[]{5}); - Container rc = new RunContainer(new char[]{3, 10}, 1); + ArrayContainer ac = new ArrayContainer(1, new char[] {5}); + Container rc = new RunContainer(new char[] {3, 10}, 1); assertEquals(new ArrayContainer(), ac.andNot(rc)); } @@ -2415,7 +2392,6 @@ public void RunContainerArg_ArrayXOR() { assertTrue(atLeastOneArray); } - @Test public void RunContainerFromBitmap() { Container rc = new RunContainer(); @@ -2445,13 +2421,11 @@ public void RunContainerFromBitmap() { assertEquals(rc, rc2); } - @Test public void RunContainerFromBitmap1() { Container rc = new RunContainer(); Container bc = new BitmapContainer(); - rc = rc.add((char) 2); bc = bc.add((char) 2); rc = rc.add((char) 3); @@ -2478,7 +2452,6 @@ public void RunContainerFromBitmap1() { assertEquals(rc, rc2); } - @Test public void RunContainerFromBitmap2() { Container rc = new RunContainer(); @@ -2508,12 +2481,10 @@ public void RunContainerFromBitmap2() { rc = rc.add((char) 65535); bc = bc.add((char) 65535); - RunContainer rc2 = new RunContainer((BitmapContainer) bc, ((RunContainer) rc).nbrruns); assertEquals(rc, rc2); } - @Test public void RunContainerFromBitmap3() { Container rc = new RunContainer(); @@ -2563,7 +2534,6 @@ public void RunContainerVSRunContainerAND() { } } - @Test public void RunContainerVSRunContainerANDNOT() { ArrayList set = new ArrayList(); @@ -2580,8 +2550,6 @@ public void RunContainerVSRunContainerANDNOT() { } } - - @Test public void RunContainerVSRunContainerOR() { ArrayList set = new ArrayList(); @@ -2614,8 +2582,6 @@ public void RunContainerVSRunContainerXOR() { } } - - @Test public void safeor() { Container rc1 = new RunContainer(); @@ -2681,8 +2647,6 @@ public void safeSerialization() throws Exception { assertEquals(container.serializedSizeInBytes(), newContainer.serializedSizeInBytes()); } - - @Test public void select() { RunContainer container = new RunContainer(); @@ -2700,13 +2664,15 @@ public void select() { @Test public void select2() { - assertThrows(IllegalArgumentException.class, () -> { - RunContainer container = new RunContainer(); - container.add((char) 0); - container.add((char) 3); - container.add((char) 118); - container.select(666); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + RunContainer container = new RunContainer(); + container.add((char) 0); + container.add((char) 3); + container.add((char) 118); + container.select(666); + }); } @Test @@ -2723,11 +2689,12 @@ public void simpleIterator() { assertFalse(i.hasNext()); } - @Test public void testAndNot() { - int[] array1 = {39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, - 39184, 39185, 39186, 39187, 39188}; + int[] array1 = { + 39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, 39184, 39185, + 39186, 39187, 39188 + }; int[] array2 = {14205}; RoaringBitmap rb1 = RoaringBitmap.bitmapOf(array1); rb1.runOptimize(); @@ -2736,8 +2703,6 @@ public void testAndNot() { assertEquals(answer.getCardinality(), array1.length); } - - @Test public void testRoaringWithOptimize() { // create the same bitmap over and over again, with optimizing it @@ -2755,7 +2720,6 @@ public void testRoaringWithOptimize() { assertEquals(1, setWithOptimize.size()); } - @Test public void testRoaringWithoutOptimize() { // create the same bitmap over and over again, without optimizing it @@ -2809,7 +2773,6 @@ public void union() { assertEquals(100, rc.getCardinality()); } - @Test public void union2() { System.out.println("union2"); @@ -2829,7 +2792,6 @@ public void union2() { assertEquals(100, rc.getCardinality()); } - @Test public void xor() { Container bc = new BitmapContainer(); @@ -2850,7 +2812,6 @@ public void xor() { assertEquals(4 * DEFAULT_MAX_SIZE, rc.getCardinality()); } - @Test public void xor_array() { Container bc = new ArrayContainer(); @@ -2871,8 +2832,6 @@ public void xor_array() { assertEquals(4 * DEFAULT_MAX_SIZE, rc.getCardinality()); } - - @Test public void xor_array_largecase_runcontainer_best() { Container bc = new ArrayContainer(); @@ -2913,7 +2872,6 @@ public void xor_array_largecase_runcontainer_best() { } } - @Test public void xor_array_mediumcase() { Container bc = new ArrayContainer(); @@ -2961,7 +2919,6 @@ public void xor_array_mediumcase() { } } - @Test public void xor_array_smallcase() { Container bc = new ArrayContainer(); @@ -2982,7 +2939,6 @@ public void xor_array_smallcase() { int rcSize = rc.getCardinality(); int bcSize = bc.getCardinality(); - Container result = rc.xor(bc); // input containers should not change (just check card) @@ -2993,7 +2949,6 @@ public void xor_array_smallcase() { assertTrue(result.contains((char) 5)); assertTrue(result.contains((char) 0)); - for (int k = 1; k < DEFAULT_MAX_SIZE / 3; ++k) { for (int i = 0; i < 5; ++i) { assertTrue(result.contains((char) (k * 10 + i))); @@ -3021,7 +2976,6 @@ public void xor1a() { assertTrue(result.contains((char) 1)); } - @Test public void xor2() { Container bc = new BitmapContainer(); @@ -3032,7 +2986,6 @@ public void xor2() { assertTrue(result.contains((char) 1)); } - @Test public void xor2a() { Container bc = new ArrayContainer(); @@ -3043,7 +2996,6 @@ public void xor2a() { assertTrue(result.contains((char) 1)); } - @Test public void xor3() { Container bc = new BitmapContainer(); @@ -3054,8 +3006,6 @@ public void xor3() { assertEquals(0, result.getCardinality()); } - - @Test public void xor3a() { Container bc = new ArrayContainer(); @@ -3066,8 +3016,6 @@ public void xor3a() { assertEquals(0, result.getCardinality()); } - - @Test public void xor4() { Container bc = new ArrayContainer(); @@ -3111,12 +3059,12 @@ public void intersects1() { assertFalse(ac.intersects(rc)); rc = rc.remove((char) 1000); - rc = rc.add(100,200); - rc = rc.add(300,500); + rc = rc.add(100, 200); + rc = rc.add(300, 500); assertFalse(rc.intersects(ac)); assertFalse(ac.intersects(rc)); - rc = rc.add(500,1000); + rc = rc.add(500, 1000); assertTrue(rc.intersects(ac)); assertTrue(ac.intersects(rc)); } @@ -3155,7 +3103,7 @@ public void intersects3() { @Test public void constructor1() { - assertThrows(RuntimeException.class, () -> new RunContainer(new char[]{1, 2, 10, 3}, 5)); + assertThrows(RuntimeException.class, () -> new RunContainer(new char[] {1, 2, 10, 3}, 5)); } @Test @@ -3171,7 +3119,7 @@ public void ensureCapacity() { @Test public void testToString() { Container rc = new RunContainer(32200, 35000); - rc.add((char)-1); + rc.add((char) -1); assertEquals("[32200,34999][65535,65535]", rc.toString()); } @@ -3190,9 +3138,9 @@ public void lazyIOR() { assertEquals(13, rc.getCardinality()); rc = new RunContainer(); - rc = rc.add(0, 1<<16); + rc = rc.add(0, 1 << 16); rc = rc.lazyIOR(ac); - assertEquals(1<<16, rc.getCardinality()); + assertEquals(1 << 16, rc.getCardinality()); } @Test @@ -3210,9 +3158,9 @@ public void lazyOR() { assertEquals(13, rc.getCardinality()); rc = new RunContainer(); - rc = rc.add(0, 1<<16); + rc = rc.add(0, 1 << 16); rc = rc.lazyOR(ac); - assertEquals(1<<16, rc.getCardinality()); + assertEquals(1 << 16, rc.getCardinality()); } @Test @@ -3250,7 +3198,7 @@ public void testLazyORFull3() { @Test public void testRangeCardinality() { BitmapContainer bc = TestBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); Container result = rc.or(bc); assertEquals(8677, result.getCardinality()); } @@ -3258,9 +3206,9 @@ public void testRangeCardinality() { @Test public void testRangeCardinality2() { BitmapContainer bc = TestBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - bc.add((char)22345); //important case to have greater element than run container - bc.add((char)Short.MAX_VALUE); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 18000}, 3); + bc.add((char) 22345); // important case to have greater element than run container + bc.add((char) Short.MAX_VALUE); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 18000}, 3); assertTrue(rc.getCardinality() > ArrayContainer.DEFAULT_MAX_SIZE); Container result = rc.andNot(bc); assertEquals(11437, result.getCardinality()); @@ -3269,7 +3217,7 @@ public void testRangeCardinality2() { @Test public void testRangeCardinality3() { BitmapContainer bc = TestBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 5200}, 3); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 5200}, 3); BitmapContainer result = (BitmapContainer) rc.and(bc); assertEquals(5046, result.getCardinality()); } @@ -3277,7 +3225,7 @@ public void testRangeCardinality3() { @Test public void testRangeCardinality4() { BitmapContainer bc = TestBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - RunContainer rc = new RunContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + RunContainer rc = new RunContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); BitmapContainer result = (BitmapContainer) rc.xor(bc); assertEquals(6031, result.getCardinality()); } @@ -3322,50 +3270,49 @@ public void testContainsBitmapContainer_EmptyContainsEmpty() { @Test public void testContainsBitmapContainer_IncludeProperSubset() { - Container rc = new RunContainer().add(0,10); - Container subset = new BitmapContainer().add(0,9); + Container rc = new RunContainer().add(0, 10); + Container subset = new BitmapContainer().add(0, 9); assertTrue(rc.contains(subset)); } - @Test public void testContainsBitmapContainer_IncludeProperSubsetDifferentStart() { - Container rc = new RunContainer().add(0,10); - Container subset = new BitmapContainer().add(1,9); + Container rc = new RunContainer().add(0, 10); + Container subset = new BitmapContainer().add(1, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsBitmapContainer_IncludeProperSubsetMultiWordRun() { - Container rc = new RunContainer().add(0,80); - Container subset = new BitmapContainer().add(0,79); + Container rc = new RunContainer().add(0, 80); + Container subset = new BitmapContainer().add(0, 79); assertTrue(rc.contains(subset)); } @Test public void testContainsBitmapContainer_ExcludeShiftedSet() { - Container rc = new RunContainer().add(0,10); - Container subset = new BitmapContainer().add(2,12); + Container rc = new RunContainer().add(0, 10); + Container subset = new BitmapContainer().add(2, 12); assertFalse(rc.contains(subset)); } @Test public void testContainsBitmapContainer_IncludeSelf() { - Container rc = new RunContainer().add(0,10); - Container subset = new BitmapContainer().add(0,10); + Container rc = new RunContainer().add(0, 10); + Container subset = new BitmapContainer().add(0, 10); assertTrue(rc.contains(subset)); } @Test public void testContainsBitmapContainer_ExcludeSuperSet() { - Container rc = new RunContainer().add(0,10); - Container superset = new BitmapContainer().add(0,20); + Container rc = new RunContainer().add(0, 10); + Container superset = new BitmapContainer().add(0, 20); assertFalse(rc.contains(superset)); } @Test public void testContainsBitmapContainer_ExcludeDisJointSet() { - Container rc = new RunContainer().add(0,10); + Container rc = new RunContainer().add(0, 10); Container disjoint = new BitmapContainer().add(20, 40); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); @@ -3373,15 +3320,15 @@ public void testContainsBitmapContainer_ExcludeDisJointSet() { @Test public void testContainsBitmapContainer_Issue721Case1() { - Container rc = new RunContainer().add(0,60).add(63,64).add(66,67); - Container subset = new BitmapContainer().add(63,64); + Container rc = new RunContainer().add(0, 60).add(63, 64).add(66, 67); + Container subset = new BitmapContainer().add(63, 64); assertTrue(rc.contains(subset)); } @Test public void testContainsBitmapContainer_Issue721Case2() { - Container rc = new RunContainer().add(0,10).add(12,13); - Container disjoint = new BitmapContainer().add(11,12); + Container rc = new RunContainer().add(0, 10).add(12, 13); + Container disjoint = new BitmapContainer().add(11, 12); assertFalse(rc.contains(disjoint)); } @@ -3401,42 +3348,42 @@ public void testContainsRunContainer_EmptyContainsEmpty() { @Test public void testContainsRunContainer_IncludeProperSubset() { - Container rc = new RunContainer().add(0,10); - Container subset = new RunContainer().add(0,9); + Container rc = new RunContainer().add(0, 10); + Container subset = new RunContainer().add(0, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsRunContainer_IncludeSelf() { - Container rc = new RunContainer().add(0,10); - Container subset = new RunContainer().add(0,10); + Container rc = new RunContainer().add(0, 10); + Container subset = new RunContainer().add(0, 10); assertTrue(rc.contains(subset)); } @Test public void testContainsRunContainer_ExcludeSuperSet() { - Container rc = new RunContainer().add(0,10); - Container superset = new RunContainer().add(0,20); + Container rc = new RunContainer().add(0, 10); + Container superset = new RunContainer().add(0, 20); assertFalse(rc.contains(superset)); } @Test public void testContainsRunContainer_IncludeProperSubsetDifferentStart() { - Container rc = new RunContainer().add(0,10); - Container subset = new RunContainer().add(1,9); + Container rc = new RunContainer().add(0, 10); + Container subset = new RunContainer().add(1, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsRunContainer_ExcludeShiftedSet() { - Container rc = new RunContainer().add(0,10); - Container subset = new RunContainer().add(2,12); + Container rc = new RunContainer().add(0, 10); + Container subset = new RunContainer().add(2, 12); assertFalse(rc.contains(subset)); } @Test public void testContainsRunContainer_ExcludeDisJointSet() { - Container rc = new RunContainer().add(0,10); + Container rc = new RunContainer().add(0, 10); Container disjoint = new RunContainer().add(20, 40); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); @@ -3451,36 +3398,36 @@ public void testContainsArrayContainer_EmptyContainsEmpty() { @Test public void testContainsArrayContainer_IncludeProperSubset() { - Container rc = new RunContainer().add(0,10); - Container subset = new ArrayContainer().add(0,9); + Container rc = new RunContainer().add(0, 10); + Container subset = new ArrayContainer().add(0, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsArrayContainer_IncludeProperSubsetDifferentStart() { - Container rc = new RunContainer().add(0,10); - Container subset = new ArrayContainer().add(2,9); + Container rc = new RunContainer().add(0, 10); + Container subset = new ArrayContainer().add(2, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsArrayContainer_ExcludeShiftedSet() { - Container rc = new RunContainer().add(0,10); - Container shifted = new ArrayContainer().add(2,12); + Container rc = new RunContainer().add(0, 10); + Container shifted = new ArrayContainer().add(2, 12); assertFalse(rc.contains(shifted)); } @Test public void testContainsArrayContainer_IncludeSelf() { - Container rc = new RunContainer().add(0,10); - Container subset = new ArrayContainer().add(0,10); + Container rc = new RunContainer().add(0, 10); + Container subset = new ArrayContainer().add(0, 10); assertTrue(rc.contains(subset)); } @Test public void testContainsArrayContainer_ExcludeSuperSet() { - Container rc = new RunContainer().add(0,10); - Container superset = new ArrayContainer().add(0,20); + Container rc = new RunContainer().add(0, 10); + Container superset = new ArrayContainer().add(0, 20); assertFalse(rc.contains(superset)); } @@ -3491,20 +3438,17 @@ public void testContainsArrayContainer_ExcludeDisJointSet() { assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); - disjoint = new ArrayContainer().add((char)512); + disjoint = new ArrayContainer().add((char) 512); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); - rc = rc.add(12,14).add(16,18).add(20,22); + rc = rc.add(12, 14).add(16, 18).add(20, 22); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); rc.trim(); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); - - - } @Test @@ -3543,7 +3487,7 @@ public void testEqualsArrayContainer_NotEqual_ArrayShifted() { public void testEqualsArrayContainer_NotEqual_ArrayDiscontiguous() { Container rc = new RunContainer().add(0, 10); Container ac = new ArrayContainer().add(0, 11); - ac.flip((char)9); + ac.flip((char) 9); assertNotEquals(rc, ac); assertNotEquals(ac, rc); } @@ -3603,18 +3547,16 @@ public void testIntersectsWithRange() { assertFalse(container.intersects(11, 1 << 16)); } - @Test public void testIntersectsWithRangeUnsigned() { Container container = new RunContainer().add(lower16Bits(-50), lower16Bits(-10)); assertFalse(container.intersects(0, 1)); assertTrue(container.intersects(0, lower16Bits(-40))); assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); - //assertFalse(container.intersects(-9, 1 << 16)); // forbidden + // assertFalse(container.intersects(-9, 1 << 16)); // forbidden assertTrue(container.intersects(11, 1 << 16)); } - @Test public void testIntersectsWithRangeManyRuns() { Container container = new RunContainer().add(0, 10).add(lower16Bits(-50), lower16Bits(-10)); @@ -3631,7 +3573,7 @@ public void testIntersectsWithRangeManyRuns() { @Test public void testContainsFull() { assertTrue(RunContainer.full().contains(0, 1 << 16)); - assertFalse(RunContainer.full().flip((char)(1 << 15)).contains(0, 1 << 16)); + assertFalse(RunContainer.full().flip((char) (1 << 15)).contains(0, 1 << 16)); } @Test @@ -3654,11 +3596,8 @@ public void testContainsRange() { @Test public void testContainsRange3() { - Container rc = new RunContainer().add(1, 100) - .add(300, 300) - .add(400, 500) - .add(502, 600) - .add(700, 10000); + Container rc = + new RunContainer().add(1, 100).add(300, 300).add(400, 500).add(502, 600).add(700, 10000); assertFalse(rc.contains(0, 100)); assertFalse(rc.contains(500, 600)); assertFalse(rc.contains(501, 600)); @@ -3670,135 +3609,139 @@ public void testContainsRange3() { @Test public void testNextValue() { - RunContainer container = new RunContainer(new char[] { 64, 64 }, 1); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(-1, container.nextValue((char)129)); + RunContainer container = new RunContainer(new char[] {64, 64}, 1); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(-1, container.nextValue((char) 129)); } @Test public void testNextValueBetweenRuns() { - RunContainer container = new RunContainer(new char[] { 64, 64, 256, 64 }, 2); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(256, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)512)); + RunContainer container = new RunContainer(new char[] {64, 64, 256, 64}, 2); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(256, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 512)); } @Test public void testNextValue2() { - RunContainer container = new RunContainer(new char[] { 64, 64, 200, 300, 5000, 200 }, 3); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)63)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(200, container.nextValue((char)129)); - assertEquals(200, container.nextValue((char)199)); - assertEquals(200, container.nextValue((char)200)); - assertEquals(250, container.nextValue((char)250)); - assertEquals(5000, container.nextValue((char)2500)); - assertEquals(5000, container.nextValue((char)5000)); - assertEquals(5200, container.nextValue((char)5200)); - assertEquals(-1, container.nextValue((char)5201)); + RunContainer container = new RunContainer(new char[] {64, 64, 200, 300, 5000, 200}, 3); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 63)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(200, container.nextValue((char) 129)); + assertEquals(200, container.nextValue((char) 199)); + assertEquals(200, container.nextValue((char) 200)); + assertEquals(250, container.nextValue((char) 250)); + assertEquals(5000, container.nextValue((char) 2500)); + assertEquals(5000, container.nextValue((char) 5000)); + assertEquals(5200, container.nextValue((char) 5200)); + assertEquals(-1, container.nextValue((char) 5201)); } @Test public void testPreviousValue1() { - RunContainer container = new RunContainer(new char[] { 64, 64 }, 1); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); + RunContainer container = new RunContainer(new char[] {64, 64}, 1); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); } @Test public void testPreviousValue2() { - RunContainer container = new RunContainer(new char[] { 64, 64, 200, 300, 5000, 200 }, 3); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - assertEquals(128, container.previousValue((char)199)); - assertEquals(200, container.previousValue((char)200)); - assertEquals(250, container.previousValue((char)250)); - assertEquals(500, container.previousValue((char)2500)); - assertEquals(5000, container.previousValue((char)5000)); - assertEquals(5200, container.previousValue((char)5200)); + RunContainer container = new RunContainer(new char[] {64, 64, 200, 300, 5000, 200}, 3); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + assertEquals(128, container.previousValue((char) 199)); + assertEquals(200, container.previousValue((char) 200)); + assertEquals(250, container.previousValue((char) 250)); + assertEquals(500, container.previousValue((char) 2500)); + assertEquals(5000, container.previousValue((char) 5000)); + assertEquals(5200, container.previousValue((char) 5200)); } @Test public void testPreviousValueUnsigned() { - RunContainer container = new RunContainer(new char[] { (char)((1 << 15) | 5), (char)0, (char)((1 << 15) | 7), (char)0}, 2); - assertEquals(-1, container.previousValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 8))); + RunContainer container = + new RunContainer( + new char[] {(char) ((1 << 15) | 5), (char) 0, (char) ((1 << 15) | 7), (char) 0}, 2); + assertEquals(-1, container.previousValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 8))); } @Test public void testNextValueUnsigned() { - RunContainer container = new RunContainer(new char[] { (char)((1 << 15) | 5), (char)0, (char)((1 << 15) | 7), (char)0}, 2); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 7))); - assertEquals(-1, container.nextValue((char)((1 << 15) | 8))); + RunContainer container = + new RunContainer( + new char[] {(char) ((1 << 15) | 5), (char) 0, (char) ((1 << 15) | 7), (char) 0}, 2); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 7))); + assertEquals(-1, container.nextValue((char) ((1 << 15) | 8))); } @Test public void testPreviousAbsentValue1() { Container container = new RunContainer().iadd(64, 129); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); } @Test public void testPreviousAbsentValue2() { Container container = new RunContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - assertEquals(199, container.previousAbsentValue((char)199)); - assertEquals(199, container.previousAbsentValue((char)200)); - assertEquals(199, container.previousAbsentValue((char)250)); - assertEquals(2500, container.previousAbsentValue((char)2500)); - assertEquals(4999, container.previousAbsentValue((char)5000)); - assertEquals(4999, container.previousAbsentValue((char)5200)); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + assertEquals(199, container.previousAbsentValue((char) 199)); + assertEquals(199, container.previousAbsentValue((char) 200)); + assertEquals(199, container.previousAbsentValue((char) 250)); + assertEquals(2500, container.previousAbsentValue((char) 2500)); + assertEquals(4999, container.previousAbsentValue((char) 5000)); + assertEquals(4999, container.previousAbsentValue((char) 5200)); } @Test public void testPreviousAbsentValueEmpty() { RunContainer container = new RunContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.previousAbsentValue((char)i)); + assertEquals(i, container.previousAbsentValue((char) i)); } } @Test public void testPreviousAbsentValueSparse() { - RunContainer container = new RunContainer(new char[] { 10, 0, 20, 0, 30, 0}, 3); - assertEquals(9, container.previousAbsentValue((char)9)); - assertEquals(9, container.previousAbsentValue((char)10)); - assertEquals(11, container.previousAbsentValue((char)11)); - assertEquals(21, container.previousAbsentValue((char)21)); - assertEquals(29, container.previousAbsentValue((char)30)); + RunContainer container = new RunContainer(new char[] {10, 0, 20, 0, 30, 0}, 3); + assertEquals(9, container.previousAbsentValue((char) 9)); + assertEquals(9, container.previousAbsentValue((char) 10)); + assertEquals(11, container.previousAbsentValue((char) 11)); + assertEquals(21, container.previousAbsentValue((char) 21)); + assertEquals(29, container.previousAbsentValue((char) 30)); } @Test @@ -3810,67 +3753,67 @@ public void testPreviousAbsentEvenBits() { } RunContainer container = new RunContainer(evenBits, 1 << 14); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i - 1, container.previousAbsentValue((char)i)); - assertEquals(i + 1, container.previousAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i - 1, container.previousAbsentValue((char) i)); + assertEquals(i + 1, container.previousAbsentValue((char) (i + 1))); } } @Test public void testPreviousAbsentValueUnsigned() { - RunContainer container = new RunContainer(new char[] { (char)((1 << 15) | 5), 0, (char)((1 << 15) | 7), 0}, 2); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.previousAbsentValue((char)((1 << 15) | 8))); + RunContainer container = + new RunContainer(new char[] {(char) ((1 << 15) | 5), 0, (char) ((1 << 15) | 7), 0}, 2); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.previousAbsentValue((char) ((1 << 15) | 8))); } - @Test public void testNextAbsentValue1() { Container container = new RunContainer().iadd(64, 129); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); } @Test public void testNextAbsentValue2() { Container container = new RunContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - assertEquals(199, container.nextAbsentValue((char)199)); - assertEquals(501, container.nextAbsentValue((char)200)); - assertEquals(501, container.nextAbsentValue((char)250)); - assertEquals(2500, container.nextAbsentValue((char)2500)); - assertEquals(5201, container.nextAbsentValue((char)5000)); - assertEquals(5201, container.nextAbsentValue((char)5200)); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + assertEquals(199, container.nextAbsentValue((char) 199)); + assertEquals(501, container.nextAbsentValue((char) 200)); + assertEquals(501, container.nextAbsentValue((char) 250)); + assertEquals(2500, container.nextAbsentValue((char) 2500)); + assertEquals(5201, container.nextAbsentValue((char) 5000)); + assertEquals(5201, container.nextAbsentValue((char) 5200)); } @Test public void testNextAbsentValueEmpty() { RunContainer container = new RunContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.nextAbsentValue((char)i)); + assertEquals(i, container.nextAbsentValue((char) i)); } } @Test public void testNextAbsentValueSparse() { - Container container = new RunContainer(new char[] { 10, 0, 20, 0, 30, 0}, 3); - assertEquals(9, container.nextAbsentValue((char)9)); - assertEquals(11, container.nextAbsentValue((char)10)); - assertEquals(11, container.nextAbsentValue((char)11)); - assertEquals(21, container.nextAbsentValue((char)21)); - assertEquals(31, container.nextAbsentValue((char)30)); + Container container = new RunContainer(new char[] {10, 0, 20, 0, 30, 0}, 3); + assertEquals(9, container.nextAbsentValue((char) 9)); + assertEquals(11, container.nextAbsentValue((char) 10)); + assertEquals(11, container.nextAbsentValue((char) 11)); + assertEquals(21, container.nextAbsentValue((char) 21)); + assertEquals(31, container.nextAbsentValue((char) 30)); } @Test @@ -3882,31 +3825,38 @@ public void testNextAbsentEvenBits() { } RunContainer container = new RunContainer(evenBits, 1 << 14); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i + 1, container.nextAbsentValue((char)i)); - assertEquals(i + 1, container.nextAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i + 1, container.nextAbsentValue((char) i)); + assertEquals(i + 1, container.nextAbsentValue((char) (i + 1))); } } @Test public void testNextAbsentValueUnsigned() { - RunContainer container = new RunContainer(new char[] { (char)((1 << 15) | 5), 0, (char)((1 << 15) | 7), 0}, 2); - assertEquals(((1 << 15) | 4), container.nextAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 8))); + RunContainer container = + new RunContainer(new char[] {(char) ((1 << 15) | 5), 0, (char) ((1 << 15) | 7), 0}, 2); + assertEquals(((1 << 15) | 4), container.nextAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 8))); } @Test public void testContains() { - RunContainer rc = new RunContainer(new char[]{23, 24}, 1); + RunContainer rc = new RunContainer(new char[] {23, 24}, 1); assertFalse(rc.contains(48, 49)); } @Test public void testIntersects() { - RunContainer rc = new RunContainer(new char[]{41, 15, 215, 0, 217, 2790, 3065, 170, 3269, 422, 3733, 43, 3833, 16, 3852, 7, 3662, 3, 3901, 2}, 10); + RunContainer rc = + new RunContainer( + new char[] { + 41, 15, 215, 0, 217, 2790, 3065, 170, 3269, 422, 3733, 43, 3833, 16, 3852, 7, 3662, 3, + 3901, 2 + }, + 10); assertFalse(rc.intersects(57, 215)); } @@ -3920,43 +3870,52 @@ public void testRangeConsumer() { container.add((char) 65530); container.iadd(65534, 65536); - ValidationRangeConsumer consumer = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - ABSENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, PRESENT - }); + ValidationRangeConsumer consumer = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + ABSENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, ABSENT, PRESENT, PRESENT, ABSENT, + PRESENT + }); container.forAllUntil(0, (char) 11, consumer); assertEquals(11, consumer.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - PRESENT, ABSENT, ABSENT, PRESENT, PRESENT - }); + ValidationRangeConsumer consumer2 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] {PRESENT, ABSENT, ABSENT, PRESENT, PRESENT}); container.forAllInRange((char) 4, (char) 9, consumer2); assertEquals(5, consumer2.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[] { - PRESENT, ABSENT, ABSENT, ABSENT, PRESENT, PRESENT - }); + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + PRESENT, ABSENT, ABSENT, ABSENT, PRESENT, PRESENT + }); container.forAllFrom((char) 65530, consumer3); assertEquals(6, consumer3.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer4 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer4 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); container.forAll(0, consumer4); consumer4.assertAllAbsentExcept(entries, 0); - ValidationRangeConsumer consumer5 = ValidationRangeConsumer.ofSize(2 * BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer5 = + ValidationRangeConsumer.ofSize(2 * BitmapContainer.MAX_CAPACITY); consumer5.acceptAllAbsent(0, BitmapContainer.MAX_CAPACITY); container.forAll(BitmapContainer.MAX_CAPACITY, consumer5); consumer5.assertAllAbsentExcept(entries, BitmapContainer.MAX_CAPACITY); // Completely Empty container = new RunContainer(); - ValidationRangeConsumer consumer6 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer6 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); container.forAll(0, consumer6); consumer6.assertAllAbsent(); // Completely Full container = new RunContainer(); container.iadd(0, BitmapContainer.MAX_CAPACITY); - ValidationRangeConsumer consumer7 = ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); + ValidationRangeConsumer consumer7 = + ValidationRangeConsumer.ofSize(BitmapContainer.MAX_CAPACITY); container.forAll(0, consumer7); consumer7.assertAllPresent(); @@ -3977,14 +3936,14 @@ public void testRangeConsumer() { @Test public void iorWithFullContainer() { - Container container = new ArrayContainer(new char[] {1, 3, 4, (char)-1}); + Container container = new ArrayContainer(new char[] {1, 3, 4, (char) -1}); container = container.ior(RunContainer.full()); assertEquals(RunContainer.full(), container); } @Test public void toBitmapContainer() { - Container rc = new RunContainer().add((char)1).add(5, 7).add(10, 21); + Container rc = new RunContainer().add((char) 1).add(5, 7).add(10, 21); BitmapContainer bitmapContainer = rc.toBitmapContainer(); assertTrue(bitmapContainer.contains((char) 1)); @@ -3995,6 +3954,6 @@ public void toBitmapContainer() { } private static int lower16Bits(int x) { - return ((char)x) & 0xFFFF; + return ((char) x) & 0xFFFF; } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestSerialization.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerialization.java index 20f39f457..0eea3deaa 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestSerialization.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerialization.java @@ -1,20 +1,26 @@ package org.roaringbitmap; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.roaringbitmap.buffer.ImmutableRoaringBitmap; import org.roaringbitmap.buffer.MutableRoaringBitmap; -import java.io.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Base64; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Random; -import java.util.Base64; - -import static org.junit.jupiter.api.Assertions.assertEquals; - class ByteBufferBackedInputStream extends InputStream { @@ -64,8 +70,6 @@ public long skip(long n) { } } - - class ByteBufferBackedOutputStream extends OutputStream { ByteBuffer buf; @@ -87,10 +91,8 @@ public synchronized void write(byte[] bytes, int off, int len) throws IOExceptio public synchronized void write(int b) throws IOException { buf.put((byte) b); } - } - public class TestSerialization { static RoaringBitmap bitmap_a; @@ -142,17 +144,18 @@ public static void init() throws IOException { */ // do not runoptimize bitmap_a1 - outbb = ByteBuffer - .allocate(bitmap_a.serializedSizeInBytes() + bitmap_empty.serializedSizeInBytes()); - presoutbb = ByteBuffer - .allocate(bitmap_a.serializedSizeInBytes() + bitmap_empty.serializedSizeInBytes()); + outbb = + ByteBuffer.allocate( + bitmap_a.serializedSizeInBytes() + bitmap_empty.serializedSizeInBytes()); + presoutbb = + ByteBuffer.allocate( + bitmap_a.serializedSizeInBytes() + bitmap_empty.serializedSizeInBytes()); ByteBufferBackedOutputStream out = new ByteBufferBackedOutputStream(presoutbb); DataOutputStream dos = new DataOutputStream(out); bitmap_empty.serialize(dos); bitmap_a.serialize(dos); presoutbb.flip(); - } private static int[] takeSortedAndDistinct(Random source, int count) { @@ -171,7 +174,6 @@ private static int[] takeSortedAndDistinct(Random source, int count) { return unboxed; } - private static int[] toArray(LinkedHashSet integers) { int[] ints = new int[integers.size()]; int i = 0; @@ -181,7 +183,6 @@ private static int[] toArray(LinkedHashSet integers) { return ints; } - @Test public void testDeserialize() throws IOException { presoutbb.rewind(); @@ -201,8 +202,6 @@ public void testDeserialize_buffer() throws IOException { assertEquals(bitmap_a, bitmap_b); } - - @Test public void testImmutableBuildingBySerialization() { presoutbb.rewind(); @@ -231,8 +230,8 @@ public void testImmutableBuildingBySerialization() { int val1 = it1.next(), val2 = it2.next(); if (val1 != val2) { if (++blabcount < 10) { - System.out - .println("disagree on " + valcount + " nonmatching values are " + val1 + " " + val2); + System.out.println( + "disagree on " + valcount + " nonmatching values are " + val1 + " " + val2); } } } @@ -245,7 +244,6 @@ public void testImmutableBuildingBySerialization() { assertEquals(cksum1, cksum2); } - @Test public void testImmutableBuildingBySerializationSimple() { System.out.println("testImmutableBuildingBySerializationSimple "); @@ -295,7 +293,6 @@ public void testMutableBuilding() { assertEquals(cksum1, cksum2); } - @Test public void testMutableBuildingBySerialization() throws IOException { presoutbb.rewind(); @@ -316,8 +313,6 @@ public void testMutableBuildingBySerialization() throws IOException { assertEquals(cksum1, cksum2); } - - @Test public void testMutableDeserializeMutable() throws IOException { presoutbb.rewind(); @@ -357,7 +352,9 @@ public void testMutableRunSerializationBasicDeserialization() throws java.io.IOE assertEquals(bitmap_am.serializedSizeInBytes(), bitmap_a.serializedSizeInBytes()); assertEquals(bitmap_amr.serializedSizeInBytes(), bitmap_ar.serializedSizeInBytes()); - ByteBuffer outbuf = ByteBuffer.allocate(2*(bitmap_a.serializedSizeInBytes() + bitmap_ar.serializedSizeInBytes())); + ByteBuffer outbuf = + ByteBuffer.allocate( + 2 * (bitmap_a.serializedSizeInBytes() + bitmap_ar.serializedSizeInBytes())); DataOutputStream out = new DataOutputStream(new ByteBufferBackedOutputStream(outbuf)); try { bitmap_a.serialize(out); @@ -388,7 +385,6 @@ public void testMutableRunSerializationBasicDeserialization() throws java.io.IOE assertEquals(bitmap_ar, bitmap_c2); assertEquals(bitmap_ar, bitmap_c3); assertEquals(bitmap_ar, bitmap_c4); - } @Test @@ -402,7 +398,6 @@ public void testMutableSerialize() throws IOException { bitmap_ar.serialize(dos); } - @Test public void testRunSerializationDeserialization() throws java.io.IOException { final int[] data = takeSortedAndDistinct(new Random(07734), 100000); @@ -438,8 +433,6 @@ public void testRunSerializationDeserialization() throws java.io.IOException { assertEquals(bitmap_a, bitmap_c); } - - @Test public void testSerialize() throws IOException { outbb.rewind(); @@ -508,4 +501,3 @@ public void testDeserializeSmallDataMutable() throws IOException { assertEquals(actual, expected); } } - diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java index 046155812..7d1546139 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializationViaByteBuffer.java @@ -1,5 +1,9 @@ package org.roaringbitmap; +import static java.nio.channels.FileChannel.MapMode.READ_WRITE; +import static java.nio.file.Files.delete; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -10,7 +14,12 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.file.Files; @@ -18,10 +27,6 @@ import java.util.UUID; import java.util.stream.Stream; -import static java.nio.channels.FileChannel.MapMode.READ_WRITE; -import static java.nio.file.Files.delete; -import static org.junit.jupiter.api.Assertions.assertEquals; - @Execution(ExecutionMode.CONCURRENT) public class TestSerializationViaByteBuffer { @@ -32,63 +37,62 @@ public static void cleanup() { public static Stream params() { return Stream.of( - Arguments.of(2, ByteOrder.BIG_ENDIAN, true), - Arguments.of(2, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(3, ByteOrder.BIG_ENDIAN, true), - Arguments.of(3, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(4, ByteOrder.BIG_ENDIAN, true), - Arguments.of(4, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(5, ByteOrder.BIG_ENDIAN, true), - Arguments.of(5, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(6, ByteOrder.BIG_ENDIAN, true), - Arguments.of(6, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(7, ByteOrder.BIG_ENDIAN, true), - Arguments.of(7, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(8, ByteOrder.BIG_ENDIAN, true), - Arguments.of(8, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(9, ByteOrder.BIG_ENDIAN, true), - Arguments.of(9, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(10, ByteOrder.BIG_ENDIAN, true), - Arguments.of(10, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(11, ByteOrder.BIG_ENDIAN, true), - Arguments.of(11, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(12, ByteOrder.BIG_ENDIAN, true), - Arguments.of(12, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(13, ByteOrder.BIG_ENDIAN, true), - Arguments.of(13, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(14, ByteOrder.BIG_ENDIAN, true), - Arguments.of(14, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(15, ByteOrder.BIG_ENDIAN, true), - Arguments.of(15, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(2, ByteOrder.BIG_ENDIAN, false), - Arguments.of(2, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(3, ByteOrder.BIG_ENDIAN, false), - Arguments.of(3, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(4, ByteOrder.BIG_ENDIAN, false), - Arguments.of(4, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(5, ByteOrder.BIG_ENDIAN, false), - Arguments.of(5, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(6, ByteOrder.BIG_ENDIAN, false), - Arguments.of(6, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(7, ByteOrder.BIG_ENDIAN, false), - Arguments.of(7, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(8, ByteOrder.BIG_ENDIAN, false), - Arguments.of(8, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(9, ByteOrder.BIG_ENDIAN, false), - Arguments.of(9, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(10, ByteOrder.BIG_ENDIAN, false), - Arguments.of(10, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(11, ByteOrder.BIG_ENDIAN, false), - Arguments.of(11, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(12, ByteOrder.BIG_ENDIAN, false), - Arguments.of(12, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(13, ByteOrder.BIG_ENDIAN, false), - Arguments.of(13, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(14, ByteOrder.BIG_ENDIAN, false), - Arguments.of(14, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(15, ByteOrder.BIG_ENDIAN, false), - Arguments.of(15, ByteOrder.LITTLE_ENDIAN, false) - ); + Arguments.of(2, ByteOrder.BIG_ENDIAN, true), + Arguments.of(2, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(3, ByteOrder.BIG_ENDIAN, true), + Arguments.of(3, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(4, ByteOrder.BIG_ENDIAN, true), + Arguments.of(4, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(5, ByteOrder.BIG_ENDIAN, true), + Arguments.of(5, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(6, ByteOrder.BIG_ENDIAN, true), + Arguments.of(6, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(7, ByteOrder.BIG_ENDIAN, true), + Arguments.of(7, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(8, ByteOrder.BIG_ENDIAN, true), + Arguments.of(8, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(9, ByteOrder.BIG_ENDIAN, true), + Arguments.of(9, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(10, ByteOrder.BIG_ENDIAN, true), + Arguments.of(10, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(11, ByteOrder.BIG_ENDIAN, true), + Arguments.of(11, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(12, ByteOrder.BIG_ENDIAN, true), + Arguments.of(12, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(13, ByteOrder.BIG_ENDIAN, true), + Arguments.of(13, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(14, ByteOrder.BIG_ENDIAN, true), + Arguments.of(14, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(15, ByteOrder.BIG_ENDIAN, true), + Arguments.of(15, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(2, ByteOrder.BIG_ENDIAN, false), + Arguments.of(2, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(3, ByteOrder.BIG_ENDIAN, false), + Arguments.of(3, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(4, ByteOrder.BIG_ENDIAN, false), + Arguments.of(4, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(5, ByteOrder.BIG_ENDIAN, false), + Arguments.of(5, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(6, ByteOrder.BIG_ENDIAN, false), + Arguments.of(6, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(7, ByteOrder.BIG_ENDIAN, false), + Arguments.of(7, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(8, ByteOrder.BIG_ENDIAN, false), + Arguments.of(8, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(9, ByteOrder.BIG_ENDIAN, false), + Arguments.of(9, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(10, ByteOrder.BIG_ENDIAN, false), + Arguments.of(10, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(11, ByteOrder.BIG_ENDIAN, false), + Arguments.of(11, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(12, ByteOrder.BIG_ENDIAN, false), + Arguments.of(12, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(13, ByteOrder.BIG_ENDIAN, false), + Arguments.of(13, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(14, ByteOrder.BIG_ENDIAN, false), + Arguments.of(14, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(15, ByteOrder.BIG_ENDIAN, false), + Arguments.of(15, ByteOrder.LITTLE_ENDIAN, false)); } private Path file; @@ -110,10 +114,10 @@ public void after() throws IOException { } } - @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testDeserializeFromMappedFile(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromMappedFile(int keys, ByteOrder order, boolean runOptimise) + throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); try (RandomAccessFile raf = new RandomAccessFile(file.toFile(), "rw")) { @@ -129,7 +133,8 @@ public void testDeserializeFromMappedFile(int keys, ByteOrder order, boolean run @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testDeserializeFromHeap(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromHeap(int keys, ByteOrder order, boolean runOptimise) + throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.wrap(serialised).order(order); @@ -140,7 +145,8 @@ public void testDeserializeFromHeap(int keys, ByteOrder order, boolean runOptimi @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testDeserializeFromDirect(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromDirect(int keys, ByteOrder order, boolean runOptimise) + throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocateDirect(serialised.length).order(order); @@ -153,7 +159,8 @@ public void testDeserializeFromDirect(int keys, ByteOrder order, boolean runOpti @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testDeserializeFromDirectWithOffset(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromDirectWithOffset(int keys, ByteOrder order, boolean runOptimise) + throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocateDirect(10 + serialised.length).order(order); @@ -167,7 +174,8 @@ public void testDeserializeFromDirectWithOffset(int keys, ByteOrder order, boole @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testSerializeCorrectOffset(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeCorrectOffset(int keys, ByteOrder order, boolean runOptimise) + throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocateDirect(10 + serialised.length).order(order); @@ -179,7 +187,8 @@ public void testSerializeCorrectOffset(int keys, ByteOrder order, boolean runOpt @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testSerializeToByteBufferDeserializeViaStream(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeToByteBufferDeserializeViaStream( + int keys, ByteOrder order, boolean runOptimise) throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocate(serialised.length).order(order); @@ -194,7 +203,8 @@ public void testSerializeToByteBufferDeserializeViaStream(int keys, ByteOrder or @ParameterizedTest(name = "{1}/{0} keys/runOptimise={2}") @MethodSource("params") - public void testSerializeToByteBufferDeserializeByteBuffer(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeToByteBufferDeserializeByteBuffer( + int keys, ByteOrder order, boolean runOptimise) throws IOException { RoaringBitmap input = SeededTestData.randomBitmap(keys); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocate(serialised.length).order(order); @@ -211,7 +221,7 @@ private static byte[] serialise(RoaringBitmap input, boolean runOptimise) throws input.runOptimize(); } try (ByteArrayOutputStream bos = new ByteArrayOutputStream(input.serializedSizeInBytes()); - DataOutputStream dos = new DataOutputStream(bos)) { + DataOutputStream dos = new DataOutputStream(bos)) { input.serialize(dos); return bos.toByteArray(); } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java index 34c4d9192..d4c0dc92e 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestSerializedSize.java @@ -1,22 +1,21 @@ package org.roaringbitmap; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + public class TestSerializedSize { @Test public void testLucaSize() { System.out.println("testLucaSize"); RoaringBitmap rb = - RoaringBitmap.bitmapOf( 2946000, 2997491, 10478289, 10490227, 10502444, 19866827); + RoaringBitmap.bitmapOf(2946000, 2997491, 10478289, 10490227, 10502444, 19866827); System.out.println("cardinality = " + rb.getCardinality()); System.out.println("total size in bytes = " + rb.getSizeInBytes()); assertTrue(rb.getSizeInBytes() <= 50); } - @Test public void testEmpty() { RoaringBitmap rb = new RoaringBitmap(); @@ -28,8 +27,6 @@ public void testEmpty() { assertTrue(rac <= c); } - - @Test public void testOne() { for (int k = 0; k < 100000; k += 100) { @@ -44,7 +41,6 @@ public void testOne() { } } - @Test public void testRange() { for (int k = 0; k < 100000; k += 100) { @@ -59,7 +55,6 @@ public void testRange() { } } - @Test public void testLarge() { for (long scale = 15; scale < 2048; scale *= 15) { @@ -68,8 +63,7 @@ public void testLarge() { int universe_size = 0; for (int k = 0; k < N; ++k) { int val = (int) (scale * k); - if (val > universe_size) - universe_size = val; + if (val > universe_size) universe_size = val; rb.add((int) (scale * k)); } universe_size++; @@ -92,10 +86,9 @@ public void testManyRanges() { for (int i = 0; i < step; ++i) { final int maxv = i * (1 << 16) + stepsize; rb.add(i * (1L << 16), i * (1L << 16) + stepsize); - if (maxv > universe_size) - universe_size = maxv; + if (maxv > universe_size) universe_size = maxv; } - long c = RoaringBitmap.maximumSerializedSize(rb.getCardinality(),universe_size); + long c = RoaringBitmap.maximumSerializedSize(rb.getCardinality(), universe_size); long ac = rb.serializedSizeInBytes(); assertTrue(ac <= c); rb.runOptimize(); @@ -107,9 +100,9 @@ public void testManyRanges() { private static int[] firstPrimes(int n) { int status = 1, num = 3; int[] answer = new int[n]; - for (int count = 0; count < n;) { + for (int count = 0; count < n; ) { double s = Math.sqrt(num); - for (int j = 2; j <= s ; j++) { + for (int j = 2; j <= s; j++) { if (num % j == 0) { status = 0; break; @@ -131,16 +124,24 @@ public void testPrimeSerializedSize() { for (int j = 1000; j < 1000 * 1000; j *= 10) { int[] primes = firstPrimes(j); RoaringBitmap rb = RoaringBitmap.bitmapOf(primes); - long vagueupperbound = RoaringBitmap.maximumSerializedSize(rb.getCardinality(), Integer.MAX_VALUE); - long upperbound = RoaringBitmap.maximumSerializedSize(rb.getCardinality(), primes[primes.length-1]+1); + long vagueupperbound = + RoaringBitmap.maximumSerializedSize(rb.getCardinality(), Integer.MAX_VALUE); + long upperbound = + RoaringBitmap.maximumSerializedSize(rb.getCardinality(), primes[primes.length - 1] + 1); long actual = rb.serializedSizeInBytes(); - System.out.println("cardinality = " + rb.getCardinality() + " serialized size = " + actual - + " silly upper bound = " + vagueupperbound + " better upper bound = "+upperbound); + System.out.println( + "cardinality = " + + rb.getCardinality() + + " serialized size = " + + actual + + " silly upper bound = " + + vagueupperbound + + " better upper bound = " + + upperbound); assertTrue(actual <= vagueupperbound); assertTrue(upperbound <= vagueupperbound); assertTrue(actual <= upperbound); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestStreams.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestStreams.java index dc31353ef..42b162cb1 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestStreams.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestStreams.java @@ -2,9 +2,10 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -17,9 +18,6 @@ import java.util.Random; import java.util.stream.Collectors; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - public class TestStreams { private static List asList(IntIterator ints) { int[] values = new int[10]; @@ -34,22 +32,23 @@ private static List asList(IntIterator ints) { } private static List asList(final CharIterator shorts) { - return asList(new IntIterator() { - @Override - public IntIterator clone() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean hasNext() { - return shorts.hasNext(); - } - - @Override - public int next() { - return shorts.next(); - } - }); + return asList( + new IntIterator() { + @Override + public IntIterator clone() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return shorts.hasNext(); + } + + @Override + public int next() { + return shorts.next(); + } + }); } private static int[] takeSortedAndDistinct(Random source, int count) { @@ -78,8 +77,10 @@ public void testViaIteration() { RoaringBitmap bitmap = RoaringBitmap.bitmapOf(data); final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator()); - final List intIteratorCopy = bitmap.stream().mapToObj(Integer::valueOf).collect(Collectors.toList()); - final List reverseIntIteratorCopy = bitmap.reverseStream().mapToObj(Integer::valueOf).collect(Collectors.toList()); + final List intIteratorCopy = + bitmap.stream().mapToObj(Integer::valueOf).collect(Collectors.toList()); + final List reverseIntIteratorCopy = + bitmap.reverseStream().mapToObj(Integer::valueOf).collect(Collectors.toList()); assertEquals(bitmap.getCardinality(), iteratorCopy.size()); assertEquals(bitmap.getCardinality(), intIteratorCopy.size()); @@ -94,8 +95,10 @@ public void testSmallIteration() { RoaringBitmap bitmap = RoaringBitmap.bitmapOf(1, 2, 3); final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator()); - final List intIteratorCopy = bitmap.stream().mapToObj(Integer::valueOf).collect(Collectors.toList()); - final List reverseIntIteratorCopy = bitmap.reverseStream().mapToObj(Integer::valueOf).collect(Collectors.toList()); + final List intIteratorCopy = + bitmap.stream().mapToObj(Integer::valueOf).collect(Collectors.toList()); + final List reverseIntIteratorCopy = + bitmap.reverseStream().mapToObj(Integer::valueOf).collect(Collectors.toList()); assertEquals(ImmutableList.of(1, 2, 3), iteratorCopy); assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestUtil.java index 3b81180e4..83d7d6634 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestUtil.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestUtil.java @@ -1,5 +1,12 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.SeededTestData.denseRegion; +import static org.roaringbitmap.SeededTestData.rleRegion; +import static org.roaringbitmap.SeededTestData.sparseRegion; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -11,209 +18,212 @@ import java.util.Arrays; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.SeededTestData.*; -import static org.roaringbitmap.SeededTestData.sparseRegion; - @Execution(ExecutionMode.CONCURRENT) public class TestUtil { - @Test - public void testUtilUnsignedIntersection() { - char[] data1 = fromShorts(new short[]{-19, -17, -15, -13, -11, -9, -7, -5, -3, -1}); - char[] data2 = fromShorts(new short[]{-18, -16, -14, -12, -10, -8, -1}); - assertTrue(Util.unsignedIntersects(data1, data1.length, data2, data2.length)); - char[] data3 = fromShorts(new short[]{-19, -17, -15, -13, -11, -9, -7}); - char[] data4 = fromShorts(new short[]{-18, -16, -14, -12, -10, -8, -6, -4, -2, 0}); - assertFalse(Util.unsignedIntersects(data3, data3.length, data4, data4.length)); - char[] data5 = {}; - char[] data6 = {}; - assertFalse(Util.unsignedIntersects(data5, data5.length, data6, data6.length)); - } - - @Test - public void testBranchyUnsignedBinarySearch() { - char[] data1 = fromShorts(new short[]{-19, -17, -15, -13, -11, -9, -7, -5, -3}); - assertEquals(8, Util.branchyUnsignedBinarySearch(data1, 0, data1.length, data1[8])); - assertEquals(0, Util.branchyUnsignedBinarySearch(data1, 0, data1.length, data1[0])); - assertEquals(data1.length-1, Util.branchyUnsignedBinarySearch(data1, data1.length-1, data1.length, data1[data1.length-1])); - assertEquals(-1, Util.branchyUnsignedBinarySearch(data1, 0, 0, (char)0)); - assertEquals(-10, Util.branchyUnsignedBinarySearch(data1, 0, data1.length, (char) -1)); - } - - @Test - public void testPartialRadixSortEmpty() { - int[] data = new int[] {}; - int[] test = Arrays.copyOf(data, data.length); - Util.partialRadixSort(test); - assertArrayEquals(data, test); - } - - @Test - public void testPartialRadixSortIsStableInSameKey() { - int[] data = new int[] {25, 1, 0, 10}; - for (int key : new int[]{0, 1 << 16, 1 << 17, 1 << 24, 1 << 25}) { - // clear the old key and prepend the new key - for (int i = 0; i < data.length; ++i) { - data[i] &= 0xFFFF; - data[i] |= key; - } - int[] test = Arrays.copyOf(data, data.length); - Util.partialRadixSort(test); - assertArrayEquals(data, test); - } - } - - @Test - public void testPartialRadixSortSortsKeysCorrectly() { - int[] keys = { - // the test expects the first key to be less than the second key, - // neither should have any of the lower 16 bits set - 1 << 16, 1 << 25, - 1 << 16, 1 << 17, - 1 << 17, 1 << 18, - 1 << 25, 1 << 26, - 1 << 23, 1 << 25, - 1 << 24, 1 << 25, - 1 << 25, 1 << 27, - 1 << 29, 1 << 30, - }; - for (int i = 0; i < keys.length; i += 2) { - int key1 = keys[i]; - int key2 = keys[i+1]; - int[] data = new int[]{key2 | 25, key1 | 1, 0, key2 | 10, 25, key1 | 10, key1, 10}; - // sort by keys, leave values stable - int[] expected = new int[]{0, 25, 10, key1 | 1, key1 | 10, key1, key2 | 25, key2 | 10}; - int[] test = Arrays.copyOf(data, data.length); - Util.partialRadixSort(test); - assertArrayEquals(expected, test); - } - } - - @Test - public void testPartialRadixSortSortsKeysCorrectlyWithDuplicates() { - int[] keys = { - // the test expects the first key to be less than the second key, - // neither should have any of the lower 16 bits set - 1 << 16, 1 << 25, - 1 << 16, 1 << 17, - 1 << 17, 1 << 18, - 1 << 25, 1 << 26, - 1 << 23, 1 << 25, - 1 << 24, 1 << 25, - 1 << 25, 1 << 27, - 1 << 29, 1 << 30, - }; - for (int i = 0; i < keys.length; i += 2) { - int key1 = keys[i]; - int key2 = keys[i + 1]; - int[] data = new int[]{key2 | 25, key1 | 1, 0, key2 | 10, 25, key1 | 10, key1, 10, - key2 | 25, key1 | 1, 0, key2 | 10, 25, key1 | 10, key1, 10}; - // sort by keys, leave values stable - int[] expected = new int[]{0, 25, 10, 0, 25, 10, key1 | 1, key1 | 10, key1, key1 | 1, key1 | 10, key1, - key2 | 25, key2 | 10, key2 | 25, key2 | 10}; - int[] test = Arrays.copyOf(data, data.length); - Util.partialRadixSort(test); - assertArrayEquals(expected, test); - } - } - - @Test - public void testAdvanceUntil() { - char[] data = fromShorts(new short[]{0, 3, 16, 18, 21, 29, 30,-342}); - assertEquals(1, Util.advanceUntil(data, -1, data.length, (char) 3)); - assertEquals(5, Util.advanceUntil(data, -1, data.length, (char) 28)); - assertEquals(5, Util.advanceUntil(data, -1, data.length, (char) 29)); - assertEquals(7, Util.advanceUntil(data, -1, data.length, (char) -342)); + @Test + public void testUtilUnsignedIntersection() { + char[] data1 = fromShorts(new short[] {-19, -17, -15, -13, -11, -9, -7, -5, -3, -1}); + char[] data2 = fromShorts(new short[] {-18, -16, -14, -12, -10, -8, -1}); + assertTrue(Util.unsignedIntersects(data1, data1.length, data2, data2.length)); + char[] data3 = fromShorts(new short[] {-19, -17, -15, -13, -11, -9, -7}); + char[] data4 = fromShorts(new short[] {-18, -16, -14, -12, -10, -8, -6, -4, -2, 0}); + assertFalse(Util.unsignedIntersects(data3, data3.length, data4, data4.length)); + char[] data5 = {}; + char[] data6 = {}; + assertFalse(Util.unsignedIntersects(data5, data5.length, data6, data6.length)); + } + + @Test + public void testBranchyUnsignedBinarySearch() { + char[] data1 = fromShorts(new short[] {-19, -17, -15, -13, -11, -9, -7, -5, -3}); + assertEquals(8, Util.branchyUnsignedBinarySearch(data1, 0, data1.length, data1[8])); + assertEquals(0, Util.branchyUnsignedBinarySearch(data1, 0, data1.length, data1[0])); + assertEquals( + data1.length - 1, + Util.branchyUnsignedBinarySearch( + data1, data1.length - 1, data1.length, data1[data1.length - 1])); + assertEquals(-1, Util.branchyUnsignedBinarySearch(data1, 0, 0, (char) 0)); + assertEquals(-10, Util.branchyUnsignedBinarySearch(data1, 0, data1.length, (char) -1)); + } + + @Test + public void testPartialRadixSortEmpty() { + int[] data = new int[] {}; + int[] test = Arrays.copyOf(data, data.length); + Util.partialRadixSort(test); + assertArrayEquals(data, test); + } + + @Test + public void testPartialRadixSortIsStableInSameKey() { + int[] data = new int[] {25, 1, 0, 10}; + for (int key : new int[] {0, 1 << 16, 1 << 17, 1 << 24, 1 << 25}) { + // clear the old key and prepend the new key + for (int i = 0; i < data.length; ++i) { + data[i] &= 0xFFFF; + data[i] |= key; + } + int[] test = Arrays.copyOf(data, data.length); + Util.partialRadixSort(test); + assertArrayEquals(data, test); } - - @Test - public void testReverseUntil() { - char[] data = fromShorts(new short[]{1, 3, 16, 18, 21, 29, 30,-342}); - assertEquals(0, Util.reverseUntil(data, data.length, data.length, (char) 0)); - assertEquals(1, Util.reverseUntil(data, data.length, data.length, (char) 3)); - assertEquals(4, Util.reverseUntil(data, data.length, data.length, (char) 28)); - assertEquals(5, Util.reverseUntil(data, data.length, data.length, (char) 29)); - assertEquals(6, Util.reverseUntil(data, data.length, data.length, (char) 30)); - assertEquals(6, Util.reverseUntil(data, data.length, data.length, (char) 31)); - assertEquals(7, Util.reverseUntil(data, data.length, data.length, (char) -342)); - } - - @Test - public void testIterateUntil() { - char[] data = fromShorts(new short[]{0, 3, 16, 18, 21, 29, 30,-342}); - assertEquals(1, Util.iterateUntil(data, 0, data.length, ((char) 3))); - assertEquals(5, Util.iterateUntil(data, 0, data.length, ((char) 28))); - assertEquals(5, Util.iterateUntil(data, 0, data.length, ((char) 29))); - assertEquals(7, Util.iterateUntil(data, 0, data.length, ((char) -342))); + } + + @Test + public void testPartialRadixSortSortsKeysCorrectly() { + int[] keys = { + // the test expects the first key to be less than the second key, + // neither should have any of the lower 16 bits set + 1 << 16, 1 << 25, + 1 << 16, 1 << 17, + 1 << 17, 1 << 18, + 1 << 25, 1 << 26, + 1 << 23, 1 << 25, + 1 << 24, 1 << 25, + 1 << 25, 1 << 27, + 1 << 29, 1 << 30, + }; + for (int i = 0; i < keys.length; i += 2) { + int key1 = keys[i]; + int key2 = keys[i + 1]; + int[] data = new int[] {key2 | 25, key1 | 1, 0, key2 | 10, 25, key1 | 10, key1, 10}; + // sort by keys, leave values stable + int[] expected = new int[] {0, 25, 10, key1 | 1, key1 | 10, key1, key2 | 25, key2 | 10}; + int[] test = Arrays.copyOf(data, data.length); + Util.partialRadixSort(test); + assertArrayEquals(expected, test); } - - static char[] fromShorts(short[] array) { - char[] result = new char[array.length]; - for (int i = 0 ; i < array.length; ++i) { - result[i] = (char)(array[i] & 0xFFFF); - } - return result; + } + + @Test + public void testPartialRadixSortSortsKeysCorrectlyWithDuplicates() { + int[] keys = { + // the test expects the first key to be less than the second key, + // neither should have any of the lower 16 bits set + 1 << 16, 1 << 25, + 1 << 16, 1 << 17, + 1 << 17, 1 << 18, + 1 << 25, 1 << 26, + 1 << 23, 1 << 25, + 1 << 24, 1 << 25, + 1 << 25, 1 << 27, + 1 << 29, 1 << 30, + }; + for (int i = 0; i < keys.length; i += 2) { + int key1 = keys[i]; + int key2 = keys[i + 1]; + int[] data = + new int[] { + key2 | 25, key1 | 1, 0, key2 | 10, 25, key1 | 10, key1, 10, key2 | 25, key1 | 1, 0, + key2 | 10, 25, key1 | 10, key1, 10 + }; + // sort by keys, leave values stable + int[] expected = + new int[] { + 0, 25, 10, 0, 25, 10, key1 | 1, key1 | 10, key1, key1 | 1, key1 | 10, key1, key2 | 25, + key2 | 10, key2 | 25, key2 | 10 + }; + int[] test = Arrays.copyOf(data, data.length); + Util.partialRadixSort(test); + assertArrayEquals(expected, test); } - - public static Stream sets() { - return Stream.of( - Arguments.of(rleRegion().toArray(), rleRegion().toArray()), - Arguments.of(denseRegion().toArray(), rleRegion().toArray()), - Arguments.of(sparseRegion().toArray(), rleRegion().toArray()), - Arguments.of(rleRegion().toArray(), denseRegion().toArray()), - Arguments.of(denseRegion().toArray(), denseRegion().toArray()), - Arguments.of(sparseRegion().toArray(), denseRegion().toArray()), - Arguments.of(rleRegion().toArray(), sparseRegion().toArray()), - Arguments.of(denseRegion().toArray(), sparseRegion().toArray()), - Arguments.of(sparseRegion().toArray(), sparseRegion().toArray()) - ); + } + + @Test + public void testAdvanceUntil() { + char[] data = fromShorts(new short[] {0, 3, 16, 18, 21, 29, 30, -342}); + assertEquals(1, Util.advanceUntil(data, -1, data.length, (char) 3)); + assertEquals(5, Util.advanceUntil(data, -1, data.length, (char) 28)); + assertEquals(5, Util.advanceUntil(data, -1, data.length, (char) 29)); + assertEquals(7, Util.advanceUntil(data, -1, data.length, (char) -342)); + } + + @Test + public void testReverseUntil() { + char[] data = fromShorts(new short[] {1, 3, 16, 18, 21, 29, 30, -342}); + assertEquals(0, Util.reverseUntil(data, data.length, data.length, (char) 0)); + assertEquals(1, Util.reverseUntil(data, data.length, data.length, (char) 3)); + assertEquals(4, Util.reverseUntil(data, data.length, data.length, (char) 28)); + assertEquals(5, Util.reverseUntil(data, data.length, data.length, (char) 29)); + assertEquals(6, Util.reverseUntil(data, data.length, data.length, (char) 30)); + assertEquals(6, Util.reverseUntil(data, data.length, data.length, (char) 31)); + assertEquals(7, Util.reverseUntil(data, data.length, data.length, (char) -342)); + } + + @Test + public void testIterateUntil() { + char[] data = fromShorts(new short[] {0, 3, 16, 18, 21, 29, 30, -342}); + assertEquals(1, Util.iterateUntil(data, 0, data.length, ((char) 3))); + assertEquals(5, Util.iterateUntil(data, 0, data.length, ((char) 28))); + assertEquals(5, Util.iterateUntil(data, 0, data.length, ((char) 29))); + assertEquals(7, Util.iterateUntil(data, 0, data.length, ((char) -342))); + } + + static char[] fromShorts(short[] array) { + char[] result = new char[array.length]; + for (int i = 0; i < array.length; ++i) { + result[i] = (char) (array[i] & 0xFFFF); } - - - @MethodSource("sets") - @ParameterizedTest - public void testIntersectBitmapWithArray(int[] set1, int[] set2) { - long[] bitmap = new long[1024]; - for (int i : set1) { - bitmap[i >>> 6] |= 1L << i; - } - long[] referenceBitmap = new long[1024]; - char[] array = new char[set2.length]; - int pos = 0; - for (int i : set2) { - referenceBitmap[i >>> 6] |= 1L << i; - array[pos++] = (char)i; - } - int expectedCardinality = 0; - for (int i = 0; i < 1024; ++i) { - referenceBitmap[i] &= bitmap[i]; - expectedCardinality += Long.bitCount(referenceBitmap[i]); - } - int cardinality = Util.intersectArrayIntoBitmap(bitmap, array, array.length); - assertEquals(expectedCardinality, cardinality); - assertArrayEquals(referenceBitmap, bitmap); + return result; + } + + public static Stream sets() { + return Stream.of( + Arguments.of(rleRegion().toArray(), rleRegion().toArray()), + Arguments.of(denseRegion().toArray(), rleRegion().toArray()), + Arguments.of(sparseRegion().toArray(), rleRegion().toArray()), + Arguments.of(rleRegion().toArray(), denseRegion().toArray()), + Arguments.of(denseRegion().toArray(), denseRegion().toArray()), + Arguments.of(sparseRegion().toArray(), denseRegion().toArray()), + Arguments.of(rleRegion().toArray(), sparseRegion().toArray()), + Arguments.of(denseRegion().toArray(), sparseRegion().toArray()), + Arguments.of(sparseRegion().toArray(), sparseRegion().toArray())); + } + + @MethodSource("sets") + @ParameterizedTest + public void testIntersectBitmapWithArray(int[] set1, int[] set2) { + long[] bitmap = new long[1024]; + for (int i : set1) { + bitmap[i >>> 6] |= 1L << i; } - - @Test - public void bitmapOfRange() { - assertBitmapRange(0, 10);// begin of first container - assertBitmapRange(0, 1 << 16 - 1);// early full container - assertBitmapRange(0, 1 << 16);// full first container - assertBitmapRange(0, 1 << 16 + 1);// full first container + one value the second - assertBitmapRange(10, 1 << 16);// without first several integers - assertBitmapRange(1 << 16, (1 << 16) * 2);// full second container - assertBitmapRange(10, 100);// some integers inside interval - assertBitmapRange((1 << 16) - 5, (1 << 16) + 7); // first to second container - assertBitmapRange(0, 100_000); // more than one container - assertBitmapRange(100_000, 200_000);// second to third container - assertBitmapRange(200_000, 400_000);// more containers inside + long[] referenceBitmap = new long[1024]; + char[] array = new char[set2.length]; + int pos = 0; + for (int i : set2) { + referenceBitmap[i >>> 6] |= 1L << i; + array[pos++] = (char) i; } - - private static void assertBitmapRange(int start, int end) { - RoaringBitmap bitmap = RoaringBitmap.bitmapOfRange(start, end); - assertEquals(end - start, bitmap.getCardinality()); - assertEquals(start, bitmap.first()); - assertEquals(end - 1, bitmap.last()); + int expectedCardinality = 0; + for (int i = 0; i < 1024; ++i) { + referenceBitmap[i] &= bitmap[i]; + expectedCardinality += Long.bitCount(referenceBitmap[i]); } + int cardinality = Util.intersectArrayIntoBitmap(bitmap, array, array.length); + assertEquals(expectedCardinality, cardinality); + assertArrayEquals(referenceBitmap, bitmap); + } + + @Test + public void bitmapOfRange() { + assertBitmapRange(0, 10); // begin of first container + assertBitmapRange(0, 1 << 16 - 1); // early full container + assertBitmapRange(0, 1 << 16); // full first container + assertBitmapRange(0, 1 << 16 + 1); // full first container + one value the second + assertBitmapRange(10, 1 << 16); // without first several integers + assertBitmapRange(1 << 16, (1 << 16) * 2); // full second container + assertBitmapRange(10, 100); // some integers inside interval + assertBitmapRange((1 << 16) - 5, (1 << 16) + 7); // first to second container + assertBitmapRange(0, 100_000); // more than one container + assertBitmapRange(100_000, 200_000); // second to third container + assertBitmapRange(200_000, 400_000); // more containers inside + } + + private static void assertBitmapRange(int start, int end) { + RoaringBitmap bitmap = RoaringBitmap.bitmapOfRange(start, end); + assertEquals(end - start, bitmap.getCardinality()); + assertEquals(start, bitmap.first()); + assertEquals(end - 1, bitmap.last()); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java index 1c5a494a6..03c936fce 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/TestVeryLargeBitmap.java @@ -1,10 +1,9 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestVeryLargeBitmap { @Test public void testSelect() { @@ -33,5 +32,4 @@ public void stupidlyLarge() { ome.printStackTrace(); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java index 4fff1ae22..64ab7550e 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/UnorderedRoaringBitmapWriterRandomisedTest.java @@ -1,5 +1,6 @@ package org.roaringbitmap; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -13,61 +14,57 @@ import java.util.Random; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; - - @Execution(ExecutionMode.CONCURRENT) public class UnorderedRoaringBitmapWriterRandomisedTest { + public static Stream tests() { + return Stream.of( + Arguments.of(generateUnorderedArray(0)), + Arguments.of(generateUnorderedArray(10)), + Arguments.of(generateUnorderedArray(100)), + Arguments.of(generateUnorderedArray(1000)), + Arguments.of(generateUnorderedArray(10000)), + Arguments.of(generateUnorderedArray(100000)), + Arguments.of(generateUnorderedArray(1000000))); + } - public static Stream tests() { - return Stream.of( - Arguments.of(generateUnorderedArray(0)), - Arguments.of(generateUnorderedArray(10)), - Arguments.of(generateUnorderedArray(100)), - Arguments.of(generateUnorderedArray(1000)), - Arguments.of(generateUnorderedArray(10000)), - Arguments.of(generateUnorderedArray(100000)), - Arguments.of(generateUnorderedArray(1000000))); + @ParameterizedTest + @MethodSource("tests") + public void bitmapOfUnorderedShouldBuildSameBitmapAsBitmapOf(int[] data) { + RoaringBitmap baseline = RoaringBitmap.bitmapOf(data); + RoaringBitmap test = RoaringBitmap.bitmapOfUnordered(data); + RoaringArray baselineHLC = baseline.highLowContainer; + RoaringArray testHLC = test.highLowContainer; + assertEquals(baselineHLC.size, testHLC.size); + for (int i = 0; i < baselineHLC.size; ++i) { + Container baselineContainer = baselineHLC.getContainerAtIndex(i); + Container rbContainer = testHLC.getContainerAtIndex(i); + assertEquals(baselineContainer, rbContainer); } + assertEquals(baseline, test); + } - @ParameterizedTest - @MethodSource("tests") - public void bitmapOfUnorderedShouldBuildSameBitmapAsBitmapOf(int[] data) { - RoaringBitmap baseline = RoaringBitmap.bitmapOf(data); - RoaringBitmap test = RoaringBitmap.bitmapOfUnordered(data); - RoaringArray baselineHLC = baseline.highLowContainer; - RoaringArray testHLC = test.highLowContainer; - assertEquals(baselineHLC.size, testHLC.size); - for (int i = 0; i < baselineHLC.size; ++i) { - Container baselineContainer = baselineHLC.getContainerAtIndex(i); - Container rbContainer = testHLC.getContainerAtIndex(i); - assertEquals(baselineContainer, rbContainer); - } - assertEquals(baseline, test); + private static int[] generateUnorderedArray(int size) { + if (size == 0) { + return new int[0]; } - - private static int[] generateUnorderedArray(int size) { - if (size == 0) { - return new int[0]; - } - Random random = new Random(); - List ints = new ArrayList<>(size); - int last = 0; - for (int i = 0; i < size; ++i) { - if (random.nextGaussian() > 0.1) { - last = last + 1; - } else { - last = last + 1 + random.nextInt(99); - } - ints.add(last); - } - Collections.shuffle(ints); - int[] data = new int[size]; - int i = 0; - for (Integer value : ints) { - data[i++] = value; - } - return data; + Random random = new Random(); + List ints = new ArrayList<>(size); + int last = 0; + for (int i = 0; i < size; ++i) { + if (random.nextGaussian() > 0.1) { + last = last + 1; + } else { + last = last + 1 + random.nextInt(99); + } + ints.add(last); + } + Collections.shuffle(ints); + int[] data = new int[size]; + int i = 0; + for (Integer value : ints) { + data[i++] = value; } + return data; + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java b/roaringbitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java index e41ea73fe..fdbf70236 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/ValidationRangeConsumer.java @@ -1,8 +1,10 @@ package org.roaringbitmap; -import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.*; +import java.util.Arrays; public class ValidationRangeConsumer implements RelativeRangeConsumer { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/art/Node16Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node16Test.java index 30984a991..86f24c7fa 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/art/Node16Test.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node16Test.java @@ -8,19 +8,19 @@ public class Node16Test { @Test public void test() { Node4 node4 = new Node4(0); - //insert 4 nodes + // insert 4 nodes for (int i = 0; i < 4; i++) { LeafNode leafNode = new LeafNode(i, i); node4 = (Node4) Node4.insert(node4, leafNode, (byte) i); } - //insert the fifth node + // insert the fifth node LeafNode leafNode4 = new LeafNode(4, 4); Node16 node16 = (Node16) Node4.insert(node4, leafNode4, (byte) 4); - //remove two nodes to shrink to node4 + // remove two nodes to shrink to node4 node16 = (Node16) node16.remove(4); Node degenerativeNode = node16.remove(3); Assertions.assertTrue(degenerativeNode instanceof Node4); - //recover to node16 by re-insert two nodes + // recover to node16 by re-insert two nodes Node4 degenerativeNode4 = (Node4) degenerativeNode; Node node = Node4.insert(degenerativeNode4, leafNode4, (byte) 4); LeafNode leafNode3 = new LeafNode(3, 3); @@ -173,7 +173,7 @@ public void testSparseNonZeroBasedKeysSearch() { // search in the "gaps" before the key { - byte bKey = (byte)(key - 1); + byte bKey = (byte) (key - 1); sr = nodes.getNearestChildPos(bKey); Assertions.assertEquals(SearchResult.Outcome.NOT_FOUND, sr.outcome); Assertions.assertFalse(sr.hasKeyPos()); @@ -184,10 +184,10 @@ public void testSparseNonZeroBasedKeysSearch() { } else { int expect = Byte.toUnsignedInt(key) - step; int result = Byte.toUnsignedInt(nodes.getChildKey(sr.getNextSmallerPos())); - Assertions.assertEquals( expect, result); + Assertions.assertEquals(expect, result); } // the NextLarger of the "key-1" should be the key - Assertions.assertEquals(keyPos ,sr.getNextLargerPos()); + Assertions.assertEquals(keyPos, sr.getNextLargerPos()); Assertions.assertEquals(key, nodes.getChildKey(sr.getNextLargerPos())); } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/art/Node48Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node48Test.java index fc04387c1..9699bc2de 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/art/Node48Test.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node48Test.java @@ -1,12 +1,13 @@ package org.roaringbitmap.art; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; public class Node48Test { @@ -46,8 +47,8 @@ public void test() throws IOException { DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); node48.serialize(dataOutputStream); Assertions.assertEquals(sizeInBytes, byteArrayOutputStream.toByteArray().length); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( - byteArrayOutputStream.toByteArray()); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); Node48 deserNode48 = (Node48) Node.deserialize(dataInputStream); currentPos = maxPos; @@ -116,7 +117,7 @@ public void testWithOffsetAndGapsBytes() { // setup data for (int i = 0; i < insertCount; i++) { - nodes = Node48.insert(nodes, leafNode, (byte) (offset + (i*step))); + nodes = Node48.insert(nodes, leafNode, (byte) (offset + (i * step))); } // check we are testing the correct data structure Assertions.assertTrue(nodes instanceof Node48); @@ -355,9 +356,9 @@ public void testSparseNonZeroBasedKeysSearch() { @Test public void testGetNextSmallerPosEdgeCase() { Node nodes = new Node48(0); - LeafNode leafNode = new LeafNode(0,0); + LeafNode leafNode = new LeafNode(0, 0); - nodes = Node48.insert(nodes, leafNode, (byte)67); + nodes = Node48.insert(nodes, leafNode, (byte) 67); // check we are testing the correct thing Assertions.assertTrue(nodes instanceof Node48); @@ -383,22 +384,22 @@ public void testGetNextPosShouldNotThrowOnLegalInputs() { public void testSetOneByte() { long[] longs = new long[Node48.LONGS_USED]; - Node48.setOneByte(0, (byte)0x67, longs); + Node48.setOneByte(0, (byte) 0x67, longs); Assertions.assertEquals(0x6700_0000_0000_0000L, longs[0]); - Node48.setOneByte(1, (byte)0x23, longs); + Node48.setOneByte(1, (byte) 0x23, longs); Assertions.assertEquals(0x6723_0000_0000_0000L, longs[0]); - Node48.setOneByte(2, (byte)0x14, longs); + Node48.setOneByte(2, (byte) 0x14, longs); Assertions.assertEquals(0x6723_1400_0000_0000L, longs[0]); - Node48.setOneByte(3, (byte)0x98, longs); + Node48.setOneByte(3, (byte) 0x98, longs); Assertions.assertEquals(0x6723_1498_0000_0000L, longs[0]); - Node48.setOneByte(249, (byte)0x67, longs); + Node48.setOneByte(249, (byte) 0x67, longs); Assertions.assertEquals(0x0067_0000_0000_0000L, longs[31]); - Node48.setOneByte(250, (byte)0x23, longs); + Node48.setOneByte(250, (byte) 0x23, longs); Assertions.assertEquals(0x0067_2300_0000_0000L, longs[31]); - Node48.setOneByte(251, (byte)0x14, longs); + Node48.setOneByte(251, (byte) 0x14, longs); Assertions.assertEquals(0x0067_2314_0000_0000L, longs[31]); - Node48.setOneByte(252, (byte)0x98, longs); + Node48.setOneByte(252, (byte) 0x98, longs); Assertions.assertEquals(0x0067_2314_9800_0000L, longs[31]); } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/art/Node4Test.java b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node4Test.java index 6b0405986..c9299c33a 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/art/Node4Test.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/art/Node4Test.java @@ -1,12 +1,13 @@ package org.roaringbitmap.art; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; public class Node4Test { @@ -44,8 +45,8 @@ public void testTheBasics() throws IOException { DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); node4.serialize(dataOutputStream); Assertions.assertEquals(bytesSize, byteArrayOutputStream.toByteArray().length); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( - byteArrayOutputStream.toByteArray()); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); Node4 deserializedNode4 = (Node4) Node.deserialize(dataInputStream); Assertions.assertEquals(0, deserializedNode4.getChildPos(key2)); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java index f446e9b3d..41252542b 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/BufferContainerBatchIteratorTest.java @@ -1,5 +1,11 @@ package org.roaringbitmap.buffer; +import static java.util.Arrays.copyOfRange; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.roaringbitmap.ContainerBatchIterator; +import org.roaringbitmap.SeededTestData; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -8,156 +14,160 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.Container; -import org.roaringbitmap.ContainerBatchIterator; -import org.roaringbitmap.SeededTestData; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.IntStream; import java.util.stream.Stream; -import static java.util.Arrays.copyOfRange; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; - @Execution(ExecutionMode.CONCURRENT) public class BufferContainerBatchIteratorTest { - private static int[][] DATA; + private static int[][] DATA; - @BeforeAll - public static void setup() { - DATA = Stream.of( - IntStream.range(0, 20000).toArray(), - IntStream.range(0, 1 << 16).toArray(), - IntStream.range(0, 1 << 16).filter(i -> i < 500 || i > 2000).filter(i -> i < (1 << 15) || i > ((1 << 15) | (1 << 8))).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 12) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 11) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 10) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 9) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 8) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 7) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 6) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 5) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 4) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 3) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 2) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> ((i >>> 1) & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 3) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 5) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 7) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 9) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 271) == 0).toArray(), - IntStream.range(0, 1 << 16).filter(i -> (i % 1000) == 0).toArray(), - IntStream.empty().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.sparseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.denseRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray(), - SeededTestData.rleRegion().toArray()).toArray(int[][]::new); - } + @BeforeAll + public static void setup() { + DATA = + Stream.of( + IntStream.range(0, 20000).toArray(), + IntStream.range(0, 1 << 16).toArray(), + IntStream.range(0, 1 << 16) + .filter(i -> i < 500 || i > 2000) + .filter(i -> i < (1 << 15) || i > ((1 << 15) | (1 << 8))) + .toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 12) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 11) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 10) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 9) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 8) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 7) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 6) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 5) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 4) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 3) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 2) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> ((i >>> 1) & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i & 1) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 3) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 5) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 7) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 9) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 271) == 0).toArray(), + IntStream.range(0, 1 << 16).filter(i -> (i % 1000) == 0).toArray(), + IntStream.empty().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.sparseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.denseRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray(), + SeededTestData.rleRegion().toArray()) + .toArray(int[][]::new); + } - @AfterAll - public static void clear() { - DATA = null; - } - - public static Stream params() { - return Stream.of(DATA) - .flatMap(array -> IntStream.concat(IntStream.of( - 512, 1024, 2048, 4096, 8192, 65536 - ), IntStream.range(0, 100).map(i -> ThreadLocalRandom.current().nextInt(1, 65536))) - .mapToObj(i -> Arguments.of(array, i))); - } + @AfterAll + public static void clear() { + DATA = null; + } + public static Stream params() { + return Stream.of(DATA) + .flatMap( + array -> + IntStream.concat( + IntStream.of(512, 1024, 2048, 4096, 8192, 65536), + IntStream.range(0, 100) + .map(i -> ThreadLocalRandom.current().nextInt(1, 65536))) + .mapToObj(i -> Arguments.of(array, i))); + } - @ParameterizedTest(name = "{1}") - @MethodSource("params") - public void test(int[] expectedValues, int batchSize) { - int[] buffer = new int[batchSize]; - MappeableContainer container = createContainer(expectedValues); - ContainerBatchIterator it = container.getBatchIterator(); - int cardinality = 0; - while (it.hasNext()) { - int from = cardinality; - cardinality += it.next(0, buffer); - assertArrayEquals( - copyOfRange(expectedValues, from, cardinality), copyOfRange(buffer, 0, cardinality - from), - "Failure with batch size " + batchSize); - } - assertEquals(expectedValues.length, cardinality); + @ParameterizedTest(name = "{1}") + @MethodSource("params") + public void test(int[] expectedValues, int batchSize) { + int[] buffer = new int[batchSize]; + MappeableContainer container = createContainer(expectedValues); + ContainerBatchIterator it = container.getBatchIterator(); + int cardinality = 0; + while (it.hasNext()) { + int from = cardinality; + cardinality += it.next(0, buffer); + assertArrayEquals( + copyOfRange(expectedValues, from, cardinality), + copyOfRange(buffer, 0, cardinality - from), + "Failure with batch size " + batchSize); } + assertEquals(expectedValues.length, cardinality); + } - - @ParameterizedTest(name = "{1}") - @MethodSource("params") - public void testAdvanceIfNeeded(int[] expectedValues, int batchSize) { - if (expectedValues.length < 2) { - return; - } - int[] buffer = new int[batchSize]; - MappeableContainer container = createContainer(expectedValues); - ContainerBatchIterator it = container.getBatchIterator(); - int cardinality = expectedValues.length / 2; - int advanceUntil = expectedValues[cardinality]; - it.advanceIfNeeded((char) advanceUntil); - while (it.hasNext()) { - int from = cardinality; - cardinality += it.next(0, buffer); - assertArrayEquals( - copyOfRange(expectedValues, from, cardinality), copyOfRange(buffer, 0, cardinality - from), - "Failure with batch size " + batchSize + " and container type " + container.getContainerName()); - } - assertEquals(expectedValues.length, cardinality); + @ParameterizedTest(name = "{1}") + @MethodSource("params") + public void testAdvanceIfNeeded(int[] expectedValues, int batchSize) { + if (expectedValues.length < 2) { + return; + } + int[] buffer = new int[batchSize]; + MappeableContainer container = createContainer(expectedValues); + ContainerBatchIterator it = container.getBatchIterator(); + int cardinality = expectedValues.length / 2; + int advanceUntil = expectedValues[cardinality]; + it.advanceIfNeeded((char) advanceUntil); + while (it.hasNext()) { + int from = cardinality; + cardinality += it.next(0, buffer); + assertArrayEquals( + copyOfRange(expectedValues, from, cardinality), + copyOfRange(buffer, 0, cardinality - from), + "Failure with batch size " + + batchSize + + " and container type " + + container.getContainerName()); } + assertEquals(expectedValues.length, cardinality); + } - private MappeableContainer createContainer(int[] expectedValues) { - MappeableContainer container = new MappeableArrayContainer(); - for (int value : expectedValues) { - container = container.add((char) value); - } - return container.runOptimize(); + private MappeableContainer createContainer(int[] expectedValues) { + MappeableContainer container = new MappeableArrayContainer(); + for (int value : expectedValues) { + container = container.add((char) value); } -} \ No newline at end of file + return container.runOptimize(); + } +} diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java index eaad7b71b..deb46a988 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/CloneBatchIteratorTest.java @@ -1,20 +1,22 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + +import org.roaringbitmap.BatchIterator; + import com.google.common.primitives.Ints; import org.junit.jupiter.api.Test; -import org.roaringbitmap.BatchIterator; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - public class CloneBatchIteratorTest { @Test public void testIndependenceOfClones() { - MutableRoaringBitmap bitmap = testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap(); + MutableRoaringBitmap bitmap = + testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap(); BatchIterator it1 = bitmap.getBatchIterator(); while (it1.hasNext()) { BatchIterator it2 = it1.clone(); @@ -32,8 +34,8 @@ public void testIndependenceOfClones() { @Test public void testIndependenceOfClones2() { - int[] c1 = new int[]{1, 10, 20}; - int[] c2 = new int[]{65560, 70000}; + int[] c1 = new int[] {1, 10, 20}; + int[] c2 = new int[] {65560, 70000}; MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); for (int x : Ints.concat(c1, c2)) { bitmap.add(x); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java index 467702664..44a49230c 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/ImmutableRoaringBitmapBatchIteratorTest.java @@ -1,5 +1,16 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.RoaringBitmapWriter.bufferWriter; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + +import org.roaringbitmap.BatchIterator; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.RoaringBitmapWriter; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -9,223 +20,279 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; -import org.roaringbitmap.BatchIterator; -import org.roaringbitmap.IntIterator; -import org.roaringbitmap.RoaringBitmapWriter; import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.RoaringBitmapWriter.bufferWriter; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class ImmutableRoaringBitmapBatchIteratorTest { - private static ImmutableRoaringBitmap[] BITMAPS; - - private static final int[] SIZES = { - 128, 256, 1024, 8192, 5, 127, 1023 - }; - - @BeforeAll - public static void beforeAll() { - BITMAPS = new ImmutableRoaringBitmap[] { - testCase().withArrayAt(0).withArrayAt(2).withArrayAt(4).withArrayAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withRunAt(2).withRunAt(4).withRunAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withRunAt(2).withBitmapAt(4).withBitmapAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).withBitmapAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withArrayAt(2).withBitmapAt(4).withRunAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withRunAt(2).withArrayAt(4).withBitmapAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withArrayAt(0).withBitmapAt(2).withRunAt(4).withArrayAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(2).withBitmapAt(4).withRunAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - testCase().withRunAt((1 << 15) | (1 << 11)).withBitmapAt((1 << 15) | (1 << 12)).withArrayAt((1 << 15) | (1 << 13)).withBitmapAt((1 << 15) | (1 << 14)).build().toMutableRoaringBitmap(), - MutableRoaringBitmap.bitmapOf(IntStream.range(1 << 10, 1 << 26).filter(i -> (i & 1) == 0).toArray()), - MutableRoaringBitmap.bitmapOf(IntStream.range(1 << 10, 1 << 25).filter(i -> ((i >>> 8) & 1) == 0).toArray()), - MutableRoaringBitmap.bitmapOf(IntStream.range(0,127).toArray()), - MutableRoaringBitmap.bitmapOf(IntStream.range(0,1024).toArray()), - MutableRoaringBitmap.bitmapOf(IntStream.concat(IntStream.range(0,256), IntStream.range(1 << 16, (1 << 16) | 256)).toArray()), - ImmutableRoaringBitmap.bitmapOf(8511), - new MutableRoaringBitmap() + private static ImmutableRoaringBitmap[] BITMAPS; + + private static final int[] SIZES = {128, 256, 1024, 8192, 5, 127, 1023}; + + @BeforeAll + public static void beforeAll() { + BITMAPS = + new ImmutableRoaringBitmap[] { + testCase() + .withArrayAt(0) + .withArrayAt(2) + .withArrayAt(4) + .withArrayAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withRunAt(2) + .withRunAt(4) + .withRunAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withRunAt(2) + .withBitmapAt(4) + .withBitmapAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withArrayAt(0) + .withBitmapAt(2) + .withRunAt(4) + .withBitmapAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withArrayAt(2) + .withBitmapAt(4) + .withRunAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withRunAt(2) + .withArrayAt(4) + .withBitmapAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withArrayAt(0) + .withBitmapAt(2) + .withRunAt(4) + .withArrayAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(2) + .withBitmapAt(4) + .withRunAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt((1 << 15) | (1 << 11)) + .withBitmapAt((1 << 15) | (1 << 12)) + .withArrayAt((1 << 15) | (1 << 13)) + .withBitmapAt((1 << 15) | (1 << 14)) + .build() + .toMutableRoaringBitmap(), + MutableRoaringBitmap.bitmapOf( + IntStream.range(1 << 10, 1 << 26).filter(i -> (i & 1) == 0).toArray()), + MutableRoaringBitmap.bitmapOf( + IntStream.range(1 << 10, 1 << 25).filter(i -> ((i >>> 8) & 1) == 0).toArray()), + MutableRoaringBitmap.bitmapOf(IntStream.range(0, 127).toArray()), + MutableRoaringBitmap.bitmapOf(IntStream.range(0, 1024).toArray()), + MutableRoaringBitmap.bitmapOf( + IntStream.concat(IntStream.range(0, 256), IntStream.range(1 << 16, (1 << 16) | 256)) + .toArray()), + ImmutableRoaringBitmap.bitmapOf(8511), + new MutableRoaringBitmap() }; - } + } - @AfterAll - public static void clear() { - BITMAPS = null; - } + @AfterAll + public static void clear() { + BITMAPS = null; + } - public static Stream params() { - return Stream.of(BITMAPS) - .flatMap(bitmap -> IntStream.of(SIZES).mapToObj(i -> Arguments.of(bitmap, i))); - } + public static Stream params() { + return Stream.of(BITMAPS) + .flatMap(bitmap -> IntStream.of(SIZES).mapToObj(i -> Arguments.of(bitmap, i))); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAsIntIterator(MutableRoaringBitmap bitmap, int batchSize) { - IntIterator it = bitmap.getBatchIterator().asIntIterator(new int[batchSize]); - RoaringBitmapWriter w = bufferWriter().constantMemory() - .initialCapacity(bitmap.highLowContainer.size()).get(); - while (it.hasNext()) { - w.add(it.next()); - } - MutableRoaringBitmap copy = w.get(); - assertEquals(bitmap, copy); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAsIntIterator(MutableRoaringBitmap bitmap, int batchSize) { + IntIterator it = bitmap.getBatchIterator().asIntIterator(new int[batchSize]); + RoaringBitmapWriter w = + bufferWriter().constantMemory().initialCapacity(bitmap.highLowContainer.size()).get(); + while (it.hasNext()) { + w.add(it.next()); } + MutableRoaringBitmap copy = w.get(); + assertEquals(bitmap, copy); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void test(MutableRoaringBitmap bitmap, int batchSize) { - int[] buffer = new int[batchSize]; - MutableRoaringBitmap result = new MutableRoaringBitmap(); - BatchIterator it = bitmap.getBatchIterator(); - int cardinality = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - cardinality += batch; - } - assertEquals(bitmap, result); - assertEquals(bitmap.getCardinality(), cardinality); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void test(MutableRoaringBitmap bitmap, int batchSize) { + int[] buffer = new int[batchSize]; + MutableRoaringBitmap result = new MutableRoaringBitmap(); + BatchIterator it = bitmap.getBatchIterator(); + int cardinality = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + cardinality += batch; } + assertEquals(bitmap, result); + assertEquals(bitmap.getCardinality(), cardinality); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAdvancedIfNeeded(MutableRoaringBitmap bitmap, int batchSize) { - final int cardinality = bitmap.getCardinality(); - if (cardinality < 2) { - return; - } - int midpoint = bitmap.select(cardinality / 2); - int[] buffer = new int[batchSize]; - MutableRoaringBitmap result = new MutableRoaringBitmap(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded(midpoint); - int consumed = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - consumed += batch; - } - MutableRoaringBitmap expected = bitmap.clone(); - expected.remove(0, midpoint & 0xFFFFFFFFL); - assertEquals(expected, result); - assertEquals(expected.getCardinality(), consumed); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAdvancedIfNeeded(MutableRoaringBitmap bitmap, int batchSize) { + final int cardinality = bitmap.getCardinality(); + if (cardinality < 2) { + return; } - - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAdvancedIfNeededToAbsentValue(MutableRoaringBitmap bitmap, int batchSize) { - long firstAbsent = bitmap.nextAbsentValue(0); - int[] buffer = new int[batchSize]; - MutableRoaringBitmap result = new MutableRoaringBitmap(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded((int) firstAbsent); - int consumed = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - consumed += batch; - } - MutableRoaringBitmap expected = bitmap.clone(); - expected.remove(0, firstAbsent & 0xFFFFFFFFL); - assertEquals(expected, result); - assertEquals(expected.getCardinality(), consumed); + int midpoint = bitmap.select(cardinality / 2); + int[] buffer = new int[batchSize]; + MutableRoaringBitmap result = new MutableRoaringBitmap(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(midpoint); + int consumed = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + consumed += batch; } + MutableRoaringBitmap expected = bitmap.clone(); + expected.remove(0, midpoint & 0xFFFFFFFFL); + assertEquals(expected, result); + assertEquals(expected.getCardinality(), consumed); + } - @ParameterizedTest(name="offset={1}") - @MethodSource("params") - public void testBatchIteratorAdvancedIfNeededBeyondLastValue(MutableRoaringBitmap bitmap, int batchSize) { - long advanceTo = bitmap.isEmpty() ? 0 : bitmap.last() + 1; - int[] buffer = new int[batchSize]; - MutableRoaringBitmap result = new MutableRoaringBitmap(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded((int) advanceTo); - int consumed = 0; - while (it.hasNext()) { - int batch = it.nextBatch(buffer); - for (int i = 0; i < batch; ++i) { - result.add(buffer[i]); - } - consumed += batch; - } - assertEquals(0, consumed); - assertTrue(result.isEmpty()); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAdvancedIfNeededToAbsentValue( + MutableRoaringBitmap bitmap, int batchSize) { + long firstAbsent = bitmap.nextAbsentValue(0); + int[] buffer = new int[batchSize]; + MutableRoaringBitmap result = new MutableRoaringBitmap(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded((int) firstAbsent); + int consumed = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + consumed += batch; } + MutableRoaringBitmap expected = bitmap.clone(); + expected.remove(0, firstAbsent & 0xFFFFFFFFL); + assertEquals(expected, result); + assertEquals(expected.getCardinality(), consumed); + } - @Test - public void testTimelyTermination() { - ImmutableRoaringBitmap bm = ImmutableRoaringBitmap.bitmapOf(8511); - BatchIterator bi = bm.getBatchIterator(); - int[] batch = new int[10]; - assertTrue(bi.hasNext()); - int n = bi.nextBatch(batch); - assertEquals(n, 1); - assertEquals(batch[0], 8511); - assertFalse(bi.hasNext()); - } - @Test - public void testTimelyTerminationAfterAdvanceIfNeeded() { - ImmutableRoaringBitmap bm = ImmutableRoaringBitmap.bitmapOf(8511); - BatchIterator bi = bm.getBatchIterator(); - assertTrue(bi.hasNext()); - bi.advanceIfNeeded(8512); - assertFalse(bi.hasNext()); + @ParameterizedTest(name = "offset={1}") + @MethodSource("params") + public void testBatchIteratorAdvancedIfNeededBeyondLastValue( + MutableRoaringBitmap bitmap, int batchSize) { + long advanceTo = bitmap.isEmpty() ? 0 : bitmap.last() + 1; + int[] buffer = new int[batchSize]; + MutableRoaringBitmap result = new MutableRoaringBitmap(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded((int) advanceTo); + int consumed = 0; + while (it.hasNext()) { + int batch = it.nextBatch(buffer); + for (int i = 0; i < batch; ++i) { + result.add(buffer[i]); + } + consumed += batch; } + assertEquals(0, consumed); + assertTrue(result.isEmpty()); + } - @Test - public void testBatchIteratorWithAdvanceIfNeeded() { - MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(3 << 16, (3 << 16) + 5, (3 << 16) + 10); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded(6); - assertTrue(it.hasNext()); - int[] batch = new int[10]; - int n = it.nextBatch(batch); - assertEquals(n, 3); - assertEquals(batch[0], 3 << 16); - assertEquals(batch[1], (3 << 16) + 5); - assertEquals(batch[2], (3 << 16) + 10); - } + @Test + public void testTimelyTermination() { + ImmutableRoaringBitmap bm = ImmutableRoaringBitmap.bitmapOf(8511); + BatchIterator bi = bm.getBatchIterator(); + int[] batch = new int[10]; + assertTrue(bi.hasNext()); + int n = bi.nextBatch(batch); + assertEquals(n, 1); + assertEquals(batch[0], 8511); + assertFalse(bi.hasNext()); + } - @ParameterizedTest - @ValueSource(ints = {10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 24}) - public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { - MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24); - bitmap.runOptimize(); - BatchIterator it = bitmap.getBatchIterator(); - it.advanceIfNeeded(number); - assertTrue(it.hasNext()); - int[] batch = new int[10]; - int n = it.nextBatch(batch); - int i = Arrays.binarySearch(batch, 0, n, number); - assertTrue(i >= 0, "key " + number + " not found"); - assertEquals(batch[i], number); - } + @Test + public void testTimelyTerminationAfterAdvanceIfNeeded() { + ImmutableRoaringBitmap bm = ImmutableRoaringBitmap.bitmapOf(8511); + BatchIterator bi = bm.getBatchIterator(); + assertTrue(bi.hasNext()); + bi.advanceIfNeeded(8512); + assertFalse(bi.hasNext()); + } - @Test - public void testBatchIteratorFillsBufferAcrossContainers() { - MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(3 << 4, 3 << 8, 3 << 12, 3 << 16, 3 << 20, 3 << 24, 3 << 28); - assertEquals(5, bitmap.highLowContainer.size()); - BatchIterator it = bitmap.getBatchIterator(); - int[] batch = new int[3]; - int n = it.nextBatch(batch); - assertEquals(3, n); - assertArrayEquals(new int[]{3 << 4, 3 << 8, 3 << 12}, batch); - n = it.nextBatch(batch); - assertEquals(3, n); - assertArrayEquals(new int[]{3 << 16, 3 << 20, 3 << 24}, batch); - n = it.nextBatch(batch); - assertEquals(1, n); - assertArrayEquals(new int[]{3 << 28}, Arrays.copyOfRange(batch, 0, 1)); - n = it.nextBatch(batch); - assertEquals(0, n); - } + @Test + public void testBatchIteratorWithAdvanceIfNeeded() { + MutableRoaringBitmap bitmap = + MutableRoaringBitmap.bitmapOf(3 << 16, (3 << 16) + 5, (3 << 16) + 10); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(6); + assertTrue(it.hasNext()); + int[] batch = new int[10]; + int n = it.nextBatch(batch); + assertEquals(n, 3); + assertEquals(batch[0], 3 << 16); + assertEquals(batch[1], (3 << 16) + 5); + assertEquals(batch[2], (3 << 16) + 10); + } + + @ParameterizedTest + @ValueSource(ints = {10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 24}) + public void testBatchIteratorWithAdvancedIfNeededWithZeroLengthRun(int number) { + MutableRoaringBitmap bitmap = + MutableRoaringBitmap.bitmapOf(10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24); + bitmap.runOptimize(); + BatchIterator it = bitmap.getBatchIterator(); + it.advanceIfNeeded(number); + assertTrue(it.hasNext()); + int[] batch = new int[10]; + int n = it.nextBatch(batch); + int i = Arrays.binarySearch(batch, 0, n, number); + assertTrue(i >= 0, "key " + number + " not found"); + assertEquals(batch[i], number); + } + + @Test + public void testBatchIteratorFillsBufferAcrossContainers() { + MutableRoaringBitmap bitmap = + MutableRoaringBitmap.bitmapOf(3 << 4, 3 << 8, 3 << 12, 3 << 16, 3 << 20, 3 << 24, 3 << 28); + assertEquals(5, bitmap.highLowContainer.size()); + BatchIterator it = bitmap.getBatchIterator(); + int[] batch = new int[3]; + int n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[] {3 << 4, 3 << 8, 3 << 12}, batch); + n = it.nextBatch(batch); + assertEquals(3, n); + assertArrayEquals(new int[] {3 << 16, 3 << 20, 3 << 24}, batch); + n = it.nextBatch(batch); + assertEquals(1, n); + assertArrayEquals(new int[] {3 << 28}, Arrays.copyOfRange(batch, 0, 1)); + n = it.nextBatch(batch); + assertEquals(0, n); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java index d6f4b578a..01ba3d83c 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringArrayTest.java @@ -1,13 +1,11 @@ package org.roaringbitmap.buffer; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertSame; +import org.junit.jupiter.api.Test; public class MutableRoaringArrayTest { - @Test public void resizeOnlyIfNecessary() { char[] keys = new char[1]; diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java index c3c35222e..d8736697c 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/MutableRoaringBitmapSubsetTest.java @@ -1,6 +1,12 @@ package org.roaringbitmap.buffer; -import com.google.common.collect.*; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.common.collect.ContiguousSet; +import com.google.common.collect.DiscreteDomain; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Range; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -9,153 +15,126 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class MutableRoaringBitmapSubsetTest { + private static final Predicate DIVISIBLE_BY_4 = i -> i % 4 == 0; - private static final Predicate DIVISIBLE_BY_4 = i -> i % 4 == 0; + private static final Predicate DIVISIBLE_BY_3 = i -> i % 3 == 0; - private static final Predicate DIVISIBLE_BY_3 = i -> i % 3 == 0; + public static Stream params() { + return Stream.of( + Arguments.of( // array vs array + ImmutableSet.of(1, 2, 3, 4), ImmutableSet.of(2, 3)), + Arguments.of( // array vs empty + ImmutableSet.of(1, 2, 3, 4), ImmutableSet.of()), + Arguments.of( // identical arrays + ImmutableSet.of(1, 2, 3, 4), ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // disjoint arrays + ImmutableSet.of(10, 12, 14, 15), ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // disjoint arrays, cardinality mismatch + ImmutableSet.of(10, 12, 14), ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // run vs array, subset + ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), + ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // run vs array, subset + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of(1, 2, 3, 4)), + Arguments.of( // run vs empty + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of()), + Arguments.of( // identical runs, 1 container + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers())), + Arguments.of( // identical runs, 2 containers + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers())), + Arguments.of( // disjoint array vs run, either side of container boundary + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of((1 << 16) + 1, (1 << 16) + 2, (1 << 16) + 3, (1 << 16) + 4)), + Arguments.of( // disjoint array vs run + ContiguousSet.create(Range.closed(3, 1 << 16), DiscreteDomain.integers()), + ImmutableSet.of(1, 2)), + Arguments.of( // run vs run, overlap with shift + ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), + ContiguousSet.create(Range.closed(1 << 4, 1 << 12), DiscreteDomain.integers())), + Arguments.of( // run vs run, subset + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), + ImmutableSet.of(1, 1 << 8)), + Arguments.of( // run vs run, overlap with shift, 2 containers + ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), + ImmutableSet.of(1 << 6, 1 << 26)), + Arguments.of( // run vs 2 container run, overlap + ImmutableSet.of(1, 1 << 16), + ContiguousSet.create(Range.closed(0, 1 << 20), DiscreteDomain.integers())), + Arguments.of( // bitmap vs intersecting array + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.of(4, 8)), + Arguments.of( // bitmap vs bitmap, cardinality mismatch + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // bitmap vs empty + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.of()), + Arguments.of( // identical bitmaps + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test)), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // bitmap vs overlapping but disjoint array + ImmutableSet.of(3, 7), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // bitmap vs overlapping but disjoint bitmap + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_3::test)), + ImmutableSet.copyOf( + Iterables.filter( + ContiguousSet.create(Range.closed(1, 1 << 15), DiscreteDomain.integers()), + DIVISIBLE_BY_4::test))), + Arguments.of( // disjoint, large (signed-negative) keys + ImmutableSet.of(0xbf09001d, 0xbf090169), ImmutableSet.of(0x8088000e, 0x80880029))); + } + @ParameterizedTest + @MethodSource("params") + public void testProperSubset(Set superSet, Set subSet) { + MutableRoaringBitmap superSetRB = create(superSet); + MutableRoaringBitmap subSetRB = create(subSet); + assertEquals(superSet.containsAll(subSet), superSetRB.contains(subSetRB)); + // reverse the test + assertEquals(subSet.containsAll(superSet), subSetRB.contains(superSetRB)); + } - public static Stream params() { - return Stream.of( - Arguments.of( // array vs array - ImmutableSet.of(1, 2, 3, 4), - ImmutableSet.of(2, 3) - ), - Arguments.of( // array vs empty - ImmutableSet.of(1, 2, 3, 4), - ImmutableSet.of() - ), - Arguments.of( // identical arrays - ImmutableSet.of(1, 2, 3, 4), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // disjoint arrays - ImmutableSet.of(10, 12, 14, 15), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of(// disjoint arrays, cardinality mismatch - ImmutableSet.of(10, 12, 14), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // run vs array, subset - ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // run vs array, subset - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of(1, 2, 3, 4) - ), - Arguments.of( // run vs empty - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of() - ), - Arguments.of( // identical runs, 1 container - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()) - ), - Arguments.of( // identical runs, 2 containers - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()) - ), - Arguments.of( // disjoint array vs run, either side of container boundary - ContiguousSet.create(Range.closed(1, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of((1 << 16) + 1, (1 << 16) + 2, (1 << 16) + 3, (1 << 16) + 4) - ), - Arguments.of( // disjoint array vs run - ContiguousSet.create(Range.closed(3, 1 << 16), DiscreteDomain.integers()), - ImmutableSet.of(1, 2) - ), - Arguments.of( // run vs run, overlap with shift - ContiguousSet.create(Range.closed(1, 1 << 8), DiscreteDomain.integers()), - ContiguousSet.create(Range.closed(1 << 4, 1 << 12), DiscreteDomain.integers()) - ), - Arguments.of( // run vs run, subset - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), - ImmutableSet.of(1, 1 << 8) - ), - Arguments.of( // run vs run, overlap with shift, 2 containers - ContiguousSet.create(Range.closed(1, 1 << 20), DiscreteDomain.integers()), - ImmutableSet.of(1 << 6, 1 << 26) - ), - Arguments.of( // run vs 2 container run, overlap - ImmutableSet.of(1, 1 << 16), - ContiguousSet.create(Range.closed(0, 1 << 20), DiscreteDomain.integers()) - ), - Arguments.of( // bitmap vs intersecting array - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.of(4, 8) - ), - Arguments.of( // bitmap vs bitmap, cardinality mismatch - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 16), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // bitmap vs empty - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.of() - ), - Arguments.of( // identical bitmaps - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // bitmap vs overlapping but disjoint array - ImmutableSet.of(3, 7), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // bitmap vs overlapping but disjoint bitmap - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_3::test)), - ImmutableSet.copyOf(Iterables.filter(ContiguousSet.create(Range.closed(1, 1 << 15), - DiscreteDomain.integers()), - DIVISIBLE_BY_4::test)) - ), - Arguments.of( // disjoint, large (signed-negative) keys - ImmutableSet.of(0xbf09001d, 0xbf090169), - ImmutableSet.of(0x8088000e, 0x80880029) - )); + private MutableRoaringBitmap create(Set set) { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + if (set instanceof ContiguousSet) { + ContiguousSet contiguousSet = (ContiguousSet) set; + rb.add(contiguousSet.first().longValue(), contiguousSet.last().longValue()); + } else { + for (Integer i : set) { + rb.add(i); + } } - - - @ParameterizedTest - @MethodSource("params") - public void testProperSubset(Set superSet, Set subSet) { - MutableRoaringBitmap superSetRB = create(superSet); - MutableRoaringBitmap subSetRB = create(subSet); - assertEquals(superSet.containsAll(subSet), superSetRB.contains(subSetRB)); - // reverse the test - assertEquals(subSet.containsAll(superSet), subSetRB.contains(superSetRB)); - } - - private MutableRoaringBitmap create(Set set) { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - if (set instanceof ContiguousSet) { - ContiguousSet contiguousSet = (ContiguousSet) set; - rb.add(contiguousSet.first().longValue(), contiguousSet.last().longValue()); - } else { - for (Integer i : set) { - rb.add(i); - } - } - return rb; - } - - + return rb; + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java index 9a6dcb1f3..c14036281 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/RoaringBitmapIntervalIntersectionTest.java @@ -1,5 +1,10 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; + +import org.roaringbitmap.RoaringBitmap; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -8,14 +13,9 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.RoaringBitmap; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class RoaringBitmapIntervalIntersectionTest { @@ -23,26 +23,78 @@ public class RoaringBitmapIntervalIntersectionTest { @BeforeAll public static void before() { - ARGS = new Arguments[] { - Arguments.of(RoaringBitmap.bitmapOf(1, 2, 3).toMutableRoaringBitmap(), 0, 1 << 16), - Arguments.of(RoaringBitmap.bitmapOf(1, 2, 3).toMutableRoaringBitmap(), 1, 1), - Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 1 << 16), - Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 256), - Arguments.of(RoaringBitmap.bitmapOf(1, 1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 256), - Arguments.of(RoaringBitmap.bitmapOf(1, 1 << 16, 1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 1L << 32), - Arguments.of(testCase().withArrayAt(10).withBitmapAt(20).withRunAt(30) - .withRange(70000L, 150000L).build().toMutableRoaringBitmap(), 70000L, 150000L), - Arguments.of(testCase().withArrayAt(10).withBitmapAt(20).withRunAt(30) - .withRange(70000L, 150000L).build().toMutableRoaringBitmap(), 71000L, 140000L), - Arguments.of(testCase().withArrayAt(0).withBitmapAt(1).withRunAt(20).build().toMutableRoaringBitmap(), 67000, 150000), - Arguments.of(testCase().withBitmapAt(0).withArrayAt(1).withRunAt(20).build().toMutableRoaringBitmap(), 67000, 150000), - Arguments.of(testCase().withBitmapAt(0).withRunAt(1).withArrayAt(20).build().toMutableRoaringBitmap(), 67000, 150000), - Arguments.of(testCase().withArrayAt(0) - .withArrayAt(1) - .withArrayAt(2) - .withBitmapAt(200) - .withRunAt(205).build().toMutableRoaringBitmap(), 199 * (1 << 16), 200 * (1 << 16) + (1 << 14)) - }; + ARGS = + new Arguments[] { + Arguments.of(RoaringBitmap.bitmapOf(1, 2, 3).toMutableRoaringBitmap(), 0, 1 << 16), + Arguments.of(RoaringBitmap.bitmapOf(1, 2, 3).toMutableRoaringBitmap(), 1, 1), + Arguments.of( + RoaringBitmap.bitmapOf(1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 1 << 16), + Arguments.of(RoaringBitmap.bitmapOf(1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 256), + Arguments.of( + RoaringBitmap.bitmapOf(1, 1 << 31 | 1 << 30).toMutableRoaringBitmap(), 0, 256), + Arguments.of( + RoaringBitmap.bitmapOf(1, 1 << 16, 1 << 31 | 1 << 30).toMutableRoaringBitmap(), + 0, + 1L << 32), + Arguments.of( + testCase() + .withArrayAt(10) + .withBitmapAt(20) + .withRunAt(30) + .withRange(70000L, 150000L) + .build() + .toMutableRoaringBitmap(), + 70000L, + 150000L), + Arguments.of( + testCase() + .withArrayAt(10) + .withBitmapAt(20) + .withRunAt(30) + .withRange(70000L, 150000L) + .build() + .toMutableRoaringBitmap(), + 71000L, + 140000L), + Arguments.of( + testCase() + .withArrayAt(0) + .withBitmapAt(1) + .withRunAt(20) + .build() + .toMutableRoaringBitmap(), + 67000, + 150000), + Arguments.of( + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(20) + .build() + .toMutableRoaringBitmap(), + 67000, + 150000), + Arguments.of( + testCase() + .withBitmapAt(0) + .withRunAt(1) + .withArrayAt(20) + .build() + .toMutableRoaringBitmap(), + 67000, + 150000), + Arguments.of( + testCase() + .withArrayAt(0) + .withArrayAt(1) + .withArrayAt(2) + .withBitmapAt(200) + .withRunAt(205) + .build() + .toMutableRoaringBitmap(), + 199 * (1 << 16), + 200 * (1 << 16) + (1 << 14)) + }; } @AfterAll @@ -50,18 +102,17 @@ public static void after() { ARGS = null; } - public static Stream params() { return Stream.of(ARGS); } - @ParameterizedTest @MethodSource("params") public void test(MutableRoaringBitmap bitmap, long minimum, long supremum) { MutableRoaringBitmap test = new MutableRoaringBitmap(); test.add(minimum, supremum); - assertEquals(ImmutableRoaringBitmap.intersects(bitmap, test), bitmap.intersects(minimum, supremum)); + assertEquals( + ImmutableRoaringBitmap.intersects(bitmap, test), bitmap.intersects(minimum, supremum)); } @ParameterizedTest @@ -69,7 +120,8 @@ public void test(MutableRoaringBitmap bitmap, long minimum, long supremum) { public void testIntersects(MutableRoaringBitmap bitmap, long minimum, long supremum) { MutableRoaringBitmap test = new MutableRoaringBitmap(); test.add(minimum, supremum); - assertEquals(MutableRoaringBitmap.intersects(bitmap, test), bitmap.intersects(minimum, supremum)); + assertEquals( + MutableRoaringBitmap.intersects(bitmap, test), bitmap.intersects(minimum, supremum)); } @ParameterizedTest diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java index dda8cce32..a6f09607e 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBitSetUtil.java @@ -1,5 +1,7 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -8,12 +10,10 @@ import java.util.BitSet; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertTrue; - @Execution(ExecutionMode.CONCURRENT) public class TestBitSetUtil { - private static BitSet appendRandomBitset(final Random random, final int offset, - final BitSet bitset, final int nbits) { + private static BitSet appendRandomBitset( + final Random random, final int offset, final BitSet bitset, final int nbits) { for (int i = 0; i < nbits; i++) { final boolean b = random.nextBoolean(); bitset.set(offset + i, b); @@ -26,7 +26,6 @@ private static BitSet randomBitset(final Random random, final int offset, final return appendRandomBitset(random, offset, bitset, length); } - private void assertEqualBitsets(final BitSet bitset, final MutableRoaringBitmap bitmap) { assertTrue(BufferBitSetUtil.equals(bitset, bitmap)); } @@ -138,9 +137,9 @@ public void testSmallBitSet10000000() { assertEqualBitsets(bitset, bitmap); } - /* - The ByteBuffer->RoaringBitmap just replicate similar tests written for BitSet/long[]->RoaringBitmap - */ + /* + The ByteBuffer->RoaringBitmap just replicate similar tests written for BitSet/long[]->RoaringBitmap + */ @Test public void testEmptyByteBuffer() { @@ -205,7 +204,7 @@ public void testRandomByteBuffer() { final Random random = new Random(8934); final int runs = 100; final int maxNbits = 500000; - for (int i = 0;i < runs; ++i) { + for (int i = 0; i < runs; ++i) { final int offset = random.nextInt(maxNbits) & Integer.MAX_VALUE; final BitSet bitset = randomBitset(random, offset, random.nextInt(maxNbits)); final MutableRoaringBitmap bitmap = BufferBitSetUtil.bitmapOf(toByteBuffer(bitset)); @@ -233,5 +232,4 @@ public void testByteArrayWithOnly1And10000000thBitSet() { private static ByteBuffer toByteBuffer(BitSet bitset) { return ByteBuffer.wrap(bitset.toByteArray()); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java index cd3cf3c7c..08f123b70 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferAdversarialInputs.java @@ -1,113 +1,123 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.roaringbitmap.TestAdversarialInputs; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.TestAdversarialInputs; -import java.io.*; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; -import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - - public class TestBufferAdversarialInputs { - public static Stream badFiles() { - return TestAdversarialInputs.badFiles(); - } - - // copy to a temporary file - protected static File copy(String resourceName) throws IOException { - File tmpFile = File.createTempFile(TestBufferAdversarialInputs.class.getName(), "bin"); - tmpFile.deleteOnExit(); - - try (InputStream input = TestAdversarialInputs.openInputstream(resourceName)) { - Files.copy(input, tmpFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - } - - return tmpFile; - } - - public ByteBuffer memoryMap(String resourceName) throws IOException { - File tmpfile = copy(resourceName); - long totalcount = tmpfile.length(); - RandomAccessFile memoryMappedFile = new RandomAccessFile(tmpfile, "r"); - ByteBuffer bb = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, totalcount); // even though we have two bitmaps, we have one map, maps are expensive!!! - memoryMappedFile.close(); // we can safely close - bb.position(0); - return bb; - } - - @Test - public void testInputGoodFile1() throws IOException { - File file = copy("/testdata/bitmapwithruns.bin"); - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - // should not throw an exception - rb.deserialize(new DataInputStream(new FileInputStream(file))); - assertEquals(rb.getCardinality(), 200100); - file.delete(); - } - - @Test - public void testInputGoodFile1Mapped() throws IOException { - ByteBuffer bb = memoryMap("/testdata/bitmapwithruns.bin"); - ImmutableRoaringBitmap rb = new ImmutableRoaringBitmap(bb); - assertEquals(rb.getCardinality(), 200100); - } - - @Test - public void testInputGoodFile2() throws IOException { - File file = copy("/testdata/bitmapwithoutruns.bin"); - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - // should not throw an exception - rb.deserialize(new DataInputStream(new FileInputStream(file))); - assertEquals(rb.getCardinality(), 200100); - file.delete(); - } - - @Test - public void testInputGoodFile2Mapped() throws IOException { - ByteBuffer bb = memoryMap("/testdata/bitmapwithoutruns.bin"); - ImmutableRoaringBitmap rb = new ImmutableRoaringBitmap(bb); - assertEquals(rb.getCardinality(), 200100); - } - - @ParameterizedTest - @MethodSource("badFiles") - public void testInputBadFileDeserialize(String file) { - assertThrows(IOException.class, () -> deserialize(file)); - } - - @ParameterizedTest - @MethodSource("badFiles") - public void testInputBadFileMap(String file) { - if (file.endsWith("7.bin")) { - assertThrows(IllegalArgumentException.class, () -> map(file)); - } else { - assertThrows(IndexOutOfBoundsException.class, () -> map(file)); - } - } - - private void deserialize(String fileName) throws IOException { - File file = copy(fileName); - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - // should not work - rb.deserialize(new DataInputStream(new FileInputStream(file))); - file.delete(); - } - - private void map(String fileName) throws IOException { - ByteBuffer bb = memoryMap(fileName); - ImmutableRoaringBitmap rb = new ImmutableRoaringBitmap(bb); - System.out.println(rb.getCardinality()); // won't get here - } + public static Stream badFiles() { + return TestAdversarialInputs.badFiles(); + } + + // copy to a temporary file + protected static File copy(String resourceName) throws IOException { + File tmpFile = File.createTempFile(TestBufferAdversarialInputs.class.getName(), "bin"); + tmpFile.deleteOnExit(); + + try (InputStream input = TestAdversarialInputs.openInputstream(resourceName)) { + Files.copy(input, tmpFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + + return tmpFile; + } + + public ByteBuffer memoryMap(String resourceName) throws IOException { + File tmpfile = copy(resourceName); + long totalcount = tmpfile.length(); + RandomAccessFile memoryMappedFile = new RandomAccessFile(tmpfile, "r"); + ByteBuffer bb = + memoryMappedFile + .getChannel() + .map( + FileChannel.MapMode.READ_ONLY, + 0, + totalcount); // even though we have two bitmaps, we have one map, maps are + // expensive!!! + memoryMappedFile.close(); // we can safely close + bb.position(0); + return bb; + } + + @Test + public void testInputGoodFile1() throws IOException { + File file = copy("/testdata/bitmapwithruns.bin"); + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + // should not throw an exception + rb.deserialize(new DataInputStream(new FileInputStream(file))); + assertEquals(rb.getCardinality(), 200100); + file.delete(); + } + + @Test + public void testInputGoodFile1Mapped() throws IOException { + ByteBuffer bb = memoryMap("/testdata/bitmapwithruns.bin"); + ImmutableRoaringBitmap rb = new ImmutableRoaringBitmap(bb); + assertEquals(rb.getCardinality(), 200100); + } + + @Test + public void testInputGoodFile2() throws IOException { + File file = copy("/testdata/bitmapwithoutruns.bin"); + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + // should not throw an exception + rb.deserialize(new DataInputStream(new FileInputStream(file))); + assertEquals(rb.getCardinality(), 200100); + file.delete(); + } + + @Test + public void testInputGoodFile2Mapped() throws IOException { + ByteBuffer bb = memoryMap("/testdata/bitmapwithoutruns.bin"); + ImmutableRoaringBitmap rb = new ImmutableRoaringBitmap(bb); + assertEquals(rb.getCardinality(), 200100); + } + + @ParameterizedTest + @MethodSource("badFiles") + public void testInputBadFileDeserialize(String file) { + assertThrows(IOException.class, () -> deserialize(file)); + } + + @ParameterizedTest + @MethodSource("badFiles") + public void testInputBadFileMap(String file) { + if (file.endsWith("7.bin")) { + assertThrows(IllegalArgumentException.class, () -> map(file)); + } else { + assertThrows(IndexOutOfBoundsException.class, () -> map(file)); + } + } + + private void deserialize(String fileName) throws IOException { + File file = copy(fileName); + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + // should not work + rb.deserialize(new DataInputStream(new FileInputStream(file))); + file.delete(); + } + + private void map(String fileName) throws IOException { + ByteBuffer bb = memoryMap(fileName); + ImmutableRoaringBitmap rb = new ImmutableRoaringBitmap(bb); + System.out.println(rb.getCardinality()); // won't get here + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java index cf9efd946..3abd87683 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestBufferRangeCardinality.java @@ -1,5 +1,7 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -9,35 +11,31 @@ import java.nio.LongBuffer; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - - public class TestBufferRangeCardinality { - - public static Stream data() { - return Stream.of( - Arguments.of(new int[]{1, 3, 5, 7, 9}, 3, 8, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 2, 8, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 3, 7, 2), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 0, 7, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9}, 0, 6, 3), - Arguments.of(new int[]{1, 3, 5, 7, 9, Short.MAX_VALUE}, 0, Short.MAX_VALUE + 1, 6), - Arguments.of(new int[]{1, 10000, 25000, Short.MAX_VALUE - 1}, 0, Short.MAX_VALUE, 4), - Arguments.of(new int[]{1 << 3, 1 << 8, 511, 512, 513, 1 << 12, 1 << 14}, 0, Short.MAX_VALUE, 7) - ); - } - - @ParameterizedTest(name = "{index}: cardinalityInBitmapRange({0},{1},{2})={3}") - @MethodSource("data") - public void testCardinalityInBitmapWordRange(int[] elements, int begin, int end, int expected) { - LongBuffer array = ByteBuffer.allocateDirect(MappeableBitmapContainer.MAX_CAPACITY / 8).asLongBuffer(); - MappeableBitmapContainer bc = new MappeableBitmapContainer(array, 0); - for (int e : elements) { - bc.add((char) e); - } - assertFalse(bc.isArrayBacked()); - assertEquals(expected, BufferUtil.cardinalityInBitmapRange(bc.bitmap, begin, end)); + public static Stream data() { + return Stream.of( + Arguments.of(new int[] {1, 3, 5, 7, 9}, 3, 8, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 2, 8, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 3, 7, 2), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 0, 7, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9}, 0, 6, 3), + Arguments.of(new int[] {1, 3, 5, 7, 9, Short.MAX_VALUE}, 0, Short.MAX_VALUE + 1, 6), + Arguments.of(new int[] {1, 10000, 25000, Short.MAX_VALUE - 1}, 0, Short.MAX_VALUE, 4), + Arguments.of( + new int[] {1 << 3, 1 << 8, 511, 512, 513, 1 << 12, 1 << 14}, 0, Short.MAX_VALUE, 7)); + } + + @ParameterizedTest(name = "{index}: cardinalityInBitmapRange({0},{1},{2})={3}") + @MethodSource("data") + public void testCardinalityInBitmapWordRange(int[] elements, int begin, int end, int expected) { + LongBuffer array = + ByteBuffer.allocateDirect(MappeableBitmapContainer.MAX_CAPACITY / 8).asLongBuffer(); + MappeableBitmapContainer bc = new MappeableBitmapContainer(array, 0); + for (int e : elements) { + bc.add((char) e); } + assertFalse(bc.isArrayBacked()); + assertEquals(expected, BufferUtil.cardinalityInBitmapRange(bc.bitmap, begin, end)); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java index 167b30329..57517a8d9 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestCompressionRates.java @@ -4,10 +4,9 @@ package org.roaringbitmap.buffer; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; public class TestCompressionRates { @@ -26,5 +25,4 @@ public void SimpleCompressionRateTest() { assertTrue(mrb.serializedSizeInBytes() * 8.0 / N < (maxval + 1)); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java index fbc548373..67e30e49b 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestContainer.java @@ -4,22 +4,23 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.roaringbitmap.CharIterator; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.CharIterator; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; -import static org.junit.jupiter.api.Assertions.*; - - /** * Various tests on Container and its subclasses, ArrayContainer, RunContainer and BitmapContainer */ @@ -27,12 +28,14 @@ @Execution(ExecutionMode.CONCURRENT) public class TestContainer { - @Test public void testNames() { - assertEquals(new MappeableBitmapContainer().getContainerName(), MappeableContainer.ContainerNames[0]); - assertEquals(new MappeableArrayContainer().getContainerName(), MappeableContainer.ContainerNames[1]); - assertEquals(new MappeableRunContainer().getContainerName(), MappeableContainer.ContainerNames[2]); + assertEquals( + new MappeableBitmapContainer().getContainerName(), MappeableContainer.ContainerNames[0]); + assertEquals( + new MappeableArrayContainer().getContainerName(), MappeableContainer.ContainerNames[1]); + assertEquals( + new MappeableRunContainer().getContainerName(), MappeableContainer.ContainerNames[2]); } public static boolean checkContent(MappeableContainer c, char[] s) { @@ -68,7 +71,6 @@ public static boolean checkContent(MappeableContainer c, char[] s) { return !fail; } - public static MappeableContainer makeContainer(char[] ss) { MappeableContainer c = new MappeableArrayContainer(); for (final char s : ss) { @@ -77,7 +79,6 @@ public static MappeableContainer makeContainer(char[] ss) { return c; } - @Test public void inotTest1() { // Array container, range is complete @@ -94,8 +95,6 @@ public void inotTest1() { assertTrue(checkContent(c, s)); } - - @Test public void inotTest10() { System.out.println("inotTest10"); @@ -108,13 +107,27 @@ public void inotTest10() { final MappeableContainer c1 = c.inot(65190, 65201); assertTrue(c1 instanceof MappeableArrayContainer); assertEquals(14, c1.getCardinality()); - assertTrue(checkContent(c1, - new char[] {0, 2, 4, (char) 65190, (char) 65191, (char) 65192, (char) 65193, - (char) 65194, (char) 65195, (char) 65196, (char) 65197, (char) 65198, - (char) 65199, (char) 65200})); + assertTrue( + checkContent( + c1, + new char[] { + 0, + 2, + 4, + (char) 65190, + (char) 65191, + (char) 65192, + (char) 65193, + (char) 65194, + (char) 65195, + (char) 65196, + (char) 65197, + (char) 65198, + (char) 65199, + (char) 65200 + })); } - @Test public void inotTest10A() { System.out.println("inotTest10A"); @@ -126,10 +139,27 @@ public void inotTest10A() { final MappeableContainer c1 = c.inot(65190, 65201); assertTrue(c1 instanceof MappeableRunContainer); assertEquals(16, c1.getCardinality()); - assertTrue(checkContent(c1, - new char[] {1, 2, 3, 4, 5, (char) 65190, (char) 65191, (char) 65192, (char) 65193, - (char) 65194, (char) 65195, (char) 65196, (char) 65197, (char) 65198, - (char) 65199, (char) 65200})); + assertTrue( + checkContent( + c1, + new char[] { + 1, + 2, + 3, + 4, + 5, + (char) 65190, + (char) 65191, + (char) 65192, + (char) 65193, + (char) 65194, + (char) 65195, + (char) 65196, + (char) 65197, + (char) 65198, + (char) 65199, + (char) 65200 + })); } @Test @@ -202,7 +232,6 @@ public void inotTest4() { assertTrue(checkContent(c, content)); } - @Test public void inotTest4A() { // Run container, range is partial, @@ -236,7 +265,6 @@ public void inotTest5() { c = c.inot(4, 1000); // back, as a bitmap assertTrue(c instanceof MappeableBitmapContainer); assertTrue(checkContent(c, content)); - } @Test @@ -260,7 +288,6 @@ public void inotTest5A() { c = c.inot(4, 1000); // back, as a bitmap assertTrue(c instanceof MappeableRunContainer); assertTrue(checkContent(c, content)); - } @Test @@ -339,7 +366,6 @@ public void inotTest8() { assertTrue(checkContent(c, content)); } - // mostly same tests, except for not. (check original unaffected) @Test public void notTest1() { @@ -465,7 +491,6 @@ public void notTest3() { } } - @Test public void notTest4() { System.out.println("notTest4"); @@ -638,7 +663,6 @@ public void notTest9() { assertTrue(checkContent(c2, content)); } - @Test public void numberOfRuns() { char[] positions = {3, 4, 5, 10, 11, 13, 15, 62, 63, 64, 65}; @@ -656,8 +680,6 @@ public void numberOfRuns() { assertEquals(rc.numberOfRuns(), bc.numberOfRuns()); } - - @Test public void rangeOfOnesTest1() { final MappeableContainer c = MappeableContainer.rangeOfOnes(4, 11); // sparse @@ -681,8 +703,6 @@ public void rangeOfOnesTest2() { assertEquals(35000 - 1000 + 1, c.getCardinality()); } - - @Test public void rangeOfOnesTest2A() { final MappeableContainer c = MappeableContainer.rangeOfOnes(1000, 35001); // dense @@ -741,7 +761,6 @@ public void transitionTest() { c = c.runOptimize(); assertEquals(c.getCardinality(), 1); assertTrue(c instanceof MappeableArrayContainer); - } @Test @@ -751,8 +770,10 @@ public void testXorContainer() throws Exception { MappeableContainer bc1 = new MappeableBitmapContainer().add(10, 20); MappeableContainer bc2 = new MappeableBitmapContainer().add(21, 30); MappeableContainer ac1 = new MappeableArrayContainer().add((char) 3).add((char) 79); - MappeableContainer ac2 = new MappeableArrayContainer().add((char) 45).add((char) 56).add((char) 109); - for (Set test : Sets.powerSet(ImmutableSet.of(rc1, rc2, bc1, bc2, ac1, ac2))) { + MappeableContainer ac2 = + new MappeableArrayContainer().add((char) 45).add((char) 56).add((char) 109); + for (Set test : + Sets.powerSet(ImmutableSet.of(rc1, rc2, bc1, bc2, ac1, ac2))) { Iterator it = test.iterator(); if (test.size() == 1) { // compare with self MappeableContainer x = it.next(); @@ -828,7 +849,7 @@ public void testConsistentToString() { MappeableArrayContainer ac = new MappeableArrayContainer(); MappeableBitmapContainer bc = new MappeableBitmapContainer(); MappeableRunContainer rc = new MappeableRunContainer(); - for (char i : new char[]{0, 2, 17, Short.MAX_VALUE, (char)-3, (char)-1}) { + for (char i : new char[] {0, 2, 17, Short.MAX_VALUE, (char) -3, (char) -1}) { ac.add(i); bc.add(i); rc.add(i); @@ -837,11 +858,8 @@ public void testConsistentToString() { assertEquals(expected, ac.toString()); assertEquals(expected, bc.toString()); - String normalizedRCstr = rc.toString() - .replaceAll("\\d+\\]\\[", "") - .replace('[', '{') - .replaceFirst(",\\d+\\]", "}"); + String normalizedRCstr = + rc.toString().replaceAll("\\d+\\]\\[", "").replace('[', '{').replaceFirst(",\\d+\\]", "}"); assertEquals(expected, normalizedRCstr); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java index f3cb11ec7..aad1ec531 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestExamples.java @@ -6,7 +6,11 @@ import org.junit.jupiter.api.Test; -import java.io.*; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java index 315fae9dc..24da6df2d 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestFastAggregation.java @@ -1,5 +1,8 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -17,10 +20,6 @@ import java.util.List; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.roaringbitmap.SeededTestData.TestDataSet.testCase; - @Execution(ExecutionMode.CONCURRENT) public class TestFastAggregation { @@ -62,8 +61,9 @@ public void testNaiveAnd() { public void testPriorityQueueOr() { int[] array1 = {1232, 3324, 123, 43243, 1322, 7897, 8767}; int[] array2 = {39173, 39174, 39175, 39176, 39177, 39178, 39179}; - int[] array3 = - {1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, 39179}; + int[] array3 = { + 1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, 39179 + }; int[] array4 = {}; ArrayList data5 = new ArrayList<>(); ArrayList data6 = new ArrayList<>(); @@ -77,28 +77,31 @@ public void testPriorityQueueOr() { assertEquals(data1, BufferFastAggregation.priorityqueue_or(data1)); assertEquals(data1, BufferFastAggregation.priorityqueue_or(data1, data4)); assertEquals(data3, BufferFastAggregation.priorityqueue_or(data5.iterator())); - assertEquals(new MutableRoaringBitmap(), - BufferFastAggregation.priorityqueue_or(data6.iterator())); + assertEquals( + new MutableRoaringBitmap(), BufferFastAggregation.priorityqueue_or(data6.iterator())); data6.add(data1); assertEquals(data1, BufferFastAggregation.priorityqueue_or(data6.iterator())); } @Test public void testPriorityQueueXor() { - assertThrows(IllegalArgumentException.class, () -> { - int[] array1 = {1232, 3324, 123, 43243, 1322, 7897, 8767}; - int[] array2 = {39173, 39174, 39175, 39176, 39177, 39178, 39179}; - int[] array3 = - {1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, 39179}; - ImmutableRoaringBitmap data1 = MutableRoaringBitmap.bitmapOf(array1); - ImmutableRoaringBitmap data2 = MutableRoaringBitmap.bitmapOf(array2); - ImmutableRoaringBitmap data3 = MutableRoaringBitmap.bitmapOf(array3); - assertEquals(data3, BufferFastAggregation.priorityqueue_xor(data1, data2)); - BufferFastAggregation.priorityqueue_xor(data1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + int[] array1 = {1232, 3324, 123, 43243, 1322, 7897, 8767}; + int[] array2 = {39173, 39174, 39175, 39176, 39177, 39178, 39179}; + int[] array3 = { + 1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, + 39179 + }; + ImmutableRoaringBitmap data1 = MutableRoaringBitmap.bitmapOf(array1); + ImmutableRoaringBitmap data2 = MutableRoaringBitmap.bitmapOf(array2); + ImmutableRoaringBitmap data3 = MutableRoaringBitmap.bitmapOf(array3); + assertEquals(data3, BufferFastAggregation.priorityqueue_xor(data1, data2)); + BufferFastAggregation.priorityqueue_xor(data1); + }); } - @Test public void testNaiveAndMapped() { int[] array1 = {39173, 39174}; @@ -117,8 +120,9 @@ public void testNaiveAndMapped() { public void testPriorityQueueOrMapped() { int[] array1 = {1232, 3324, 123, 43243, 1322, 7897, 8767}; int[] array2 = {39173, 39174, 39175, 39176, 39177, 39178, 39179}; - int[] array3 = - {1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, 39179}; + int[] array3 = { + 1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, 39179 + }; int[] array4 = {}; ArrayList data5 = new ArrayList<>(); ArrayList data6 = new ArrayList<>(); @@ -132,8 +136,8 @@ public void testPriorityQueueOrMapped() { assertEquals(data1, BufferFastAggregation.priorityqueue_or(data1)); assertEquals(data1, BufferFastAggregation.priorityqueue_or(data1, data4)); assertEquals(data3, BufferFastAggregation.priorityqueue_or(data5.iterator())); - assertEquals(new MutableRoaringBitmap(), - BufferFastAggregation.priorityqueue_or(data6.iterator())); + assertEquals( + new MutableRoaringBitmap(), BufferFastAggregation.priorityqueue_or(data6.iterator())); data6.add(data1); assertEquals(data1, BufferFastAggregation.priorityqueue_or(data6.iterator())); } @@ -142,14 +146,14 @@ public void testBigOrMapped() { MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); MutableRoaringBitmap rb3 = new MutableRoaringBitmap(); - for(int k = 100; k < 10000; ++k) { - if((k % 3) == 0) { + for (int k = 100; k < 10000; ++k) { + if ((k % 3) == 0) { rb1.add(k); } - if((k % 3) == 1) { + if ((k % 3) == 1) { rb2.add(k); } - if((k % 3) == 2) { + if ((k % 3) == 2) { rb3.add(k); } } @@ -157,82 +161,228 @@ public void testBigOrMapped() { ImmutableRoaringBitmap data2 = toMapped(rb2); ImmutableRoaringBitmap data3 = toMapped(rb3); MutableRoaringBitmap mrb = data1.clone().toMutableRoaringBitmap(); - mrb.add(100L,10000L); - assertEquals(mrb, BufferFastAggregation.or(data1,data2,data3)); + mrb.add(100L, 10000L); + assertEquals(mrb, BufferFastAggregation.or(data1, data2, data3)); } @Test public void testPriorityQueueXorMapped() { - assertThrows(IllegalArgumentException.class, () -> { - int[] array1 = {1232, 3324, 123, 43243, 1322, 7897, 8767}; - int[] array2 = {39173, 39174, 39175, 39176, 39177, 39178, 39179}; - int[] array3 = - {1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, 39179}; - ImmutableRoaringBitmap data1 = toMapped(MutableRoaringBitmap.bitmapOf(array1)); - ImmutableRoaringBitmap data2 = toMapped(MutableRoaringBitmap.bitmapOf(array2)); - ImmutableRoaringBitmap data3 = toMapped(MutableRoaringBitmap.bitmapOf(array3)); - assertEquals(data3, BufferFastAggregation.priorityqueue_xor(data1, data2)); - BufferFastAggregation.priorityqueue_xor(data1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + int[] array1 = {1232, 3324, 123, 43243, 1322, 7897, 8767}; + int[] array2 = {39173, 39174, 39175, 39176, 39177, 39178, 39179}; + int[] array3 = { + 1232, 3324, 123, 43243, 1322, 7897, 8767, 39173, 39174, 39175, 39176, 39177, 39178, + 39179 + }; + ImmutableRoaringBitmap data1 = toMapped(MutableRoaringBitmap.bitmapOf(array1)); + ImmutableRoaringBitmap data2 = toMapped(MutableRoaringBitmap.bitmapOf(array2)); + ImmutableRoaringBitmap data3 = toMapped(MutableRoaringBitmap.bitmapOf(array3)); + assertEquals(data3, BufferFastAggregation.priorityqueue_xor(data1, data2)); + BufferFastAggregation.priorityqueue_xor(data1); + }); } - public static Stream bitmaps() { return Stream.of( - Arguments.of(Arrays.asList( - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build().toMutableRoaringBitmap(), - testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build().toMutableRoaringBitmap(), - testCase().withArrayAt(0).withRunAt(1).withBitmapAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(3).withRunAt(4).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withArrayAt(0).withBitmapAt(1).withRunAt(2).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withArrayAt(1).withBitmapAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withRunAt(1).withArrayAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(2).withRunAt(4).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withArrayAt(1).withRunAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withArrayAt(0).withArrayAt(1).withArrayAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withBitmapAt(2).withBitmapAt(4).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withRunAt(1).withRunAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withArrayAt(0).withArrayAt(1).withArrayAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withBitmapAt(2).withArrayAt(4).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withRunAt(1).withArrayAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withArrayAt(0).withArrayAt(1).withBitmapAt(2).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withBitmapAt(2).withBitmapAt(4).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withRunAt(1).withBitmapAt(2).build().toMutableRoaringBitmap() - )), - Arguments.of(Arrays.asList( - testCase().withArrayAt(20).build().toMutableRoaringBitmap(), - testCase().withBitmapAt(0).withBitmapAt(1).withBitmapAt(4).build().toMutableRoaringBitmap(), - testCase().withRunAt(0).withRunAt(1).withBitmapAt(3).build().toMutableRoaringBitmap() - )) - ); + Arguments.of( + Arrays.asList( + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withBitmapAt(0) + .withRunAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withRunAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withRunAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withArrayAt(0) + .withRunAt(1) + .withBitmapAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withArrayAt(0) + .withRunAt(1) + .withBitmapAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withArrayAt(0) + .withRunAt(1) + .withBitmapAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(3) + .withRunAt(4) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withArrayAt(0) + .withBitmapAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withArrayAt(1) + .withBitmapAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withRunAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(2) + .withRunAt(4) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withArrayAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withArrayAt(0) + .withArrayAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withBitmapAt(2) + .withBitmapAt(4) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withRunAt(1) + .withRunAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withArrayAt(0) + .withArrayAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withBitmapAt(2) + .withArrayAt(4) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withRunAt(1) + .withArrayAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase() + .withArrayAt(0) + .withArrayAt(1) + .withBitmapAt(2) + .build() + .toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withBitmapAt(2) + .withBitmapAt(4) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withRunAt(1) + .withBitmapAt(2) + .build() + .toMutableRoaringBitmap())), + Arguments.of( + Arrays.asList( + testCase().withArrayAt(20).build().toMutableRoaringBitmap(), + testCase() + .withBitmapAt(0) + .withBitmapAt(1) + .withBitmapAt(4) + .build() + .toMutableRoaringBitmap(), + testCase() + .withRunAt(0) + .withRunAt(1) + .withBitmapAt(3) + .build() + .toMutableRoaringBitmap()))); } - @MethodSource("bitmaps") @ParameterizedTest(name = "testWorkShyAnd") public void testWorkShyAnd(List list) { @@ -263,7 +413,7 @@ public void testWorkShyAndIterator(List bitmaps) { public void testWorkShyAndDirect(List list) { ImmutableRoaringBitmap[] bitmaps = list.toArray(new ImmutableRoaringBitmap[0]); for (int i = 0; i < bitmaps.length; ++i) { - bitmaps[i] = toDirect((MutableRoaringBitmap)bitmaps[i]); + bitmaps[i] = toDirect((MutableRoaringBitmap) bitmaps[i]); } long[] buffer = new long[1024]; MutableRoaringBitmap result = BufferFastAggregation.and(buffer, bitmaps); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java index 94945668f..ea07d5f0e 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestForEach.java @@ -1,10 +1,10 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; import org.roaringbitmap.IntConsumer; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class TestForEach { @@ -14,53 +14,60 @@ public void testContinuous() { bitmap.add(100L, 10000L); final MutableInteger cardinality = new MutableInteger(); - bitmap.forEach(new IntConsumer() { - int expected = 100; - @Override - public void accept(int value) { - cardinality.value++; - assertEquals(value, expected++); - }}); + bitmap.forEach( + new IntConsumer() { + int expected = 100; + + @Override + public void accept(int value) { + cardinality.value++; + assertEquals(value, expected++); + } + }); assertEquals(cardinality.value, bitmap.getCardinality()); } @Test public void testDense() { MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - for(int k = 0; k < 100000; k+=3) - bitmap.add(k); + for (int k = 0; k < 100000; k += 3) bitmap.add(k); final MutableInteger cardinality = new MutableInteger(); - bitmap.forEach(new IntConsumer() { - int expected = 0; - @Override - public void accept(int value) { - cardinality.value++; - assertEquals(value, expected); - expected += 3; - }}); + bitmap.forEach( + new IntConsumer() { + int expected = 0; + + @Override + public void accept(int value) { + cardinality.value++; + assertEquals(value, expected); + expected += 3; + } + }); assertEquals(cardinality.value, bitmap.getCardinality()); } - @Test public void testSparse() { MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - for(int k = 0; k < 100000; k+=3000) - bitmap.add(k); + for (int k = 0; k < 100000; k += 3000) bitmap.add(k); final MutableInteger cardinality = new MutableInteger(); - bitmap.forEach(new IntConsumer() { - int expected = 0; - @Override - public void accept(int value) { - cardinality.value++; - assertEquals(value, expected); - expected+=3000; - }}); + bitmap.forEach( + new IntConsumer() { + int expected = 0; + + @Override + public void accept(int value) { + cardinality.value++; + assertEquals(value, expected); + expected += 3000; + } + }); assertEquals(cardinality.value, bitmap.getCardinality()); } } + class MutableInteger { public int value = 0; } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java index cc8f0a2ff..20dfa11ff 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmap.java @@ -4,24 +4,41 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.Util.toUnsignedLong; + +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.InvalidRoaringFormat; +import org.roaringbitmap.RoaringBitmapWriter; +import org.roaringbitmap.SeededTestData; +import org.roaringbitmap.Util; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.roaringbitmap.*; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; +import java.util.TreeSet; import java.util.stream.IntStream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.Util.toUnsignedLong; - /** * Generic testing of the roaring bitmaps */ @@ -32,31 +49,32 @@ public class TestImmutableRoaringBitmap { static ByteBuffer serializeRoaring(ImmutableRoaringBitmap mrb) throws IOException { byte[] backingArray = new byte[mrb.serializedSizeInBytes() + 1024]; ByteBuffer outbb = ByteBuffer.wrap(backingArray, 1024, mrb.serializedSizeInBytes()).slice(); - DataOutputStream dos = new DataOutputStream(new OutputStream() { - ByteBuffer mBB; - - OutputStream init(ByteBuffer mbb) { - mBB = mbb; - return this; - } - - @Override - public void write(byte[] b) {} - - @Override - public void write(byte[] b, int off, int l) { - mBB.put(b, off, l); - } - - @Override - public void write(int b) { - mBB.put((byte) b); - } - }.init(outbb)); + DataOutputStream dos = + new DataOutputStream( + new OutputStream() { + ByteBuffer mBB; + + OutputStream init(ByteBuffer mbb) { + mBB = mbb; + return this; + } + + @Override + public void write(byte[] b) {} + + @Override + public void write(byte[] b, int off, int l) { + mBB.put(b, off, l); + } + + @Override + public void write(int b) { + mBB.put((byte) b); + } + }.init(outbb)); mrb.serialize(dos); dos.close(); - return outbb; } @@ -108,10 +126,8 @@ public void ANDNOTtest() { rr.andNot(rr2); assertEquals(correct, rr); assertEquals(correct.hashCode(), rr.hashCode()); - } - @Test public void andnottest4() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -135,8 +151,6 @@ public void andnottest4() { assertEquals(rb2, off); } - - @Test public void andnottest4A() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -163,8 +177,6 @@ public void andnottest4A() { assertEquals(rb2, off); } - - @Test public void ANDNOTtestA() { // both have run containers @@ -217,10 +229,8 @@ public void ANDNOTtestA() { rr.andNot(rr2); assertEquals(correct, rr); assertEquals(correct.hashCode(), rr.hashCode()); - } - @Test public void ANDNOTtestB() { // first one has run containers but not second. @@ -272,11 +282,8 @@ public void ANDNOTtestB() { rr.andNot(rr2); assertEquals(correct, rr); assertEquals(correct.hashCode(), rr.hashCode()); - } - - @Test public void ANDNOTtestC() { // second has run containers, but not first @@ -330,7 +337,6 @@ public void ANDNOTtestC() { assertEquals(correct.hashCode(), rr.hashCode()); } - @Test public void fliptest1() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -343,8 +349,6 @@ public void fliptest1() { assertEquals(result, rb2); } - - @Test public void fliptest2() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -357,8 +361,6 @@ public void fliptest2() { assertEquals(result, rb2); } - - @Test public void MappeableContainersAccessTest() throws IOException { MutableRoaringBitmap mr = new MutableRoaringBitmap(); @@ -437,14 +439,16 @@ public void MappeableContainersAccessTest() throws IOException { (mr2.getMappeableRoaringArray().getContainerAtIndex(0)) instanceof MappeableArrayContainer); assertTrue( (mr2.getMappeableRoaringArray().getContainerAtIndex(1)) instanceof MappeableArrayContainer); - assertTrue((mr2.getMappeableRoaringArray() - .getContainerAtIndex(2)) instanceof MappeableBitmapContainer); + assertTrue( + (mr2.getMappeableRoaringArray().getContainerAtIndex(2)) + instanceof MappeableBitmapContainer); assertTrue( (mr2.getMappeableRoaringArray().getContainerAtIndex(3)) instanceof MappeableArrayContainer); assertTrue( (mr2.getMappeableRoaringArray().getContainerAtIndex(4)) instanceof MappeableArrayContainer); - assertTrue((mr2.getMappeableRoaringArray() - .getContainerAtIndex(5)) instanceof MappeableBitmapContainer); + assertTrue( + (mr2.getMappeableRoaringArray().getContainerAtIndex(5)) + instanceof MappeableBitmapContainer); assertEquals(256, mr2.getMappeableRoaringArray().getContainerAtIndex(0).getCardinality()); assertEquals(4000, mr2.getMappeableRoaringArray().getContainerAtIndex(1).getCardinality()); @@ -568,7 +572,6 @@ public void MappeableContainersAccessTestA() throws IOException { assertEquals(0, mr3.getCardinality()); } - @Test public void testContains() throws IOException { System.out.println("test contains"); @@ -606,7 +609,6 @@ public void testContainsA() throws IOException { } } - @Test public void testHash() { MutableRoaringBitmap rbm1 = new MutableRoaringBitmap(); @@ -618,10 +620,8 @@ public void testHash() { assertEquals(rbm1.hashCode(), rbm2.hashCode()); } - - @SuppressWarnings("resource") -@Test + @Test public void testHighBits() throws IOException { // version without any runcontainers (earlier serialization version) for (int offset = 1 << 14; offset < 1 << 18; offset *= 2) { @@ -634,35 +634,37 @@ public void testHighBits() throws IOException { } int[] array = rb.toArray(); ByteBuffer b = ByteBuffer.allocate(rb.serializedSizeInBytes()); - rb.serialize(new DataOutputStream(new OutputStream() { - ByteBuffer mBB; - - @Override - public void close() {} - - @Override - public void flush() {} - - OutputStream init(final ByteBuffer mbb) { - mBB = mbb; - return this; - } - - @Override - public void write(final byte[] b) { - mBB.put(b); - } - - @Override - public void write(final byte[] b, final int off, final int l) { - mBB.put(b, off, l); - } - - @Override - public void write(final int b) { - mBB.put((byte) b); - } - }.init(b))); + rb.serialize( + new DataOutputStream( + new OutputStream() { + ByteBuffer mBB; + + @Override + public void close() {} + + @Override + public void flush() {} + + OutputStream init(final ByteBuffer mbb) { + mBB = mbb; + return this; + } + + @Override + public void write(final byte[] b) { + mBB.put(b); + } + + @Override + public void write(final byte[] b, final int off, final int l) { + mBB.put(b, off, l); + } + + @Override + public void write(final int b) { + mBB.put((byte) b); + } + }.init(b))); b.flip(); ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(b); assertEquals(irb, rb); @@ -707,35 +709,37 @@ public void testHighBitsA() throws IOException { // } // assertTrue(pos+runlength == array.length); ByteBuffer b = ByteBuffer.allocate(rb.serializedSizeInBytes()); - rb.serialize(new DataOutputStream(new OutputStream() { - ByteBuffer mBB; - - @Override - public void close() {} - - @Override - public void flush() {} - - OutputStream init(final ByteBuffer mbb) { - mBB = mbb; - return this; - } - - @Override - public void write(final byte[] b) { - mBB.put(b); - } - - @Override - public void write(final byte[] b, final int off, final int l) { - mBB.put(b, off, l); - } - - @Override - public void write(final int b) { - mBB.put((byte) b); - } - }.init(b))); + rb.serialize( + new DataOutputStream( + new OutputStream() { + ByteBuffer mBB; + + @Override + public void close() {} + + @Override + public void flush() {} + + OutputStream init(final ByteBuffer mbb) { + mBB = mbb; + return this; + } + + @Override + public void write(final byte[] b) { + mBB.put(b); + } + + @Override + public void write(final byte[] b, final int off, final int l) { + mBB.put(b, off, l); + } + + @Override + public void write(final int b) { + mBB.put((byte) b); + } + }.init(b))); b.flip(); ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(b); assertEquals(irb, rb); @@ -755,8 +759,6 @@ public void write(final int b) { } } - - @SuppressWarnings("resource") @Test public void testProperSerialization() throws IOException { @@ -770,35 +772,37 @@ public void testProperSerialization() throws IOException { } } ByteBuffer b = ByteBuffer.allocate(r.serializedSizeInBytes()); - r.serialize(new DataOutputStream(new OutputStream() { - ByteBuffer mBB; - - @Override - public void close() {} - - @Override - public void flush() {} - - OutputStream init(final ByteBuffer mbb) { - mBB = mbb; - return this; - } - - @Override - public void write(final byte[] b) { - mBB.put(b); - } - - @Override - public void write(final byte[] b, final int off, final int l) { - mBB.put(b, off, l); - } - - @Override - public void write(final int b) { - mBB.put((byte) b); - } - }.init(b))); + r.serialize( + new DataOutputStream( + new OutputStream() { + ByteBuffer mBB; + + @Override + public void close() {} + + @Override + public void flush() {} + + OutputStream init(final ByteBuffer mbb) { + mBB = mbb; + return this; + } + + @Override + public void write(final byte[] b) { + mBB.put(b); + } + + @Override + public void write(final byte[] b, final int off, final int l) { + mBB.put(b, off, l); + } + + @Override + public void write(final int b) { + mBB.put((byte) b); + } + }.init(b))); b.flip(); ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(b); assertEquals(irb, r); @@ -822,35 +826,37 @@ public void testProperSerializationA() throws IOException { } r.runOptimize(); ByteBuffer b = ByteBuffer.allocate(r.serializedSizeInBytes()); - r.serialize(new DataOutputStream(new OutputStream() { - ByteBuffer mBB; - - @Override - public void close() {} - - @Override - public void flush() {} - - OutputStream init(final ByteBuffer mbb) { - mBB = mbb; - return this; - } - - @Override - public void write(final byte[] b) { - mBB.put(b); - } - - @Override - public void write(final byte[] b, final int off, final int l) { - mBB.put(b, off, l); - } - - @Override - public void write(final int b) { - mBB.put((byte) b); - } - }.init(b))); + r.serialize( + new DataOutputStream( + new OutputStream() { + ByteBuffer mBB; + + @Override + public void close() {} + + @Override + public void flush() {} + + OutputStream init(final ByteBuffer mbb) { + mBB = mbb; + return this; + } + + @Override + public void write(final byte[] b) { + mBB.put(b); + } + + @Override + public void write(final byte[] b, final int off, final int l) { + mBB.put(b, off, l); + } + + @Override + public void write(final int b) { + mBB.put((byte) b); + } + }.init(b))); b.flip(); ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(b); assertEquals(irb.hashCode(), r.hashCode()); @@ -895,14 +901,11 @@ public void testSerializeImmutableA() throws IOException { } } - - - @Test public void testRangedOr() { int length = 1000; int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests + Random random = new Random(1234); // please use deterministic tests for (int test = 0; test < 50; ++test) { final MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); final MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); @@ -925,12 +928,12 @@ public void testRangedOr() { for (int iter = 0; iter < NUM_ITER; iter++) { long rangeStart = random.nextInt(length - 1); // +1 to ensure rangeEnd >rangeStart, may - long rangeLength = random.nextInt(length - (int)rangeStart) + 1; + long rangeLength = random.nextInt(length - (int) rangeStart) + 1; long rangeEnd = rangeStart + rangeLength; Set expectedResultSet = new TreeSet<>(); - for (int i = (int)rangeStart; i < rangeEnd; i++) { + for (int i = (int) rangeStart; i < rangeEnd; i++) { if (unionSet.contains(i)) { - expectedResultSet.add((int)i); + expectedResultSet.add((int) i); } } List list = new ArrayList<>(); @@ -952,7 +955,7 @@ public void testRangedOr() { public void testRangedAnd() { int length = 1000; int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests + Random random = new Random(1234); // please use deterministic tests for (int test = 0; test < 50; ++test) { final MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); final MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); @@ -1001,7 +1004,7 @@ public void testRangedAnd() { public void testRangedXor() { int length = 1000; int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests + Random random = new Random(1234); // please use deterministic tests for (int test = 0; test < 50; ++test) { final MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); final MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); @@ -1028,10 +1031,10 @@ public void testRangedXor() { for (int iter = 0; iter < NUM_ITER; iter++) { long rangeStart = random.nextInt(length - 1); // +1 to ensure rangeEnd >rangeStart, may - long rangeLength = random.nextInt(length - (int)rangeStart) + 1; + long rangeLength = random.nextInt(length - (int) rangeStart) + 1; long rangeEnd = rangeStart + rangeLength; Set expectedResultSet = new TreeSet<>(); - for (int i = (int)rangeStart; i < rangeEnd; i++) { + for (int i = (int) rangeStart; i < rangeEnd; i++) { if (xorSet.contains(i)) { expectedResultSet.add(i); } @@ -1055,7 +1058,7 @@ public void testRangedXor() { public void testRangedAndNot() { int length = 1000; int NUM_ITER = 10; - Random random = new Random(1234);// please use deterministic tests + Random random = new Random(1234); // please use deterministic tests for (int test = 0; test < 50; ++test) { final MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); final MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); @@ -1101,126 +1104,118 @@ public void testRangedAndNot() { } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorAnd() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full overlap is on 300000 to 399999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full overlap is on 300000 to 399999 - MutableRoaringBitmap result = ImmutableRoaringBitmap.and(list.iterator(), 350000L, 450000L); - MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.and(list.iterator(), 350000, 450000); + MutableRoaringBitmap result = ImmutableRoaringBitmap.and(list.iterator(), 350000L, 450000L); + MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.and(list.iterator(), 350000, 450000); assertEquals(result, resultInt); - assertEquals(50000, result.getCardinality()); - + assertEquals(50000, result.getCardinality()); - // empty ranges get empty result - resultInt = ImmutableRoaringBitmap.and(list.iterator(), 300000, 200000); - result = ImmutableRoaringBitmap.and(list.iterator(), 300000L, 200000L); + // empty ranges get empty result + resultInt = ImmutableRoaringBitmap.and(list.iterator(), 300000, 200000); + result = ImmutableRoaringBitmap.and(list.iterator(), 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorOr() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full union is 200000 to 499999 + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - MutableRoaringBitmap result = ImmutableRoaringBitmap.or(list.iterator(), 250000L, 550000L); - MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.or(list.iterator(), 250000, 550000); + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full union is 200000 to 499999 + MutableRoaringBitmap result = ImmutableRoaringBitmap.or(list.iterator(), 250000L, 550000L); + MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.or(list.iterator(), 250000, 550000); assertEquals(result, resultInt); - assertEquals(250000, result.getCardinality()); - + assertEquals(250000, result.getCardinality()); - // empty ranges get empty result - resultInt = ImmutableRoaringBitmap.or(list.iterator(), 300000, 200000); - result = ImmutableRoaringBitmap.or(list.iterator(), 300000L, 200000L); + // empty ranges get empty result + resultInt = ImmutableRoaringBitmap.or(list.iterator(), 300000, 200000); + result = ImmutableRoaringBitmap.or(list.iterator(), 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorAndNot() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full andNOToverlap is on 200000 to 299999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full andNOToverlap is on 200000 to 299999 - MutableRoaringBitmap result = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000L, 450000L); - MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000, 450000); + MutableRoaringBitmap result = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000L, 450000L); + MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.andNot(rb1, rb2, 250000, 450000); assertEquals(result, resultInt); - assertEquals(50000, result.getCardinality()); - + assertEquals(50000, result.getCardinality()); - // empty ranges get empty result - resultInt = ImmutableRoaringBitmap.andNot(rb1, rb2, 300000, 200000); - result = ImmutableRoaringBitmap.andNot(rb1, rb2, 300000L, 200000L); + // empty ranges get empty result + resultInt = ImmutableRoaringBitmap.andNot(rb1, rb2, 300000, 200000); + result = ImmutableRoaringBitmap.andNot(rb1, rb2, 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedIteratorXor() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - List list = new ArrayList<>(); - list.add(rb1); - list.add(rb2); + List list = new ArrayList<>(); + list.add(rb1); + list.add(rb2); - rb1.add(200000L, 400000L); // two normal positive ranges - rb2.add(300000L, 500000L); // full XOR is 200000 to 299999, 400000-4999999 + rb1.add(200000L, 400000L); // two normal positive ranges + rb2.add(300000L, 500000L); // full XOR is 200000 to 299999, 400000-4999999 - MutableRoaringBitmap result = ImmutableRoaringBitmap.xor(list.iterator(), 250000L, 450000L); - MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.xor(list.iterator(), 250000, 450000); + MutableRoaringBitmap result = ImmutableRoaringBitmap.xor(list.iterator(), 250000L, 450000L); + MutableRoaringBitmap resultInt = ImmutableRoaringBitmap.xor(list.iterator(), 250000, 450000); assertEquals(result, resultInt); - assertEquals(100000, result.getCardinality()); + assertEquals(100000, result.getCardinality()); - - // empty ranges get empty result - resultInt = ImmutableRoaringBitmap.xor(list.iterator(), 300000, 200000); - result = ImmutableRoaringBitmap.xor(list.iterator(), 300000L, 200000L); + // empty ranges get empty result + resultInt = ImmutableRoaringBitmap.xor(list.iterator(), 300000, 200000); + result = ImmutableRoaringBitmap.xor(list.iterator(), 300000L, 200000L); assertEquals(result, resultInt); - assertEquals(0, resultInt.getCardinality()); + assertEquals(0, resultInt.getCardinality()); } @Test public void testFirstLast_CreateSparseContainersAfterRun() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); rb.add(1L, 1 << 14); - for(int i = 18; i < 31; ++i) { + for (int i = 18; i < 31; ++i) { int x = 1 << i; rb.add(x); assertEquals(1, rb.toImmutableRoaringBitmap().first()); @@ -1231,12 +1226,16 @@ public void testFirstLast_CreateSparseContainersAfterRun() { @Test public void testEmptyFirst() { - assertThrows(NoSuchElementException.class, () -> new MutableRoaringBitmap().toImmutableRoaringBitmap().first()); + assertThrows( + NoSuchElementException.class, + () -> new MutableRoaringBitmap().toImmutableRoaringBitmap().first()); } @Test public void testEmptyLast() { - assertThrows(NoSuchElementException.class, () -> new MutableRoaringBitmap().toImmutableRoaringBitmap().last()); + assertThrows( + NoSuchElementException.class, + () -> new MutableRoaringBitmap().toImmutableRoaringBitmap().last()); } @Test @@ -1253,7 +1252,7 @@ public void testFirstLast() { assertEquals(2, rb.toImmutableRoaringBitmap().first()); assertEquals((1 << 14) - 1, rb.toImmutableRoaringBitmap().last()); - rb.add(1L<< 15, 1L << 30); + rb.add(1L << 15, 1L << 30); assertEquals(2, rb.toImmutableRoaringBitmap().first()); assertEquals((1L << 30) - 1, rb.toImmutableRoaringBitmap().last()); } @@ -1282,8 +1281,8 @@ public void testHammingSimilarity_BigVsSmall() { big.add(1, 2, 3, 4); big.add(1L << 17, 1L << 30); big.flip((1 << 17) | (1 << 16)); - for(int i = 1 << 18; i < 1 << 19; ++i) { - if(i % 3 == 0) { + for (int i = 1 << 18; i < 1 << 19; ++i) { + if (i % 3 == 0) { big.flip(i); } } @@ -1295,8 +1294,8 @@ public void testHammingSimilarity_BigVsSmall() { @Test public void testHammingSimilarity_Shifted() { ImmutableRoaringBitmap baseline = ImmutableRoaringBitmap.bitmapOf(1, 2, 3, 4); - ImmutableRoaringBitmap shifted = ImmutableRoaringBitmap.bitmapOf((1 << 17) + 1, (1 << 17) + 2, - (1 << 17) + 3, (1 << 17) + 4); + ImmutableRoaringBitmap shifted = + ImmutableRoaringBitmap.bitmapOf((1 << 17) + 1, (1 << 17) + 2, (1 << 17) + 3, (1 << 17) + 4); assertFalse(baseline.isHammingSimilar(shifted, 0)); } @@ -1374,11 +1373,279 @@ public void testAndNotCardinality_646() { @Test public void testAndNotCardinality_648() { - ImmutableRoaringBitmap s1 = ImmutableRoaringBitmap.bitmapOf(-1388308580, 236217409, -805382570, 612285977, 1389629939, 851442526, 375756307, 61533603, 1908301308, 2097309572, 204769050, 703198559, -545810986, 2090296816, -87319453, 158018332, -685188145, -566739002, -1446363859, -372441875, -957637004, -1144076256, -1248859542, -160225853, 14707613, 866274329, 1550526350, 877999004, -1784269953, 1274953255, 1490490469, -1340013077, 2067958239, 51232349, 2060711699, -1802459974, 2039829040, -2079650027, -278950425, 1145674649, 298101576, 1687655442, 1209489632, -762136131, 399832491, 1077638711, -635674559, -1643781464, -1067907341, 144525399, 651571848, 1893053071, -2058528151, 1592871441, 84583235, 374119809, -867104416, -1941224259, 787356209, 1972857336, -720703901, -1310021857, -1831922816, 181898740, 600942551, -1745822849, -856908487, 2060184086, -1217485514, -1680395029, 1539735915, 2042390564, -1539856946, 1824974207, 1695025297, 1908431629, -395090370, -1688185468, 570601902, -701368853, -1211735380, -825285093, 788089714, -857723909, 1400502194, 285106906, -1450842998, -2125215206, 1451519492, -1559357910, 1157633452, -387704829, 2036134025, 1051239778, -1542956455, 357879569, 1962230155, -1994777800, 672516512, 174507423, -299175291, 821891018, 1062886766, -1313955904, 1732661804, -767116537, 1352149580, 2001322279, 1698147357, 40451458, 996819026, 1904959950, 2058544757, 1514282221, 234242255, -1364505429, 1498471146, 1134429786, -918860049, 1430732385, 644983298, 793600316, -1726956640, -538511147, -1945670935, 291567421, 1033590420, -1831809482, 985031287, -773476240, 1724734191, -1364525376, 1208307142, -2126741265, -1851759120, 1083333467, 185208087, -375950074, 48210573, -843304856, -295266615, -843941360, -524390895, -102924717, 836117637, 683196001, -1824825594, -1470017798, -1554712054, 291236023, -907874606, 2068945326, -899352179, -1488751007, -449279886, -1085935420, -2094131785, -474243782, 1306756671, 1353254318, 86944198, 1148225154, 487252515, -229770314, -1484325603, 109043190, -252122045, 1431750974, 1667547537, -1775516477, -512978266, -216545450, -486550865, -1193721685, -1108677522, -628326149, -1568065979, -675571394); - ImmutableRoaringBitmap s2 = ImmutableRoaringBitmap.bitmapOf(2060184086, 704452713, 1236293943, -178539376, 2037977331, -78910667, -587409880, 204769050, -854426111, 90628341, -1411939301, -927754519, -211274987, 998450197, -1515133464, -1652963250, 499001553, 383696025, -2019580769, 1583380373, -79264832, 1065614902, 1243463658, 424214238, 1124141647, 271662535, 1415634429, 1893053071, -1624960757, -1933550809, -1170233109, -542340662, -1681838238, 292656484, 1587781520, -1463647396, -124042559, -162307067, 1411905814, -1524651941, 1935844108, 1992426746, 422443777, 679395872, -764857187, -401706366, -2007177999, 1044794027, -1561188953, 1627034126, -401273669, -123973748, -694963705, 838892817, -1640102435, 852253834, -23120023, -2072644924, 1140820264, -550227319, -1692730465, 1491150291, 1607642920, -1015774573, -1801713682, -752796152, -439281693, -792361100, -188208805, 808883165, -1364525376, 896915854, -1672522244, -1718572341); - ImmutableRoaringBitmap s3 = ImmutableRoaringBitmap.bitmapOf(-30718004, -1652963250, -762136131, -1552606582, -1933550809, -1230616126, 736584428, -2136360654, 1097548480, 192408815, -295266615); + ImmutableRoaringBitmap s1 = + ImmutableRoaringBitmap.bitmapOf( + -1388308580, + 236217409, + -805382570, + 612285977, + 1389629939, + 851442526, + 375756307, + 61533603, + 1908301308, + 2097309572, + 204769050, + 703198559, + -545810986, + 2090296816, + -87319453, + 158018332, + -685188145, + -566739002, + -1446363859, + -372441875, + -957637004, + -1144076256, + -1248859542, + -160225853, + 14707613, + 866274329, + 1550526350, + 877999004, + -1784269953, + 1274953255, + 1490490469, + -1340013077, + 2067958239, + 51232349, + 2060711699, + -1802459974, + 2039829040, + -2079650027, + -278950425, + 1145674649, + 298101576, + 1687655442, + 1209489632, + -762136131, + 399832491, + 1077638711, + -635674559, + -1643781464, + -1067907341, + 144525399, + 651571848, + 1893053071, + -2058528151, + 1592871441, + 84583235, + 374119809, + -867104416, + -1941224259, + 787356209, + 1972857336, + -720703901, + -1310021857, + -1831922816, + 181898740, + 600942551, + -1745822849, + -856908487, + 2060184086, + -1217485514, + -1680395029, + 1539735915, + 2042390564, + -1539856946, + 1824974207, + 1695025297, + 1908431629, + -395090370, + -1688185468, + 570601902, + -701368853, + -1211735380, + -825285093, + 788089714, + -857723909, + 1400502194, + 285106906, + -1450842998, + -2125215206, + 1451519492, + -1559357910, + 1157633452, + -387704829, + 2036134025, + 1051239778, + -1542956455, + 357879569, + 1962230155, + -1994777800, + 672516512, + 174507423, + -299175291, + 821891018, + 1062886766, + -1313955904, + 1732661804, + -767116537, + 1352149580, + 2001322279, + 1698147357, + 40451458, + 996819026, + 1904959950, + 2058544757, + 1514282221, + 234242255, + -1364505429, + 1498471146, + 1134429786, + -918860049, + 1430732385, + 644983298, + 793600316, + -1726956640, + -538511147, + -1945670935, + 291567421, + 1033590420, + -1831809482, + 985031287, + -773476240, + 1724734191, + -1364525376, + 1208307142, + -2126741265, + -1851759120, + 1083333467, + 185208087, + -375950074, + 48210573, + -843304856, + -295266615, + -843941360, + -524390895, + -102924717, + 836117637, + 683196001, + -1824825594, + -1470017798, + -1554712054, + 291236023, + -907874606, + 2068945326, + -899352179, + -1488751007, + -449279886, + -1085935420, + -2094131785, + -474243782, + 1306756671, + 1353254318, + 86944198, + 1148225154, + 487252515, + -229770314, + -1484325603, + 109043190, + -252122045, + 1431750974, + 1667547537, + -1775516477, + -512978266, + -216545450, + -486550865, + -1193721685, + -1108677522, + -628326149, + -1568065979, + -675571394); + ImmutableRoaringBitmap s2 = + ImmutableRoaringBitmap.bitmapOf( + 2060184086, + 704452713, + 1236293943, + -178539376, + 2037977331, + -78910667, + -587409880, + 204769050, + -854426111, + 90628341, + -1411939301, + -927754519, + -211274987, + 998450197, + -1515133464, + -1652963250, + 499001553, + 383696025, + -2019580769, + 1583380373, + -79264832, + 1065614902, + 1243463658, + 424214238, + 1124141647, + 271662535, + 1415634429, + 1893053071, + -1624960757, + -1933550809, + -1170233109, + -542340662, + -1681838238, + 292656484, + 1587781520, + -1463647396, + -124042559, + -162307067, + 1411905814, + -1524651941, + 1935844108, + 1992426746, + 422443777, + 679395872, + -764857187, + -401706366, + -2007177999, + 1044794027, + -1561188953, + 1627034126, + -401273669, + -123973748, + -694963705, + 838892817, + -1640102435, + 852253834, + -23120023, + -2072644924, + 1140820264, + -550227319, + -1692730465, + 1491150291, + 1607642920, + -1015774573, + -1801713682, + -752796152, + -439281693, + -792361100, + -188208805, + 808883165, + -1364525376, + 896915854, + -1672522244, + -1718572341); + ImmutableRoaringBitmap s3 = + ImmutableRoaringBitmap.bitmapOf( + -30718004, + -1652963250, + -762136131, + -1552606582, + -1933550809, + -1230616126, + 736584428, + -2136360654, + 1097548480, + 192408815, + -295266615); ImmutableRoaringBitmap s1AndS2 = ImmutableRoaringBitmap.and(s1, s2); - assertEquals(ImmutableRoaringBitmap.andNot(s1AndS2, s3).getCardinality(), ImmutableRoaringBitmap.andNotCardinality(s1AndS2, s3)); + assertEquals( + ImmutableRoaringBitmap.andNot(s1AndS2, s3).getCardinality(), + ImmutableRoaringBitmap.andNotCardinality(s1AndS2, s3)); } @Test @@ -1388,7 +1655,6 @@ public void testRankOverflow() { assertEquals(1, ImmutableRoaringBitmap.bitmapOf(65537).rank(65538)); } - @Test public void testNegativeAdd() { MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); @@ -1466,22 +1732,22 @@ public void testContainsRange_SmallBitmap() { @Test public void testContainsRange_DirtyBitmap() { - RoaringBitmapWriter writer = RoaringBitmapWriter.bufferWriter().constantMemory().get(); - IntStream.range(0, 1_000_000) - .map(i -> i * 2) - .forEach(writer::add); + RoaringBitmapWriter writer = + RoaringBitmapWriter.bufferWriter().constantMemory().get(); + IntStream.range(0, 1_000_000).map(i -> i * 2).forEach(writer::add); writer.flush(); MutableRoaringBitmap bitmap = writer.getUnderlying(); assertFalse(bitmap.contains(0L, 2_000_000L)); assertFalse(bitmap.contains(0L, 2L)); assertTrue(bitmap.contains(0L, 1L)); - assertTrue(bitmap.contains(1L << 10, 1| (1L << 10))); + assertTrue(bitmap.contains(1L << 10, 1 | (1L << 10))); assertFalse(bitmap.contains(1L << 31, 1L << 32)); } @Test public void testNextValue() { - ImmutableRoaringBitmap bitmap = SeededTestData.TestDataSet.testCase() + ImmutableRoaringBitmap bitmap = + SeededTestData.TestDataSet.testCase() .withRunAt(0) .withBitmapAt(1) .withArrayAt(2) @@ -1496,7 +1762,7 @@ public void testNextValue() { long b1 = 0; int b2 = 0; while (b1 >= 0 && b2 >= 0) { - b1 = bitmap.nextValue((int)b1 + 1); + b1 = bitmap.nextValue((int) b1 + 1); b2 = bitset.nextSetBit(b2 + 1); assertEquals(b1, b2); } @@ -1504,14 +1770,16 @@ public void testNextValue() { @Test public void testPreviousValue() { - MutableRoaringBitmap bitmap = SeededTestData.TestDataSet.testCase() + MutableRoaringBitmap bitmap = + SeededTestData.TestDataSet.testCase() .withRunAt(0) .withBitmapAt(1) .withArrayAt(2) .withRunAt(3) .withBitmapAt(4) .withArrayAt(5) - .build().toMutableRoaringBitmap(); + .build() + .toMutableRoaringBitmap(); BitSet bitset = new BitSet(); bitmap.forEach((IntConsumer) bitset::set); @@ -1552,14 +1820,14 @@ public void testRangeCardinalityAtBoundary() { assertEquals(1, r.rangeCardinality(60000, 70000)); } - @Test public void testAbsentBits() { int count = 50; List offsets = Arrays.asList(0, 1, -1, 10, -10, 100, -100); for (int i = 0; i < count; i++) { - ImmutableRoaringBitmap bitmap = SeededTestData.TestDataSet.testCase() + ImmutableRoaringBitmap bitmap = + SeededTestData.TestDataSet.testCase() .withRunAt(0) .withBitmapAt(1) .withArrayAt(2) @@ -1586,13 +1854,16 @@ public void testAbsentBits() { @Test public void invalidCookie() { - assertThrows(InvalidRoaringFormat.class, () -> new ImmutableRoaringBitmap(ByteBuffer.allocate(8))); + assertThrows( + InvalidRoaringFormat.class, () -> new ImmutableRoaringBitmap(ByteBuffer.allocate(8))); } + @Test public void testContainerSizeRoaringBitmapMultiple() { ImmutableRoaringBitmap r = ImmutableRoaringBitmap.bitmapOf(1, 1000000); assertEquals(2, r.getContainerCount()); } + @Test public void testContainerSizeRoaringBitmapSingle() { ImmutableRoaringBitmap r = ImmutableRoaringBitmap.bitmapOf(1); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java index 09cd36706..432f5a337 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestImmutableRoaringBitmapOrNot.java @@ -1,11 +1,16 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.Util.toUnsignedLong; + +import org.roaringbitmap.IntIterator; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.IntIterator; import java.io.IOException; import java.nio.ByteBuffer; @@ -15,412 +20,408 @@ import java.util.List; import java.util.Map; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.Util.toUnsignedLong; - @Execution(ExecutionMode.CONCURRENT) public class TestImmutableRoaringBitmapOrNot { - @Test - public void orNot1() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + @Test + public void orNot1() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb.add(2); - rb.add(1); - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(2); + rb.add(1); + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - rb2.add(1 << 16);// 65536 - rb2.add(3 << 16);//196608 + rb2.add(1 << 16); // 65536 + rb2.add(3 << 16); // 196608 - rb.orNot(rb2, (4 << 16) - 1); + rb.orNot(rb2, (4 << 16) - 1); - assertEquals((4 << 16) - 1, rb.getCardinality()); + assertEquals((4 << 16) - 1, rb.getCardinality()); - IntIterator iterator = rb.getIntIterator(); + IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (4 << 16) - 1; ++i) { - assertTrue(iterator.hasNext()); - assertEquals(i, iterator.next()); - } - assertFalse(iterator.hasNext()); + for (int i = 0; i < (4 << 16) - 1; ++i) { + assertTrue(iterator.hasNext()); + assertEquals(i, iterator.next()); } + assertFalse(iterator.hasNext()); + } - @Test - public void orNot2() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + @Test + public void orNot2() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb.add(0); - rb.add(1 << 16); // 65536 - rb.add(3 << 16); //196608 + rb.add(0); + rb.add(1 << 16); // 65536 + rb.add(3 << 16); // 196608 - rb2.add((4 << 16) - 1); //262143 + rb2.add((4 << 16) - 1); // 262143 - rb.orNot(rb2, 4 << 16); + rb.orNot(rb2, 4 << 16); - assertEquals((4 << 16) - 1, rb.getCardinality()); + assertEquals((4 << 16) - 1, rb.getCardinality()); - IntIterator iterator = rb.getIntIterator(); + IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (4 << 16) - 1; ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next()); - } - assertFalse(iterator.hasNext()); + for (int i = 0; i < (4 << 16) - 1; ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next()); } - - @Test - public void orNot3() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - rb.add(2 << 16); - - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(1 << 14); //16384 - rb2.add(3 << 16); //196608 - - rb.orNot(rb2, (5 << 16)); - assertEquals((5 << 16) - 2, rb.getCardinality()); - - IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (5 << 16); ++i) { - if ((i != (1 << 14)) && (i != (3 << 16))) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - } - assertFalse(iterator.hasNext()); + assertFalse(iterator.hasNext()); + } + + @Test + public void orNot3() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + rb.add(2 << 16); + + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add(1 << 14); // 16384 + rb2.add(3 << 16); // 196608 + + rb.orNot(rb2, (5 << 16)); + assertEquals((5 << 16) - 2, rb.getCardinality()); + + IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (5 << 16); ++i) { + if ((i != (1 << 14)) && (i != (3 << 16))) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); + } } + assertFalse(iterator.hasNext()); + } - @Test - public void orNot4() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - rb.add(1); + @Test + public void orNot4() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + rb.add(1); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(3 << 16); //196608 + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add(3 << 16); // 196608 - rb.orNot(rb2, (2 << 16) + (2 << 14)); //131072 + 32768 = 163840 - assertEquals((2 << 16) + (2 << 14), rb.getCardinality()); + rb.orNot(rb2, (2 << 16) + (2 << 14)); // 131072 + 32768 = 163840 + assertEquals((2 << 16) + (2 << 14), rb.getCardinality()); - IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (2 << 16) + (2 << 14); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - assertFalse(iterator.hasNext()); + IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (2 << 16) + (2 << 14); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } + assertFalse(iterator.hasNext()); + } - @Test - public void orNot5() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); + @Test + public void orNot5() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); - rb.add(1); - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(1); + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb.orNot(rb2, (5 << 16)); - assertEquals((5 << 16), rb.getCardinality()); + rb.orNot(rb2, (5 << 16)); + assertEquals((5 << 16), rb.getCardinality()); - IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (5 << 16); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - assertFalse(iterator.hasNext()); + IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (5 << 16); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } + assertFalse(iterator.hasNext()); + } - @Test - public void orNot6() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); + @Test + public void orNot6() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); - rb.add(1); - rb.add((1 << 16) - 1); // 65535 - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + rb.add(1); + rb.add((1 << 16) - 1); // 65535 + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb.orNot(rb2, (1 << 14)); - - // {[0, 2^14], 65535, 65536, 131072, 196608} - assertEquals((1 << 14) + 4, rb.getCardinality()); - - IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (1 << 14); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } + rb.orNot(rb2, (1 << 14)); - assertTrue(iterator.hasNext()); - assertEquals((1 << 16) - 1, iterator.next()); + // {[0, 2^14], 65535, 65536, 131072, 196608} + assertEquals((1 << 14) + 4, rb.getCardinality()); - assertTrue(iterator.hasNext()); - assertEquals(1 << 16, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(2 << 16, iterator.next()); - - assertTrue(iterator.hasNext()); - assertEquals(3 << 16, iterator.next()); - - assertFalse(iterator.hasNext()); + IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (1 << 14); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } - @Test - public void orNot7() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); + assertTrue(iterator.hasNext()); + assertEquals((1 << 16) - 1, iterator.next()); - rb.add(1 << 16); // 65536 - rb.add(2 << 16); //131072 - rb.add(3 << 16); //196608 + assertTrue(iterator.hasNext()); + assertEquals(1 << 16, iterator.next()); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + assertTrue(iterator.hasNext()); + assertEquals(2 << 16, iterator.next()); - rb.orNot(rb2, (1 << 14)); + assertTrue(iterator.hasNext()); + assertEquals(3 << 16, iterator.next()); - // {[0, 2^14], 65536, 131072, 196608} - assertEquals((1 << 14) + 3, rb.getCardinality()); + assertFalse(iterator.hasNext()); + } - IntIterator iterator = rb.getIntIterator(); - for (int i = 0; i < (1 << 14); ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } + @Test + public void orNot7() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + rb.add(1 << 16); // 65536 + rb.add(2 << 16); // 131072 + rb.add(3 << 16); // 196608 - assertTrue(iterator.hasNext()); - assertEquals(1 << 16, iterator.next()); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - assertTrue(iterator.hasNext()); - assertEquals(2 << 16, iterator.next()); + rb.orNot(rb2, (1 << 14)); - assertTrue(iterator.hasNext()); - assertEquals(3 << 16, iterator.next()); + // {[0, 2^14], 65536, 131072, 196608} + assertEquals((1 << 14) + 3, rb.getCardinality()); - assertFalse(iterator.hasNext()); + IntIterator iterator = rb.getIntIterator(); + for (int i = 0; i < (1 << 14); ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); } + assertTrue(iterator.hasNext()); + assertEquals(1 << 16, iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(2 << 16, iterator.next()); - @Test - public void orNot9() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - - rb1.add(1 << 16); // 65536 - rb1.add(2 << 16); //131072 - rb1.add(3 << 16); //196608 + assertTrue(iterator.hasNext()); + assertEquals(3 << 16, iterator.next()); + assertFalse(iterator.hasNext()); + } - { - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - MutableRoaringBitmap answer1 = ImmutableRoaringBitmap.orNot(rb1, rb2, (1 << 14)); + @Test + public void orNot9() { + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - // {[0, 2^14] | {65536} {131072} {196608}} - assertEquals((1 << 14) + 3, answer1.getCardinality()); - - IntIterator iterator1 = answer1.getIntIterator(); - for (int i = 0; i < (1 << 14); ++i) { - assertTrue(iterator1.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator1.next(), "Error on iteration " + i); - } - assertEquals(1 << 16, iterator1.next()); - assertEquals(2 << 16, iterator1.next()); - assertEquals(3 << 16, iterator1.next()); - } - - { - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb1, rb2, (2 << 16)); - - // {[0, 2^16] | 131072, 196608} - assertEquals((2 << 16) + 2, answer.getCardinality()); - - IntIterator iterator = answer.getIntIterator(); - for (int i = 0; i < (2 << 16) + 1; ++i) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - assertEquals(196608, iterator.next()); - } + rb1.add(1 << 16); // 65536 + rb1.add(2 << 16); // 131072 + rb1.add(3 << 16); // 196608 + { + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap answer1 = ImmutableRoaringBitmap.orNot(rb1, rb2, (1 << 14)); - { - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add((1 << 16) + (1 << 13)); - rb2.add((1 << 16) + (1 << 14)); - rb2.add((1 << 16) + (1 << 15)); - MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb1, rb2, (2 << 16)); - - // {[0, 2^16] | 196608} - assertEquals((2 << 16) - 1, answer.getCardinality()); - - IntIterator iterator = answer.getIntIterator(); - for (int i = 0; i < (2 << 16) + 1; ++i) { - if ((i != (1 << 16) + (1 << 13)) && (i != (1 << 16) + (1 << 14)) && (i != (1 << 16) + (1 << 15))) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - } - assertEquals(196608, iterator.next()); - } - - { - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(1 << 16); - rb2.add(3 << 16); - rb2.add(4 << 16); - - MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb1, rb2, (5 << 16)); - - // {[0, 2^16]} - assertEquals((5 << 16) - 1, answer.getCardinality()); - - IntIterator iterator = answer.getIntIterator(); - for (int i = 0; i < (5 << 16); ++i) { - if (i != (4 << 16)) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - } - assertFalse(iterator.hasNext(), "Number of elements " + (2 << 16)); - } + // {[0, 2^14] | {65536} {131072} {196608}} + assertEquals((1 << 14) + 3, answer1.getCardinality()); - { - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(1 << 16); - rb2.add(3 << 16); - rb2.add(4 << 16); - - MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb2, rb1, (5 << 16)); - - // {[0, 2^16]} - assertEquals((5 << 16) - 1, answer.getCardinality()); - - IntIterator iterator = answer.getIntIterator(); - for (int i = 0; i < (5 << 16); ++i) { - if (i != (2 << 16)) { - assertTrue(iterator.hasNext(), "Error on iteration " + i); - assertEquals(i, iterator.next(), "Error on iteration " + i); - } - } - assertFalse(iterator.hasNext(), "Number of elements " + (2 << 16)); - } + IntIterator iterator1 = answer1.getIntIterator(); + for (int i = 0; i < (1 << 14); ++i) { + assertTrue(iterator1.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator1.next(), "Error on iteration " + i); + } + assertEquals(1 << 16, iterator1.next()); + assertEquals(2 << 16, iterator1.next()); + assertEquals(3 << 16, iterator1.next()); } - @Test - public void orNot10() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - - rb.add(5); - rb2.add(10); + { + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb1, rb2, (2 << 16)); - rb.orNot(rb2, 6); + // {[0, 2^16] | 131072, 196608} + assertEquals((2 << 16) + 2, answer.getCardinality()); - assertEquals(5, rb.last()); + IntIterator iterator = answer.getIntIterator(); + for (int i = 0; i < (2 << 16) + 1; ++i) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); + } + assertEquals(196608, iterator.next()); } - @Test - public void orNot11() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - - rb.add((int) (65535L * 65536L + 65523)); - rb2.add((int) (65493L * 65536L + 65520)); - - MutableRoaringBitmap rb3 = ImmutableRoaringBitmap.orNot(rb, rb2, 65535L * 65536L + 65524); - - assertEquals((int)(65535L * 65536L + 65523), rb3.last()); + { + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add((1 << 16) + (1 << 13)); + rb2.add((1 << 16) + (1 << 14)); + rb2.add((1 << 16) + (1 << 15)); + MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb1, rb2, (2 << 16)); + + // {[0, 2^16] | 196608} + assertEquals((2 << 16) - 1, answer.getCardinality()); + + IntIterator iterator = answer.getIntIterator(); + for (int i = 0; i < (2 << 16) + 1; ++i) { + if ((i != (1 << 16) + (1 << 13)) + && (i != (1 << 16) + (1 << 14)) + && (i != (1 << 16) + (1 << 15))) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); + } + } + assertEquals(196608, iterator.next()); } - @Test - public void orNotAgainstFullBitmap() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - MutableRoaringBitmap full = new MutableRoaringBitmap(); - full.add(0, 0x40000L); - rb.orNot(full, 0x30000L); - assertTrue(rb.isEmpty()); - } + { + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add(1 << 16); + rb2.add(3 << 16); + rb2.add(4 << 16); - @Test - public void orNotNonEmptyAgainstFullBitmap() { - MutableRoaringBitmap rb = MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001); - MutableRoaringBitmap full = new MutableRoaringBitmap(); - full.add((long)0, (long)0x40000); - rb.orNot(full, 0x30000); - assertEquals(MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001), rb); - } + MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb1, rb2, (5 << 16)); - @Test - public void orNotAgainstFullBitmapStatic() { - MutableRoaringBitmap rb = new MutableRoaringBitmap(); - MutableRoaringBitmap full = new MutableRoaringBitmap(); - full.add(0, 0x40000L); - MutableRoaringBitmap result = ImmutableRoaringBitmap.orNot(rb, full, 0x30000L); - assertTrue(result.isEmpty()); - } + // {[0, 2^16]} + assertEquals((5 << 16) - 1, answer.getCardinality()); - @Test - public void orNotNonEmptyAgainstFullBitmapStatic() { - MutableRoaringBitmap rb = MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001); - MutableRoaringBitmap full = new MutableRoaringBitmap(); - full.add(0, 0x40000L); - assertEquals(MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001), ImmutableRoaringBitmap.orNot(rb, full, 0x30000L)); + IntIterator iterator = answer.getIntIterator(); + for (int i = 0; i < (5 << 16); ++i) { + if (i != (4 << 16)) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); + } + } + assertFalse(iterator.hasNext(), "Number of elements " + (2 << 16)); } - @Test - @SuppressWarnings("unchecked") - public void testBigOrNot() throws IOException { - byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); - Map info = new ObjectMapper().readerFor(Map.class).readValue(bytes); - List base64Bitmaps = (List)info.get("bitmaps"); - ByteBuffer lBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(0))); - ByteBuffer rBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(1))); - MutableRoaringBitmap l = new MutableRoaringBitmap(); - l.deserialize(lBuffer); - MutableRoaringBitmap r = new MutableRoaringBitmap(); - r.deserialize(rBuffer); - - MutableRoaringBitmap range = new MutableRoaringBitmap(); - long limit = toUnsignedLong(l.last()) + 1; - range.add(0, limit); - range.andNot(r); - MutableRoaringBitmap expected = MutableRoaringBitmap.or(l, range); - - MutableRoaringBitmap actual = l.clone(); - actual.orNot(r, limit); - assertEquals(expected, actual); - } + { + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add(1 << 16); + rb2.add(3 << 16); + rb2.add(4 << 16); + MutableRoaringBitmap answer = ImmutableRoaringBitmap.orNot(rb2, rb1, (5 << 16)); - @Test - @SuppressWarnings("unchecked") - public void testBigOrNotStatic() throws IOException { - byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); - Map info = new ObjectMapper().readerFor(Map.class).readValue(bytes); - List base64Bitmaps = (List)info.get("bitmaps"); - ByteBuffer lBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(0))); - ByteBuffer rBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(1))); - MutableRoaringBitmap l = new MutableRoaringBitmap(); - l.deserialize(lBuffer); - MutableRoaringBitmap r = new MutableRoaringBitmap(); - r.deserialize(rBuffer); - - MutableRoaringBitmap range = new MutableRoaringBitmap(); - long limit = toUnsignedLong(l.last()) + 1; - range.add(0, limit); - range.andNot(r); - MutableRoaringBitmap expected = MutableRoaringBitmap.or(l, range); - - MutableRoaringBitmap actual = ImmutableRoaringBitmap.orNot(l, r, limit); - assertEquals(expected, actual); - } + // {[0, 2^16]} + assertEquals((5 << 16) - 1, answer.getCardinality()); + IntIterator iterator = answer.getIntIterator(); + for (int i = 0; i < (5 << 16); ++i) { + if (i != (2 << 16)) { + assertTrue(iterator.hasNext(), "Error on iteration " + i); + assertEquals(i, iterator.next(), "Error on iteration " + i); + } + } + assertFalse(iterator.hasNext(), "Number of elements " + (2 << 16)); + } + } + + @Test + public void orNot10() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + + rb.add(5); + rb2.add(10); + + rb.orNot(rb2, 6); + + assertEquals(5, rb.last()); + } + + @Test + public void orNot11() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + + rb.add((int) (65535L * 65536L + 65523)); + rb2.add((int) (65493L * 65536L + 65520)); + + MutableRoaringBitmap rb3 = ImmutableRoaringBitmap.orNot(rb, rb2, 65535L * 65536L + 65524); + + assertEquals((int) (65535L * 65536L + 65523), rb3.last()); + } + + @Test + public void orNotAgainstFullBitmap() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + MutableRoaringBitmap full = new MutableRoaringBitmap(); + full.add(0, 0x40000L); + rb.orNot(full, 0x30000L); + assertTrue(rb.isEmpty()); + } + + @Test + public void orNotNonEmptyAgainstFullBitmap() { + MutableRoaringBitmap rb = MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001); + MutableRoaringBitmap full = new MutableRoaringBitmap(); + full.add((long) 0, (long) 0x40000); + rb.orNot(full, 0x30000); + assertEquals(MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001), rb); + } + + @Test + public void orNotAgainstFullBitmapStatic() { + MutableRoaringBitmap rb = new MutableRoaringBitmap(); + MutableRoaringBitmap full = new MutableRoaringBitmap(); + full.add(0, 0x40000L); + MutableRoaringBitmap result = ImmutableRoaringBitmap.orNot(rb, full, 0x30000L); + assertTrue(result.isEmpty()); + } + + @Test + public void orNotNonEmptyAgainstFullBitmapStatic() { + MutableRoaringBitmap rb = MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001); + MutableRoaringBitmap full = new MutableRoaringBitmap(); + full.add(0, 0x40000L); + assertEquals( + MutableRoaringBitmap.bitmapOf(1, 0x10001, 0x20001), + ImmutableRoaringBitmap.orNot(rb, full, 0x30000L)); + } + + @Test + @SuppressWarnings("unchecked") + public void testBigOrNot() throws IOException { + byte[] bytes = + Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); + Map info = new ObjectMapper().readerFor(Map.class).readValue(bytes); + List base64Bitmaps = (List) info.get("bitmaps"); + ByteBuffer lBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(0))); + ByteBuffer rBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(1))); + MutableRoaringBitmap l = new MutableRoaringBitmap(); + l.deserialize(lBuffer); + MutableRoaringBitmap r = new MutableRoaringBitmap(); + r.deserialize(rBuffer); + + MutableRoaringBitmap range = new MutableRoaringBitmap(); + long limit = toUnsignedLong(l.last()) + 1; + range.add(0, limit); + range.andNot(r); + MutableRoaringBitmap expected = MutableRoaringBitmap.or(l, range); + + MutableRoaringBitmap actual = l.clone(); + actual.orNot(r, limit); + assertEquals(expected, actual); + } + + @Test + @SuppressWarnings("unchecked") + public void testBigOrNotStatic() throws IOException { + byte[] bytes = + Files.readAllBytes(Paths.get("src/test/resources/testdata/ornot-fuzz-failure.json")); + Map info = new ObjectMapper().readerFor(Map.class).readValue(bytes); + List base64Bitmaps = (List) info.get("bitmaps"); + ByteBuffer lBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(0))); + ByteBuffer rBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(base64Bitmaps.get(1))); + MutableRoaringBitmap l = new MutableRoaringBitmap(); + l.deserialize(lBuffer); + MutableRoaringBitmap r = new MutableRoaringBitmap(); + r.deserialize(rBuffer); + + MutableRoaringBitmap range = new MutableRoaringBitmap(); + long limit = toUnsignedLong(l.last()) + 1; + range.add(0, limit); + range.andNot(r); + MutableRoaringBitmap expected = MutableRoaringBitmap.or(l, range); + + MutableRoaringBitmap actual = ImmutableRoaringBitmap.orNot(l, r, limit); + assertEquals(expected, actual); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java index 24199e7cf..9f9fd1279 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIntIteratorFlyweight.java @@ -2,24 +2,24 @@ * (c) the authors Licensed under the Apache License, Version 2.0. */ - package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.PeekableIntIterator; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.primitives.Ints; import org.junit.jupiter.api.Test; -import org.roaringbitmap.IntIterator; -import org.roaringbitmap.PeekableIntIterator; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - public class TestIntIteratorFlyweight { private static List asList(IntIterator ints) { int[] values = new int[10]; @@ -42,7 +42,7 @@ private static int[] takeSortedAndDistinct(Random source, int count) { } while (!ints.add(next)); } // we add a range of continuous values - for(int k = 1000; k < 10000; ++k) { + for (int k = 1000; k < 10000; ++k) { ints.add(k); } int[] unboxed = Ints.toArray(ints); @@ -50,8 +50,6 @@ private static int[] takeSortedAndDistinct(Random source, int count) { return unboxed; } - - @Test public void testEmptyIteration() { BufferIntIteratorFlyweight iter = new BufferIntIteratorFlyweight(); @@ -65,7 +63,6 @@ public void testEmptyIteration() { assertFalse(reverseIter.hasNext()); } - @Test public void testIteration() { final Random source = new Random(0xcb000a2b9b5bdfb6L); @@ -77,17 +74,16 @@ public void testIteration() { BufferIntIteratorFlyweight iter2 = new BufferIntIteratorFlyweight(bitmap); PeekableIntIterator j = bitmap.getIntIterator(); - for(int k = 0; k < data.length; k+=3) { + for (int k = 0; k < data.length; k += 3) { iter2.advanceIfNeeded(data[k]); iter2.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); - assertEquals(j.peekNext(),data[k]); - assertEquals(iter2.peekNext(),data[k]); + assertEquals(j.peekNext(), data[k]); + assertEquals(iter2.peekNext(), data[k]); } new BufferIntIteratorFlyweight(bitmap).advanceIfNeeded(-1); - bitmap.getIntIterator().advanceIfNeeded(-1);// should not crash - + bitmap.getIntIterator().advanceIfNeeded(-1); // should not crash BufferReverseIntIteratorFlyweight reverseIter = new BufferReverseIntIteratorFlyweight(); reverseIter.wrap(bitmap); @@ -102,7 +98,6 @@ public void testIteration() { assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy); } - @Test public void testIterationFromBitmap() { final Random source = new Random(0xcb000a2b9b5bdfb6L); @@ -110,12 +105,12 @@ public void testIterationFromBitmap() { MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(data); BufferIntIteratorFlyweight iter = new BufferIntIteratorFlyweight(bitmap); - assertEquals(iter.peekNext(),data[0]); - assertEquals(iter.peekNext(),data[0]); + assertEquals(iter.peekNext(), data[0]); + assertEquals(iter.peekNext(), data[0]); BufferIntIteratorFlyweight iter2 = new BufferIntIteratorFlyweight(bitmap); PeekableIntIterator j = bitmap.getIntIterator(); - for(int k = 0; k < data.length; k+=3) { + for (int k = 0; k < data.length; k += 3) { iter2.advanceIfNeeded(data[k]); iter2.advanceIfNeeded(data[k]); j.advanceIfNeeded(data[k]); @@ -124,8 +119,6 @@ public void testIterationFromBitmap() { assertEquals(data[k], iter2.peekNext()); } - - BufferReverseIntIteratorFlyweight reverseIter = new BufferReverseIntIteratorFlyweight(bitmap); final List intIteratorCopy = asList(iter); @@ -138,7 +131,6 @@ public void testIterationFromBitmap() { assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy); } - @Test public void testIterationFromBitmapClone() { final Random source = new Random(0xcb000a2b9b5bdfb6L); @@ -147,7 +139,8 @@ public void testIterationFromBitmapClone() { BufferIntIteratorFlyweight iter = new BufferIntIteratorFlyweight(bitmap); - BufferReverseIntIteratorFlyweight reverseIter = (BufferReverseIntIteratorFlyweight) new BufferReverseIntIteratorFlyweight(bitmap).clone(); + BufferReverseIntIteratorFlyweight reverseIter = + (BufferReverseIntIteratorFlyweight) new BufferReverseIntIteratorFlyweight(bitmap).clone(); final List intIteratorCopy = asList(iter); final List reverseIntIteratorCopy = asList(reverseIter); @@ -217,6 +210,4 @@ public void testSmallIteration() { assertEquals(ImmutableList.of(1, 2, 3), intIteratorCopy); assertEquals(ImmutableList.of(3, 2, 1), reverseIntIteratorCopy); } - - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java index 457af4f93..c0fad4c9f 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestIterators.java @@ -4,6 +4,12 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.PeekableIntIterator; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -11,21 +17,20 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.CharIterator; -import org.roaringbitmap.IntIterator; -import org.roaringbitmap.PeekableIntIterator; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.LongBuffer; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Random; import java.util.stream.Collectors; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - @Execution(ExecutionMode.CONCURRENT) public class TestIterators { @@ -42,26 +47,27 @@ private static List asList(IntIterator ints) { } private static List asList(final CharIterator shorts) { - return asList(new IntIterator() { - @Override - public IntIterator clone() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean hasNext() { - return shorts.hasNext(); - } - - @Override - public int next() { - return shorts.next(); - } - }); + return asList( + new IntIterator() { + @Override + public IntIterator clone() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return shorts.hasNext(); + } + + @Override + public int next() { + return shorts.next(); + } + }); } - - private static int[] takeSortedAndDistinct(Random source, int count, Comparator comparator) { + private static int[] takeSortedAndDistinct( + Random source, int count, Comparator comparator) { HashSet ints = new HashSet(count); for (int size = 0; size < count; size++) { int next; @@ -83,18 +89,22 @@ public void testCorruptionInfiniteLoop() { bitmap.add(Integer.MAX_VALUE - 2); // Adding this one leads to the issue bitmap.add(Integer.MAX_VALUE - 3); - bitmap.forEach((org.roaringbitmap.IntConsumer) e -> { - if (!bitmap.contains(e)) { - throw new IllegalStateException("Not expecting to find: " + e); - } - }); + bitmap.forEach( + (org.roaringbitmap.IntConsumer) + e -> { + if (!bitmap.contains(e)) { + throw new IllegalStateException("Not expecting to find: " + e); + } + }); bitmap.runOptimize(); // This is the line causing the issue - bitmap.forEach((org.roaringbitmap.IntConsumer) e -> { - if (!bitmap.contains(e)) { - throw new IllegalStateException("Not expecting to find: " + e); - } - }); + bitmap.forEach( + (org.roaringbitmap.IntConsumer) + e -> { + if (!bitmap.contains(e)) { + throw new IllegalStateException("Not expecting to find: " + e); + } + }); } @Test @@ -102,7 +112,7 @@ public void testBitmapIteration() { final MappeableBitmapContainer bits = new MappeableBitmapContainer(2, LongBuffer.allocate(2).put(0x1l).put(1l << 63)); - assertEquals(asList(bits.getCharIterator()), ImmutableList.of(0, 127)); + assertEquals(asList(bits.getCharIterator()), ImmutableList.of(0, 127)); assertEquals(asList(bits.getReverseCharIterator()), ImmutableList.of(127, 0)); } @@ -114,7 +124,6 @@ public void testEmptyIteration() { assertFalse(MutableRoaringBitmap.bitmapOf().getReverseIntIterator().hasNext()); } - @Test public void testIteration() { final Random source = new Random(0xcb000a2b9b5bdfb6l); @@ -132,11 +141,11 @@ public void testIteration() { assertEquals(bitmap.getCardinality(), reverseIntIteratorCopy.size()); assertEquals(Ints.asList(data), iteratorCopy); assertEquals(Ints.asList(data), intIteratorCopy); - assertEquals(Ints.asList(data).stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy); + assertEquals( + Ints.asList(data).stream().sorted().collect(Collectors.toList()), signedIntIteratorCopy); assertEquals(Lists.reverse(Ints.asList(data)), reverseIntIteratorCopy); } - @Test public void testIteration1() { final Random source = new Random(0xcb000a2b9b5bdfb6l); @@ -183,7 +192,8 @@ public void testIteration1() { @Test public void testSmallIteration() { - MutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(1, 2, 3, -1, -2147483648 , 2147483647, 0); + MutableRoaringBitmap bitmap = + MutableRoaringBitmap.bitmapOf(1, 2, 3, -1, -2147483648, 2147483647, 0); final List iteratorCopy = ImmutableList.copyOf(bitmap.iterator()); final List intIteratorCopy = asList(bitmap.getIntIterator()); @@ -268,10 +278,10 @@ public void testSkipsSignedIterator() { public void testSkipsDense() { MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); int N = 100000; - for(int i = 0; i < N; ++i) { + for (int i = 0; i < N; ++i) { bitmap.add(2 * i); } - for(int i = 0; i < N; ++i) { + for (int i = 0; i < N; ++i) { PeekableIntIterator pii = bitmap.getIntIterator(); pii.advanceIfNeeded(2 * i); assertEquals(pii.peekNext(), 2 * i); @@ -297,7 +307,7 @@ public void testSkipsRun() { MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); bitmap.add(4L, 100000L); bitmap.runOptimize(); - for(int i = 4; i < 100000; ++i) { + for (int i = 4; i < 100000; ++i) { PeekableIntIterator pii = bitmap.getIntIterator(); pii.advanceIfNeeded(i); assertEquals(pii.peekNext(), i); @@ -314,35 +324,33 @@ public void testEmptySkips() { @Test public void testIteratorsOnLargeBitmap() throws IOException { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - int inc = Short.MAX_VALUE; + int inc = Short.MAX_VALUE; - for (long i = -Integer.MIN_VALUE; i < Integer.MAX_VALUE; i += inc) { - bitmap.add((int) i); - } + for (long i = -Integer.MIN_VALUE; i < Integer.MAX_VALUE; i += inc) { + bitmap.add((int) i); + } - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - bitmap.serialize(dos); - dos.close(); - ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray()); - ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb); - int j = 0; - - // we can iterate over the mutable bitmap - for (int i : bitmap) { - j += i; - } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + bitmap.serialize(dos); + dos.close(); + ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray()); + ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb); + int j = 0; + + // we can iterate over the mutable bitmap + for (int i : bitmap) { + j += i; + } - int jj = 0; - - // we can iterate over the immutable bitmap - for (int i : rrback1) { - jj+= i; - } - assertEquals(j, jj); + int jj = 0; + // we can iterate over the immutable bitmap + for (int i : rrback1) { + jj += i; + } + assertEquals(j, jj); } } - diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java index 02b7090ad..0a72a2aed 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableArrayContainer.java @@ -1,9 +1,15 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.roaringbitmap.IntConsumer; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.IntConsumer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -12,32 +18,34 @@ import java.nio.CharBuffer; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.*; - @Execution(ExecutionMode.CONCURRENT) public class TestMappeableArrayContainer { @Test public void addEmptyRange() { MappeableContainer ac = new MappeableArrayContainer(); - ac = ac.iadd(1,1); + ac = ac.iadd(1, 1); assertEquals(0, ac.getCardinality()); } @Test public void addInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer ac = new MappeableArrayContainer(); - ac.add(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer ac = new MappeableArrayContainer(); + ac.add(13, 1); + }); } @Test public void iaddInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer ac = new MappeableArrayContainer(); - ac.iadd(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer ac = new MappeableArrayContainer(); + ac.iadd(13, 1); + }); } @Test @@ -62,7 +70,7 @@ public void iaddSanityTest() { @Test public void remove() { MappeableContainer ac = new MappeableArrayContainer(); - ac = ac.iadd(1,3); + ac = ac.iadd(1, 3); ac = ac.remove((char) 2); assertEquals(1, ac.getCardinality()); assertTrue(ac.contains((char) 1)); @@ -70,25 +78,29 @@ public void remove() { @Test public void removeInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer ac = new MappeableArrayContainer(); - ac.remove(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer ac = new MappeableArrayContainer(); + ac.remove(13, 1); + }); } @Test public void iremoveEmptyRange() { MappeableContainer ac = new MappeableArrayContainer(); - ac.remove(1,1); + ac.remove(1, 1); assertEquals(0, ac.getCardinality()); } @Test public void iremoveInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer ac = new MappeableArrayContainer(); - ac.iremove(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer ac = new MappeableArrayContainer(); + ac.iremove(13, 1); + }); } @Test @@ -171,9 +183,9 @@ static MappeableArrayContainer newArrayContainer(int firstOfRun, final int lastO @Test public void iand() { MappeableContainer ac = new MappeableArrayContainer(); - ac = ac.add(10,20); + ac = ac.add(10, 20); MappeableContainer bc = new MappeableBitmapContainer(); - bc = bc.add(15,25); + bc = bc.add(15, 25); ac.iand(bc); assertEquals(5, ac.getCardinality()); for (int i = 15; i < 20; i++) { @@ -184,8 +196,8 @@ public void iand() { @Test public void iandNotArray() { MappeableContainer ac = new MappeableArrayContainer(); - ac = ac.add(10,20); - MappeableContainer ac2 = newArrayContainer(15,25); + ac = ac.add(10, 20); + MappeableContainer ac2 = newArrayContainer(15, 25); ac.iandNot(ac2); assertEquals(5, ac.getCardinality()); for (int i = 10; i < 15; i++) { @@ -196,9 +208,9 @@ public void iandNotArray() { @Test public void iandNotBitmap() { MappeableContainer ac = new MappeableArrayContainer(); - ac = ac.add(10,20); + ac = ac.add(10, 20); MappeableContainer bc = new MappeableBitmapContainer(); - bc = bc.add(15,25); + bc = bc.add(15, 25); ac.iandNot(bc); assertEquals(5, ac.getCardinality()); for (int i = 10; i < 15; i++) { @@ -209,9 +221,9 @@ public void iandNotBitmap() { @Test public void intersects() { MappeableContainer ac1 = new MappeableArrayContainer(); - ac1 = ac1.add(10,20); + ac1 = ac1.add(10, 20); MappeableContainer ac2 = new MappeableArrayContainer(); - ac2 = ac2.add(15,25); + ac2 = ac2.add(15, 25); assertTrue(ac1.intersects(ac2)); } @@ -241,8 +253,8 @@ public void roundtrip() throws Exception { @Test public void orArray() { - MappeableContainer ac = newArrayContainer(0,8192); - MappeableContainer ac2 = newArrayContainer(15,25); + MappeableContainer ac = newArrayContainer(0, 8192); + MappeableContainer ac2 = newArrayContainer(15, 25); ac = ac.or(ac2); assertEquals(8192, ac.getCardinality()); for (int i = 0; i < 8192; i++) { @@ -252,8 +264,8 @@ public void orArray() { @Test public void xorArray() { - MappeableContainer ac = newArrayContainer(0,8192); - MappeableContainer ac2 = newArrayContainer(15,25); + MappeableContainer ac = newArrayContainer(0, 8192); + MappeableContainer ac2 = newArrayContainer(15, 25); ac = ac.xor(ac2); assertEquals(8182, ac.getCardinality()); for (int i = 0; i < 15; i++) { @@ -267,14 +279,16 @@ public void xorArray() { @Test public void foreach() { MappeableContainer ac = newArrayContainer(0, 64); - ac.forEach((char) 0, new IntConsumer() { - int expected = 0; + ac.forEach( + (char) 0, + new IntConsumer() { + int expected = 0; - @Override - public void accept(int value) { - assertEquals(value, expected++); - } - }); + @Override + public void accept(int value) { + assertEquals(value, expected++); + } + }); } @Test @@ -321,15 +335,15 @@ public void testToString() { @Test public void testContainsRunContainer_Issue723Case1() { - MappeableContainer ac = new MappeableArrayContainer().add(0,10); - MappeableContainer subset = new MappeableRunContainer().add(5,6); + MappeableContainer ac = new MappeableArrayContainer().add(0, 10); + MappeableContainer subset = new MappeableRunContainer().add(5, 6); assertTrue(ac.contains(subset)); } @Test public void testContainsRunContainer_Issue723Case2() { - MappeableContainer ac = new MappeableArrayContainer().add(0,10); - MappeableContainer rc = new MappeableRunContainer().add(5,11); + MappeableContainer ac = new MappeableArrayContainer().add(0, 10); + MappeableContainer rc = new MappeableRunContainer().add(5, 11); assertFalse(ac.contains(rc)); } @@ -382,10 +396,10 @@ public void testIntersectsWithRange() { assertFalse(container.intersects(11, lower16Bits(-1))); } - @Test public void testIntersectsWithRange2() { - MappeableContainer container = new MappeableArrayContainer().add(lower16Bits(-50), lower16Bits(-10)); + MappeableContainer container = + new MappeableArrayContainer().add(lower16Bits(-50), lower16Bits(-10)); assertFalse(container.intersects(0, 1)); assertTrue(container.intersects(0, lower16Bits(-40))); assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); @@ -393,13 +407,10 @@ public void testIntersectsWithRange2() { assertTrue(container.intersects(11, 1 << 16)); } - @Test public void testIntersectsWithRange3() { - MappeableContainer container = new MappeableArrayContainer() - .add((char) 1) - .add((char) 300) - .add((char) 1024); + MappeableContainer container = + new MappeableArrayContainer().add((char) 1).add((char) 300).add((char) 1024); assertTrue(container.intersects(0, 300)); assertTrue(container.intersects(1, 300)); assertFalse(container.intersects(2, 300)); @@ -423,9 +434,7 @@ public void testContainsRange() { @Test public void testContainsRange2() { - MappeableContainer ac = new MappeableArrayContainer() - .add((char)1).add((char)10) - .add(20, 100); + MappeableContainer ac = new MappeableArrayContainer().add((char) 1).add((char) 10).add(20, 100); assertFalse(ac.contains(1, 21)); assertFalse(ac.contains(1, 20)); assertTrue(ac.contains(1, 2)); @@ -444,251 +453,268 @@ public void testContainsRangeUnsigned() { @Test public void testNextValueBeforeStart() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(10, container.nextValue((char)5)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(10, container.nextValue((char) 5)); } @Test public void testNextValue() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(10, container.nextValue((char)10)); - assertEquals(20, container.nextValue((char)11)); - assertEquals(30, container.nextValue((char)30)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(10, container.nextValue((char) 10)); + assertEquals(20, container.nextValue((char) 11)); + assertEquals(30, container.nextValue((char) 30)); } @Test public void testNextValueAfterEnd() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(-1, container.nextValue((char)31)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(-1, container.nextValue((char) 31)); } @Test public void testNextValue2() { MappeableContainer container = new MappeableArrayContainer().iadd(64, 129); assertTrue(container instanceof MappeableArrayContainer); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(-1, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)5000)); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(-1, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 5000)); } @Test public void testNextValueBetweenRuns() { MappeableContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(256, 321); assertTrue(container instanceof MappeableArrayContainer); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(256, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)512)); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(256, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 512)); } @Test public void testNextValue3() { - MappeableContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + MappeableContainer container = + new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); assertTrue(container instanceof MappeableArrayContainer); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)63)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(200, container.nextValue((char)129)); - assertEquals(200, container.nextValue((char)199)); - assertEquals(200, container.nextValue((char)200)); - assertEquals(250, container.nextValue((char)250)); - assertEquals(5000, container.nextValue((char)2500)); - assertEquals(5000, container.nextValue((char)5000)); - assertEquals(5200, container.nextValue((char)5200)); - assertEquals(-1, container.nextValue((char)5201)); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 63)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(200, container.nextValue((char) 129)); + assertEquals(200, container.nextValue((char) 199)); + assertEquals(200, container.nextValue((char) 200)); + assertEquals(250, container.nextValue((char) 250)); + assertEquals(5000, container.nextValue((char) 2500)); + assertEquals(5000, container.nextValue((char) 5000)); + assertEquals(5200, container.nextValue((char) 5200)); + assertEquals(-1, container.nextValue((char) 5201)); } @Test public void testPreviousValue1() { MappeableContainer container = new MappeableArrayContainer().iadd(64, 129); assertTrue(container instanceof MappeableArrayContainer); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); } @Test public void testPreviousValue2() { - MappeableContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + MappeableContainer container = + new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); assertTrue(container instanceof MappeableArrayContainer); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - assertEquals(128, container.previousValue((char)199)); - assertEquals(200, container.previousValue((char)200)); - assertEquals(250, container.previousValue((char)250)); - assertEquals(500, container.previousValue((char)2500)); - assertEquals(5000, container.previousValue((char)5000)); - assertEquals(5200, container.previousValue((char)5200)); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + assertEquals(128, container.previousValue((char) 199)); + assertEquals(200, container.previousValue((char) 200)); + assertEquals(250, container.previousValue((char) 250)); + assertEquals(500, container.previousValue((char) 2500)); + assertEquals(5000, container.previousValue((char) 5000)); + assertEquals(5200, container.previousValue((char) 5200)); } @Test public void testPreviousValueBeforeStart() { - MappeableContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(-1, container.previousValue((char)5)); + MappeableContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(-1, container.previousValue((char) 5)); } @Test public void testPreviousValueSparse() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(-1, container.previousValue((char)9)); - assertEquals(10, container.previousValue((char)10)); - assertEquals(10, container.previousValue((char)11)); - assertEquals(20, container.previousValue((char)21)); - assertEquals(30, container.previousValue((char)30)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(-1, container.previousValue((char) 9)); + assertEquals(10, container.previousValue((char) 10)); + assertEquals(10, container.previousValue((char) 11)); + assertEquals(20, container.previousValue((char) 21)); + assertEquals(30, container.previousValue((char) 30)); } @Test public void testPreviousValueUnsigned() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}), 2); - assertEquals(-1, container.previousValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 8))); + MappeableArrayContainer container = + new MappeableArrayContainer( + CharBuffer.wrap(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}), 2); + assertEquals(-1, container.previousValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 8))); } @Test public void testNextValueUnsigned() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}), 2); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 7))); - assertEquals(-1, container.nextValue((char)((1 << 15) | 8))); + MappeableArrayContainer container = + new MappeableArrayContainer( + CharBuffer.wrap(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}), 2); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 7))); + assertEquals(-1, container.nextValue((char) ((1 << 15) | 8))); } @Test public void testPreviousValueAfterEnd() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(30, container.previousValue((char)31)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(30, container.previousValue((char) 31)); } @Test public void testPreviousAbsentValue1() { MappeableContainer container = new MappeableArrayContainer().iadd(64, 129); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); } @Test public void testPreviousAbsentValue2() { - MappeableContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - assertEquals(199, container.previousAbsentValue((char)199)); - assertEquals(199, container.previousAbsentValue((char)200)); - assertEquals(199, container.previousAbsentValue((char)250)); - assertEquals(2500, container.previousAbsentValue((char)2500)); - assertEquals(4999, container.previousAbsentValue((char)5000)); - assertEquals(4999, container.previousAbsentValue((char)5200)); + MappeableContainer container = + new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + assertEquals(199, container.previousAbsentValue((char) 199)); + assertEquals(199, container.previousAbsentValue((char) 200)); + assertEquals(199, container.previousAbsentValue((char) 250)); + assertEquals(2500, container.previousAbsentValue((char) 2500)); + assertEquals(4999, container.previousAbsentValue((char) 5000)); + assertEquals(4999, container.previousAbsentValue((char) 5200)); } @Test public void testPreviousAbsentValueEmpty() { MappeableArrayContainer container = new MappeableArrayContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.previousAbsentValue((char)i)); + assertEquals(i, container.previousAbsentValue((char) i)); } } @Test public void testPreviousAbsentValueSparse() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(9, container.previousAbsentValue((char)9)); - assertEquals(9, container.previousAbsentValue((char)10)); - assertEquals(11, container.previousAbsentValue((char)11)); - assertEquals(21, container.previousAbsentValue((char)21)); - assertEquals(29, container.previousAbsentValue((char)30)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(9, container.previousAbsentValue((char) 9)); + assertEquals(9, container.previousAbsentValue((char) 10)); + assertEquals(11, container.previousAbsentValue((char) 11)); + assertEquals(21, container.previousAbsentValue((char) 21)); + assertEquals(29, container.previousAbsentValue((char) 30)); } @Test public void testPreviousAbsentValueUnsigned() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}), 2); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.previousAbsentValue((char)((1 << 15) | 8))); + MappeableArrayContainer container = + new MappeableArrayContainer( + CharBuffer.wrap(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}), 2); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.previousAbsentValue((char) ((1 << 15) | 8))); } - @Test public void testNextAbsentValue1() { MappeableContainer container = new MappeableArrayContainer().iadd(64, 129); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); } @Test public void testNextAbsentValue2() { - MappeableContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - assertEquals(199, container.nextAbsentValue((char)199)); - assertEquals(501, container.nextAbsentValue((char)200)); - assertEquals(501, container.nextAbsentValue((char)250)); - assertEquals(2500, container.nextAbsentValue((char)2500)); - assertEquals(5201, container.nextAbsentValue((char)5000)); - assertEquals(5201, container.nextAbsentValue((char)5200)); + MappeableContainer container = + new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + assertEquals(199, container.nextAbsentValue((char) 199)); + assertEquals(501, container.nextAbsentValue((char) 200)); + assertEquals(501, container.nextAbsentValue((char) 250)); + assertEquals(2500, container.nextAbsentValue((char) 2500)); + assertEquals(5201, container.nextAbsentValue((char) 5000)); + assertEquals(5201, container.nextAbsentValue((char) 5200)); } @Test public void testNextAbsentValueEmpty() { MappeableArrayContainer container = new MappeableArrayContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.nextAbsentValue((char)i)); + assertEquals(i, container.nextAbsentValue((char) i)); } } @Test public void testNextAbsentValueSparse() { - MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3); - assertEquals(9, container.nextAbsentValue((char)9)); - assertEquals(11, container.nextAbsentValue((char)10)); - assertEquals(11, container.nextAbsentValue((char)11)); - assertEquals(21, container.nextAbsentValue((char)21)); - assertEquals(31, container.nextAbsentValue((char)30)); + MappeableArrayContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3); + assertEquals(9, container.nextAbsentValue((char) 9)); + assertEquals(11, container.nextAbsentValue((char) 10)); + assertEquals(11, container.nextAbsentValue((char) 11)); + assertEquals(21, container.nextAbsentValue((char) 21)); + assertEquals(31, container.nextAbsentValue((char) 30)); } @Test public void testNextAbsentValueUnsigned() { char[] array = {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}; MappeableArrayContainer container = new MappeableArrayContainer(CharBuffer.wrap(array), 2); - assertEquals(((1 << 15) | 4), container.nextAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 8))); + assertEquals(((1 << 15) | 4), container.nextAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 8))); } @Test @@ -728,6 +754,6 @@ public void testOrInto() { } private static int lower16Bits(int x) { - return ((char)x); + return ((char) x); } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java index c8c8f2911..8b9ec4a4d 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainer.java @@ -4,6 +4,16 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; +import static org.roaringbitmap.buffer.TestMappeableArrayContainer.newArrayContainer; + +import org.roaringbitmap.BitmapContainer; +import org.roaringbitmap.CharIterator; +import org.roaringbitmap.IntConsumer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -11,9 +21,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.BitmapContainer; -import org.roaringbitmap.CharIterator; -import org.roaringbitmap.IntConsumer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -25,18 +32,16 @@ import java.util.Arrays; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; -import static org.roaringbitmap.buffer.TestMappeableArrayContainer.newArrayContainer; - @Execution(ExecutionMode.CONCURRENT) public class TestMappeableBitmapContainer { private static MappeableBitmapContainer emptyContainer() { return new MappeableBitmapContainer(0, LongBuffer.allocate(1)); } + static MappeableBitmapContainer generateContainer(char min, char max, int sample) { - LongBuffer array = ByteBuffer.allocateDirect(MappeableBitmapContainer.MAX_CAPACITY / 8).asLongBuffer(); + LongBuffer array = + ByteBuffer.allocateDirect(MappeableBitmapContainer.MAX_CAPACITY / 8).asLongBuffer(); MappeableBitmapContainer bc = new MappeableBitmapContainer(array, 0); for (int i = min; i < max; i++) { if (i % sample != 0) bc.add((char) i); @@ -55,12 +60,12 @@ public void testToString() { @Test public void testXOR() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -72,12 +77,12 @@ public void testXOR() { @Test public void testANDNOT() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -91,39 +96,35 @@ public void testANDNOT() { assertEquals(0, bc3.getCardinality()); } - @Test public void testAND() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); } } MappeableRunContainer rc = new MappeableRunContainer(); - rc.iadd(0, 1<<16); + rc.iadd(0, 1 << 16); bc = (MappeableBitmapContainer) bc.iand(rc); bc = (MappeableBitmapContainer) bc.iand(bc2); assertEquals(bc, bc2); assertEquals(0, bc.iand(bc3).getCardinality()); } - - @Test public void testOR() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -134,25 +135,24 @@ public void testOR() { bc2 = (MappeableBitmapContainer) bc2.ior(bc); assertEquals(bc, bc2); MappeableRunContainer rc = new MappeableRunContainer(); - rc.iadd(0, 1<<16); + rc.iadd(0, 1 << 16); assertEquals(0, bc.iandNot(rc).getCardinality()); } private static void removeArray(MappeableBitmapContainer bc) { - LongBuffer array = ByteBuffer.allocateDirect((1<<16)/8).asLongBuffer(); - for(int k = 0; k < bc.bitmap.limit(); ++k) - array.put(k, bc.bitmap.get(k)); + LongBuffer array = ByteBuffer.allocateDirect((1 << 16) / 8).asLongBuffer(); + for (int k = 0; k < bc.bitmap.limit(); ++k) array.put(k, bc.bitmap.get(k)); bc.bitmap = array; } @Test public void testXORNoArray() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -166,12 +166,12 @@ public void testXORNoArray() { @Test public void testANDNOTNoArray() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -183,15 +183,14 @@ public void testANDNOTNoArray() { assertEquals(bc, bc3); } - @Test public void testANDNoArray() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -206,16 +205,14 @@ public void testANDNoArray() { assertEquals(0, bc.iand(bc3).getCardinality()); } - - @Test public void testORNoArray() { - MappeableBitmapContainer bc = new MappeableBitmapContainer(100,10000); + MappeableBitmapContainer bc = new MappeableBitmapContainer(100, 10000); MappeableBitmapContainer bc2 = new MappeableBitmapContainer(); MappeableBitmapContainer bc3 = new MappeableBitmapContainer(); - for(int i = 100; i < 10000; ++i) { - if((i%2 ) == 0) { + for (int i = 100; i < 10000; ++i) { + if ((i % 2) == 0) { bc2.add((char) i); } else { bc3.add((char) i); @@ -232,22 +229,21 @@ public void testORNoArray() { @Test public void runConstructorForBitmap() { System.out.println("runConstructorForBitmap"); - for(int start = 0; start <= (1<<16); start += 4096 ) { - for(int end = start; end <= (1<<16); end += 4096 ) { - LongBuffer array = ByteBuffer.allocateDirect((1<<16)/8).asLongBuffer(); - MappeableBitmapContainer bc = new MappeableBitmapContainer(start,end); - MappeableBitmapContainer bc2 = new MappeableBitmapContainer(array,0); + for (int start = 0; start <= (1 << 16); start += 4096) { + for (int end = start; end <= (1 << 16); end += 4096) { + LongBuffer array = ByteBuffer.allocateDirect((1 << 16) / 8).asLongBuffer(); + MappeableBitmapContainer bc = new MappeableBitmapContainer(start, end); + MappeableBitmapContainer bc2 = new MappeableBitmapContainer(array, 0); assertFalse(bc2.isArrayBacked()); - MappeableBitmapContainer bc3 = (MappeableBitmapContainer) bc2.add(start,end); - bc2.iadd(start,end); - assertEquals(bc.getCardinality(), end-start); - assertEquals(bc2.getCardinality(), end-start); + MappeableBitmapContainer bc3 = (MappeableBitmapContainer) bc2.add(start, end); + bc2.iadd(start, end); + assertEquals(bc.getCardinality(), end - start); + assertEquals(bc2.getCardinality(), end - start); assertEquals(bc, bc2); assertEquals(bc, bc3); - assertEquals(0,bc2.remove(start, end).getCardinality()); - assertEquals(bc2.getCardinality(), end-start); - assertEquals(0,bc2.not(start, end).getCardinality()); - + assertEquals(0, bc2.remove(start, end).getCardinality()); + assertEquals(bc2.getCardinality(), end - start); + assertEquals(0, bc2.not(start, end).getCardinality()); } } } @@ -255,126 +251,132 @@ public void runConstructorForBitmap() { @Test public void runConstructorForBitmap2() { System.out.println("runConstructorForBitmap2"); - for(int start = 0; start <= (1<<16); start += 63 ) { - for(int end = start; end <= (1<<16); end += 63 ) { - LongBuffer array = ByteBuffer.allocateDirect((1<<16)/8).asLongBuffer(); - MappeableBitmapContainer bc = new MappeableBitmapContainer(start,end); - MappeableBitmapContainer bc2 = new MappeableBitmapContainer(array,0); + for (int start = 0; start <= (1 << 16); start += 63) { + for (int end = start; end <= (1 << 16); end += 63) { + LongBuffer array = ByteBuffer.allocateDirect((1 << 16) / 8).asLongBuffer(); + MappeableBitmapContainer bc = new MappeableBitmapContainer(start, end); + MappeableBitmapContainer bc2 = new MappeableBitmapContainer(array, 0); assertFalse(bc2.isArrayBacked()); - MappeableBitmapContainer bc3 = (MappeableBitmapContainer) bc2.add(start,end); - bc2.iadd(start,end); - assertEquals(bc.getCardinality(), end-start); - assertEquals(bc2.getCardinality(), end-start); + MappeableBitmapContainer bc3 = (MappeableBitmapContainer) bc2.add(start, end); + bc2.iadd(start, end); + assertEquals(bc.getCardinality(), end - start); + assertEquals(bc2.getCardinality(), end - start); assertEquals(bc, bc2); assertEquals(bc, bc3); - assertEquals(0,bc2.remove(start, end).getCardinality()); - assertEquals(bc2.getCardinality(), end-start); - assertEquals(0,bc2.not(start, end).getCardinality()); + assertEquals(0, bc2.remove(start, end).getCardinality()); + assertEquals(bc2.getCardinality(), end - start); + assertEquals(0, bc2.not(start, end).getCardinality()); } } } - @Test public void testRangeCardinality() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); bc = (MappeableBitmapContainer) bc.add(200, 2000); assertEquals(8280, bc.cardinality); } @Test public void testRangeCardinality2() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); bc.iadd(200, 2000); assertEquals(8280, bc.cardinality); } @Test public void testRangeCardinality3() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); - MappeableRunContainer rc = TestMappeableRunContainer.generateContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = + TestMappeableRunContainer.generateContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc.ior(rc); assertEquals(8677, bc.cardinality); } @Test public void testRangeCardinality4() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); - MappeableRunContainer rc = TestMappeableRunContainer.generateContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = + TestMappeableRunContainer.generateContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc = (MappeableBitmapContainer) bc.andNot(rc); assertEquals(5274, bc.cardinality); } @Test public void testRangeCardinality5() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); - MappeableRunContainer rc = TestMappeableRunContainer.generateContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = + TestMappeableRunContainer.generateContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc.iandNot(rc); assertEquals(5274, bc.cardinality); } @Test public void testRangeCardinality6() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); - MappeableRunContainer rc = TestMappeableRunContainer.generateContainer(new char[]{7, 300, 400, 900, 1400, 5200}, 3); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = + TestMappeableRunContainer.generateContainer(new char[] {7, 300, 400, 900, 1400, 5200}, 3); bc = (MappeableBitmapContainer) bc.iand(rc); assertEquals(5046, bc.cardinality); } @Test public void testRangeCardinality7() { - MappeableBitmapContainer bc = generateContainer((char)100, (char)10000, 5); - MappeableRunContainer rc = TestMappeableRunContainer.generateContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + MappeableBitmapContainer bc = generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = + TestMappeableRunContainer.generateContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); bc.ixor(rc); assertEquals(6031, bc.cardinality); } @Test public void testNextTooLarge() { - assertThrows(IndexOutOfBoundsException.class, () -> - emptyContainer().nextSetBit(Short.MAX_VALUE + 1)); + assertThrows( + IndexOutOfBoundsException.class, () -> emptyContainer().nextSetBit(Short.MAX_VALUE + 1)); } @Test public void testNextTooSmall() { - assertThrows(IndexOutOfBoundsException.class, () -> - emptyContainer().nextSetBit(-1)); + assertThrows(IndexOutOfBoundsException.class, () -> emptyContainer().nextSetBit(-1)); } @Test public void testPreviousTooLarge() { - assertThrows(IndexOutOfBoundsException.class, () -> - emptyContainer().prevSetBit(Short.MAX_VALUE + 1)); + assertThrows( + IndexOutOfBoundsException.class, () -> emptyContainer().prevSetBit(Short.MAX_VALUE + 1)); } @Test public void testPreviousTooSmall() { - assertThrows(IndexOutOfBoundsException.class, () -> - emptyContainer().prevSetBit(-1)); + assertThrows(IndexOutOfBoundsException.class, () -> emptyContainer().prevSetBit(-1)); } @Test public void addInvalidRange() { - assertThrows(RuntimeException.class, () -> { - MappeableBitmapContainer bc = new MappeableBitmapContainer(); - bc.add(10, 1); - }); + assertThrows( + RuntimeException.class, + () -> { + MappeableBitmapContainer bc = new MappeableBitmapContainer(); + bc.add(10, 1); + }); } @Test public void iaddInvalidRange() { - assertThrows(RuntimeException.class, () -> { - MappeableBitmapContainer bc = new MappeableBitmapContainer(); - bc.iadd(10, 1); - }); + assertThrows( + RuntimeException.class, + () -> { + MappeableBitmapContainer bc = new MappeableBitmapContainer(); + bc.iadd(10, 1); + }); } @Test public void iand() { MappeableBitmapContainer bc = new MappeableBitmapContainer(); MappeableRunContainer rc = new MappeableRunContainer(); - bc.iadd(1,13); - rc.iadd(5,27); + bc.iadd(1, 13); + rc.iadd(5, 27); MappeableContainer result = bc.iand(rc); assertEquals(8, result.getCardinality()); for (char i = 5; i < 13; i++) { @@ -386,8 +388,8 @@ public void iand() { public void ior() { MappeableBitmapContainer bc = new MappeableBitmapContainer(); MappeableRunContainer rc = new MappeableRunContainer(); - bc.iadd(1,13); - rc.iadd(5,27); + bc.iadd(1, 13); + rc.iadd(5, 27); MappeableContainer result = bc.ior(rc); assertEquals(26, result.getCardinality()); for (char i = 1; i < 27; i++) { @@ -398,22 +400,24 @@ public void ior() { @Test public void iremoveEmptyRange() { MappeableBitmapContainer bc = new MappeableBitmapContainer(); - bc.iremove(1,1); + bc.iremove(1, 1); assertEquals(0, bc.getCardinality()); } @Test public void iremoveInvalidRange() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableBitmapContainer bc = new MappeableBitmapContainer(); - bc.iremove(13, 1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableBitmapContainer bc = new MappeableBitmapContainer(); + bc.iremove(13, 1); + }); } @Test public void iremove() { MappeableBitmapContainer bc = new MappeableBitmapContainer(); - bc.iremove(1,13); + bc.iremove(1, 13); assertEquals(0, bc.getCardinality()); } @@ -431,8 +435,8 @@ public void iremove2() { @Test public void numberOfRuns() { MappeableContainer bc = new MappeableBitmapContainer(); - bc = bc.add(1,13); - bc = bc.add(19,27); + bc = bc.add(1, 13); + bc = bc.add(19, 27); assertEquals(2, bc.numberOfRuns()); } @@ -446,11 +450,13 @@ public void numberOfRuns2() { @Test public void selectInvalidPosition() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer bc = new MappeableBitmapContainer(); - bc = bc.add(1, 13); - bc.select(100); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer bc = new MappeableBitmapContainer(); + bc = bc.add(1, 13); + bc.select(100); + }); } @Test @@ -601,14 +607,16 @@ public void foreach() { LongBuffer buffer = LongBuffer.allocate(MAX_CAPACITY / 64); buffer.put(~0L); MappeableContainer bc = new MappeableBitmapContainer(buffer.asReadOnlyBuffer(), 64); - bc.forEach((char) 0, new IntConsumer() { - int expected = 0; + bc.forEach( + (char) 0, + new IntConsumer() { + int expected = 0; - @Override - public void accept(int value) { - assertEquals(value, expected++); - } - }); + @Override + public void accept(int value) { + assertEquals(value, expected++); + } + }); } @Test @@ -707,12 +715,15 @@ public void testLazyORFull3() { @Test public void testFirstLast_SlicedBuffer() { - LongBuffer buffer = LongBuffer.allocate(MAX_CAPACITY / 64) - .put(0, 1L << 62) - .put(1, 1L << 2 | 1L << 32) - .slice() - .asReadOnlyBuffer(); - assertFalse(BufferUtil.isBackedBySimpleArray(buffer), "Sanity check - aiming to test non array backed branch"); + LongBuffer buffer = + LongBuffer.allocate(MAX_CAPACITY / 64) + .put(0, 1L << 62) + .put(1, 1L << 2 | 1L << 32) + .slice() + .asReadOnlyBuffer(); + assertFalse( + BufferUtil.isBackedBySimpleArray(buffer), + "Sanity check - aiming to test non array backed branch"); MappeableBitmapContainer mbc = new MappeableBitmapContainer(buffer, 3); assertEquals(62, mbc.first()); assertEquals(96, mbc.last()); @@ -729,25 +740,27 @@ public void testIntersectsWithRange() { public static Stream bitmapsForRangeIntersection() { return Stream.of( - Arguments.of(new MappeableBitmapContainer().add((char)60), 0, 61, true), - Arguments.of(new MappeableBitmapContainer().add((char)60), 0, 60, false), - Arguments.of(new MappeableBitmapContainer().add((char)1000), 0, 1001, true), - Arguments.of(new MappeableBitmapContainer().add((char)1000), 0, 1000, false), - Arguments.of(new MappeableBitmapContainer().add((char)1000), 0, 10000, true) - ); + Arguments.of(new MappeableBitmapContainer().add((char) 60), 0, 61, true), + Arguments.of(new MappeableBitmapContainer().add((char) 60), 0, 60, false), + Arguments.of(new MappeableBitmapContainer().add((char) 1000), 0, 1001, true), + Arguments.of(new MappeableBitmapContainer().add((char) 1000), 0, 1000, false), + Arguments.of(new MappeableBitmapContainer().add((char) 1000), 0, 10000, true)); } @ParameterizedTest @MethodSource("bitmapsForRangeIntersection") - public void testIntersectsWithRangeUpperBoundaries(MappeableContainer container, int min, int sup, boolean intersects) { + public void testIntersectsWithRangeUpperBoundaries( + MappeableContainer container, int min, int sup, boolean intersects) { assertEquals(intersects, container.intersects(min, sup)); } - @Test public void testIntersectsWithRangeHitScan() { - MappeableContainer container = new MappeableBitmapContainer().add(0, 10) - .add(500, 512).add(lower16Bits(-50), lower16Bits(-10)); + MappeableContainer container = + new MappeableBitmapContainer() + .add(0, 10) + .add(500, 512) + .add(lower16Bits(-50), lower16Bits(-10)); assertTrue(container.intersects(0, 1)); assertTrue(container.intersects(0, 101)); assertTrue(container.intersects(0, 1 << 16)); @@ -755,30 +768,31 @@ public void testIntersectsWithRangeHitScan() { assertTrue(container.intersects(501, 511)); } - @Test public void testIntersectsWithRangeUnsigned() { - MappeableContainer container = new MappeableBitmapContainer().add(lower16Bits(-50), lower16Bits(-10)); + MappeableContainer container = + new MappeableBitmapContainer().add(lower16Bits(-50), lower16Bits(-10)); assertFalse(container.intersects(0, 1)); assertTrue(container.intersects(0, lower16Bits(-40))); assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); assertFalse(container.intersects(lower16Bits(-9), lower16Bits(-1))); - //assertTrue(container.intersects(11, (char)-1));// forbidden + // assertTrue(container.intersects(11, (char)-1));// forbidden } @Test public void testIntersectsAtEndWord() { - MappeableContainer container = new MappeableBitmapContainer().add(lower16Bits(-500), lower16Bits(-10)); + MappeableContainer container = + new MappeableBitmapContainer().add(lower16Bits(-500), lower16Bits(-10)); assertTrue(container.intersects(lower16Bits(-50), lower16Bits(-10))); assertTrue(container.intersects(lower16Bits(-400), lower16Bits(-11))); assertTrue(container.intersects(lower16Bits(-11), lower16Bits(-1))); assertFalse(container.intersects(lower16Bits(-10), lower16Bits(-1))); } - @Test public void testIntersectsAtEndWord2() { - MappeableContainer container = new MappeableBitmapContainer().add(lower16Bits(500), lower16Bits(-500)); + MappeableContainer container = + new MappeableBitmapContainer().add(lower16Bits(500), lower16Bits(-500)); assertTrue(container.intersects(lower16Bits(-650), lower16Bits(-500))); assertTrue(container.intersects(lower16Bits(-501), lower16Bits(-1))); assertFalse(container.intersects(lower16Bits(-500), lower16Bits(-1))); @@ -790,7 +804,8 @@ public void testContainsRangeSingleWord() { long[] bitmap = evenBits(); bitmap[10] = -1L; int cardinality = 32 + 1 << 15; - MappeableBitmapContainer container = new MappeableBitmapContainer(LongBuffer.wrap(bitmap), cardinality); + MappeableBitmapContainer container = + new MappeableBitmapContainer(LongBuffer.wrap(bitmap), cardinality); assertTrue(container.contains(0, 1)); assertTrue(container.contains(64 * 10, 64 * 11)); assertFalse(container.contains(64 * 10, 2 + 64 * 11)); @@ -804,7 +819,8 @@ public void testContainsRangeMultiWord() { bitmap[11] = -1L; bitmap[12] |= ((1L << 32) - 1); int cardinality = 32 + 32 + 16 + 1 << 15; - MappeableBitmapContainer container = new MappeableBitmapContainer(LongBuffer.wrap(bitmap), cardinality); + MappeableBitmapContainer container = + new MappeableBitmapContainer(LongBuffer.wrap(bitmap), cardinality); assertTrue(container.contains(0, 1)); assertFalse(container.contains(64 * 10, (64 * 13) - 30)); assertTrue(container.contains(64 * 10, (64 * 13) - 31)); @@ -813,13 +829,13 @@ public void testContainsRangeMultiWord() { assertFalse(container.contains(64 * 10, 2 + 64 * 13)); } - @Test public void testContainsRangeSubWord() { long[] bitmap = evenBits(); bitmap[bitmap.length - 1] = ~((1L << 63) | 1L); int cardinality = 32 + 32 + 16 + 1 << 15; - MappeableBitmapContainer container = new MappeableBitmapContainer(LongBuffer.wrap(bitmap), cardinality); + MappeableBitmapContainer container = + new MappeableBitmapContainer(LongBuffer.wrap(bitmap), cardinality); assertFalse(container.contains(64 * 1023, 64 * 1024)); assertFalse(container.contains(64 * 1023, 64 * 1024 - 1)); assertTrue(container.contains(1 + 64 * 1023, 64 * 1024 - 1)); @@ -830,273 +846,316 @@ public void testContainsRangeSubWord() { @Test public void testNextValue() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3).toBitmapContainer(); - assertEquals(10, container.nextValue((char)10)); - assertEquals(20, container.nextValue((char)11)); - assertEquals(30, container.nextValue((char)30)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3) + .toBitmapContainer(); + assertEquals(10, container.nextValue((char) 10)); + assertEquals(20, container.nextValue((char) 11)); + assertEquals(30, container.nextValue((char) 30)); } @Test public void testNextValueAfterEnd() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3).toBitmapContainer(); - assertEquals(-1, container.nextValue((char)31)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3) + .toBitmapContainer(); + assertEquals(-1, container.nextValue((char) 31)); } @Test public void testNextValue2() { - MappeableBitmapContainer container = new MappeableBitmapContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(-1, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)5000)); + MappeableBitmapContainer container = + new MappeableBitmapContainer().iadd(64, 129).toBitmapContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(-1, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 5000)); } @Test public void testNextValueBetweenRuns() { - MappeableBitmapContainer container = new MappeableBitmapContainer().iadd(64, 129).iadd(256, 321).toBitmapContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(256, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)512)); + MappeableBitmapContainer container = + new MappeableBitmapContainer().iadd(64, 129).iadd(256, 321).toBitmapContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(256, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 512)); } @Test public void testNextValue3() { - MappeableBitmapContainer container = new MappeableBitmapContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)63)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(200, container.nextValue((char)129)); - assertEquals(200, container.nextValue((char)199)); - assertEquals(200, container.nextValue((char)200)); - assertEquals(250, container.nextValue((char)250)); - assertEquals(5000, container.nextValue((char)2500)); - assertEquals(5000, container.nextValue((char)5000)); - assertEquals(5200, container.nextValue((char)5200)); - assertEquals(-1, container.nextValue((char)5201)); + MappeableBitmapContainer container = + new MappeableBitmapContainer() + .iadd(64, 129) + .iadd(200, 501) + .iadd(5000, 5201) + .toBitmapContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 63)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(200, container.nextValue((char) 129)); + assertEquals(200, container.nextValue((char) 199)); + assertEquals(200, container.nextValue((char) 200)); + assertEquals(250, container.nextValue((char) 250)); + assertEquals(5000, container.nextValue((char) 2500)); + assertEquals(5000, container.nextValue((char) 5000)); + assertEquals(5200, container.nextValue((char) 5200)); + assertEquals(-1, container.nextValue((char) 5201)); } @Test public void testPreviousValue1() { - MappeableBitmapContainer container = new MappeableBitmapContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); + MappeableBitmapContainer container = + new MappeableBitmapContainer().iadd(64, 129).toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); } @Test public void testPreviousValue2() { - MappeableBitmapContainer container = new MappeableBitmapContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - assertEquals(128, container.previousValue((char)199)); - assertEquals(200, container.previousValue((char)200)); - assertEquals(250, container.previousValue((char)250)); - assertEquals(500, container.previousValue((char)2500)); - assertEquals(5000, container.previousValue((char)5000)); - assertEquals(5200, container.previousValue((char)5200)); + MappeableBitmapContainer container = + new MappeableBitmapContainer() + .iadd(64, 129) + .iadd(200, 501) + .iadd(5000, 5201) + .toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + assertEquals(128, container.previousValue((char) 199)); + assertEquals(200, container.previousValue((char) 200)); + assertEquals(250, container.previousValue((char) 250)); + assertEquals(500, container.previousValue((char) 2500)); + assertEquals(5000, container.previousValue((char) 5000)); + assertEquals(5200, container.previousValue((char) 5200)); } @Test public void testPreviousValueBeforeStart() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)5)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3) + .toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 5)); } @Test public void testPreviousValueSparse() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3).toBitmapContainer(); - assertEquals(-1, container.previousValue((char)9)); - assertEquals(10, container.previousValue((char)10)); - assertEquals(10, container.previousValue((char)11)); - assertEquals(20, container.previousValue((char)21)); - assertEquals(30, container.previousValue((char)30)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3) + .toBitmapContainer(); + assertEquals(-1, container.previousValue((char) 9)); + assertEquals(10, container.previousValue((char) 10)); + assertEquals(10, container.previousValue((char) 11)); + assertEquals(20, container.previousValue((char) 21)); + assertEquals(30, container.previousValue((char) 30)); } @Test public void testPreviousValueAfterEnd() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3).toBitmapContainer(); - assertEquals(30, container.previousValue((char)31)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3) + .toBitmapContainer(); + assertEquals(30, container.previousValue((char) 31)); } @Test public void testPreviousEvenBits() { MappeableContainer container = new BitmapContainer(evenBits(), 1 << 15).toMappeableContainer(); - assertEquals(0, container.previousValue((char)0)); - assertEquals(0, container.previousValue((char)1)); - assertEquals(2, container.previousValue((char)2)); - assertEquals(2, container.previousValue((char)3)); + assertEquals(0, container.previousValue((char) 0)); + assertEquals(0, container.previousValue((char) 1)); + assertEquals(2, container.previousValue((char) 2)); + assertEquals(2, container.previousValue((char) 3)); } @Test public void testPreviousValueUnsigned() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}), 2) + MappeableBitmapContainer container = + new MappeableArrayContainer( + CharBuffer.wrap(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}), 2) .toBitmapContainer(); - assertEquals(-1, container.previousValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 8))); + assertEquals(-1, container.previousValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 8))); } @Test public void testNextValueUnsigned() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { (char)((1 << 15) | 5), (char)((1 << 15) | 7)}), 2).toBitmapContainer(); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 7))); - assertEquals(-1, container.nextValue((char)((1 << 15) | 8))); + MappeableBitmapContainer container = + new MappeableArrayContainer( + CharBuffer.wrap(new char[] {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}), 2) + .toBitmapContainer(); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 7))); + assertEquals(-1, container.nextValue((char) ((1 << 15) | 8))); } - @Test public void testPreviousAbsentValue1() { - MappeableBitmapContainer container = new MappeableArrayContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); + MappeableBitmapContainer container = + new MappeableArrayContainer().iadd(64, 129).toBitmapContainer(); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); } @Test public void testPreviousAbsentValue2() { - MappeableBitmapContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201).toBitmapContainer(); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - assertEquals(199, container.previousAbsentValue((char)199)); - assertEquals(199, container.previousAbsentValue((char)200)); - assertEquals(199, container.previousAbsentValue((char)250)); - assertEquals(2500, container.previousAbsentValue((char)2500)); - assertEquals(4999, container.previousAbsentValue((char)5000)); - assertEquals(4999, container.previousAbsentValue((char)5200)); + MappeableBitmapContainer container = + new MappeableArrayContainer() + .iadd(64, 129) + .iadd(200, 501) + .iadd(5000, 5201) + .toBitmapContainer(); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + assertEquals(199, container.previousAbsentValue((char) 199)); + assertEquals(199, container.previousAbsentValue((char) 200)); + assertEquals(199, container.previousAbsentValue((char) 250)); + assertEquals(2500, container.previousAbsentValue((char) 2500)); + assertEquals(4999, container.previousAbsentValue((char) 5000)); + assertEquals(4999, container.previousAbsentValue((char) 5200)); } @Test public void testPreviousAbsentValueEmpty() { MappeableBitmapContainer container = new MappeableArrayContainer().toBitmapContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.previousAbsentValue((char)i)); + assertEquals(i, container.previousAbsentValue((char) i)); } } @Test public void testPreviousAbsentValueSparse() { - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(new char[] { 10, 20, 30}), 3).toBitmapContainer(); - assertEquals(9, container.previousAbsentValue((char)9)); - assertEquals(9, container.previousAbsentValue((char)10)); - assertEquals(11, container.previousAbsentValue((char)11)); - assertEquals(21, container.previousAbsentValue((char)21)); - assertEquals(29, container.previousAbsentValue((char)30)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(new char[] {10, 20, 30}), 3) + .toBitmapContainer(); + assertEquals(9, container.previousAbsentValue((char) 9)); + assertEquals(9, container.previousAbsentValue((char) 10)); + assertEquals(11, container.previousAbsentValue((char) 11)); + assertEquals(21, container.previousAbsentValue((char) 21)); + assertEquals(29, container.previousAbsentValue((char) 30)); } @Test public void testPreviousAbsentEvenBits() { MappeableContainer container = new BitmapContainer(evenBits(), 1 << 15).toMappeableContainer(); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i - 1, container.previousAbsentValue((char)i)); - assertEquals(i + 1, container.previousAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i - 1, container.previousAbsentValue((char) i)); + assertEquals(i + 1, container.previousAbsentValue((char) (i + 1))); } } @Test public void testPreviousAbsentValueUnsigned() { char[] array = {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}; - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(array), 2).toBitmapContainer(); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.previousAbsentValue((char)((1 << 15) | 8))); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(array), 2).toBitmapContainer(); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.previousAbsentValue((char) ((1 << 15) | 8))); } - @Test public void testNextAbsentValue1() { - MappeableBitmapContainer container = new MappeableArrayContainer().iadd(64, 129).toBitmapContainer(); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); + MappeableBitmapContainer container = + new MappeableArrayContainer().iadd(64, 129).toBitmapContainer(); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); } @Test public void testNextAbsentValue2() { - MappeableBitmapContainer container = new MappeableArrayContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201) + MappeableBitmapContainer container = + new MappeableArrayContainer() + .iadd(64, 129) + .iadd(200, 501) + .iadd(5000, 5201) .toBitmapContainer(); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - assertEquals(199, container.nextAbsentValue((char)199)); - assertEquals(501, container.nextAbsentValue((char)200)); - assertEquals(501, container.nextAbsentValue((char)250)); - assertEquals(2500, container.nextAbsentValue((char)2500)); - assertEquals(5201, container.nextAbsentValue((char)5000)); - assertEquals(5201, container.nextAbsentValue((char)5200)); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + assertEquals(199, container.nextAbsentValue((char) 199)); + assertEquals(501, container.nextAbsentValue((char) 200)); + assertEquals(501, container.nextAbsentValue((char) 250)); + assertEquals(2500, container.nextAbsentValue((char) 2500)); + assertEquals(5201, container.nextAbsentValue((char) 5000)); + assertEquals(5201, container.nextAbsentValue((char) 5200)); } @Test public void testNextAbsentValueEmpty() { MappeableBitmapContainer container = new MappeableArrayContainer().toBitmapContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.nextAbsentValue((char)i)); + assertEquals(i, container.nextAbsentValue((char) i)); } } @Test public void testNextAbsentValueSparse() { char[] array = {10, 20, 30}; - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(array), 3).toBitmapContainer(); - assertEquals(9, container.nextAbsentValue((char)9)); - assertEquals(11, container.nextAbsentValue((char)10)); - assertEquals(11, container.nextAbsentValue((char)11)); - assertEquals(21, container.nextAbsentValue((char)21)); - assertEquals(31, container.nextAbsentValue((char)30)); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(array), 3).toBitmapContainer(); + assertEquals(9, container.nextAbsentValue((char) 9)); + assertEquals(11, container.nextAbsentValue((char) 10)); + assertEquals(11, container.nextAbsentValue((char) 11)); + assertEquals(21, container.nextAbsentValue((char) 21)); + assertEquals(31, container.nextAbsentValue((char) 30)); } @Test public void testNextAbsentEvenBits() { int cardinality = 32 + 1 << 15; - MappeableBitmapContainer container = new MappeableBitmapContainer(LongBuffer.wrap(evenBits()), cardinality); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i + 1, container.nextAbsentValue((char)i)); - assertEquals(i + 1, container.nextAbsentValue((char)(i+1))); + MappeableBitmapContainer container = + new MappeableBitmapContainer(LongBuffer.wrap(evenBits()), cardinality); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i + 1, container.nextAbsentValue((char) i)); + assertEquals(i + 1, container.nextAbsentValue((char) (i + 1))); } } @Test public void testNextAbsentValueUnsigned() { char[] array = {(char) ((1 << 15) | 5), (char) ((1 << 15) | 7)}; - MappeableBitmapContainer container = new MappeableArrayContainer(CharBuffer.wrap(array), 2).toBitmapContainer(); - assertEquals(((1 << 15) | 4), container.nextAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 8))); + MappeableBitmapContainer container = + new MappeableArrayContainer(CharBuffer.wrap(array), 2).toBitmapContainer(); + assertEquals(((1 << 15) | 4), container.nextAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 8))); } @Test @@ -1142,7 +1201,6 @@ private static long[] evenBits() { } private static int lower16Bits(int x) { - return ((char)x); + return ((char) x); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java index 85b3f190f..b3ed445fb 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableBitmapContainerCharIterator.java @@ -1,44 +1,46 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.roaringbitmap.buffer.MappeableArrayContainer.DEFAULT_MAX_SIZE; + +import org.roaringbitmap.PeekableCharIterator; + import com.google.common.primitives.Ints; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.PeekableCharIterator; import java.util.Arrays; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.roaringbitmap.buffer.MappeableArrayContainer.DEFAULT_MAX_SIZE; - @Execution(ExecutionMode.CONCURRENT) public class TestMappeableBitmapContainerCharIterator { - private static List asList(PeekableCharIterator ints) { - int[] values = new int[10]; - int size = 0; - while (ints.hasNext()) { - if (!(size < values.length)) { - values = Arrays.copyOf(values, values.length * 2); - } - values[size++] = ints.next(); - } - return Ints.asList(Arrays.copyOf(values, size)); + private static List asList(PeekableCharIterator ints) { + int[] values = new int[10]; + int size = 0; + while (ints.hasNext()) { + if (!(size < values.length)) { + values = Arrays.copyOf(values, values.length * 2); + } + values[size++] = ints.next(); } + return Ints.asList(Arrays.copyOf(values, size)); + } - @Test - public void testClone() { - MappeableBitmapContainer mappeableBitmapContainer = new MappeableBitmapContainer(); - for (int k = 0; k < 2 * DEFAULT_MAX_SIZE; ++k) { - mappeableBitmapContainer.add((char) (k * 10)); - } - MappeableBitmapContainerCharIterator tmbc = new MappeableBitmapContainerCharIterator(mappeableBitmapContainer); - PeekableCharIterator tmbcClone = tmbc.clone(); - assertNotNull(tmbcClone); - final List tmbcList = asList(tmbc); - final List tmbcCloneList = asList(tmbcClone); - assertEquals(tmbcList, tmbcCloneList); + @Test + public void testClone() { + MappeableBitmapContainer mappeableBitmapContainer = new MappeableBitmapContainer(); + for (int k = 0; k < 2 * DEFAULT_MAX_SIZE; ++k) { + mappeableBitmapContainer.add((char) (k * 10)); } + MappeableBitmapContainerCharIterator tmbc = + new MappeableBitmapContainerCharIterator(mappeableBitmapContainer); + PeekableCharIterator tmbcClone = tmbc.clone(); + assertNotNull(tmbcClone); + final List tmbcList = asList(tmbc); + final List tmbcCloneList = asList(tmbcClone); + assertEquals(tmbcList, tmbcCloneList); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java index 2dec26118..19e81d987 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMappeableRunContainer.java @@ -1,5 +1,11 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; +import static org.roaringbitmap.buffer.TestMappeableArrayContainer.newArrayContainer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -14,10 +20,6 @@ import java.nio.LongBuffer; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.buffer.MappeableBitmapContainer.MAX_CAPACITY; -import static org.roaringbitmap.buffer.TestMappeableArrayContainer.newArrayContainer; - @Execution(ExecutionMode.CONCURRENT) public class TestMappeableRunContainer { @@ -67,17 +69,19 @@ public void not() { static MappeableRunContainer newRunContainer(int firstOfRun, final int lastOfRun) { CharBuffer buffer = CharBuffer.allocate(2); buffer.put((char) firstOfRun); - buffer.put((char) (lastOfRun-firstOfRun-1)); + buffer.put((char) (lastOfRun - firstOfRun - 1)); return new MappeableRunContainer(buffer.asReadOnlyBuffer(), 1); } @Test public void selectInvalidPosition() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer bc = new MappeableRunContainer(); - bc = bc.add(1, 13); - bc.select(100); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer bc = new MappeableRunContainer(); + bc = bc.add(1, 13); + bc.select(100); + }); } @Test @@ -221,18 +225,20 @@ public void testLazyORFull3() { @Test public void testRangeCardinality() { - MappeableBitmapContainer bc = TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - MappeableRunContainer rc = generateContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + MappeableBitmapContainer bc = + TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = generateContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); MappeableContainer result = rc.or(bc); assertEquals(8677, result.getCardinality()); } @Test public void testRangeCardinality2() { - MappeableBitmapContainer bc = TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - bc.add((char)22345); //important case to have greater element than run container - bc.add((char)Short.MAX_VALUE); - MappeableRunContainer rc = generateContainer(new char[]{7, 300, 400, 900, 1400, 18000}, 3); + MappeableBitmapContainer bc = + TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); + bc.add((char) 22345); // important case to have greater element than run container + bc.add((char) Short.MAX_VALUE); + MappeableRunContainer rc = generateContainer(new char[] {7, 300, 400, 900, 1400, 18000}, 3); assertTrue(rc.getCardinality() > MappeableArrayContainer.DEFAULT_MAX_SIZE); MappeableContainer result = rc.andNot(bc); assertEquals(11437, result.getCardinality()); @@ -240,16 +246,18 @@ public void testRangeCardinality2() { @Test public void testRangeCardinality3() { - MappeableBitmapContainer bc = TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - MappeableRunContainer rc = generateContainer(new char[]{7, 300, 400, 900, 1400, 5200}, 3); + MappeableBitmapContainer bc = + TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = generateContainer(new char[] {7, 300, 400, 900, 1400, 5200}, 3); MappeableBitmapContainer result = (MappeableBitmapContainer) rc.and(bc); assertEquals(5046, result.getCardinality()); } @Test public void testRangeCardinality4() { - MappeableBitmapContainer bc = TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); - MappeableRunContainer rc = generateContainer(new char[]{7, 300, 400, 900, 1400, 2200}, 3); + MappeableBitmapContainer bc = + TestMappeableBitmapContainer.generateContainer((char) 100, (char) 10000, 5); + MappeableRunContainer rc = generateContainer(new char[] {7, 300, 400, 900, 1400, 2200}, 3); MappeableBitmapContainer result = (MappeableBitmapContainer) rc.xor(bc); assertEquals(6031, result.getCardinality()); } @@ -290,7 +298,7 @@ public void testEqualsArrayContainer_NotEqual_ArrayShifted() { public void testEqualsArrayContainer_NotEqual_ArrayDiscontiguous() { MappeableContainer rc = new MappeableRunContainer().add(0, 10); MappeableContainer ac = new MappeableArrayContainer().add(0, 11); - ac.flip((char)9); + ac.flip((char) 9); assertFalse(rc.equals(ac)); assertFalse(ac.equals(rc)); } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java index b81bd2355..85ac81c31 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemory.java @@ -1,19 +1,22 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestMemory { @Test public void testGCStability() { final int N = 10000; final int M = 5000000; - System.out.println("[testGCStability] testing GC stability with " + N + " bitmaps containing ~" - + M / N + " values each on average"); + System.out.println( + "[testGCStability] testing GC stability with " + + N + + " bitmaps containing ~" + + M / N + + " values each on average"); System.out.println("Universe size = " + M); final MutableRoaringBitmap[] bitmaps = new MutableRoaringBitmap[N]; for (int i = 0; i < N; i++) { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java index 1605cabfc..c5dd83db1 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestMemoryMapping.java @@ -4,13 +4,27 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.RoaringBitmap; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.roaringbitmap.IntIterator; -import org.roaringbitmap.RoaringBitmap; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; @@ -21,9 +35,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import static org.junit.jupiter.api.Assertions.*; - - class ByteBufferBackedInputStream extends InputStream { ByteBuffer buf; @@ -72,7 +83,6 @@ public long skip(long n) { } } - class ByteBufferBackedOutputStream extends OutputStream { ByteBuffer buf; @@ -94,10 +104,8 @@ public synchronized void write(byte[] bytes, int off, int len) throws IOExceptio public synchronized void write(int b) throws IOException { buf.put((byte) b); } - } - @SuppressWarnings({"static-method"}) public class TestMemoryMapping { @@ -217,8 +225,11 @@ public static void initFiles() throws IOException { rb2.serialize(dos); long paft = fos.getChannel().position(); if (paft - pbef != rb2.serializedSizeInBytes()) { - throw new RuntimeException("wrong serializedSizeInBytes:: paft-pbef = " + (paft - pbef) - + ", serializedSize = " + rb2.serializedSizeInBytes()); + throw new RuntimeException( + "wrong serializedSizeInBytes:: paft-pbef = " + + (paft - pbef) + + ", serializedSize = " + + rb2.serializedSizeInBytes()); } dos.flush(); rambitmaps.add(rb2); @@ -249,7 +260,9 @@ public static void initFiles() throws IOException { ImmutableRoaringBitmap newbitmap = new ImmutableRoaringBitmap(bb); if (newbitmap.serializedSizeInBytes() != rambitmaps.get(k).serializedSizeInBytes()) { throw new RuntimeException( - "faulty reported serialization size " + newbitmap.serializedSizeInBytes() + " " + "faulty reported serialization size " + + newbitmap.serializedSizeInBytes() + + " " + rambitmaps.get(k).serializedSizeInBytes()); } if (!newbitmap.equals(rambitmaps.get(k))) { @@ -262,8 +275,12 @@ public static void initFiles() throws IOException { } } final long aft = System.currentTimeMillis(); - System.out.println("[TestMemoryMapping] Mapped " + (offsets.size() - 1) + " bitmaps in " - + (aft - bef) + "ms"); + System.out.println( + "[TestMemoryMapping] Mapped " + + (offsets.size() - 1) + + " bitmaps in " + + (aft - bef) + + "ms"); } finally { memoryMappedFile.close(); } @@ -349,10 +366,18 @@ public void intersections() { } for (int k = 0; k < mappedbitmaps.size() - 4; k += 4) { - final MutableRoaringBitmap rb = BufferFastAggregation.and(mappedbitmaps.get(k), - mappedbitmaps.get(k + 1), mappedbitmaps.get(k + 3), mappedbitmaps.get(k + 4)); - final MutableRoaringBitmap rbram = BufferFastAggregation.and(rambitmaps.get(k), - rambitmaps.get(k + 1), rambitmaps.get(k + 3), rambitmaps.get(k + 4)); + final MutableRoaringBitmap rb = + BufferFastAggregation.and( + mappedbitmaps.get(k), + mappedbitmaps.get(k + 1), + mappedbitmaps.get(k + 3), + mappedbitmaps.get(k + 4)); + final MutableRoaringBitmap rbram = + BufferFastAggregation.and( + rambitmaps.get(k), + rambitmaps.get(k + 1), + rambitmaps.get(k + 3), + rambitmaps.get(k + 4)); assertTrue(rb.equals(rbram)); } } @@ -384,27 +409,28 @@ public void multithreadingTest() throws InterruptedException, IOException { for (int i = 0; i < numThreads; i++) { final int ti = i; - executorService.execute(new Runnable() { - - @Override - public void run() { - ready.countDown(); - try { - ready.await(); - final int elementToCheck = Short.MAX_VALUE * ti; - for (int j = 0; j < 10000000; j++) { + executorService.execute( + new Runnable() { + + @Override + public void run() { + ready.countDown(); try { - assertTrue(rrback1.contains(elementToCheck)); - } catch (Throwable t) { - errors[ti] = t; + ready.await(); + final int elementToCheck = Short.MAX_VALUE * ti; + for (int j = 0; j < 10000000; j++) { + try { + assertTrue(rrback1.contains(elementToCheck)); + } catch (Throwable t) { + errors[ti] = t; + } + } + } catch (Throwable e) { + errors[ti] = e; } + finished.countDown(); } - } catch (Throwable e) { - errors[ti] = e; - } - finished.countDown(); - } - }); + }); } finished.await(5, TimeUnit.SECONDS); for (int i = 0; i < numThreads; i++) { @@ -415,18 +441,14 @@ public void run() { } } - @Test - public void containsTest() throws IOException { + public void containsTest() throws IOException { System.out.println("[containsTest]"); - for(int z = 0; z < 100; ++z) { + for (int z = 0; z < 100; ++z) { final MutableRoaringBitmap rr1 = new MutableRoaringBitmap(); - for(int k = 0; k < 100; k+=10) - rr1.add(k + z); - for(int k = 100000; k < 200000; k+=2) - rr1.add(k + z); - for(int k = 400000; k < 500000; k++) - rr1.add(k + z); + for (int k = 0; k < 100; k += 10) rr1.add(k + z); + for (int k = 100000; k < 200000; k += 2) rr1.add(k + z); + for (int k = 400000; k < 500000; k++) rr1.add(k + z); rr1.runOptimize(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); @@ -436,13 +458,12 @@ public void containsTest() throws IOException { final ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb); assertEquals(rrback1.getLongSizeInBytes(), rr1.getLongSizeInBytes()); assertEquals(rrback1.serializedSizeInBytes(), rr1.serializedSizeInBytes()); - for(int k = 0; k < 1000000; k += 100) { + for (int k = 0; k < 1000000; k += 100) { assertEquals(rrback1.contains(k), rr1.contains(k)); } } } - @Test public void oneFormat() throws IOException { System.out.println("[TestMemoryMapping] testing format compatibility"); @@ -462,11 +483,10 @@ public void oneFormat() throws IOException { arr = null; RoaringBitmap rrasroaring = rr.toRoaringBitmap(); assertEquals(newr, rrasroaring); - System.out - .println("[TestMemoryMapping] testing compat. bitmap " + k + " out of " + ms + ". ok."); + System.out.println( + "[TestMemoryMapping] testing compat. bitmap " + k + " out of " + ms + ". ok."); } System.out.println("[TestMemoryMapping] Format compatibility ok"); - } @Test @@ -535,7 +555,6 @@ public void standardTest1() throws IOException { assertEquals(rr1.hashCode(), rrback1c.hashCode()); assertEquals(rr2.hashCode(), rrback2.hashCode()); assertEquals(rr2.hashCode(), rrback2c.hashCode()); - } @Test @@ -544,8 +563,11 @@ public void testIterator() { final int ms = mappedbitmaps.size(); System.out.println("We first test in-memory (RoaringBitmap) iterators."); for (int k = 0; k < ms; ++k) { - System.out.println("[TestMemoryMapping] testing copy via iterators using RoaringBitmap copy " - + k + " out of " + ms); + System.out.println( + "[TestMemoryMapping] testing copy via iterators using RoaringBitmap copy " + + k + + " out of " + + ms); final RoaringBitmap target = mappedbitmaps.get(k).toRoaringBitmap(); final int truecard = target.getCardinality(); System.out.println("Cardinality = " + truecard); @@ -577,8 +599,12 @@ public void testIterator() { long t4 = System.nanoTime(); System.out.println(" iterator two ns/ops = " + (t4 - t3) * 1.0 / truecard); assertEquals(truecard, card2); - System.out.println("[TestMemoryMapping] testing copy via iterators using RoaringBitmap copy " - + k + " out of " + ms + " ok"); + System.out.println( + "[TestMemoryMapping] testing copy via iterators using RoaringBitmap copy " + + k + + " out of " + + ms + + " ok"); } System.out.println("Next, we test mapped (ImmutableRoaringBitmap) iterators."); @@ -617,8 +643,8 @@ public void testIterator() { long t4 = System.nanoTime(); System.out.println(" iterator two ns/ops = " + (t4 - t3) * 1.0 / truecard); assertEquals(truecard, card2); - System.out - .println("[TestMemoryMapping] testing copy via iterators " + k + " out of " + ms + " ok"); + System.out.println( + "[TestMemoryMapping] testing copy via iterators " + k + " out of " + ms + " ok"); } System.out.println("[TestMemoryMapping] testing a custom iterator copy "); @@ -647,10 +673,18 @@ public void testIterator() { public void unions() { System.out.println("[TestMemoryMapping] testing Unions"); for (int k = 0; k < mappedbitmaps.size() - 4; k += 4) { - final MutableRoaringBitmap rb = BufferFastAggregation.or(mappedbitmaps.get(k), - mappedbitmaps.get(k + 1), mappedbitmaps.get(k + 3), mappedbitmaps.get(k + 4)); - final MutableRoaringBitmap rbram = BufferFastAggregation.or(rambitmaps.get(k), - rambitmaps.get(k + 1), rambitmaps.get(k + 3), rambitmaps.get(k + 4)); + final MutableRoaringBitmap rb = + BufferFastAggregation.or( + mappedbitmaps.get(k), + mappedbitmaps.get(k + 1), + mappedbitmaps.get(k + 3), + mappedbitmaps.get(k + 4)); + final MutableRoaringBitmap rbram = + BufferFastAggregation.or( + rambitmaps.get(k), + rambitmaps.get(k + 1), + rambitmaps.get(k + 3), + rambitmaps.get(k + 4)); assertTrue(rb.equals(rbram)); } } @@ -659,10 +693,18 @@ public void unions() { public void XORs() { System.out.println("[TestMemoryMapping] testing XORs"); for (int k = 0; k < mappedbitmaps.size() - 4; k += 4) { - final MutableRoaringBitmap rb = BufferFastAggregation.xor(mappedbitmaps.get(k), - mappedbitmaps.get(k + 1), mappedbitmaps.get(k + 3), mappedbitmaps.get(k + 4)); - final MutableRoaringBitmap rbram = BufferFastAggregation.xor(rambitmaps.get(k), - rambitmaps.get(k + 1), rambitmaps.get(k + 3), rambitmaps.get(k + 4)); + final MutableRoaringBitmap rb = + BufferFastAggregation.xor( + mappedbitmaps.get(k), + mappedbitmaps.get(k + 1), + mappedbitmaps.get(k + 3), + mappedbitmaps.get(k + 4)); + final MutableRoaringBitmap rbram = + BufferFastAggregation.xor( + rambitmaps.get(k), + rambitmaps.get(k + 1), + rambitmaps.get(k + 3), + rambitmaps.get(k + 4)); assertTrue(rb.equals(rbram)); } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java index b606d97a0..054b40060 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRange.java @@ -1,14 +1,16 @@ package org.roaringbitmap.buffer; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.roaringbitmap.IntIterator; +import org.junit.jupiter.api.Test; + import java.util.BitSet; import java.util.Random; -import static org.junit.jupiter.api.Assertions.*; - - public class TestRange { @Test public void flip64() { @@ -22,20 +24,20 @@ public void flip64() { } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedMemberFlip() { MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); rb1.flip(300000, 500000); MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); rb2.flip(300000L, 500000L); assertEquals(rb1, rb2); - rb1.flip(Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2.flip(Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1.flip(Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2.flip(Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } - private static int fillWithRandomBits(final MutableRoaringBitmap bitmap, final BitSet bitset, - final int bits) { + private static int fillWithRandomBits( + final MutableRoaringBitmap bitmap, final BitSet bitset, final int bits) { int added = 0; Random r = new Random(1011); for (int j = 0; j < bits; j++) { @@ -78,7 +80,7 @@ public void rangeAddRemoveBig() { } rbinplace.add(start, end); rbstatic = MutableRoaringBitmap.add(rbstatic, start, end); - bs.set((int)start, (int)end); + bs.set((int) start, (int) end); // start = r.nextInt(65536 * 20); @@ -102,7 +104,7 @@ public void rangeAddRemoveBig() { } rbinplace.add(start, end); rbstatic = MutableRoaringBitmap.add(rbstatic, start, end); - bs.set((int)start, (int)end); + bs.set((int) start, (int) end); // start = r.nextInt(65536 * 20); @@ -114,7 +116,7 @@ public void rangeAddRemoveBig() { } rbinplace.add(start, end); rbstatic = MutableRoaringBitmap.add(rbstatic, start, end); - bs.set((int)start, (int)end); + bs.set((int) start, (int) end); // start = r.nextInt(20) * 65536; end = r.nextInt(65536 * 20); @@ -125,7 +127,7 @@ public void rangeAddRemoveBig() { } rbinplace.remove(start, end); rbstatic = MutableRoaringBitmap.remove(rbstatic, start, end); - bs.clear((int)start, (int)end); + bs.clear((int) start, (int) end); // start = r.nextInt(65536 * 20); @@ -137,7 +139,7 @@ public void rangeAddRemoveBig() { } rbinplace.remove(start, end); rbstatic = MutableRoaringBitmap.remove(rbstatic, start, end); - bs.clear((int)start, (int)end); + bs.clear((int) start, (int) end); } assertTrue(TestRoaringBitmap.equals(bs, rbstatic)); assertTrue(TestRoaringBitmap.equals(bs, rbinplace)); @@ -198,8 +200,6 @@ public void setTest1A() { assertTrue(TestRoaringBitmap.equals(bs, rb1)); } - - @Test public void setTest2() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -227,7 +227,6 @@ public void setTest2A() { assertTrue(TestRoaringBitmap.equals(bs, rb)); } - @Test public void setTest3() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -245,7 +244,6 @@ public void setTest3() { assertTrue(TestRoaringBitmap.equals(bs, rb)); } - @Test public void setTest3A() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -265,7 +263,6 @@ public void setTest3A() { assertTrue(TestRoaringBitmap.equals(bs, rb2)); } - @Test public void setTest4() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -440,7 +437,6 @@ public void setTest7A() { assertEquals(rb2, rb3); assertTrue(TestRoaringBitmap.equals(bs, rb3)); - rb3 = MutableRoaringBitmap.add(rb3, 65536 * 3 + 195L, 65536 * 3 + 245); bs.set(65536 * 3 + 195, 65536 * 3 + 245); rb2.add(65536L * 3 + 195, 65536L * 3 + 245); @@ -453,7 +449,6 @@ public void setTest7A() { // now removing - rb3 = MutableRoaringBitmap.remove(rb3, 65536L * 3 + 195, 65536L * 3 + 245); bs.clear(65536 * 3 + 195, 65536 * 3 + 245); rb2.remove(65536L * 3 + 195, 65536L * 3 + 245); @@ -475,14 +470,11 @@ public void setTest7A() { assertEquals(rb2, rb3); assertTrue(TestRoaringBitmap.equals(bs, rb3)); - rb2 = MutableRoaringBitmap.remove(rb1, 130L, 185L); bs.clear(130, 185); rb.remove(130L, 185L); assertEquals(rb2, rb); assertTrue(TestRoaringBitmap.equals(bs, rb2)); - - } @Test @@ -598,7 +590,7 @@ public void testClearRanges() { public void testFlipRanges() { int N = 256; for (long end = 1; end < N; ++end) { - for (long start = 0; start < end; ++start) { + for (long start = 0; start < end; ++start) { MutableRoaringBitmap bs1 = new MutableRoaringBitmap(); for (int k = (int) start; k < end; ++k) { bs1.flip(k); @@ -690,7 +682,7 @@ private void testRangeRemovalWithRandomBits(boolean withRunCompression) { } // clear and check bitmap, if really empty - bitmap.remove(0L, (long) bits); + bitmap.remove(0L, (long) bits); assertEquals(0, bitmap.getCardinality(), "fails with bits: " + bitset); assertTrue(bitmap.isEmpty()); @@ -719,7 +711,7 @@ public void testSetRanges() { for (long end = 1; end < N; ++end) { for (long start = 0; start < end; ++start) { MutableRoaringBitmap bs1 = new MutableRoaringBitmap(); - for (int k = (int)start; k < end; ++k) { + for (int k = (int) start; k < end; ++k) { bs1.add(k); } MutableRoaringBitmap bs2 = new MutableRoaringBitmap(); @@ -747,7 +739,6 @@ public void testStaticClearRanges() { } } - @Test public void testStaticSetRanges() { int N = 256; @@ -765,91 +756,88 @@ public void testStaticSetRanges() { } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedStaticAdd() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap.add(rb1, 300000, 500000); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - MutableRoaringBitmap.add(rb2,300000L, 500000L); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap.add(rb1, 300000, 500000); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap.add(rb2, 300000L, 500000L); assertEquals(rb1, rb2); - MutableRoaringBitmap.add( rb1, Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - MutableRoaringBitmap.add( rb2, Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + MutableRoaringBitmap.add(rb1, Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + MutableRoaringBitmap.add(rb2, Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedStaticFlip() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap.flip(rb1, 300000, 500000); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - MutableRoaringBitmap.flip(rb2,300000L, 500000L); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap.flip(rb1, 300000, 500000); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap.flip(rb2, 300000L, 500000L); assertEquals(rb1, rb2); - MutableRoaringBitmap.flip( rb1, Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - MutableRoaringBitmap.flip( rb2, Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + MutableRoaringBitmap.flip(rb1, Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + MutableRoaringBitmap.flip(rb2, Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedStaticRemove() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - MutableRoaringBitmap.add(rb1,200000L, 400000L); - MutableRoaringBitmap.remove(rb1, 300000, 500000); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - MutableRoaringBitmap.add(rb2,200000L, 400000L); - MutableRoaringBitmap.remove(rb2,300000L, 500000L); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + MutableRoaringBitmap.add(rb1, 200000L, 400000L); + MutableRoaringBitmap.remove(rb1, 300000, 500000); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + MutableRoaringBitmap.add(rb2, 200000L, 400000L); + MutableRoaringBitmap.remove(rb2, 300000L, 500000L); assertEquals(rb1, rb2); - MutableRoaringBitmap.add( rb1, Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - MutableRoaringBitmap.add( rb2, Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - MutableRoaringBitmap.remove( rb1, Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - MutableRoaringBitmap.remove( rb2, Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + MutableRoaringBitmap.add(rb1, Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + MutableRoaringBitmap.add(rb2, Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + MutableRoaringBitmap.remove(rb1, Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + MutableRoaringBitmap.remove(rb2, Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedAdd() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - rb1.add(300000, 500000); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(300000L, 500000L); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + rb1.add(300000, 500000); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add(300000L, 500000L); assertEquals(rb1, rb2); - rb1.add( Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2.add( Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1.add(Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2.add(Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } - @Test - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public void testDeprecatedRemove() { - MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - rb1.add(200000L, 400000L); - rb1.remove(300000, 500000); - MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(200000L, 400000L); - rb2.remove(300000L, 500000L); + MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); + rb1.add(200000L, 400000L); + rb1.remove(300000, 500000); + MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); + rb2.add(200000L, 400000L); + rb2.remove(300000L, 500000L); assertEquals(rb1, rb2); - rb1.add(Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - rb2.add(Integer.MAX_VALUE+200000L, Integer.MAX_VALUE+400000L); - rb1.remove(Integer.MAX_VALUE+300000, Integer.MAX_VALUE+500000); - rb2.remove(Integer.MAX_VALUE+300000L, Integer.MAX_VALUE+500000L); + rb1.add(Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + rb2.add(Integer.MAX_VALUE + 200000L, Integer.MAX_VALUE + 400000L); + rb1.remove(Integer.MAX_VALUE + 300000, Integer.MAX_VALUE + 500000); + rb2.remove(Integer.MAX_VALUE + 300000L, Integer.MAX_VALUE + 500000L); assertEquals(rb1, rb2); } @Test public void regressionTestIssue588() { // see https://github.com/RoaringBitmap/RoaringBitmap/issues/588 - int valueInBitmap = 27470832; - int baseValue = 27597418; - int minValueThatWorks = 27459584; - ImmutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(valueInBitmap); - assertTrue(bitmap.intersects(minValueThatWorks, baseValue)); - assertTrue(bitmap.intersects(minValueThatWorks-1, baseValue)); + int valueInBitmap = 27470832; + int baseValue = 27597418; + int minValueThatWorks = 27459584; + ImmutableRoaringBitmap bitmap = MutableRoaringBitmap.bitmapOf(valueInBitmap); + assertTrue(bitmap.intersects(minValueThatWorks, baseValue)); + assertTrue(bitmap.intersects(minValueThatWorks - 1, baseValue)); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java index ea5949550..33bc432f3 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestReverseMappeableRunContainer.java @@ -1,66 +1,67 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.roaringbitmap.CharIterator; + import com.google.common.primitives.Ints; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.CharIterator; import java.util.Arrays; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - @Execution(ExecutionMode.CONCURRENT) public class TestReverseMappeableRunContainer { - private static List asList(CharIterator ints) { - int[] values = new int[10]; - int size = 0; - while (ints.hasNext()) { - if (!(size < values.length)) { - values = Arrays.copyOf(values, values.length * 2); - } - values[size++] = ints.next(); - } - return Ints.asList(Arrays.copyOf(values, size)); + private static List asList(CharIterator ints) { + int[] values = new int[10]; + int size = 0; + while (ints.hasNext()) { + if (!(size < values.length)) { + values = Arrays.copyOf(values, values.length * 2); + } + values[size++] = ints.next(); } + return Ints.asList(Arrays.copyOf(values, size)); + } - @Test - public void testClone() { - MappeableRunContainer mappeableRunContainer = new MappeableRunContainer(); - for (char i = 10; i < 20; ++i) { - mappeableRunContainer.add(i); - } - ReverseMappeableRunContainerCharIterator rmr = new ReverseMappeableRunContainerCharIterator(mappeableRunContainer); - CharIterator rmrClone = rmr.clone(); - final List rmrList = asList(rmr); - assertNotNull(rmrClone); - final List rmrCloneList = asList(rmrClone); - assertEquals(rmrList, rmrCloneList); + @Test + public void testClone() { + MappeableRunContainer mappeableRunContainer = new MappeableRunContainer(); + for (char i = 10; i < 20; ++i) { + mappeableRunContainer.add(i); } + ReverseMappeableRunContainerCharIterator rmr = + new ReverseMappeableRunContainerCharIterator(mappeableRunContainer); + CharIterator rmrClone = rmr.clone(); + final List rmrList = asList(rmr); + assertNotNull(rmrClone); + final List rmrCloneList = asList(rmrClone); + assertEquals(rmrList, rmrCloneList); + } - @Test - public void testNextAsInt() { - MappeableRunContainer mappeableRunContainer = new MappeableRunContainer(); - for (char i = 10; i < 15; ++i) { - mappeableRunContainer.add(i); - } - ReverseMappeableRunContainerCharIterator rmr = new ReverseMappeableRunContainerCharIterator(mappeableRunContainer); - assertEquals(14, rmr.nextAsInt()); - rmr.next(); - rmr.next(); - rmr.next(); - rmr.next(); - rmr.next(); - rmr.nextAsInt(); - rmr.nextAsInt(); - rmr.nextAsInt(); - rmr.nextAsInt(); - rmr.nextAsInt(); - assertEquals(13, rmr.nextAsInt()); + @Test + public void testNextAsInt() { + MappeableRunContainer mappeableRunContainer = new MappeableRunContainer(); + for (char i = 10; i < 15; ++i) { + mappeableRunContainer.add(i); } + ReverseMappeableRunContainerCharIterator rmr = + new ReverseMappeableRunContainerCharIterator(mappeableRunContainer); + assertEquals(14, rmr.nextAsInt()); + rmr.next(); + rmr.next(); + rmr.next(); + rmr.next(); + rmr.next(); + rmr.nextAsInt(); + rmr.nextAsInt(); + rmr.nextAsInt(); + rmr.nextAsInt(); + rmr.nextAsInt(); + assertEquals(13, rmr.nextAsInt()); + } } - - diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java index 3c4c387bb..547d89144 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java @@ -4,21 +4,39 @@ package org.roaringbitmap.buffer; - +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.roaringbitmap.IntConsumer; +import org.roaringbitmap.IntIterator; +import org.roaringbitmap.PeekableIntIterator; +import org.roaringbitmap.RoaringBitmap; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.*; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; - +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Vector; /** * Generic testing of the roaring bitmaps @@ -28,28 +46,28 @@ public class TestRoaringBitmap { @Test public void testRangeCardinality() { - MutableRoaringBitmap r = new MutableRoaringBitmap(); - long Min = 0L; - long Max = 1000000L; - r.add(Min, Max); - for(long s = Min; s <= Max ; s+= 100 ) { - for(long e = s; e <= Max; e+= 100 ) { - assertEquals(e - s, r.rangeCardinality(s, e)); - } - } + MutableRoaringBitmap r = new MutableRoaringBitmap(); + long Min = 0L; + long Max = 1000000L; + r.add(Min, Max); + for (long s = Min; s <= Max; s += 100) { + for (long e = s; e <= Max; e += 100) { + assertEquals(e - s, r.rangeCardinality(s, e)); + } + } } @Test public void testRangeCardinality2() { - MutableRoaringBitmap r = new MutableRoaringBitmap(); - long Min = 1L << 16; - long Max = 1L << 18; - r.add(Min, Max); - for(long s = Min; s <= Max ; s+= 1024 ) { - for(long e = s; e <= Max; e+= 1024 ) { - assertEquals(e - s, r.rangeCardinality(s, e)); - } - } + MutableRoaringBitmap r = new MutableRoaringBitmap(); + long Min = 1L << 16; + long Max = 1L << 18; + r.add(Min, Max); + for (long s = Min; s <= Max; s += 1024) { + for (long e = s; e <= Max; e += 1024) { + assertEquals(e - s, r.rangeCardinality(s, e)); + } + } } @Test @@ -58,21 +76,19 @@ public void testMultipleAdd() { bitmap.add(1); bitmap.add(1, 2, 3); bitmap.add(0xFFFFFFFF); - bitmap.add(0xFFFFFFFEL,0xFFFFFFFFL); - assertEquals("{1,2,3,4294967294,4294967295}",bitmap.toString()); + bitmap.add(0xFFFFFFFEL, 0xFFFFFFFFL); + assertEquals("{1,2,3,4294967294,4294967295}", bitmap.toString()); } @Test public void binaryTest() throws IOException { Random rand = new Random(1234); rand.setSeed(11111); - for(int z = 0; z < 1000; ++z) { + for (int z = 0; z < 1000; ++z) { final MutableRoaringBitmap rr1 = new MutableRoaringBitmap(); - for(int k = 0; k < 100; k++) - rr1.add((rand.nextInt() & 0xFFFF) << 16); + for (int k = 0; k < 100; k++) rr1.add((rand.nextInt() & 0xFFFF) << 16); final MutableRoaringBitmap rr2 = new MutableRoaringBitmap(); - for(int k = 0; k < 100; k++) - rr2.add((rand.nextInt() & 0xFFFF) << 16); + for (int k = 0; k < 100; k++) rr2.add((rand.nextInt() & 0xFFFF) << 16); ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); DataOutputStream dos1 = new DataOutputStream(bos1); rr1.serialize(dos1); @@ -85,195 +101,197 @@ public void binaryTest() throws IOException { dos2.close(); ByteBuffer bb2 = ByteBuffer.wrap(bos2.toByteArray()); final ImmutableRoaringBitmap rrback2 = new ImmutableRoaringBitmap(bb2); - assertEquals(ImmutableRoaringBitmap.and(rrback1, rrback2), - MutableRoaringBitmap.and(rr1, rr2)); - assertEquals(ImmutableRoaringBitmap.and(rrback2, rrback1), - MutableRoaringBitmap.and(rr2, rr1)); - assertEquals(ImmutableRoaringBitmap.andNot(rrback1, rrback2), - MutableRoaringBitmap.andNot(rr1, rr2)); - assertEquals(ImmutableRoaringBitmap.andNot(rrback2, rrback1), - MutableRoaringBitmap.andNot(rr2, rr1)); - assertEquals(ImmutableRoaringBitmap.xor(rrback1, rrback2), - MutableRoaringBitmap.xor(rr1, rr2)); - assertEquals(ImmutableRoaringBitmap.xor(rrback2, rrback1), - MutableRoaringBitmap.xor(rr2, rr1)); - assertEquals(ImmutableRoaringBitmap.or(rrback1, rrback2), - MutableRoaringBitmap.or(rr1, rr2)); - assertEquals(ImmutableRoaringBitmap.or(rrback2, rrback1), - MutableRoaringBitmap.or(rr2, rr1)); - } - } - - @Test - public void testStringer() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(1); - bitmap.add(2); - bitmap.add(3); - bitmap.add(0xFFFFFFFF); - assertEquals("{1,2,3,4294967295}",bitmap.toString()); - } - - @Test - public void report128() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(59798854); - bitmap.add(91274955); - bitmap.add(97569495); - bitmap.add(101993170); - PeekableIntIterator it = bitmap.getIntIterator(); - it.advanceIfNeeded(100620278); - assertTrue(it.hasNext()); - assertEquals(101993170, it.next()); - assertFalse(it.hasNext()); - } - - @Test - public void report128_fly() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(59798854); - bitmap.add(91274955); - bitmap.add(97569495); - bitmap.add(101993170); - BufferIntIteratorFlyweight it = new BufferIntIteratorFlyweight(); - it.wrap(bitmap); - it.advanceIfNeeded(100620278); - assertTrue(it.hasNext()); - assertEquals(101993170, it.next()); - assertFalse(it.hasNext()); - } - @Test - public void limitBug2() { - class MyConsumer implements IntConsumer { - public int count = 0; - @Override public void accept(int value) { count++; } - } - - MutableRoaringBitmap r = new MutableRoaringBitmap(); - int count = 0; - for (int i = 0; i < 500; i++) { - for (int j = 0; j < 9943; j++) { - if (i % 2 == 0) r.add(count); count++; - } - } - MutableRoaringBitmap limited = r.limit(1000000); - assertEquals(1000000,limited.getCardinality()); - MyConsumer c = new MyConsumer(); - limited.forEach(c); - assertEquals(1000000,c.count); - assertEquals(1000000,limited.toArray().length); - - } + assertEquals( + ImmutableRoaringBitmap.and(rrback1, rrback2), MutableRoaringBitmap.and(rr1, rr2)); + assertEquals( + ImmutableRoaringBitmap.and(rrback2, rrback1), MutableRoaringBitmap.and(rr2, rr1)); + assertEquals( + ImmutableRoaringBitmap.andNot(rrback1, rrback2), MutableRoaringBitmap.andNot(rr1, rr2)); + assertEquals( + ImmutableRoaringBitmap.andNot(rrback2, rrback1), MutableRoaringBitmap.andNot(rr2, rr1)); + assertEquals( + ImmutableRoaringBitmap.xor(rrback1, rrback2), MutableRoaringBitmap.xor(rr1, rr2)); + assertEquals( + ImmutableRoaringBitmap.xor(rrback2, rrback1), MutableRoaringBitmap.xor(rr2, rr1)); + assertEquals(ImmutableRoaringBitmap.or(rrback1, rrback2), MutableRoaringBitmap.or(rr1, rr2)); + assertEquals(ImmutableRoaringBitmap.or(rrback2, rrback1), MutableRoaringBitmap.or(rr2, rr1)); + } + } + + @Test + public void testStringer() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(1); + bitmap.add(2); + bitmap.add(3); + bitmap.add(0xFFFFFFFF); + assertEquals("{1,2,3,4294967295}", bitmap.toString()); + } + + @Test + public void report128() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(59798854); + bitmap.add(91274955); + bitmap.add(97569495); + bitmap.add(101993170); + PeekableIntIterator it = bitmap.getIntIterator(); + it.advanceIfNeeded(100620278); + assertTrue(it.hasNext()); + assertEquals(101993170, it.next()); + assertFalse(it.hasNext()); + } + + @Test + public void report128_fly() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(59798854); + bitmap.add(91274955); + bitmap.add(97569495); + bitmap.add(101993170); + BufferIntIteratorFlyweight it = new BufferIntIteratorFlyweight(); + it.wrap(bitmap); + it.advanceIfNeeded(100620278); + assertTrue(it.hasNext()); + assertEquals(101993170, it.next()); + assertFalse(it.hasNext()); + } + + @Test + public void limitBug2() { + class MyConsumer implements IntConsumer { + public int count = 0; + + @Override + public void accept(int value) { + count++; + } + } + + MutableRoaringBitmap r = new MutableRoaringBitmap(); + int count = 0; + for (int i = 0; i < 500; i++) { + for (int j = 0; j < 9943; j++) { + if (i % 2 == 0) r.add(count); + count++; + } + } + MutableRoaringBitmap limited = r.limit(1000000); + assertEquals(1000000, limited.getCardinality()); + MyConsumer c = new MyConsumer(); + limited.forEach(c); + assertEquals(1000000, c.count); + assertEquals(1000000, limited.toArray().length); + } @Test public void limitTest() { MutableRoaringBitmap r = new MutableRoaringBitmap(); r.add(0l, 10000000l); - assertEquals(1,r.limit(1).getCardinality()); - assertEquals(10,r.limit(10).getCardinality()); - assertEquals(100,r.limit(100).getCardinality()); - assertEquals(1000,r.limit(1000).getCardinality()); - assertEquals(10000,r.limit(10000).getCardinality()); - assertEquals(100000,r.limit(100000).getCardinality()); - assertEquals(1000000,r.limit(1000000).getCardinality()); + assertEquals(1, r.limit(1).getCardinality()); + assertEquals(10, r.limit(10).getCardinality()); + assertEquals(100, r.limit(100).getCardinality()); + assertEquals(1000, r.limit(1000).getCardinality()); + assertEquals(10000, r.limit(10000).getCardinality()); + assertEquals(100000, r.limit(100000).getCardinality()); + assertEquals(1000000, r.limit(1000000).getCardinality()); } @Test public void pointerContainerTest() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); - for (int i = 0; i < (1 << 16); i+=2) { + for (int i = 0; i < (1 << 16); i += 2) { rb.add(i); } - for (int i = (1 << 16); i < 2*((1 << 16)); i+= 512) { + for (int i = (1 << 16); i < 2 * ((1 << 16)); i += 512) { rb.add(i); } - for (int i = 2*(1 << 16); i < 3*((1 << 16)); i++) { + for (int i = 2 * (1 << 16); i < 3 * ((1 << 16)); i++) { rb.add(i); } rb.runOptimize(); MappeableContainerPointer cp = rb.getContainerPointer(); - MappeableContainerPointer cpo = (MappeableContainerPointer) cp.clone(); + MappeableContainerPointer cpo = (MappeableContainerPointer) cp.clone(); assertNotEquals(cp.getContainer(), null); assertNotEquals(cpo.getContainer(), null); - assertEquals(cp.compareTo(cpo),0); + assertEquals(cp.compareTo(cpo), 0); - assertEquals(cp.getCardinality(), (1<<16)/2); + assertEquals(cp.getCardinality(), (1 << 16) / 2); assertTrue(cp.isBitmapContainer()); assertFalse(cp.isRunContainer()); cp.advance(); - assertTrue(cp.compareTo(cpo)>0); + assertTrue(cp.compareTo(cpo) > 0); assertNotEquals(cp.getContainer(), null); - assertEquals(cp.getCardinality(), (1<<16)/512); + assertEquals(cp.getCardinality(), (1 << 16) / 512); assertFalse(cp.isBitmapContainer()); assertFalse(cp.isRunContainer()); cp.advance(); - assertTrue(cp.compareTo(cpo)>0); + assertTrue(cp.compareTo(cpo) > 0); assertNotEquals(cp.getContainer(), null); - assertEquals(cp.getCardinality(), (1<<16)); + assertEquals(cp.getCardinality(), (1 << 16)); assertFalse(cp.isBitmapContainer()); assertTrue(cp.isRunContainer()); cpo.advance(); - assertTrue(cp.compareTo(cpo)>0); + assertTrue(cp.compareTo(cpo) > 0); cpo.advance(); - assertTrue(cp.compareTo(cpo)==0); + assertTrue(cp.compareTo(cpo) == 0); cp.advance(); assertEquals(cp.getContainer(), null); - } + @Test public void pointerImmutableContainerTest() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); - for (int i = 0; i < (1 << 16); i+=2) { + for (int i = 0; i < (1 << 16); i += 2) { rb.add(i); } - for (int i = (1 << 16); i < 2*((1 << 16)); i+= 512) { + for (int i = (1 << 16); i < 2 * ((1 << 16)); i += 512) { rb.add(i); } - for (int i = 2*(1 << 16); i < 3*((1 << 16)); i++) { + for (int i = 2 * (1 << 16); i < 3 * ((1 << 16)); i++) { rb.add(i); } rb.runOptimize(); - ImmutableRoaringBitmap irb =toMapped(rb); + ImmutableRoaringBitmap irb = toMapped(rb); MappeableContainerPointer cp = irb.getContainerPointer(); - MappeableContainerPointer cpo = (MappeableContainerPointer) cp.clone(); + MappeableContainerPointer cpo = (MappeableContainerPointer) cp.clone(); assertNotEquals(cp.getContainer(), null); assertNotEquals(cpo.getContainer(), null); - assertEquals(cp.compareTo(cpo),0); + assertEquals(cp.compareTo(cpo), 0); - assertEquals(cp.getCardinality(), (1<<16)/2); + assertEquals(cp.getCardinality(), (1 << 16) / 2); assertTrue(cp.isBitmapContainer()); assertFalse(cp.isRunContainer()); cp.advance(); - assertTrue(cp.compareTo(cpo)>0); + assertTrue(cp.compareTo(cpo) > 0); assertNotEquals(cp.getContainer(), null); - assertEquals(cp.getCardinality(), (1<<16)/512); + assertEquals(cp.getCardinality(), (1 << 16) / 512); assertFalse(cp.isBitmapContainer()); assertFalse(cp.isRunContainer()); cp.advance(); - assertTrue(cp.compareTo(cpo)>0); + assertTrue(cp.compareTo(cpo) > 0); assertNotEquals(cp.getContainer(), null); - assertEquals(cp.getCardinality(), (1<<16)); + assertEquals(cp.getCardinality(), (1 << 16)); assertFalse(cp.isBitmapContainer()); assertTrue(cp.isRunContainer()); cpo.advance(); - assertTrue(cp.compareTo(cpo)>0); + assertTrue(cp.compareTo(cpo) > 0); cpo.advance(); - assertTrue(cp.compareTo(cpo)==0); + assertTrue(cp.compareTo(cpo) == 0); cp.advance(); assertEquals(cp.getContainer(), null); - } private static ImmutableRoaringBitmap toMapped(MutableRoaringBitmap r) { @@ -289,7 +307,6 @@ private static ImmutableRoaringBitmap toMapped(MutableRoaringBitmap r) { return new ImmutableRoaringBitmap(bb); } - @Test public void conversionTest() { RoaringBitmap rb = new RoaringBitmap(); @@ -308,25 +325,21 @@ public void conversionTest() { assertEquals(rb, rb2); ImmutableRoaringBitmap irb = toMapped(mrb); assertEquals(irb.toRoaringBitmap(), rb2); - } - @Test + @Test public void testFlipBigInts() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); for (int i = 0; i < 1 << 20; ++i) { - rb.flip((1<<31)+i); + rb.flip((1 << 31) + i); assertEquals(rb.getCardinality(), i + 1); } for (int i = (1 << 20) - 1; i >= 0; --i) { - rb.flip((1<<31)+i); + rb.flip((1 << 31) + i); assertEquals(rb.getCardinality(), i); } } - - - @Test public void testFlipOnEmpty() { MutableRoaringBitmap r1 = new MutableRoaringBitmap(); @@ -389,464 +402,468 @@ public void testAstesana() { @Test public void testOr001() { - int[] array1 = {22871, 22873, 22876, 22880, 22886, 22889, 22893, 22897, 22901, 22905, 22910, - 22915, 22919, 22927, 22934, 22940, 24750, 38579, 48470, 50533, 53256, 53717, 53752, 53802, - 53938, 54727, 54865, 55202, 55815, 55822, 55940, 56711, 56977, 57122, 59933, 60037, 60402, - 60520, 60853, 61163, 61340, 61549, 61632, 62097, 62373, 62961, 62993, 63031, 63075, 64209, - 64644, 64762, 64893, 64927, 64997, 65117, 65128, 65173, 65201, 65472, 65536, 65622, 66092, - 66162, 66302, 66381, 66551, 103979, 104644, 106866, 117285, 123372, 127548, 132167, 132168, - 136283, 136433, 137661, 138019, 138239, 138380, 138816, 138916, 138933, 139414, 140342, - 140914, 142751, 142994, 143895, 145081, 147331, 147686, 148021, 148375, 148587, 149114, - 149734, 152696, 153608, 154741, 154932, 155263, 157121, 158947, 159444, 161102, 161383, - 162735, 164298, 168043, 169398, 169536, 170419, 170846, 171153, 177016, 177471, 178305, - 178673, 183731, 183936, 184083, 184106, 185663, 188371, 189495, 189531, 196189, 198419, - 198758, 198796, 200645, 201137, 216865, 216936, 217770, 217810, 217836, 217909, 218569, - 218700, 218931, 219363, 220009, 225925, 234706, 241183, 241561, 242140, 242281, 245018, - 245056, 249935, 250442, 250615, 251696, 252825, 254178, 256788, 256906, 257289, 258833, - 260432, 260563, 260930, 262684, 262834, 263128, 265919, 268662, 269542, 270217, 271673, - 273776, 274560, 275649, 305458, 306241, 306550, 307580, 310891, 312701, 313514, 318134, - 319185, 320757, 321280, 322046, 322743, 323211, 324667, 325382, 326450, 327159, 328836, - 329075, 331179, 332836, 332997, 333071, 333205, 333488, 333595, 335045, 335803, 336417, - 336610, 338487, 339827, 339992, 346123, 348858, 351257, 351957, 353896, 354559, 357142, - 358253, 366662, 378768, 391984, 392282, 415077, 429446, 429449, 429452, 429453, 429476, - 429480, 429486, 429492, 429497, 429501, 429504, 429505, 429510, 429515, 429519, 429524, - 429530, 429533, 429541, 429546, 429553, 429554, 429564, 429572, 429577, 429579, 429586, - 429589, 429596, 429604, 429606, 429612, 429615, 429616, 429624, 429632, 429639, 429642, - 429646, 429651, 429656, 429664, 429670, 429674, 429678, 429681, 429686, 429695, 429701, - 429706, 429717, 429721, 429725, 429733, 429736, 429739, 429743, 429748, 429754, 429761, - 429767, 429772, 429780, 429791, 429792, 429793, 429794, 429795, 429817, 429822, 429823, - 429831, 429836, 429842, 429849, 429855, 429859, 429863, 429866, 429873, 429876, 429882, - 429885, 429900, 429903, 429913, 429921, 429923, 429927, 429932, 429939, 429947, 429950, - 429955, 429964, 429968, 429974, 429982, 429987, 429993, 429999, 430003, 430011, 430015, - 430023, 430028, 430033, 430039, 430044, 430048, 430053, 430057, 430059, 430063, 430068, - 430073, 430077, 430082, 430086, 430093, 430098, 430101, 430114, 430120, 430126, 430131, - 430135, 430139, 430144, 430149, 430155, 430157, 430167, 430175, 430181, 430186, 430194, - 430195, 430196, 430214, 430223, 430228, 430236, 430253, 430258, 430263, 430269, 430277, - 430284, 430288, 430293, 430297, 430303, 430309, 430316, 430321, 430332, 430338, 430343, - 430346, 430348, 430355, 430358, 430369, 430375, 430384, 430391, 430397, 430410, 430415, - 430420, 430424, 430430, 430435, 430437, 430445, 430449, 430461, 430467, 430473, 430482, - 430486, 430490, 430496, 430500, 430506, 430511, 430515, 430535, 430539, 430550, 430568, - 430575, 430581, 430588, 430591, 430596, 430605, 430612, 430617, 430625, 430629, 430633, - 430638, 430643, 430649, 430656, 430663, 430666, 430672, 430679, 430684, 430692, 430696, - 430700, 430707, 430716, 430723, 430728, 430733, 430745, 430751, 430755, 430759, 430767, - 430770, 430782, 430787, 430791, 430804, 430810, 430814, 430821, 430825, 430829, 430833, - 430838, 430844, 430849, 430852, 430859, 430864, 430867, 430870, 430877, 430881, 430887, - 430891, 430896, 430901, 430907, 430912, 430917, 430923, 430927, 430932, 430936, 430944, - 430947, 430953, 430959, 430967, 430971, 430979, 430985, 430989, 430993, 430997, 431003, - 431006, 431015, 431021, 431022, 431033, 431039, 431046, 431050, 431054, 431059, 431065, - 431069, 431074, 431081, 431085, 431092, 431097, 431104, 431110, 431120, 431125, 431133, - 431138, 431142, 431147, 431157, 431164, 431171, 431175, 431180, 431186, 431190, 431195, - 431207, 431213, 431218, 431220, 431224, 431228, 431233, 431235, 431240, 431245, 431251, - 431259, 431264, 431271, 431272, 431280, 431287, 431294, 431299, 431307, 431315, 431319, - 431324, 431330, 431334, 431339, 431345, 431352, 431356, 431363, 431375, 431379, 431383, - 431388, 431393, 431398, 431405, 431409, 431416, 431422, 431426, 431433, 431438, 431444, - 431451, 431455, 431464, 431469, 431472, 431477, 431483, 431490, 431496, 431506, 431513, - 431516, 431521, 431526, 431534, 431536, 431545, 431550, 431559, 431564, 431571, 431573, - 431579, 431584, 431587, 431592, 431604, 431614, 431624, 431629, 431634, 431638, 431645, - 431651, 431659, 431663, 431674, 431678, 431684, 431692, 431696, 431700, 431706, 431712, - 431719, 431723, 431729, 431736, 431741, 431747, 431755, 431758, 431762, 431767, 431777, - 431782, 431787, 431791, 431796, 431799, 431805, 431809, 431814, 431819, 431823, 431828, - 431832, 431838, 431842, 431849, 431853, 431858, 431862, 431866, 431869, 431874, 431881, - 431887, 431894, 431900, 431906, 431912, 431917, 431925, 431931, 431936, 431943, 431948, - 431956, 431958, 431964, 431971, 431976, 431981, 431988, 431994, 431998, 432008, 432012, - 432024, 432029, 432033, 432038, 432045, 432048, 432058, 432062, 432066, 432070, 432076, - 432077, 432087, 432093, 432098, 432104, 432114, 432123, 432128, 432133, 432139, 432145, - 432151, 432161, 432168, 432177, 432181, 432188, 432189, 432203, 432209, 432216, 432222, - 432227, 432232, 432242, 432247, 432256, 432259, 432264, 432269, 432271, 432277, 432286, - 432294, 432297, 432302, 432308, 432313, 432319, 432326, 432331, 432337, 432345, 432349, - 432353, 432356, 432361, 432366, 432370, 432378, 432384, 432390, 432391, 432397, 432400, - 432403, 432408, 432413, 432419, 432422, 432427, 432433, 432440, 432443, 432450, 432455, - 432460, 432466, 432467, 432481, 432489, 432493, 432498, 432504, 432511, 432513, 432517, - 432525, 432531, 432537, 432544, 432546, 432555, 432561, 432565, 432569, 432574, 432579, - 432586, 432590, 432597, 432605, 432611, 432619, 432626, 432630, 432637, 432644, 432646, - 432653, 432654, 432664, 432670, 432674, 432679, 432682, 432687, 432694, 432706, 432711, - 432714, 432721, 432726, 432732, 432741, 432747, 432753, 432755, 432761, 432764, 432768, - 432774, 432779, 432784, 432792, 432798, 432801, 432808, 432815, 432823, 432825, 432833, - 432838, 432842, 432847, 432853, 432861, 432866, 432873, 432879, 432889, 432895, 432901, - 432906, 432913, 432917, 432920, 432926, 432935, 432940, 432949, 432953, 432958, 432960, - 432966, 432967, 432968, 432969, 432970, 432971, 432972, 432996, 432999, 433004, 433010, - 433020, 433026, 433029, 433033, 433042, 433045, 433050, 433054, 433058, 433062, 433065, - 433070, 433076, 433086, 433095, 433101, 433102, 433116, 433122, 433129, 433132, 433140, - 433146, 433151, 433157, 433163, 433169, 433176, 433181, 433188, 433198, 433204, 433219, - 433229, 433236, 433240, 433246, 433250, 433259, 433263, 433274, 433277, 433282, 433286, - 433291, 433295, 433299, 433306, 433316, 433318, 433322, 433327, 433335, 433342, 433348, - 433351, 433359, 433362, 433367, 433371, 433377, 433384, 433393, 433398, 433403, 433407, - 433411, 433425, 433430, 433437, 433441, 433445, 433452, 433453, 433458, 433462, 433469, - 433473, 433478, 433484, 433490, 433495, 433501, 433506, 433514, 433517, 433521, 433527, - 433534, 433544, 433549, 433552, 433561, 433565, 433569, 433576, 433585, 433589, 433594, - 433597, 433600, 433603, 433606, 433613, 433619, 433623, 433627, 433639, 433643, 433648, - 433654, 433658, 433665, 433673, 433678, 433681, 433689, 433696, 433704, 433709, 433716, - 433721, 433725, 433729, 433734, 433738, 433744, 433749, 433755, 433760, 433766, 433771, - 433776, 433781, 433785, 433790, 433798, 433803, 433810, 433814, 433817, 433822, 433828, - 433833, 433837, 433843, 433849, 433852, 433858, 433863, 433871, 433875, 433881, 433883, - 433884, 433897, 433903, 433909, 433913, 433921, 433926, 433932, 433936, 433942, 433946, - 433951, 433959, 433965, 433976, 433981, 433989, 433996, 434004, 434011, 434013, 434019, - 434023, 434029, 434036, 434041, 434048, 434050, 434056, 434060, 434068, 434074, 434079, - 434085, 434091, 434096, 434100, 434105, 434110, 434119, 434123, 434129, 434133, 434139, - 434146, 434150, 434156, 434161, 434168, 434173, 434183, 434188, 434193, 434200, 434208, - 434213, 434219, 434223, 434229, 434235, 434241, 434247, 434258, 434262, 434269, 434275, - 434282, 434287, 434291, 434296, 434303, 434308, 434313, 434316, 434323, 434327, 434335, - 434342, 434349, 434353, 434360, 434366, 434372, 434373, 434381, 434387, 434392, 434397, - 434401, 434403, 434409, 434414, 434420, 434427, 434433, 434440, 434445, 434449, 434454, - 434460, 434467, 434473, 434479, 434481, 434490, 434494, 434501, 434505, 434510, 434517, - 434526, 434537, 434542, 434548, 434553, 434558, 434563, 434569, 434574, 434580, 434586, - 434588, 434595, 434603, 434606, 434617, 434620, 434626, 434630, 434638, 434644, 434647, - 434651, 434658, 434666, 434671, 434679, 434681, 434685, 434692, 434699, 434703, 434708, - 434713, 434720, 434723, 434729, 434734, 434738, 434742, 434746, 434753, 434762, 434766, - 434773, 434781, 434790, 434799, 434805, 434810, 434814, 434823, 434831, 434839, 434845, - 434850, 434856, 434859, 434863, 434869, 434870, 434882, 434890, 434896, 434899, 434906, - 434912, 434917, 434921, 434930, 434935, 434940, 434945, 434949, 434956, 434961, 434967, - 434977, 434982, 434987, 434992, 434995, 435002, 435005, 435009, 435016, 435021, 435025, - 435028, 435034, 435041, 435050, 435055, 435065, 435069, 435075, 435078, 435083, 435091, - 435097, 435102, 435105, 435107, 435113, 435118, 435124, 435131, 435141, 435144, 435150, - 435154, 435159, 435167, 435171, 435177, 435181, 435187, 435192, 435198, 435204, 435211, - 435212, 435221, 435228, 435231, 435237, 435244, 435246, 435254, 435258, 435264, 435275, - 435283, 435289, 435301, 435304, 435312, 435318, 435323, 435329, 435334, 435340, 435343, - 435347, 435351, 435358, 435363, 435368, 435375, 435382, 435388, 435391, 435396, 435399, - 435405, 435412, 435416, 435422, 435425, 435429, 435437, 435444, 435447, 435453, 435458, - 435470, 435477, 435486, 435491, 435497, 435500, 435511, 435516, 435520, 435526, 435533, - 435539, 435545, 435551, 435559, 435564, 435569, 435575, 435579, 435585, 435590, 435597, - 435599, 435600, 435610, 435616, 435618, 435623, 435628, 435636, 435643, 435649, 435654, - 435659, 435663, 435671, 435675, 435678, 435683, 435689, 435702, 435705, 435712, 435718, - 435749, 435755, 435759, 435764, 435771, 435775, 435780, 435785, 435791, 435794, 435802, - 435811, 435816, 435822, 435828, 435833, 435838, 435844, 435851, 435859, 435861, 435866, - 435869, 435876, 435882, 435890, 435897, 435900, 435908, 435913, 435923, 435929, 435934, - 435937, 435942, 435945, 435951, 435953, 435959, 435965, 435969, 435975, 435982, 435987, - 435992, 436000, 436008, 436013, 436017, 436022, 436027, 436033, 436038, 436043, 436048, - 436052, 436062, 436065, 436069, 436073, 436079, 436088, 436092, 436100, 436106, 436116, - 436123, 436127, 436133, 436139, 436147, 436153, 436159, 436165, 436172, 436179, 436184, - 436190, 436194, 436199, 436206, 436210, 436211, 436217, 436223, 436229, 436234, 436240, - 436245, 436253, 436258, 436262, 436268, 436273, 436282, 436287, 436294, 436303, 436306, - 436313, 436316, 436321, 436329, 436337, 436341, 436349, 436353, 436358, 436365, 436368, - 436373, 436378, 436387, 436391, 436396, 436401, 436408, 436412, 436420, 436423, 436428, - 436435, 436441, 436447, 436451, 436461, 436463, 436467, 436471, 436477, 436479, 436485, - 436489, 436494, 436502, 436509, 436512, 436518, 436529, 436538, 436543, 436552, 436553, - 436560, 436564, 436569, 436575, 436580, 436585, 436591, 436597, 436603, 436605, 436610, - 436616, 436619, 436628, 436633, 436637, 436640, 436644, 436649, 436653, 436659, 436666, - 436674, 436681, 436687, 436694, 436700, 436703, 436710, 436720, 436723, 436730, 436735, - 436742, 436748, 436756, 436761, 436766, 436772, 436778, 436783, 436787, 436792, 436799, - 436808, 436810, 436812, 436817, 436823, 436832, 436838, 436845, 436849, 436853, 436859, - 436865, 436872, 436878, 436882, 436885, 436891, 436898, 436903, 436910, 436911, 436922, - 436928, 436932, 436939, 436942, 436948, 436950, 436956, 436963, 436968, 436975, 436984, - 436988, 436994, 437003, 437009, 437013, 437020, 437023, 437028, 437033, 437043, 437053, - 437058, 437063, 437073, 437076, 437079, 437089, 437093, 437095, 437101, 437111, 437119, - 437121, 437127, 437135, 437140, 437147, 437151, 437155, 437160, 437165, 437171, 437173, - 437180, 437186, 437194, 437199, 437205, 437213, 437217, 437223, 437227, 437231, 437243, - 437250, 437256, 437261, 437267, 437271, 437277, 437284, 437289, 437295, 437300, 437304, - 437312, 437322, 437326, 437333, 437338, 437354, 437357, 437362, 437366, 437370, 437374, - 437380, 437386, 437391, 437395, 437399, 437404, 437412, 437416, 437419, 437427, 437432, - 437433, 437451, 437456, 437461, 437467, 437468, 437477, 437485, 437492, 437495, 437501, - 437502, 437506, 437513, 437524, 437526, 437539, 437544, 437552, 437558, 437562, 437568, - 437573, 437578, 437587, 437592, 437596, 437600, 437605, 437610, 437619, 437625, 437630, - 437631, 437639, 437647, 437648, 437655, 437661, 437667, 437672, 437676, 437680, 437687, - 437689, 437693, 437697, 437704, 437707, 437716, 437723, 437730, 437737, 437740, 437741, - 437757, 437763, 437771, 437778, 437784, 437789, 437793, 437800, 437804, 437811, 437812, - 437819, 437823, 437827, 437833, 437841, 437844, 437853, 437857, 437861, 437866, 437874, - 437881, 437886, 437892, 437901, 437902, 437909, 437914, 437922, 437928, 437934, 437939, - 437948, 437951, 437957, 437963, 437965, 437971, 437980, 437985, 437990, 437996, 438002, - 438008, 438013, 438017, 438025, 438030, 438036, 438041, 438052, 438060, 438065, 438072, - 438073, 438079, 438084, 438091, 438097, 438099, 438107, 438111, 438119, 438125, 438136, - 438144, 438148, 438153, 438158, 438164, 438166, 438173, 438176, 438183, 438184, 438192, - 438198, 438204, 438209, 438216, 438228, 438231, 438237, 438243, 438248, 438257, 438267, - 438269, 438274, 438282, 438287, 438295, 438301, 438306, 438313, 438318, 438323, 438328, - 438335, 438339, 438346, 438352, 438357, 438363, 438370, 438374, 438380, 438384, 438388, - 438394, 438399, 438404, 438409, 438413, 438422, 438428, 438436, 438439, 438444, 438453, - 438461, 438471, 438477, 438483, 438491, 438503, 438505, 438511, 438518, 438527, 438531, - 438541, 438546, 438552, 438556, 438562, 438566, 438570, 438580, 438585, 438593, 438595, - 438603, 438605, 438607, 438614, 438619, 438626, 438631, 438634, 438641, 438646, 438652, - 438657, 438663, 438664, 438665, 438673, 438677, 438682, 438692, 438700, 438706, 438708, - 438715, 438723, 438727, 438737, 438742, 438753, 438760, 438764, 438771, 438775, 438780, - 438783, 438789, 438797, 438806, 438810, 438815, 438832, 438837, 438841, 438845, 438852, - 438860, 438865, 438873, 438883, 438884, 438896, 438908, 438912, 438920, 438924, 438927, - 438934, 438936, 438940, 438946, 438953, 438961, 438968, 438976, 438980, 438985, 438994, - 439006, 439011, 439017, 439021, 439027, 439032, 439036, 439043, 439047, 439055, 439059, - 439065, 439070, 439075, 439083, 439087, 439093, 439099, 439104, 439109, 439114, 439120, - 439123, 439128, 439130, 439134, 439139, 439147, 439157, 439162, 439167, 439172, 439178, - 439183, 439187, 439194, 439201, 439205, 439210, 439216, 439222, 439225, 439231, 439235, - 439245, 439251, 439255, 439261, 439277, 439282, 439288, 439295, 439302, 439308, 439309, - 439314, 439320, 439328, 439332, 439339, 439345, 439350, 439354, 439359, 439365, 439372, - 439377, 439379, 439386, 439391, 439404, 439410, 439416, 439419, 439425, 439430, 439434, - 439438, 439455, 439461, 439465, 439472, 439476, 439482, 439488, 439493, 439496, 439506, - 439510, 439516, 439521, 439527, 439536, 439543, 439551, 439554, 439557, 439564, 439569, - 439574, 439577, 439584, 439588, 439593, 439597, 439602, 439607, 439613, 439618, 439624, - 439625, 439633, 439638, 439641, 439645, 439650, 439655, 439659, 439669, 439670, 439671, - 439682, 439692, 439696, 439701, 439709, 439718, 439725, 439730, 439733, 439739, 439745, - 439757, 439764, 439768, 439771, 439778, 439783, 439788, 439796, 439805, 439811, 439815, - 439820, 439827, 439830, 439840, 439846, 439850, 439854, 439865, 439873, 439879, 439886, - 439891, 439898, 439903, 439909, 439917, 439925, 439928, 439933, 439938, 439944, 439948, - 439955, 439959, 439965, 439969, 439974, 439988, 439989, 440005, 440008, 440011, 440015, - 440020, 440026, 440030, 440035, 440043, 440044, 440055, 440060, 440078, 440091, 440096, - 440101, 440106, 440111, 440116, 440120, 440134, 440139, 440143, 440149, 440157, 440163, - 440167, 440171, 440179, 440187, 440191, 440196, 440201, 440207, 440213, 440218, 440223, - 440228, 440233, 440239, 440244, 440249, 440256, 440262, 440268, 440274, 440277, 440282, - 440289, 440295, 440307, 440311, 440315, 440321, 440327, 440331, 440336, 440341, 440346, - 440355, 440361, 440368, 440375, 440379, 440388, 440394, 440399, 440402, 440410, 440413, - 440421, 440427, 440431, 440435, 440440, 440446, 440454, 440461, 440467, 440476, 440481, - 440486, 440490, 440495, 440500, 440506, 440512, 440523, 440529, 440533, 440539, 440546, - 440552, 440560, 440568, 440578, 440584, 440590, 440594, 440598, 440606, 440612, 440620, - 440623, 440629, 440634, 440641, 440647, 440651, 440655, 440663, 440669, 440674, 440682, - 440689, 440694, 440698, 440702, 440706, 440713, 440719, 440727, 440733, 440737, 440743, - 440747, 440753, 440760, 440767, 440772, 440779, 440783, 440789, 440792, 440798, 440806, - 440808, 440812, 440819, 440823, 440826, 440830, 440835, 440840, 440845, 440853, 440856, - 440861, 440867, 440872, 440876, 440882, 440888, 440893, 440903, 440910, 440915, 440921, - 440927, 440933, 440938, 440945, 440950, 440958, 440966, 440969, 440973, 440977, 440983, - 440987, 440992, 440996, 441005, 441008, 441013, 441028, 441035, 441042, 441047, 441052, - 441056, 441061, 441068, 441075, 441080, 441087, 441094, 441097, 441106, 441111, 441115, - 441121, 441125, 441132, 441136, 441143, 441150, 441157, 441161, 441167, 441171, 441175, - 441179, 441185, 441193, 441196, 441200, 441204, 441210, 441216, 441223, 441226, 441234, - 441238, 441243, 441253, 441260, 441268, 441276, 441287, 441294, 441297, 441306, 441313, - 441315, 441323, 441332, 441339, 441346, 441353, 441358, 441362, 441368, 441373, 441378, - 441382, 441390, 441394, 441399, 441404, 441411, 441416, 441420, 441427, 441432, 441440, - 441445, 441448, 441453, 441456, 441461, 441467, 441473, 441479, 441484, 441491, 441497, - 441506, 441509, 441515, 441521, 441526, 441531, 441535, 441542, 441547, 441551, 441555, - 441559, 441565, 441569, 441574, 441579, 441596, 441599, 441605, 441610, 441617, 441619, - 441623, 441628, 441630, 441636, 441637, 441651, 441652, 441662, 441664, 441667, 441671, - 441681, 441684, 441689, 441693, 441701, 441705, 441710, 441718, 441720, 441726, 441740, - 441746, 441757, 441759, 441766, 441773, 441775, 441780, 441793, 441794, 441799, 441807, - 441817, 441822, 441828, 441831, 441834, 441838, 441845, 441853, 441857, 441863, 441866, - 441872, 441880, 441883, 441886, 441891, 441895, 441900, 441910, 441915, 441921, 441928, - 441934, 441939, 441945, 441947, 441952, 441957, 441964, 441971, 441974, 441980, 441985, - 441990, 441994, 441998, 442002, 442007, 442010, 442017, 442019, 442027, 442043, 442046, - 442054, 442060, 442067, 442074, 442076, 442081, 442086, 442093, 442099, 442103, 442108, - 442112, 442120, 442131, 442135, 442139, 442144, 442148, 442156, 442161, 442165, 442170, - 442181, 442186, 442192, 442197, 442203, 442220, 442226, 442233, 442239, 442245, 442249, - 442254, 442259, 442267, 442275, 442281, 442284, 442287, 442292, 442299, 442308, 442314, - 442318, 442325, 442332, 442333, 442334, 442346, 442351, 442354, 442358, 442364, 442370, - 442372, 442377, 442381, 442389, 442397, 442402, 442409, 442415, 442419, 442424, 442430, - 442438, 442443, 442451, 442459, 442470, 442473, 442482, 442490, 442496, 442501, 442506, - 442514, 442520, 442524, 442530, 442534, 442541, 442546, 442549, 442554, 442558, 442563, - 442573, 442586, 442591, 442595, 442600, 442607, 442613, 442618, 442624, 442628, 442632, - 442640, 442647, 442651, 442657, 442666, 442674, 442679, 442682, 442686, 442692, 442699, - 442705, 442714, 442718, 442722, 442729, 442734, 442739, 442748, 442751, 442754, 442757, - 442765, 442770, 442778, 442783, 442792, 442798, 442802, 442813, 442820, 442829, 442833, - 442841, 442845, 442851, 442857, 442860, 442865, 442871, 442877, 442882, 442886, 442892, - 442898, 442904, 442906, 442911, 442915, 442922, 442929, 442934, 442940, 442944, 442946, - 442952, 442956, 442963, 442971, 442973, 442979, 442985, 442997, 443001, 443006, 443017, - 443019, 443024, 443027, 443036, 443046, 443050, 443057, 443066, 443069, 443078, 443083, - 443089, 443093, 443100, 443104, 443109, 443118, 443126, 443134, 443141, 443146, 443151, - 443158, 443164, 443169, 443174, 443179, 443182, 443189, 443195, 443198, 443206, 443211, - 443213, 443214, 443222, 443224, 443228, 443235, 443240, 443246, 443255, 443259, 443269, - 443270, 443277, 443285, 443291, 443299, 443303, 443311, 443313, 443319, 443322, 443328, - 443338, 443342, 443350, 443351, 443356, 443362, 443365, 443368, 443371, 443375, 443378, - 443384, 443388, 443391, 443397, 443404, 443412, 443416, 443421, 443424, 443428, 443433, - 443438, 443442, 443449, 443462, 443463, 443470, 443474, 443482, 443490, 443495, 443499, - 443506, 443519, 443523, 443527, 443533, 443540, 443548, 443550, 443556, 443559, 443564, - 443568, 443574, 443582, 443589, 443594, 443596, 443602, 443610, 443612, 443616, 443620, - 443625, 443631, 443638, 443643, 443649, 443656, 443660, 443669, 443672, 443680, 443691, - 443695, 443699, 443706, 443710, 443714, 443718, 443721, 443726, 443734, 443739, 443745, - 443752, 443758, 443765, 443771, 443774, 443781, 443786, 443789, 443793, 443797, 443802, - 443811, 443812, 443820, 443829, 443832, 443838, 443847, 443851, 443856, 443857, 443864, - 443871, 443877, 443886, 443892, 443896, 443903, 443909, 443913, 443920, 443925, 443930, - 443935, 443942, 443946, 443954, 443963, 443966, 443969, 443975, 443979, 443982, 443988, - 443996, 443999, 444003, 444007, 444012, 444019, 444026, 444030, 444040, 444049, 444056, - 444060, 444064, 444069, 444073, 444075, 444078, 444083, 444091, 444098, 444103, 444111, - 444121, 444124, 444130, 444136, 444140, 444145, 444150, 444156, 444162, 444168, 444172, - 444179, 444182, 444186, 444189, 444193, 444198, 444203, 444208, 444212, 444218, 444225, - 444231, 444234, 444240, 444246, 444258, 444265, 444273, 444277, 444281, 444288, 444292, - 444298, 444301, 444309, 444314, 444319, 444327, 444332, 444338, 444349, 444354, 444359, - 444364, 444374, 444377, 444381, 444386, 444388, 444394, 444401, 444406, 444417, 444422, - 444429, 444438, 444439, 444448, 444449, 444456, 444461, 444467, 444473, 444480, 444486, - 444490, 444495, 444500, 444503, 444508, 444514, 444518, 444525, 444528, 444535, 444540, - 444544, 444550, 444556, 444563, 444570, 444576, 444580, 444583, 444587, 444591, 444599, - 444605, 444608, 444612, 444619, 444629, 444635, 444643, 444646, 444652, 444660, 444671, - 444676, 444681, 444686, 444690, 444696, 444703, 444710, 444711, 444720, 444723, 444734, - 444742, 444752, 444758, 444763, 444767, 444770, 444774, 444786, 444789, 444794, 444800, - 444809, 444818, 444822, 444830, 444836, 444841, 444846, 444853, 444859, 444866, 444873, - 444878, 444885, 444890, 444896, 444904, 444907, 444914, 444922, 444924, 444931, 446357, - 488475, 495304, 496119, 497438, 498593, 498603, 498917, 499048, 499713, 500776, 501348, - 503424, 508844, 518359, 519305, 519446, 523627, 523776, 523878, 523902, 524135, 524329, - 524515, 524611, 524686, 524798, 524852, 525209, 525700, 525913, 525954, 526158, 526332, - 526356, 536810, 537279, 563933, 578719, 579248, 579791, 584191, 591485, 592871, 613176, - 615012, 616428, 619153, 636103, 640708, 643141, 645080, 646349, 647043, 649345, 651085, - 652849, 653092, 653169, 653227, 653586, 655241, 656093, 658355, 658564, 659381, 659518, - 690513, 693218, 693746, 694340, 694842, 695155, 695563, 695776, 696380, 697608, 697797, - 698222, 698835, 699307, 700154, 700203, 700235, 700404, 700806, 700900, 701796, 702155, - 702956, 702998, 705105, 705377, 705631, 708650, 709265, 709787, 725122, 735376, 737115, - 737174, 738005, 741377, 741986, 746045, 746404, 746590, 748212, 753574, 754379, 764728, - 765776, 766863, 769126, 782626, 782723, 783529, 786875, 787544, 807281, 811132, 821933, - 822194, 829768, 830997, 831095, 832481, 834082, 844664, 845574, 845764, 846820, 849481, - 855607, 857775, 872350, 876126, 902029, 903509, 904449, 904469, 905915, 910463, 911856, - 924365, 928664, 929314, 929606, 929983, 930478, 933195, 933819, 935628, 935911, 935922, - 936002, 937668, 941895, 942677, 943721, 944661, 944980, 945121, 945268, 945360, 950756, - 951007, 959993, 960787, 961048, 961084, 961238, 961589, 962000, 962797, 962827, 962910, - 963788, 964272, 964343, 964431, 964573, 964949, 965017, 965036, 965041, 965598, 965674, - 965957, 966014, 966032, 966092, 966144, 966226, 966234, 966265, 966291, 978103, 980858, - 987212, 987458, 987498, 988368, 988513, 988939, 990571, 993183, 1005493, 1007972, 1008230, - 1009675, 1010075, 1010685, 1011441, 1011828, 1012269, 1012310, 1013612, 1013907, 1014379, - 1018659, 1018923, 1022035, 1024567, 1024568, 1025024, 1026699, 1027212, 1027840, 1029108, - 1031846, 1032670, 1032970, 1034016, 1039255, 1040626, 1040796, 1043457, 1043632, 1051053, - 1052581, 1091611, 1092316, 1092564, 1092634, 1096386, 1096820, 1098606, 1104201, 1107101, - 1110019, 1111384, 1111707, 1128990, 1129111, 1129147, 1129160, 1129367, 1129408, 1129508, - 1129577, 1129699, 1129750, 1129840, 1129951, 1129988, 1130041, 1130139, 1130177, 1130241, - 1130248, 1130268, 1130276, 1130367, 1130540, 1130562, 1130636, 1130637, 1130662, 1130716, - 1131139, 1131218, 1131250, 1131454, 1131541, 1131775, 1132208, 1132280, 1132901, 1133264, - 1133474, 1133475, 1133764, 1133841, 1133988, 1134290, 1134533, 1134553, 1134614, 1134667, - 1134710, 1134861, 1134896, 1135008, 1135178, 1135544, 1135551, 1135573, 1136260, 1136385, - 1136458, 1136782, 1136960, 1137342, 1137713, 1137824, 1138160, 1138291, 1138340, 1138457, - 1138468, 1138516, 1138526, 1138610, 1138648, 1138700, 1138801, 1138869, 1138999, 1139010, - 1139102, 1139114, 1139145, 1139302, 1139322, 1139417, 1139496, 1139581, 1139668, 1139852, - 1139930, 1139958, 1140325, 1140616, 1140811, 1140861, 1141056, 1141197, 1141311, 1141346, - 1141551, 1141666, 1141735, 1141786, 1141895, 1142017, 1142228, 1142242, 1142415, 1142484, - 1142579, 1142599, 1142867, 1142929, 1143057, 1143132, 1143191, 1143203, 1143293, 1143476, - 1143860, 1143997, 1144044, 1144321, 1144338, 1144459, 1144548, 1144564, 1144588, 1144592, - 1144606, 1144623, 1144718, 1144792, 1144906, 1144997, 1145007, 1145082, 1145274, 1145380, - 1145430, 1145584, 1145731, 1145778, 1145869, 1145914, 1145925, 1146025, 1146158, 1146212, - 1146223, 1146448, 1146594, 1146663, 1146761, 1146803, 1146826, 1146833, 1146898, 1147078, - 1147099, 1147330, 1147382, 1147424, 1147431, 1147472, 1147545, 1147592, 1147627, 1147657, - 1147742, 1148005, 1148699, 1155013, 1155166, 1155915, 1178902, 1179255, 1180871, 1184802, - 1187587, 1190670, 1198632, 1198646, 1198832, 1199211, 1199259, 1199330, 1200318, 1200824, - 1200959, 1201200, 1202513, 1210077, 1210208, 1210296, 1211774, 1211775, 1211776, 1211777, - 1212528, 1212529, 1212843, 1216377, 1219904, 1220650, 1232492, 1235492, 1243381, 1243807, - 1267467, 1267561, 1267615, 1267691, 1267708, 1267731, 1267797, 1273165, 1278015, 1278076, - 1278615, 1279032, 1279185, 1279756, 1281009, 1281074, 1282368, 1284002, 1284572, 1285041, - 1285278, 1285788, 1285969, 1286573, 1286679, 1287001, 1287466, 1287714, 1287819, 1288542, - 1288897, 1289486, 1290086, 1290286, 1291047, 1291363, 1291498, 1291749, 1291853, 1292129, - 1292571, 1292828, 1292855, 1292859, 1292892, 1292893, 1292909, 1292910, 1292956, 1292957, - 1292985, 1293133, 1293185, 1293926, 1294446, 1294490, 1294571, 1294966, 1295003, 1295395, - 1295491, 1296604, 1298327, 1298527, 1298685, 1300235, 1300501, 1301193, 1301345, 1301536, - 1301908, 1301969, 1301988, 1302146, 1302158, 1302810, 1303060, 1303244, 1303275, 1303487, - 1303721, 1303831, 1303943, 1304875, 1305210, 1305677, 1305687, 1306397, 1306865, 1307044, - 1307745, 1307926, 1308080, 1308680, 1309204, 1309475, 1310596, 1312574, 1313313, 1313764, - 1313792, 1313963, 1314093, 1314284, 1314743, 1315154, 1315292, 1315503, 1315994, 1316517, - 1316872, 1316909, 1317089, 1317327, 1318223, 1319657, 1321070, 1321083, 1321495, 1321517, - 1322195, 1322221, 1322293, 1322330, 1322471, 1322496, 1322569, 1322634, 1322716, 1322859, - 1323066, 1323356, 1323530, 1323539, 1323614, 1323868, 1323925, 1328650, 1329210, 1332937, - 1333431, 1335482, 1338092, 1342268, 1345890, 1346245, 1346532, 1346613, 1346783, 1347371, - 1347858, 1348077, 1348468, 1349166, 1349298, 1349335, 1350775, 1350809, 1351329, 1352877}; - int[] array2 = {14402, 14403, 14404, 14405, 14406, 14407, 23246, 23247, 23248, 23249, 23250, - 23936, 23937, 23938, 23939, 23940, 23941, 23942, 29721, 29722, 29723, 29724, 29725, 30226, - 30227, 30228, 30229, 30230, 32141, 32142, 32143, 47737, 47738, 47739, 47740, 47741, 47742, - 47743, 47744, 47745, 47746, 47747, 47748, 47749, 47750, 47751, 47752, 68770, 68771, 68772, - 68773, 68774, 68775, 68776, 68777, 68778, 68779, 68780, 72301, 72302, 83071, 83072, 83073, - 83074, 85302, 85303, 85304, 85305, 85306, 85307, 85308, 85309, 85310, 85311, 85312, 85313, - 85314, 85315, 85316, 97108, 97109, 97110, 97111, 103442, 103443, 103444, 103445, 103446, - 103447, 103448, 103449, 103450, 103451, 103452, 103453, 103454, 103455, 103456, 103457, - 103458, 103459, 103460, 103461, 103462, 103463, 103464, 103465, 103466, 103467, 103468, - 103469, 128488, 128489, 128490, 128491, 128492, 128493, 135003, 135004, 135005, 135006, - 135007, 135008, 135009, 135010, 135011, 135012, 135013, 135014, 140363, 140364, 140365, - 140366, 140367, 140368, 140369, 140370, 140371, 140372, 149844, 149845, 149846, 149847, - 149848, 149849, 149850, 149851, 149852, 149853, 149854, 149855, 149856, 149857, 149858, - 149859, 149860, 149861, 149862, 149863, 149864, 172805, 172806, 172807, 172808, 172809, - 172810, 172811, 172812, 172813, 172814, 172815, 172816, 172817, 172818, 172819, 172820, - 172821, 172822, 172823, 172824, 172825, 172826, 172827, 172828, 172829, 172830, 172831, - 172832, 172833, 172834, 172835, 172836, 172837, 172838, 172839, 172840, 172841, 172842, - 172843, 172844, 172845, 172846, 172847, 172848, 172849, 172850, 172851, 172852, 172853, - 172854, 172855, 172856, 172857, 172858, 172859, 172860, 172861, 172862, 172863, 172864, - 172865, 172866, 172867, 172868, 172869, 172870, 172871, 202530, 202531, 202532, 209488, - 209489, 209490, 209491, 209492, 209493, 209494, 209495, 209496, 209497, 209498, 209499, - 209500, 209501, 209502, 209503, 209504, 209505, 209506, 225554, 225555, 225556, 225557, - 225558, 225559, 225560, 225561, 225562, 225563, 225564, 225565, 225566, 225567, 225568, - 225569, 225570, 225571, 225572, 225573, 225574, 225575, 225576, 225577, 225578, 225579, - 225580, 225581, 227917, 227918, 227919, 227920, 227921, 227922, 227923, 227924, 227925, - 227926, 227927, 227928, 227929, 227930, 227931, 227932, 227933, 227934, 227935, 227936, - 227937, 227938, 227939, 252773, 252774, 252775, 252776, 252777, 252778, 252779, 252780, - 252781, 252782, 252783, 252784, 252785, 252786, 252787, 252788, 252789, 252790, 252791, - 252792, 252793, 252794, 278695, 278696, 278697, 278698, 278699, 301237, 301238, 301239, - 301240, 301241, 301242, 301243, 301244, 301245, 301246, 301247, 301248, 301249, 301250, - 301251, 301252, 301253, 301254, 301255, 301256, 301257, 301258, 301259, 301260, 301261, - 301262, 301263, 301264, 301265, 320515, 320516, 320517, 320518, 320519, 320520, 320521, - 320522, 320523, 320524, 320525, 320526, 320527, 320528, 320529, 320530, 320531, 320532, - 320533, 320534, 320535, 320536, 320537, 320538, 320539, 320540, 320541, 320542, 320543, - 320544, 320545, 320546, 320547, 320548, 329641, 329642, 329643, 329644, 329645, 329646, - 329647, 329648, 329649, 329650, 329651, 329652, 329653, 329654, 329655, 329656, 329657, - 329658, 329659, 342703, 342704, 342705, 342706, 349520, 349521, 349522, 349523, 349524, - 349525, 349526, 349527, 349528, 349529, 349530, 362716, 362717, 362718, 362719, 362720, - 362721, 362722, 362723, 362724, 362725, 362726, 362727, 378643, 378644, 378645, 378646, - 390154, 390155, 390156, 390157, 390158, 390159, 390160, 390161, 390162, 390163, 390164, - 390165, 390166, 390167, 390168, 390169, 395108, 395109, 395110, 395111, 395112, 395113, - 395114, 395115, 403260, 403261, 403262, 403263, 403264, 403265, 403266, 403267, 403268, - 403269, 403270, 403271, 417315, 417316, 417317, 417318, 417319, 417320, 432653, 432654, - 432655, 432656, 432657, 432658, 432659, 432660, 432661, 432662, 432663, 432664, 432665, - 432666, 432667, 432668, 432669, 432670, 432671, 432672, 432673, 432674, 432675, 432676, - 432677, 432678, 449394, 449395, 449396, 449397, 449398, 459961, 459962, 459963, 459964, - 474537, 474538, 474539, 474540, 474541, 474542, 474543, 474544, 474545, 474546, 474547, - 474548, 474549, 474550, 474551, 474552, 474553, 474554, 474555, 474556, 474557, 474558, - 474559, 474560, 474561, 474562, 474563, 474564, 474565, 474566, 474567, 474568, 474569, - 474570, 474571, 474572, 474573, 474574, 474575, 474576, 474577, 474578, 474579, 474580, - 474581, 474582, 474583, 474584, 474585, 474586, 474587, 474588, 474589, 474590, 474591, - 474592, 474593, 474594, 474595, 474596, 474597, 483571, 483572, 483573, 483574, 483575, - 483576, 489641, 489642, 489643, 489644, 489645, 489646, 489647, 489648, 489649, 489650, - 489651, 491296, 491297, 491298, 495868, 495869, 495870, 502769, 502770, 502771, 502772, - 502773, 502774, 502775, 502776, 502777, 502778, 502779, 502780, 502781, 502782, 502783, - 513810, 513811, 513812, 513813, 513814, 513815, 513816, 513817, 513818, 513819, 513820, - 513821, 513822, 513823, 513824, 513825, 513826, 513827, 513828, 513829, 513830, 513831, - 513832, 517220, 517221, 517222, 517223, 517224, 517225, 517226, 517227, 519778, 519779, - 519780, 519781, 519782, 519783, 519784, 519785, 524240, 524241, 524242, 524243, 524244, - 524245, 524246, 524247, 524248, 524249, 527255, 527256, 527257, 527258, 527259, 533697, - 533698, 533699, 533700, 533701, 533702, 533703, 533704, 533705, 533706, 533707, 533708, - 533709, 539237, 539238, 539239, 539240, 539241, 539242, 539243, 562203, 562204, 562205, - 562206, 569773, 569774, 569775, 569776, 569777, 569778, 569779, 569780, 569781, 569782, - 569783, 569784, 569785, 569786, 569787, 569788, 569789, 569790, 569791, 569792, 569793, - 569794, 569795, 569796, 569797, 569798, 569799, 569800, 569801, 569802, 569803, 569804, - 569805, 569806, 569807, 569808, 569809, 569810, 569811, 569812, 569813, 569814, 569815, - 569816, 569817, 569818, 569819, 569820, 569821, 580161, 580162, 580163, 580164, 580165, - 580166, 580167, 580168, 580169, 580170, 580171, 580172, 580173, 580174, 580175, 580176, - 588299, 588300, 588301, 588302, 588303, 588304, 588305, 588306, 588307, 588308, 588309, - 588310, 588311, 588312, 588313, 588314, 588315, 588316, 588317, 588318, 588319, 588320, - 588321, 588322, 588323, 588324, 588325, 588326, 588327, 588328, 588329, 588330, 588331, - 588332, 588333, 588334, 588335, 608580, 608581, 608582, 608583, 608584, 608585, 608586, - 608587, 608588, 608589, 608590, 608591, 608592, 608593, 608594, 608595, 608596, 608597, - 608598, 608599, 608600, 608601, 608602, 608603, 608604, 608605, 618326, 618327, 618328, - 618329, 618330, 618331, 618332, 618333, 618334, 618335, 618336, 618337, 618338, 618339, - 618340, 618341, 618342, 618343, 618344, 618345, 618346, 618347, 618348, 618349, 626895, - 626896, 626897, 626898, 626899, 626900, 635313, 635314, 635315, 635316, 635317, 635318, - 635319, 635320, 635321, 635322, 635323, 635324, 635325, 635326, 635327, 635328, 635329, - 635330, 635331, 635332, 635333, 635334, 635335, 635336, 635337, 635338, 635339, 635340, - 635341, 635342, 635343, 635344, 635345, 635346, 635347, 635348, 635349, 635350, 635351, - 635352, 635353, 635354, 635355, 648087, 648088, 648089, 648090, 648091, 648092, 648093, - 648094, 648095, 648096, 648097, 648098, 648099, 648100, 648101, 648102, 648103, 648104, - 648105, 648106, 648107, 648108, 648109, 648110, 661574, 661575, 661576, 661577, 674566, - 674567, 674568, 674569, 674570, 674571, 674572, 674573, 674574, 674575, 674576, 674577, - 674578, 674579, 674580, 674581, 674582, 674583, 674584, 674585, 689328, 689329, 689330, - 689331, 689332, 689333, 689334, 689335, 689336, 689337, 697978, 697979, 697980, 697981, - 697982, 697983, 697984, 697985, 697986, 697987, 697988, 697989, 697990, 697991, 697992, - 697993, 697994, 726676, 726677, 726678, 726679, 726680, 726681, 782220, 782221, 782222, - 782223, 782224, 782225, 782226, 782227, 782228, 782229, 782230, 782231, 782232, 782233, - 782234, 782235, 782236, 782237, 782238, 782239, 797574, 797575, 797576, 797577, 797578, - 797579, 797580, 797581, 797582, 804283, 804284, 804285, 822332, 822333, 822334, 822335, - 822336, 831020, 831021, 831022, 831023, 831024, 831025, 831026, 831027, 831028, 831029, - 831030, 831031, 831032, 831033, 831034, 831035, 831036, 831037, 831038, 831039, 831040, - 847227, 847228, 847229, 847230, 847231, 847232, 847233, 847234, 847235, 847236, 847237, - 847238, 847239, 847240, 847241, 847242, 847243, 847244, 847245, 857616, 857617, 857618, - 857619, 857620, 857621, 857622, 857623, 857624, 857625, 867324, 867325, 867326, 867327, - 867328, 867329, 867330, 867331, 867332, 867333, 867334, 867335, 867336, 867337, 867338, - 867339, 877587, 877588, 877589, 877590, 877591, 877592, 877593, 877594, 877595, 877596, - 877597, 877598, 877599, 877600, 877601, 877602, 877603, 877604, 877605, 877606, 877607, - 877608, 877609, 877610, 877611, 877612, 877613, 877614, 877615, 896235, 896236, 896237, - 896238, 896239, 896240, 916629, 916630, 916631, 916632, 929361, 929362, 929363, 929364, - 929365, 929366, 929367, 929368, 929369, 929370, 929371, 948695, 948696, 948697, 948698, - 948699, 948700, 948701, 948702, 949573, 949574, 957768, 957769, 957770, 957771, 957772, - 957773, 957774, 957775, 961032, 961033, 961034, 961035, 987440, 987441, 987442, 987443, - 1001434, 1001435, 1001436, 1001437, 1001438, 1001439, 1001440, 1001441, 1001442, 1001443, - 1001444, 1001445, 1001446, 1001447, 1001448, 1001449, 1001450, 1001451, 1001452, 1001453, - 1001454, 1001455, 1001456, 1001457, 1001458, 1001459, 1001460, 1009985, 1009986, 1009987, - 1009988, 1009989, 1037191, 1037192, 1037193, 1037194, 1037195, 1037196, 1037197, 1037198, - 1037199, 1037200, 1037201, 1037202, 1037203, 1037204, 1053198, 1053199, 1053200, 1053201, - 1053202, 1053203, 1053204, 1053205, 1053206, 1053207, 1053208, 1053209, 1053210, 1053211, - 1053212, 1053213, 1053214, 1053215, 1053216, 1053217, 1053218, 1053219, 1053220, 1053221, - 1053222, 1053223, 1053224, 1084019, 1084020, 1084021, 1084022, 1084023, 1084024, 1084025, - 1088361, 1088362, 1088363, 1088364, 1088365, 1088366, 1089312, 1089313, 1089314, 1089315, - 1089316, 1089317, 1089318, 1092235, 1092236, 1092237, 1092238, 1092239, 1092240, 1092241, - 1092242, 1092243, 1092244, 1102836, 1102837, 1102838, 1102839, 1102840, 1102841, 1102842, - 1102843, 1102844, 1102845, 1102846, 1102847, 1108575, 1108576, 1108577, 1108578, 1108579, - 1108580, 1108581, 1108582, 1108583, 1108584, 1108585, 1108586, 1108587, 1108588, 1108589, - 1108590, 1108591, 1108592, 1108593, 1108594, 1108595, 1108596, 1108597, 1108598, 1134091, - 1134092, 1134093, 1134094, 1134095, 1134096, 1134097, 1134098, 1134099, 1134100, 1134101, - 1134102, 1134103, 1134104, 1134105, 1134106, 1134107, 1134108, 1134109, 1134110, 1134111, - 1134112, 1134113, 1134114, 1134115, 1134116, 1134117, 1134118, 1134119, 1134120, 1134121, - 1134122, 1134123, 1134124, 1134125, 1134126, 1134127, 1134128, 1134129, 1151732, 1151733, - 1151734, 1151735, 1151736, 1151737, 1151738, 1151739, 1151740, 1151741, 1151742, 1151743, - 1151744, 1151745, 1151746, 1151747, 1199223, 1199224, 1199225, 1199226, 1203252, 1203253, - 1203254, 1203255, 1203256, 1203257, 1203258, 1203259, 1203260, 1217223, 1217224, 1217225, - 1217226, 1226505, 1226506, 1226507, 1226508, 1226509, 1226510, 1226511, 1226512, 1231411, - 1231412, 1231413, 1231414, 1231415, 1231416, 1231417, 1231418, 1231419, 1231420, 1231421, - 1231422, 1231423, 1243464, 1243465, 1243466, 1243467, 1243468, 1243469, 1243470, 1247919, - 1247920, 1247921, 1255972, 1255973, 1255974, 1255975, 1255976, 1255977, 1255978, 1255979, - 1255980, 1263675, 1263676, 1263677, 1263678, 1263679, 1277693, 1277694, 1277695, 1277696, - 1277697, 1277698, 1277699, 1277700, 1283492, 1283493, 1283494, 1283495, 1283496, 1283497, - 1283498, 1283499, 1283500, 1283501, 1283502, 1283503, 1283504, 1283505, 1283506, 1283507, - 1283508, 1283509, 1283510, 1283511, 1283512, 1283513, 1283514, 1325789, 1325790, 1325791, - 1325792, 1325793, 1325794, 1325795, 1325796, 1325797, 1325798, 1325799}; + int[] array1 = { + 22871, 22873, 22876, 22880, 22886, 22889, 22893, 22897, 22901, 22905, 22910, 22915, 22919, + 22927, 22934, 22940, 24750, 38579, 48470, 50533, 53256, 53717, 53752, 53802, 53938, 54727, + 54865, 55202, 55815, 55822, 55940, 56711, 56977, 57122, 59933, 60037, 60402, 60520, 60853, + 61163, 61340, 61549, 61632, 62097, 62373, 62961, 62993, 63031, 63075, 64209, 64644, 64762, + 64893, 64927, 64997, 65117, 65128, 65173, 65201, 65472, 65536, 65622, 66092, 66162, 66302, + 66381, 66551, 103979, 104644, 106866, 117285, 123372, 127548, 132167, 132168, 136283, 136433, + 137661, 138019, 138239, 138380, 138816, 138916, 138933, 139414, 140342, 140914, 142751, + 142994, 143895, 145081, 147331, 147686, 148021, 148375, 148587, 149114, 149734, 152696, + 153608, 154741, 154932, 155263, 157121, 158947, 159444, 161102, 161383, 162735, 164298, + 168043, 169398, 169536, 170419, 170846, 171153, 177016, 177471, 178305, 178673, 183731, + 183936, 184083, 184106, 185663, 188371, 189495, 189531, 196189, 198419, 198758, 198796, + 200645, 201137, 216865, 216936, 217770, 217810, 217836, 217909, 218569, 218700, 218931, + 219363, 220009, 225925, 234706, 241183, 241561, 242140, 242281, 245018, 245056, 249935, + 250442, 250615, 251696, 252825, 254178, 256788, 256906, 257289, 258833, 260432, 260563, + 260930, 262684, 262834, 263128, 265919, 268662, 269542, 270217, 271673, 273776, 274560, + 275649, 305458, 306241, 306550, 307580, 310891, 312701, 313514, 318134, 319185, 320757, + 321280, 322046, 322743, 323211, 324667, 325382, 326450, 327159, 328836, 329075, 331179, + 332836, 332997, 333071, 333205, 333488, 333595, 335045, 335803, 336417, 336610, 338487, + 339827, 339992, 346123, 348858, 351257, 351957, 353896, 354559, 357142, 358253, 366662, + 378768, 391984, 392282, 415077, 429446, 429449, 429452, 429453, 429476, 429480, 429486, + 429492, 429497, 429501, 429504, 429505, 429510, 429515, 429519, 429524, 429530, 429533, + 429541, 429546, 429553, 429554, 429564, 429572, 429577, 429579, 429586, 429589, 429596, + 429604, 429606, 429612, 429615, 429616, 429624, 429632, 429639, 429642, 429646, 429651, + 429656, 429664, 429670, 429674, 429678, 429681, 429686, 429695, 429701, 429706, 429717, + 429721, 429725, 429733, 429736, 429739, 429743, 429748, 429754, 429761, 429767, 429772, + 429780, 429791, 429792, 429793, 429794, 429795, 429817, 429822, 429823, 429831, 429836, + 429842, 429849, 429855, 429859, 429863, 429866, 429873, 429876, 429882, 429885, 429900, + 429903, 429913, 429921, 429923, 429927, 429932, 429939, 429947, 429950, 429955, 429964, + 429968, 429974, 429982, 429987, 429993, 429999, 430003, 430011, 430015, 430023, 430028, + 430033, 430039, 430044, 430048, 430053, 430057, 430059, 430063, 430068, 430073, 430077, + 430082, 430086, 430093, 430098, 430101, 430114, 430120, 430126, 430131, 430135, 430139, + 430144, 430149, 430155, 430157, 430167, 430175, 430181, 430186, 430194, 430195, 430196, + 430214, 430223, 430228, 430236, 430253, 430258, 430263, 430269, 430277, 430284, 430288, + 430293, 430297, 430303, 430309, 430316, 430321, 430332, 430338, 430343, 430346, 430348, + 430355, 430358, 430369, 430375, 430384, 430391, 430397, 430410, 430415, 430420, 430424, + 430430, 430435, 430437, 430445, 430449, 430461, 430467, 430473, 430482, 430486, 430490, + 430496, 430500, 430506, 430511, 430515, 430535, 430539, 430550, 430568, 430575, 430581, + 430588, 430591, 430596, 430605, 430612, 430617, 430625, 430629, 430633, 430638, 430643, + 430649, 430656, 430663, 430666, 430672, 430679, 430684, 430692, 430696, 430700, 430707, + 430716, 430723, 430728, 430733, 430745, 430751, 430755, 430759, 430767, 430770, 430782, + 430787, 430791, 430804, 430810, 430814, 430821, 430825, 430829, 430833, 430838, 430844, + 430849, 430852, 430859, 430864, 430867, 430870, 430877, 430881, 430887, 430891, 430896, + 430901, 430907, 430912, 430917, 430923, 430927, 430932, 430936, 430944, 430947, 430953, + 430959, 430967, 430971, 430979, 430985, 430989, 430993, 430997, 431003, 431006, 431015, + 431021, 431022, 431033, 431039, 431046, 431050, 431054, 431059, 431065, 431069, 431074, + 431081, 431085, 431092, 431097, 431104, 431110, 431120, 431125, 431133, 431138, 431142, + 431147, 431157, 431164, 431171, 431175, 431180, 431186, 431190, 431195, 431207, 431213, + 431218, 431220, 431224, 431228, 431233, 431235, 431240, 431245, 431251, 431259, 431264, + 431271, 431272, 431280, 431287, 431294, 431299, 431307, 431315, 431319, 431324, 431330, + 431334, 431339, 431345, 431352, 431356, 431363, 431375, 431379, 431383, 431388, 431393, + 431398, 431405, 431409, 431416, 431422, 431426, 431433, 431438, 431444, 431451, 431455, + 431464, 431469, 431472, 431477, 431483, 431490, 431496, 431506, 431513, 431516, 431521, + 431526, 431534, 431536, 431545, 431550, 431559, 431564, 431571, 431573, 431579, 431584, + 431587, 431592, 431604, 431614, 431624, 431629, 431634, 431638, 431645, 431651, 431659, + 431663, 431674, 431678, 431684, 431692, 431696, 431700, 431706, 431712, 431719, 431723, + 431729, 431736, 431741, 431747, 431755, 431758, 431762, 431767, 431777, 431782, 431787, + 431791, 431796, 431799, 431805, 431809, 431814, 431819, 431823, 431828, 431832, 431838, + 431842, 431849, 431853, 431858, 431862, 431866, 431869, 431874, 431881, 431887, 431894, + 431900, 431906, 431912, 431917, 431925, 431931, 431936, 431943, 431948, 431956, 431958, + 431964, 431971, 431976, 431981, 431988, 431994, 431998, 432008, 432012, 432024, 432029, + 432033, 432038, 432045, 432048, 432058, 432062, 432066, 432070, 432076, 432077, 432087, + 432093, 432098, 432104, 432114, 432123, 432128, 432133, 432139, 432145, 432151, 432161, + 432168, 432177, 432181, 432188, 432189, 432203, 432209, 432216, 432222, 432227, 432232, + 432242, 432247, 432256, 432259, 432264, 432269, 432271, 432277, 432286, 432294, 432297, + 432302, 432308, 432313, 432319, 432326, 432331, 432337, 432345, 432349, 432353, 432356, + 432361, 432366, 432370, 432378, 432384, 432390, 432391, 432397, 432400, 432403, 432408, + 432413, 432419, 432422, 432427, 432433, 432440, 432443, 432450, 432455, 432460, 432466, + 432467, 432481, 432489, 432493, 432498, 432504, 432511, 432513, 432517, 432525, 432531, + 432537, 432544, 432546, 432555, 432561, 432565, 432569, 432574, 432579, 432586, 432590, + 432597, 432605, 432611, 432619, 432626, 432630, 432637, 432644, 432646, 432653, 432654, + 432664, 432670, 432674, 432679, 432682, 432687, 432694, 432706, 432711, 432714, 432721, + 432726, 432732, 432741, 432747, 432753, 432755, 432761, 432764, 432768, 432774, 432779, + 432784, 432792, 432798, 432801, 432808, 432815, 432823, 432825, 432833, 432838, 432842, + 432847, 432853, 432861, 432866, 432873, 432879, 432889, 432895, 432901, 432906, 432913, + 432917, 432920, 432926, 432935, 432940, 432949, 432953, 432958, 432960, 432966, 432967, + 432968, 432969, 432970, 432971, 432972, 432996, 432999, 433004, 433010, 433020, 433026, + 433029, 433033, 433042, 433045, 433050, 433054, 433058, 433062, 433065, 433070, 433076, + 433086, 433095, 433101, 433102, 433116, 433122, 433129, 433132, 433140, 433146, 433151, + 433157, 433163, 433169, 433176, 433181, 433188, 433198, 433204, 433219, 433229, 433236, + 433240, 433246, 433250, 433259, 433263, 433274, 433277, 433282, 433286, 433291, 433295, + 433299, 433306, 433316, 433318, 433322, 433327, 433335, 433342, 433348, 433351, 433359, + 433362, 433367, 433371, 433377, 433384, 433393, 433398, 433403, 433407, 433411, 433425, + 433430, 433437, 433441, 433445, 433452, 433453, 433458, 433462, 433469, 433473, 433478, + 433484, 433490, 433495, 433501, 433506, 433514, 433517, 433521, 433527, 433534, 433544, + 433549, 433552, 433561, 433565, 433569, 433576, 433585, 433589, 433594, 433597, 433600, + 433603, 433606, 433613, 433619, 433623, 433627, 433639, 433643, 433648, 433654, 433658, + 433665, 433673, 433678, 433681, 433689, 433696, 433704, 433709, 433716, 433721, 433725, + 433729, 433734, 433738, 433744, 433749, 433755, 433760, 433766, 433771, 433776, 433781, + 433785, 433790, 433798, 433803, 433810, 433814, 433817, 433822, 433828, 433833, 433837, + 433843, 433849, 433852, 433858, 433863, 433871, 433875, 433881, 433883, 433884, 433897, + 433903, 433909, 433913, 433921, 433926, 433932, 433936, 433942, 433946, 433951, 433959, + 433965, 433976, 433981, 433989, 433996, 434004, 434011, 434013, 434019, 434023, 434029, + 434036, 434041, 434048, 434050, 434056, 434060, 434068, 434074, 434079, 434085, 434091, + 434096, 434100, 434105, 434110, 434119, 434123, 434129, 434133, 434139, 434146, 434150, + 434156, 434161, 434168, 434173, 434183, 434188, 434193, 434200, 434208, 434213, 434219, + 434223, 434229, 434235, 434241, 434247, 434258, 434262, 434269, 434275, 434282, 434287, + 434291, 434296, 434303, 434308, 434313, 434316, 434323, 434327, 434335, 434342, 434349, + 434353, 434360, 434366, 434372, 434373, 434381, 434387, 434392, 434397, 434401, 434403, + 434409, 434414, 434420, 434427, 434433, 434440, 434445, 434449, 434454, 434460, 434467, + 434473, 434479, 434481, 434490, 434494, 434501, 434505, 434510, 434517, 434526, 434537, + 434542, 434548, 434553, 434558, 434563, 434569, 434574, 434580, 434586, 434588, 434595, + 434603, 434606, 434617, 434620, 434626, 434630, 434638, 434644, 434647, 434651, 434658, + 434666, 434671, 434679, 434681, 434685, 434692, 434699, 434703, 434708, 434713, 434720, + 434723, 434729, 434734, 434738, 434742, 434746, 434753, 434762, 434766, 434773, 434781, + 434790, 434799, 434805, 434810, 434814, 434823, 434831, 434839, 434845, 434850, 434856, + 434859, 434863, 434869, 434870, 434882, 434890, 434896, 434899, 434906, 434912, 434917, + 434921, 434930, 434935, 434940, 434945, 434949, 434956, 434961, 434967, 434977, 434982, + 434987, 434992, 434995, 435002, 435005, 435009, 435016, 435021, 435025, 435028, 435034, + 435041, 435050, 435055, 435065, 435069, 435075, 435078, 435083, 435091, 435097, 435102, + 435105, 435107, 435113, 435118, 435124, 435131, 435141, 435144, 435150, 435154, 435159, + 435167, 435171, 435177, 435181, 435187, 435192, 435198, 435204, 435211, 435212, 435221, + 435228, 435231, 435237, 435244, 435246, 435254, 435258, 435264, 435275, 435283, 435289, + 435301, 435304, 435312, 435318, 435323, 435329, 435334, 435340, 435343, 435347, 435351, + 435358, 435363, 435368, 435375, 435382, 435388, 435391, 435396, 435399, 435405, 435412, + 435416, 435422, 435425, 435429, 435437, 435444, 435447, 435453, 435458, 435470, 435477, + 435486, 435491, 435497, 435500, 435511, 435516, 435520, 435526, 435533, 435539, 435545, + 435551, 435559, 435564, 435569, 435575, 435579, 435585, 435590, 435597, 435599, 435600, + 435610, 435616, 435618, 435623, 435628, 435636, 435643, 435649, 435654, 435659, 435663, + 435671, 435675, 435678, 435683, 435689, 435702, 435705, 435712, 435718, 435749, 435755, + 435759, 435764, 435771, 435775, 435780, 435785, 435791, 435794, 435802, 435811, 435816, + 435822, 435828, 435833, 435838, 435844, 435851, 435859, 435861, 435866, 435869, 435876, + 435882, 435890, 435897, 435900, 435908, 435913, 435923, 435929, 435934, 435937, 435942, + 435945, 435951, 435953, 435959, 435965, 435969, 435975, 435982, 435987, 435992, 436000, + 436008, 436013, 436017, 436022, 436027, 436033, 436038, 436043, 436048, 436052, 436062, + 436065, 436069, 436073, 436079, 436088, 436092, 436100, 436106, 436116, 436123, 436127, + 436133, 436139, 436147, 436153, 436159, 436165, 436172, 436179, 436184, 436190, 436194, + 436199, 436206, 436210, 436211, 436217, 436223, 436229, 436234, 436240, 436245, 436253, + 436258, 436262, 436268, 436273, 436282, 436287, 436294, 436303, 436306, 436313, 436316, + 436321, 436329, 436337, 436341, 436349, 436353, 436358, 436365, 436368, 436373, 436378, + 436387, 436391, 436396, 436401, 436408, 436412, 436420, 436423, 436428, 436435, 436441, + 436447, 436451, 436461, 436463, 436467, 436471, 436477, 436479, 436485, 436489, 436494, + 436502, 436509, 436512, 436518, 436529, 436538, 436543, 436552, 436553, 436560, 436564, + 436569, 436575, 436580, 436585, 436591, 436597, 436603, 436605, 436610, 436616, 436619, + 436628, 436633, 436637, 436640, 436644, 436649, 436653, 436659, 436666, 436674, 436681, + 436687, 436694, 436700, 436703, 436710, 436720, 436723, 436730, 436735, 436742, 436748, + 436756, 436761, 436766, 436772, 436778, 436783, 436787, 436792, 436799, 436808, 436810, + 436812, 436817, 436823, 436832, 436838, 436845, 436849, 436853, 436859, 436865, 436872, + 436878, 436882, 436885, 436891, 436898, 436903, 436910, 436911, 436922, 436928, 436932, + 436939, 436942, 436948, 436950, 436956, 436963, 436968, 436975, 436984, 436988, 436994, + 437003, 437009, 437013, 437020, 437023, 437028, 437033, 437043, 437053, 437058, 437063, + 437073, 437076, 437079, 437089, 437093, 437095, 437101, 437111, 437119, 437121, 437127, + 437135, 437140, 437147, 437151, 437155, 437160, 437165, 437171, 437173, 437180, 437186, + 437194, 437199, 437205, 437213, 437217, 437223, 437227, 437231, 437243, 437250, 437256, + 437261, 437267, 437271, 437277, 437284, 437289, 437295, 437300, 437304, 437312, 437322, + 437326, 437333, 437338, 437354, 437357, 437362, 437366, 437370, 437374, 437380, 437386, + 437391, 437395, 437399, 437404, 437412, 437416, 437419, 437427, 437432, 437433, 437451, + 437456, 437461, 437467, 437468, 437477, 437485, 437492, 437495, 437501, 437502, 437506, + 437513, 437524, 437526, 437539, 437544, 437552, 437558, 437562, 437568, 437573, 437578, + 437587, 437592, 437596, 437600, 437605, 437610, 437619, 437625, 437630, 437631, 437639, + 437647, 437648, 437655, 437661, 437667, 437672, 437676, 437680, 437687, 437689, 437693, + 437697, 437704, 437707, 437716, 437723, 437730, 437737, 437740, 437741, 437757, 437763, + 437771, 437778, 437784, 437789, 437793, 437800, 437804, 437811, 437812, 437819, 437823, + 437827, 437833, 437841, 437844, 437853, 437857, 437861, 437866, 437874, 437881, 437886, + 437892, 437901, 437902, 437909, 437914, 437922, 437928, 437934, 437939, 437948, 437951, + 437957, 437963, 437965, 437971, 437980, 437985, 437990, 437996, 438002, 438008, 438013, + 438017, 438025, 438030, 438036, 438041, 438052, 438060, 438065, 438072, 438073, 438079, + 438084, 438091, 438097, 438099, 438107, 438111, 438119, 438125, 438136, 438144, 438148, + 438153, 438158, 438164, 438166, 438173, 438176, 438183, 438184, 438192, 438198, 438204, + 438209, 438216, 438228, 438231, 438237, 438243, 438248, 438257, 438267, 438269, 438274, + 438282, 438287, 438295, 438301, 438306, 438313, 438318, 438323, 438328, 438335, 438339, + 438346, 438352, 438357, 438363, 438370, 438374, 438380, 438384, 438388, 438394, 438399, + 438404, 438409, 438413, 438422, 438428, 438436, 438439, 438444, 438453, 438461, 438471, + 438477, 438483, 438491, 438503, 438505, 438511, 438518, 438527, 438531, 438541, 438546, + 438552, 438556, 438562, 438566, 438570, 438580, 438585, 438593, 438595, 438603, 438605, + 438607, 438614, 438619, 438626, 438631, 438634, 438641, 438646, 438652, 438657, 438663, + 438664, 438665, 438673, 438677, 438682, 438692, 438700, 438706, 438708, 438715, 438723, + 438727, 438737, 438742, 438753, 438760, 438764, 438771, 438775, 438780, 438783, 438789, + 438797, 438806, 438810, 438815, 438832, 438837, 438841, 438845, 438852, 438860, 438865, + 438873, 438883, 438884, 438896, 438908, 438912, 438920, 438924, 438927, 438934, 438936, + 438940, 438946, 438953, 438961, 438968, 438976, 438980, 438985, 438994, 439006, 439011, + 439017, 439021, 439027, 439032, 439036, 439043, 439047, 439055, 439059, 439065, 439070, + 439075, 439083, 439087, 439093, 439099, 439104, 439109, 439114, 439120, 439123, 439128, + 439130, 439134, 439139, 439147, 439157, 439162, 439167, 439172, 439178, 439183, 439187, + 439194, 439201, 439205, 439210, 439216, 439222, 439225, 439231, 439235, 439245, 439251, + 439255, 439261, 439277, 439282, 439288, 439295, 439302, 439308, 439309, 439314, 439320, + 439328, 439332, 439339, 439345, 439350, 439354, 439359, 439365, 439372, 439377, 439379, + 439386, 439391, 439404, 439410, 439416, 439419, 439425, 439430, 439434, 439438, 439455, + 439461, 439465, 439472, 439476, 439482, 439488, 439493, 439496, 439506, 439510, 439516, + 439521, 439527, 439536, 439543, 439551, 439554, 439557, 439564, 439569, 439574, 439577, + 439584, 439588, 439593, 439597, 439602, 439607, 439613, 439618, 439624, 439625, 439633, + 439638, 439641, 439645, 439650, 439655, 439659, 439669, 439670, 439671, 439682, 439692, + 439696, 439701, 439709, 439718, 439725, 439730, 439733, 439739, 439745, 439757, 439764, + 439768, 439771, 439778, 439783, 439788, 439796, 439805, 439811, 439815, 439820, 439827, + 439830, 439840, 439846, 439850, 439854, 439865, 439873, 439879, 439886, 439891, 439898, + 439903, 439909, 439917, 439925, 439928, 439933, 439938, 439944, 439948, 439955, 439959, + 439965, 439969, 439974, 439988, 439989, 440005, 440008, 440011, 440015, 440020, 440026, + 440030, 440035, 440043, 440044, 440055, 440060, 440078, 440091, 440096, 440101, 440106, + 440111, 440116, 440120, 440134, 440139, 440143, 440149, 440157, 440163, 440167, 440171, + 440179, 440187, 440191, 440196, 440201, 440207, 440213, 440218, 440223, 440228, 440233, + 440239, 440244, 440249, 440256, 440262, 440268, 440274, 440277, 440282, 440289, 440295, + 440307, 440311, 440315, 440321, 440327, 440331, 440336, 440341, 440346, 440355, 440361, + 440368, 440375, 440379, 440388, 440394, 440399, 440402, 440410, 440413, 440421, 440427, + 440431, 440435, 440440, 440446, 440454, 440461, 440467, 440476, 440481, 440486, 440490, + 440495, 440500, 440506, 440512, 440523, 440529, 440533, 440539, 440546, 440552, 440560, + 440568, 440578, 440584, 440590, 440594, 440598, 440606, 440612, 440620, 440623, 440629, + 440634, 440641, 440647, 440651, 440655, 440663, 440669, 440674, 440682, 440689, 440694, + 440698, 440702, 440706, 440713, 440719, 440727, 440733, 440737, 440743, 440747, 440753, + 440760, 440767, 440772, 440779, 440783, 440789, 440792, 440798, 440806, 440808, 440812, + 440819, 440823, 440826, 440830, 440835, 440840, 440845, 440853, 440856, 440861, 440867, + 440872, 440876, 440882, 440888, 440893, 440903, 440910, 440915, 440921, 440927, 440933, + 440938, 440945, 440950, 440958, 440966, 440969, 440973, 440977, 440983, 440987, 440992, + 440996, 441005, 441008, 441013, 441028, 441035, 441042, 441047, 441052, 441056, 441061, + 441068, 441075, 441080, 441087, 441094, 441097, 441106, 441111, 441115, 441121, 441125, + 441132, 441136, 441143, 441150, 441157, 441161, 441167, 441171, 441175, 441179, 441185, + 441193, 441196, 441200, 441204, 441210, 441216, 441223, 441226, 441234, 441238, 441243, + 441253, 441260, 441268, 441276, 441287, 441294, 441297, 441306, 441313, 441315, 441323, + 441332, 441339, 441346, 441353, 441358, 441362, 441368, 441373, 441378, 441382, 441390, + 441394, 441399, 441404, 441411, 441416, 441420, 441427, 441432, 441440, 441445, 441448, + 441453, 441456, 441461, 441467, 441473, 441479, 441484, 441491, 441497, 441506, 441509, + 441515, 441521, 441526, 441531, 441535, 441542, 441547, 441551, 441555, 441559, 441565, + 441569, 441574, 441579, 441596, 441599, 441605, 441610, 441617, 441619, 441623, 441628, + 441630, 441636, 441637, 441651, 441652, 441662, 441664, 441667, 441671, 441681, 441684, + 441689, 441693, 441701, 441705, 441710, 441718, 441720, 441726, 441740, 441746, 441757, + 441759, 441766, 441773, 441775, 441780, 441793, 441794, 441799, 441807, 441817, 441822, + 441828, 441831, 441834, 441838, 441845, 441853, 441857, 441863, 441866, 441872, 441880, + 441883, 441886, 441891, 441895, 441900, 441910, 441915, 441921, 441928, 441934, 441939, + 441945, 441947, 441952, 441957, 441964, 441971, 441974, 441980, 441985, 441990, 441994, + 441998, 442002, 442007, 442010, 442017, 442019, 442027, 442043, 442046, 442054, 442060, + 442067, 442074, 442076, 442081, 442086, 442093, 442099, 442103, 442108, 442112, 442120, + 442131, 442135, 442139, 442144, 442148, 442156, 442161, 442165, 442170, 442181, 442186, + 442192, 442197, 442203, 442220, 442226, 442233, 442239, 442245, 442249, 442254, 442259, + 442267, 442275, 442281, 442284, 442287, 442292, 442299, 442308, 442314, 442318, 442325, + 442332, 442333, 442334, 442346, 442351, 442354, 442358, 442364, 442370, 442372, 442377, + 442381, 442389, 442397, 442402, 442409, 442415, 442419, 442424, 442430, 442438, 442443, + 442451, 442459, 442470, 442473, 442482, 442490, 442496, 442501, 442506, 442514, 442520, + 442524, 442530, 442534, 442541, 442546, 442549, 442554, 442558, 442563, 442573, 442586, + 442591, 442595, 442600, 442607, 442613, 442618, 442624, 442628, 442632, 442640, 442647, + 442651, 442657, 442666, 442674, 442679, 442682, 442686, 442692, 442699, 442705, 442714, + 442718, 442722, 442729, 442734, 442739, 442748, 442751, 442754, 442757, 442765, 442770, + 442778, 442783, 442792, 442798, 442802, 442813, 442820, 442829, 442833, 442841, 442845, + 442851, 442857, 442860, 442865, 442871, 442877, 442882, 442886, 442892, 442898, 442904, + 442906, 442911, 442915, 442922, 442929, 442934, 442940, 442944, 442946, 442952, 442956, + 442963, 442971, 442973, 442979, 442985, 442997, 443001, 443006, 443017, 443019, 443024, + 443027, 443036, 443046, 443050, 443057, 443066, 443069, 443078, 443083, 443089, 443093, + 443100, 443104, 443109, 443118, 443126, 443134, 443141, 443146, 443151, 443158, 443164, + 443169, 443174, 443179, 443182, 443189, 443195, 443198, 443206, 443211, 443213, 443214, + 443222, 443224, 443228, 443235, 443240, 443246, 443255, 443259, 443269, 443270, 443277, + 443285, 443291, 443299, 443303, 443311, 443313, 443319, 443322, 443328, 443338, 443342, + 443350, 443351, 443356, 443362, 443365, 443368, 443371, 443375, 443378, 443384, 443388, + 443391, 443397, 443404, 443412, 443416, 443421, 443424, 443428, 443433, 443438, 443442, + 443449, 443462, 443463, 443470, 443474, 443482, 443490, 443495, 443499, 443506, 443519, + 443523, 443527, 443533, 443540, 443548, 443550, 443556, 443559, 443564, 443568, 443574, + 443582, 443589, 443594, 443596, 443602, 443610, 443612, 443616, 443620, 443625, 443631, + 443638, 443643, 443649, 443656, 443660, 443669, 443672, 443680, 443691, 443695, 443699, + 443706, 443710, 443714, 443718, 443721, 443726, 443734, 443739, 443745, 443752, 443758, + 443765, 443771, 443774, 443781, 443786, 443789, 443793, 443797, 443802, 443811, 443812, + 443820, 443829, 443832, 443838, 443847, 443851, 443856, 443857, 443864, 443871, 443877, + 443886, 443892, 443896, 443903, 443909, 443913, 443920, 443925, 443930, 443935, 443942, + 443946, 443954, 443963, 443966, 443969, 443975, 443979, 443982, 443988, 443996, 443999, + 444003, 444007, 444012, 444019, 444026, 444030, 444040, 444049, 444056, 444060, 444064, + 444069, 444073, 444075, 444078, 444083, 444091, 444098, 444103, 444111, 444121, 444124, + 444130, 444136, 444140, 444145, 444150, 444156, 444162, 444168, 444172, 444179, 444182, + 444186, 444189, 444193, 444198, 444203, 444208, 444212, 444218, 444225, 444231, 444234, + 444240, 444246, 444258, 444265, 444273, 444277, 444281, 444288, 444292, 444298, 444301, + 444309, 444314, 444319, 444327, 444332, 444338, 444349, 444354, 444359, 444364, 444374, + 444377, 444381, 444386, 444388, 444394, 444401, 444406, 444417, 444422, 444429, 444438, + 444439, 444448, 444449, 444456, 444461, 444467, 444473, 444480, 444486, 444490, 444495, + 444500, 444503, 444508, 444514, 444518, 444525, 444528, 444535, 444540, 444544, 444550, + 444556, 444563, 444570, 444576, 444580, 444583, 444587, 444591, 444599, 444605, 444608, + 444612, 444619, 444629, 444635, 444643, 444646, 444652, 444660, 444671, 444676, 444681, + 444686, 444690, 444696, 444703, 444710, 444711, 444720, 444723, 444734, 444742, 444752, + 444758, 444763, 444767, 444770, 444774, 444786, 444789, 444794, 444800, 444809, 444818, + 444822, 444830, 444836, 444841, 444846, 444853, 444859, 444866, 444873, 444878, 444885, + 444890, 444896, 444904, 444907, 444914, 444922, 444924, 444931, 446357, 488475, 495304, + 496119, 497438, 498593, 498603, 498917, 499048, 499713, 500776, 501348, 503424, 508844, + 518359, 519305, 519446, 523627, 523776, 523878, 523902, 524135, 524329, 524515, 524611, + 524686, 524798, 524852, 525209, 525700, 525913, 525954, 526158, 526332, 526356, 536810, + 537279, 563933, 578719, 579248, 579791, 584191, 591485, 592871, 613176, 615012, 616428, + 619153, 636103, 640708, 643141, 645080, 646349, 647043, 649345, 651085, 652849, 653092, + 653169, 653227, 653586, 655241, 656093, 658355, 658564, 659381, 659518, 690513, 693218, + 693746, 694340, 694842, 695155, 695563, 695776, 696380, 697608, 697797, 698222, 698835, + 699307, 700154, 700203, 700235, 700404, 700806, 700900, 701796, 702155, 702956, 702998, + 705105, 705377, 705631, 708650, 709265, 709787, 725122, 735376, 737115, 737174, 738005, + 741377, 741986, 746045, 746404, 746590, 748212, 753574, 754379, 764728, 765776, 766863, + 769126, 782626, 782723, 783529, 786875, 787544, 807281, 811132, 821933, 822194, 829768, + 830997, 831095, 832481, 834082, 844664, 845574, 845764, 846820, 849481, 855607, 857775, + 872350, 876126, 902029, 903509, 904449, 904469, 905915, 910463, 911856, 924365, 928664, + 929314, 929606, 929983, 930478, 933195, 933819, 935628, 935911, 935922, 936002, 937668, + 941895, 942677, 943721, 944661, 944980, 945121, 945268, 945360, 950756, 951007, 959993, + 960787, 961048, 961084, 961238, 961589, 962000, 962797, 962827, 962910, 963788, 964272, + 964343, 964431, 964573, 964949, 965017, 965036, 965041, 965598, 965674, 965957, 966014, + 966032, 966092, 966144, 966226, 966234, 966265, 966291, 978103, 980858, 987212, 987458, + 987498, 988368, 988513, 988939, 990571, 993183, 1005493, 1007972, 1008230, 1009675, 1010075, + 1010685, 1011441, 1011828, 1012269, 1012310, 1013612, 1013907, 1014379, 1018659, 1018923, + 1022035, 1024567, 1024568, 1025024, 1026699, 1027212, 1027840, 1029108, 1031846, 1032670, + 1032970, 1034016, 1039255, 1040626, 1040796, 1043457, 1043632, 1051053, 1052581, 1091611, + 1092316, 1092564, 1092634, 1096386, 1096820, 1098606, 1104201, 1107101, 1110019, 1111384, + 1111707, 1128990, 1129111, 1129147, 1129160, 1129367, 1129408, 1129508, 1129577, 1129699, + 1129750, 1129840, 1129951, 1129988, 1130041, 1130139, 1130177, 1130241, 1130248, 1130268, + 1130276, 1130367, 1130540, 1130562, 1130636, 1130637, 1130662, 1130716, 1131139, 1131218, + 1131250, 1131454, 1131541, 1131775, 1132208, 1132280, 1132901, 1133264, 1133474, 1133475, + 1133764, 1133841, 1133988, 1134290, 1134533, 1134553, 1134614, 1134667, 1134710, 1134861, + 1134896, 1135008, 1135178, 1135544, 1135551, 1135573, 1136260, 1136385, 1136458, 1136782, + 1136960, 1137342, 1137713, 1137824, 1138160, 1138291, 1138340, 1138457, 1138468, 1138516, + 1138526, 1138610, 1138648, 1138700, 1138801, 1138869, 1138999, 1139010, 1139102, 1139114, + 1139145, 1139302, 1139322, 1139417, 1139496, 1139581, 1139668, 1139852, 1139930, 1139958, + 1140325, 1140616, 1140811, 1140861, 1141056, 1141197, 1141311, 1141346, 1141551, 1141666, + 1141735, 1141786, 1141895, 1142017, 1142228, 1142242, 1142415, 1142484, 1142579, 1142599, + 1142867, 1142929, 1143057, 1143132, 1143191, 1143203, 1143293, 1143476, 1143860, 1143997, + 1144044, 1144321, 1144338, 1144459, 1144548, 1144564, 1144588, 1144592, 1144606, 1144623, + 1144718, 1144792, 1144906, 1144997, 1145007, 1145082, 1145274, 1145380, 1145430, 1145584, + 1145731, 1145778, 1145869, 1145914, 1145925, 1146025, 1146158, 1146212, 1146223, 1146448, + 1146594, 1146663, 1146761, 1146803, 1146826, 1146833, 1146898, 1147078, 1147099, 1147330, + 1147382, 1147424, 1147431, 1147472, 1147545, 1147592, 1147627, 1147657, 1147742, 1148005, + 1148699, 1155013, 1155166, 1155915, 1178902, 1179255, 1180871, 1184802, 1187587, 1190670, + 1198632, 1198646, 1198832, 1199211, 1199259, 1199330, 1200318, 1200824, 1200959, 1201200, + 1202513, 1210077, 1210208, 1210296, 1211774, 1211775, 1211776, 1211777, 1212528, 1212529, + 1212843, 1216377, 1219904, 1220650, 1232492, 1235492, 1243381, 1243807, 1267467, 1267561, + 1267615, 1267691, 1267708, 1267731, 1267797, 1273165, 1278015, 1278076, 1278615, 1279032, + 1279185, 1279756, 1281009, 1281074, 1282368, 1284002, 1284572, 1285041, 1285278, 1285788, + 1285969, 1286573, 1286679, 1287001, 1287466, 1287714, 1287819, 1288542, 1288897, 1289486, + 1290086, 1290286, 1291047, 1291363, 1291498, 1291749, 1291853, 1292129, 1292571, 1292828, + 1292855, 1292859, 1292892, 1292893, 1292909, 1292910, 1292956, 1292957, 1292985, 1293133, + 1293185, 1293926, 1294446, 1294490, 1294571, 1294966, 1295003, 1295395, 1295491, 1296604, + 1298327, 1298527, 1298685, 1300235, 1300501, 1301193, 1301345, 1301536, 1301908, 1301969, + 1301988, 1302146, 1302158, 1302810, 1303060, 1303244, 1303275, 1303487, 1303721, 1303831, + 1303943, 1304875, 1305210, 1305677, 1305687, 1306397, 1306865, 1307044, 1307745, 1307926, + 1308080, 1308680, 1309204, 1309475, 1310596, 1312574, 1313313, 1313764, 1313792, 1313963, + 1314093, 1314284, 1314743, 1315154, 1315292, 1315503, 1315994, 1316517, 1316872, 1316909, + 1317089, 1317327, 1318223, 1319657, 1321070, 1321083, 1321495, 1321517, 1322195, 1322221, + 1322293, 1322330, 1322471, 1322496, 1322569, 1322634, 1322716, 1322859, 1323066, 1323356, + 1323530, 1323539, 1323614, 1323868, 1323925, 1328650, 1329210, 1332937, 1333431, 1335482, + 1338092, 1342268, 1345890, 1346245, 1346532, 1346613, 1346783, 1347371, 1347858, 1348077, + 1348468, 1349166, 1349298, 1349335, 1350775, 1350809, 1351329, 1352877 + }; + int[] array2 = { + 14402, 14403, 14404, 14405, 14406, 14407, 23246, 23247, 23248, 23249, 23250, 23936, 23937, + 23938, 23939, 23940, 23941, 23942, 29721, 29722, 29723, 29724, 29725, 30226, 30227, 30228, + 30229, 30230, 32141, 32142, 32143, 47737, 47738, 47739, 47740, 47741, 47742, 47743, 47744, + 47745, 47746, 47747, 47748, 47749, 47750, 47751, 47752, 68770, 68771, 68772, 68773, 68774, + 68775, 68776, 68777, 68778, 68779, 68780, 72301, 72302, 83071, 83072, 83073, 83074, 85302, + 85303, 85304, 85305, 85306, 85307, 85308, 85309, 85310, 85311, 85312, 85313, 85314, 85315, + 85316, 97108, 97109, 97110, 97111, 103442, 103443, 103444, 103445, 103446, 103447, 103448, + 103449, 103450, 103451, 103452, 103453, 103454, 103455, 103456, 103457, 103458, 103459, + 103460, 103461, 103462, 103463, 103464, 103465, 103466, 103467, 103468, 103469, 128488, + 128489, 128490, 128491, 128492, 128493, 135003, 135004, 135005, 135006, 135007, 135008, + 135009, 135010, 135011, 135012, 135013, 135014, 140363, 140364, 140365, 140366, 140367, + 140368, 140369, 140370, 140371, 140372, 149844, 149845, 149846, 149847, 149848, 149849, + 149850, 149851, 149852, 149853, 149854, 149855, 149856, 149857, 149858, 149859, 149860, + 149861, 149862, 149863, 149864, 172805, 172806, 172807, 172808, 172809, 172810, 172811, + 172812, 172813, 172814, 172815, 172816, 172817, 172818, 172819, 172820, 172821, 172822, + 172823, 172824, 172825, 172826, 172827, 172828, 172829, 172830, 172831, 172832, 172833, + 172834, 172835, 172836, 172837, 172838, 172839, 172840, 172841, 172842, 172843, 172844, + 172845, 172846, 172847, 172848, 172849, 172850, 172851, 172852, 172853, 172854, 172855, + 172856, 172857, 172858, 172859, 172860, 172861, 172862, 172863, 172864, 172865, 172866, + 172867, 172868, 172869, 172870, 172871, 202530, 202531, 202532, 209488, 209489, 209490, + 209491, 209492, 209493, 209494, 209495, 209496, 209497, 209498, 209499, 209500, 209501, + 209502, 209503, 209504, 209505, 209506, 225554, 225555, 225556, 225557, 225558, 225559, + 225560, 225561, 225562, 225563, 225564, 225565, 225566, 225567, 225568, 225569, 225570, + 225571, 225572, 225573, 225574, 225575, 225576, 225577, 225578, 225579, 225580, 225581, + 227917, 227918, 227919, 227920, 227921, 227922, 227923, 227924, 227925, 227926, 227927, + 227928, 227929, 227930, 227931, 227932, 227933, 227934, 227935, 227936, 227937, 227938, + 227939, 252773, 252774, 252775, 252776, 252777, 252778, 252779, 252780, 252781, 252782, + 252783, 252784, 252785, 252786, 252787, 252788, 252789, 252790, 252791, 252792, 252793, + 252794, 278695, 278696, 278697, 278698, 278699, 301237, 301238, 301239, 301240, 301241, + 301242, 301243, 301244, 301245, 301246, 301247, 301248, 301249, 301250, 301251, 301252, + 301253, 301254, 301255, 301256, 301257, 301258, 301259, 301260, 301261, 301262, 301263, + 301264, 301265, 320515, 320516, 320517, 320518, 320519, 320520, 320521, 320522, 320523, + 320524, 320525, 320526, 320527, 320528, 320529, 320530, 320531, 320532, 320533, 320534, + 320535, 320536, 320537, 320538, 320539, 320540, 320541, 320542, 320543, 320544, 320545, + 320546, 320547, 320548, 329641, 329642, 329643, 329644, 329645, 329646, 329647, 329648, + 329649, 329650, 329651, 329652, 329653, 329654, 329655, 329656, 329657, 329658, 329659, + 342703, 342704, 342705, 342706, 349520, 349521, 349522, 349523, 349524, 349525, 349526, + 349527, 349528, 349529, 349530, 362716, 362717, 362718, 362719, 362720, 362721, 362722, + 362723, 362724, 362725, 362726, 362727, 378643, 378644, 378645, 378646, 390154, 390155, + 390156, 390157, 390158, 390159, 390160, 390161, 390162, 390163, 390164, 390165, 390166, + 390167, 390168, 390169, 395108, 395109, 395110, 395111, 395112, 395113, 395114, 395115, + 403260, 403261, 403262, 403263, 403264, 403265, 403266, 403267, 403268, 403269, 403270, + 403271, 417315, 417316, 417317, 417318, 417319, 417320, 432653, 432654, 432655, 432656, + 432657, 432658, 432659, 432660, 432661, 432662, 432663, 432664, 432665, 432666, 432667, + 432668, 432669, 432670, 432671, 432672, 432673, 432674, 432675, 432676, 432677, 432678, + 449394, 449395, 449396, 449397, 449398, 459961, 459962, 459963, 459964, 474537, 474538, + 474539, 474540, 474541, 474542, 474543, 474544, 474545, 474546, 474547, 474548, 474549, + 474550, 474551, 474552, 474553, 474554, 474555, 474556, 474557, 474558, 474559, 474560, + 474561, 474562, 474563, 474564, 474565, 474566, 474567, 474568, 474569, 474570, 474571, + 474572, 474573, 474574, 474575, 474576, 474577, 474578, 474579, 474580, 474581, 474582, + 474583, 474584, 474585, 474586, 474587, 474588, 474589, 474590, 474591, 474592, 474593, + 474594, 474595, 474596, 474597, 483571, 483572, 483573, 483574, 483575, 483576, 489641, + 489642, 489643, 489644, 489645, 489646, 489647, 489648, 489649, 489650, 489651, 491296, + 491297, 491298, 495868, 495869, 495870, 502769, 502770, 502771, 502772, 502773, 502774, + 502775, 502776, 502777, 502778, 502779, 502780, 502781, 502782, 502783, 513810, 513811, + 513812, 513813, 513814, 513815, 513816, 513817, 513818, 513819, 513820, 513821, 513822, + 513823, 513824, 513825, 513826, 513827, 513828, 513829, 513830, 513831, 513832, 517220, + 517221, 517222, 517223, 517224, 517225, 517226, 517227, 519778, 519779, 519780, 519781, + 519782, 519783, 519784, 519785, 524240, 524241, 524242, 524243, 524244, 524245, 524246, + 524247, 524248, 524249, 527255, 527256, 527257, 527258, 527259, 533697, 533698, 533699, + 533700, 533701, 533702, 533703, 533704, 533705, 533706, 533707, 533708, 533709, 539237, + 539238, 539239, 539240, 539241, 539242, 539243, 562203, 562204, 562205, 562206, 569773, + 569774, 569775, 569776, 569777, 569778, 569779, 569780, 569781, 569782, 569783, 569784, + 569785, 569786, 569787, 569788, 569789, 569790, 569791, 569792, 569793, 569794, 569795, + 569796, 569797, 569798, 569799, 569800, 569801, 569802, 569803, 569804, 569805, 569806, + 569807, 569808, 569809, 569810, 569811, 569812, 569813, 569814, 569815, 569816, 569817, + 569818, 569819, 569820, 569821, 580161, 580162, 580163, 580164, 580165, 580166, 580167, + 580168, 580169, 580170, 580171, 580172, 580173, 580174, 580175, 580176, 588299, 588300, + 588301, 588302, 588303, 588304, 588305, 588306, 588307, 588308, 588309, 588310, 588311, + 588312, 588313, 588314, 588315, 588316, 588317, 588318, 588319, 588320, 588321, 588322, + 588323, 588324, 588325, 588326, 588327, 588328, 588329, 588330, 588331, 588332, 588333, + 588334, 588335, 608580, 608581, 608582, 608583, 608584, 608585, 608586, 608587, 608588, + 608589, 608590, 608591, 608592, 608593, 608594, 608595, 608596, 608597, 608598, 608599, + 608600, 608601, 608602, 608603, 608604, 608605, 618326, 618327, 618328, 618329, 618330, + 618331, 618332, 618333, 618334, 618335, 618336, 618337, 618338, 618339, 618340, 618341, + 618342, 618343, 618344, 618345, 618346, 618347, 618348, 618349, 626895, 626896, 626897, + 626898, 626899, 626900, 635313, 635314, 635315, 635316, 635317, 635318, 635319, 635320, + 635321, 635322, 635323, 635324, 635325, 635326, 635327, 635328, 635329, 635330, 635331, + 635332, 635333, 635334, 635335, 635336, 635337, 635338, 635339, 635340, 635341, 635342, + 635343, 635344, 635345, 635346, 635347, 635348, 635349, 635350, 635351, 635352, 635353, + 635354, 635355, 648087, 648088, 648089, 648090, 648091, 648092, 648093, 648094, 648095, + 648096, 648097, 648098, 648099, 648100, 648101, 648102, 648103, 648104, 648105, 648106, + 648107, 648108, 648109, 648110, 661574, 661575, 661576, 661577, 674566, 674567, 674568, + 674569, 674570, 674571, 674572, 674573, 674574, 674575, 674576, 674577, 674578, 674579, + 674580, 674581, 674582, 674583, 674584, 674585, 689328, 689329, 689330, 689331, 689332, + 689333, 689334, 689335, 689336, 689337, 697978, 697979, 697980, 697981, 697982, 697983, + 697984, 697985, 697986, 697987, 697988, 697989, 697990, 697991, 697992, 697993, 697994, + 726676, 726677, 726678, 726679, 726680, 726681, 782220, 782221, 782222, 782223, 782224, + 782225, 782226, 782227, 782228, 782229, 782230, 782231, 782232, 782233, 782234, 782235, + 782236, 782237, 782238, 782239, 797574, 797575, 797576, 797577, 797578, 797579, 797580, + 797581, 797582, 804283, 804284, 804285, 822332, 822333, 822334, 822335, 822336, 831020, + 831021, 831022, 831023, 831024, 831025, 831026, 831027, 831028, 831029, 831030, 831031, + 831032, 831033, 831034, 831035, 831036, 831037, 831038, 831039, 831040, 847227, 847228, + 847229, 847230, 847231, 847232, 847233, 847234, 847235, 847236, 847237, 847238, 847239, + 847240, 847241, 847242, 847243, 847244, 847245, 857616, 857617, 857618, 857619, 857620, + 857621, 857622, 857623, 857624, 857625, 867324, 867325, 867326, 867327, 867328, 867329, + 867330, 867331, 867332, 867333, 867334, 867335, 867336, 867337, 867338, 867339, 877587, + 877588, 877589, 877590, 877591, 877592, 877593, 877594, 877595, 877596, 877597, 877598, + 877599, 877600, 877601, 877602, 877603, 877604, 877605, 877606, 877607, 877608, 877609, + 877610, 877611, 877612, 877613, 877614, 877615, 896235, 896236, 896237, 896238, 896239, + 896240, 916629, 916630, 916631, 916632, 929361, 929362, 929363, 929364, 929365, 929366, + 929367, 929368, 929369, 929370, 929371, 948695, 948696, 948697, 948698, 948699, 948700, + 948701, 948702, 949573, 949574, 957768, 957769, 957770, 957771, 957772, 957773, 957774, + 957775, 961032, 961033, 961034, 961035, 987440, 987441, 987442, 987443, 1001434, 1001435, + 1001436, 1001437, 1001438, 1001439, 1001440, 1001441, 1001442, 1001443, 1001444, 1001445, + 1001446, 1001447, 1001448, 1001449, 1001450, 1001451, 1001452, 1001453, 1001454, 1001455, + 1001456, 1001457, 1001458, 1001459, 1001460, 1009985, 1009986, 1009987, 1009988, 1009989, + 1037191, 1037192, 1037193, 1037194, 1037195, 1037196, 1037197, 1037198, 1037199, 1037200, + 1037201, 1037202, 1037203, 1037204, 1053198, 1053199, 1053200, 1053201, 1053202, 1053203, + 1053204, 1053205, 1053206, 1053207, 1053208, 1053209, 1053210, 1053211, 1053212, 1053213, + 1053214, 1053215, 1053216, 1053217, 1053218, 1053219, 1053220, 1053221, 1053222, 1053223, + 1053224, 1084019, 1084020, 1084021, 1084022, 1084023, 1084024, 1084025, 1088361, 1088362, + 1088363, 1088364, 1088365, 1088366, 1089312, 1089313, 1089314, 1089315, 1089316, 1089317, + 1089318, 1092235, 1092236, 1092237, 1092238, 1092239, 1092240, 1092241, 1092242, 1092243, + 1092244, 1102836, 1102837, 1102838, 1102839, 1102840, 1102841, 1102842, 1102843, 1102844, + 1102845, 1102846, 1102847, 1108575, 1108576, 1108577, 1108578, 1108579, 1108580, 1108581, + 1108582, 1108583, 1108584, 1108585, 1108586, 1108587, 1108588, 1108589, 1108590, 1108591, + 1108592, 1108593, 1108594, 1108595, 1108596, 1108597, 1108598, 1134091, 1134092, 1134093, + 1134094, 1134095, 1134096, 1134097, 1134098, 1134099, 1134100, 1134101, 1134102, 1134103, + 1134104, 1134105, 1134106, 1134107, 1134108, 1134109, 1134110, 1134111, 1134112, 1134113, + 1134114, 1134115, 1134116, 1134117, 1134118, 1134119, 1134120, 1134121, 1134122, 1134123, + 1134124, 1134125, 1134126, 1134127, 1134128, 1134129, 1151732, 1151733, 1151734, 1151735, + 1151736, 1151737, 1151738, 1151739, 1151740, 1151741, 1151742, 1151743, 1151744, 1151745, + 1151746, 1151747, 1199223, 1199224, 1199225, 1199226, 1203252, 1203253, 1203254, 1203255, + 1203256, 1203257, 1203258, 1203259, 1203260, 1217223, 1217224, 1217225, 1217226, 1226505, + 1226506, 1226507, 1226508, 1226509, 1226510, 1226511, 1226512, 1231411, 1231412, 1231413, + 1231414, 1231415, 1231416, 1231417, 1231418, 1231419, 1231420, 1231421, 1231422, 1231423, + 1243464, 1243465, 1243466, 1243467, 1243468, 1243469, 1243470, 1247919, 1247920, 1247921, + 1255972, 1255973, 1255974, 1255975, 1255976, 1255977, 1255978, 1255979, 1255980, 1263675, + 1263676, 1263677, 1263678, 1263679, 1277693, 1277694, 1277695, 1277696, 1277697, 1277698, + 1277699, 1277700, 1283492, 1283493, 1283494, 1283495, 1283496, 1283497, 1283498, 1283499, + 1283500, 1283501, 1283502, 1283503, 1283504, 1283505, 1283506, 1283507, 1283508, 1283509, + 1283510, 1283511, 1283512, 1283513, 1283514, 1325789, 1325790, 1325791, 1325792, 1325793, + 1325794, 1325795, 1325796, 1325797, 1325798, 1325799 + }; MutableRoaringBitmap rb1 = MutableRoaringBitmap.bitmapOf(array1); MutableRoaringBitmap rb2 = MutableRoaringBitmap.bitmapOf(array2); MutableRoaringBitmap rrb1 = rb1.clone(); @@ -858,8 +875,10 @@ public void testOr001() { @Test public void testAndNot() { - int[] array1 = {39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, - 39184, 39185, 39186, 39187, 39188}; + int[] array1 = { + 39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, 39184, 39185, + 39186, 39187, 39188 + }; int[] array2 = {14205}; MutableRoaringBitmap rb1 = MutableRoaringBitmap.bitmapOf(array1); MutableRoaringBitmap rb2 = MutableRoaringBitmap.bitmapOf(array2); @@ -909,7 +928,6 @@ public void testHighBits() { } } - @Test public void testCheckedRemove() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -932,7 +950,6 @@ public void testCheckedRemove() { } } - @Test public void testCheckedAdd() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -980,13 +997,13 @@ public void testSetUtilIntersection() { assertTrue(Arrays.equals(expectedresult, result)); } - @Test public void testXORSimple() { MutableRoaringBitmap a = MutableRoaringBitmap.bitmapOf(73647, 83469); - MutableRoaringBitmap b = MutableRoaringBitmap.bitmapOf(1, 2, 3, 5, 6, 8, 9, 10, 11, 13, 14, 16, - 17, 18, 19, 20, 21, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 39, 40, 41, 50, 51, 69, - 79, 80, 81, 88, 89, 172); + MutableRoaringBitmap b = + MutableRoaringBitmap.bitmapOf( + 1, 2, 3, 5, 6, 8, 9, 10, 11, 13, 14, 16, 17, 18, 19, 20, 21, 25, 26, 27, 28, 29, 30, 32, + 33, 34, 35, 36, 37, 39, 40, 41, 50, 51, 69, 79, 80, 81, 88, 89, 172); MutableRoaringBitmap rxor = ImmutableRoaringBitmap.xor(a, b); MutableRoaringBitmap ror = MutableRoaringBitmap.or(a, b); assertTrue(rxor.equals(ror)); @@ -1009,25 +1026,23 @@ public void testRank() { } } - @Test public void testRankBigInts() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); for (int k = 0; k < 100000; k += 7) { - rb.add((1<<31)+k); + rb.add((1 << 31) + k); } for (int k = 100000; k < 200000; k += 1000) { - rb.add((1<<31)+k); + rb.add((1 << 31) + k); } for (int k = 0; k < 100000; ++k) { - assertEquals(1 + k / 7, rb.rank((1<<31)+k)); + assertEquals(1 + k / 7, rb.rank((1 << 31) + k)); } for (int k = 100000; k < 200000; ++k) { - assertEquals(1 + 100000 / 7 + 1 + (k - 100000) / 1000, rb.rank((1<<31)+k)); + assertEquals(1 + 100000 / 7 + 1 + (k - 100000) / 1000, rb.rank((1 << 31) + k)); } } - @Test public void testSelect() { for (int gap = 1; gap <= 1024; gap *= 2) { @@ -1041,16 +1056,15 @@ public void testSelect() { } } - @Test public void testSelectBigInts() { for (int gap = 1; gap <= 1024; gap *= 2) { MutableRoaringBitmap rb = new MutableRoaringBitmap(); for (int k = 0; k < 100000; k += gap) { - rb.add((1<<31)+k); + rb.add((1 << 31) + k); } for (int k = 0; k < 100000 / gap; ++k) { - assertEquals((1<<31)+k * gap, rb.select(k)); + assertEquals((1 << 31) + k * gap, rb.select(k)); } } } @@ -1072,14 +1086,12 @@ public void testLimit() { } } - - @Test public void testLimitBitInts() { for (int gap = 1; gap <= 1024; gap *= 2) { MutableRoaringBitmap rb = new MutableRoaringBitmap(); for (int k = 0; k < 100000; k += gap) { - rb.add((1<<31)+k); + rb.add((1 << 31) + k); } int thiscard = rb.getCardinality(); for (int k = 0; k < thiscard; k += 100) { @@ -1091,59 +1103,69 @@ public void testLimitBitInts() { } } - @Test public void testHorizontalOrCardinality() { int[] vals = {65535, 131071, 196607, 262143, 327679, 393215, 458751, 524287}; final MutableRoaringBitmap[] b = new MutableRoaringBitmap[2]; b[0] = MutableRoaringBitmap.bitmapOf(vals); b[1] = MutableRoaringBitmap.bitmapOf(vals); - MutableRoaringBitmap a = BufferFastAggregation.or(new Iterator() { - int k = 0; - - @Override - public boolean hasNext() { - return k < b.length; - } - - @Override - public void remove() {} - - @Override - public ImmutableRoaringBitmap next() { - return b[k++]; - } - }); + MutableRoaringBitmap a = + BufferFastAggregation.or( + new Iterator() { + int k = 0; + + @Override + public boolean hasNext() { + return k < b.length; + } + + @Override + public void remove() {} + + @Override + public ImmutableRoaringBitmap next() { + return b[k++]; + } + }); assertEquals(8, a.getCardinality()); } - - @Test + @Test public void testHorizontalOrCardinalityBigInts() { - int[] vals = {(1<<31)+65535, (1<<31)+131071, (1<<31)+196607, (1<<31)+262143, (1<<31)+327679, (1<<31)+393215, (1<<31)+458751, (1<<31)+524287}; + int[] vals = { + (1 << 31) + 65535, + (1 << 31) + 131071, + (1 << 31) + 196607, + (1 << 31) + 262143, + (1 << 31) + 327679, + (1 << 31) + 393215, + (1 << 31) + 458751, + (1 << 31) + 524287 + }; final MutableRoaringBitmap[] b = new MutableRoaringBitmap[2]; b[0] = MutableRoaringBitmap.bitmapOf(vals); b[1] = MutableRoaringBitmap.bitmapOf(vals); - MutableRoaringBitmap a = BufferFastAggregation.or(new Iterator() { - int k = 0; - - @Override - public boolean hasNext() { - return k < b.length; - } - - @Override - public void remove() {} - - @Override - public ImmutableRoaringBitmap next() { - return b[k++]; - } - }); + MutableRoaringBitmap a = + BufferFastAggregation.or( + new Iterator() { + int k = 0; + + @Override + public boolean hasNext() { + return k < b.length; + } + + @Override + public void remove() {} + + @Override + public ImmutableRoaringBitmap next() { + return b[k++]; + } + }); assertEquals(8, a.getCardinality()); } - @Test public void testContains() throws IOException { MutableRoaringBitmap rbm1 = new MutableRoaringBitmap(); @@ -1263,7 +1285,6 @@ public void andnottest4() { assertEquals(rb2, off); rb2.andNot(rb); assertEquals(rb2, off); - } @Test @@ -1430,7 +1451,6 @@ public void andtest3() { final int[] arrayres = rrand.toArray(); assertTrue(Arrays.equals(arrayand, arrayres)); - } @Test @@ -1473,7 +1493,6 @@ public void andtest4() { final MutableRoaringBitmap rc = MutableRoaringBitmap.and(rb, rb2); rb.and(rb2); assertEquals(rc.getCardinality(), rb.getCardinality()); - } @Test @@ -1523,7 +1542,7 @@ public void trimTest() { MappeableContainerPointer cp = ra.getContainerPointer(); while (cp.getContainer() != null) { if (cp.isBitmapContainer()) { - ; //nothing wasted + ; // nothing wasted } else if (cp.isRunContainer()) { MappeableRunContainer rc = (MappeableRunContainer) cp.getContainer(); wastedBytes += Short.BYTES * (rc.valueslength.limit() - rc.numberOfRuns()); @@ -1633,8 +1652,7 @@ public void cardinalityTest() { } assertEquals(MutableRoaringBitmap.and(rb, rb2).getCardinality(), N / offset); assertEquals(MutableRoaringBitmap.or(rb, rb2).getCardinality(), 2 * N - N / offset); - assertEquals(MutableRoaringBitmap.xor(rb, rb2).getCardinality(), - 2 * N - 2 * N / offset); + assertEquals(MutableRoaringBitmap.xor(rb, rb2).getCardinality(), 2 * N - 2 * N / offset); } } } @@ -1995,15 +2013,14 @@ public void flipTestBigInt() { final MutableRoaringBitmap rb = new MutableRoaringBitmap(); rb.add((int) (Integer.MAX_VALUE + 100000L)); rb.add((int) (Integer.MAX_VALUE + 100002L)); - final MutableRoaringBitmap rb2 = MutableRoaringBitmap.flip(rb, Integer.MAX_VALUE+100001L , - Integer.MAX_VALUE+200000L); + final MutableRoaringBitmap rb2 = + MutableRoaringBitmap.flip(rb, Integer.MAX_VALUE + 100001L, Integer.MAX_VALUE + 200000L); assertEquals(99999, rb2.getCardinality()); assertTrue(rb2.contains((int) (Integer.MAX_VALUE + 100000L))); assertFalse(rb2.contains((int) (Integer.MAX_VALUE + 100002L))); assertTrue(rb2.contains((int) (Integer.MAX_VALUE + 199999L))); } - @Test public void flipTestBig() { final int numCases = 1000; @@ -2019,9 +2036,8 @@ public void flipTestBig() { end = start + r.nextInt(100); } rb.flip(start, end); - if (start < end) - { - bs.flip((int)start, (int) end); // throws exception + if (start < end) { + bs.flip((int) start, (int) end); // throws exception } // otherwise // insert some more ANDs to keep things sparser @@ -2031,7 +2047,7 @@ public void flipTestBig() { final long startM = r.nextInt(65536 * 20); final long endM = startM + 100000; mask.flip(startM, endM); - mask1.flip((int)startM, (int)endM); + mask1.flip((int) startM, (int) endM); mask.flip(0L, 65536L * 20 + 100000); mask1.flip(0, 65536 * 20 + 100000); rb.and(mask); @@ -2068,20 +2084,19 @@ public void flipTestBigA() { } if ((i & 1) == 0) { - rb2 = MutableRoaringBitmap.flip(rb1, (long)start, (long)end); + rb2 = MutableRoaringBitmap.flip(rb1, (long) start, (long) end); // tweak the other, catch bad sharing long r1 = r.nextInt(65536 * 20); long r2 = r.nextInt(65536 * 20); rb1.flip(r1, r2); } else { - rb1 = MutableRoaringBitmap.flip(rb2, (long) start,(long) end); + rb1 = MutableRoaringBitmap.flip(rb2, (long) start, (long) end); long r1 = r.nextInt(65536 * 20); long r2 = r.nextInt(65536 * 20); rb2.flip(r1, r2); } - if (start < end) - { + if (start < end) { bs.flip(start, end); // throws exception } // otherwise @@ -2091,7 +2106,7 @@ public void flipTestBigA() { final BitSet mask1 = new BitSet(); final int startM = r.nextInt(65536 * 20); final int endM = startM + 100000; - mask.flip((long)startM, (long)endM); + mask.flip((long) startM, (long) endM); mask1.flip(startM, endM); mask.flip(0L, 65536L * 20 + 100000); mask1.flip(0, 65536 * 20 + 100000); @@ -2147,7 +2162,6 @@ public void ortest() { rr.or(rr2); final int[] arrayirr = rr.toArray(); assertTrue(Arrays.equals(array, arrayirr)); - } @Test @@ -2352,7 +2366,6 @@ public void ortest4() { assertEquals(rb2.getCardinality() + rb.getCardinality(), orresult2.getCardinality()); rb.or(rb2); assertTrue(rb.equals(orresult2)); - } @Test @@ -2363,11 +2376,11 @@ public void orNot() { rb.add(2); rb.add(1); rb.add(1 << 16); // 65 536 - rb.add(2 << 16); //131 072 - rb.add(3 << 16); //196 608 + rb.add(2 << 16); // 131 072 + rb.add(3 << 16); // 196 608 - rb2.add(1 << 16);// 65 536 - rb2.add(3 << 16);//196 608 + rb2.add(1 << 16); // 65 536 + rb2.add(3 << 16); // 196 608 rb.orNot(rb2, (4 << 16) - 1); @@ -2382,7 +2395,6 @@ public void orNot() { assertFalse(iterator.hasNext()); } - @Test public void orNotRegressionTest() { long len = 3L; @@ -2419,7 +2431,6 @@ public void orNotLimitLowerThanFirstPreservesBitmap() { assertEquals(one, MutableRoaringBitmap.bitmapOf(32)); } - @Test public void orNotLimitHigherThanFirstBitPreservesBitmap() { MutableRoaringBitmap one = new MutableRoaringBitmap(); @@ -2439,9 +2450,9 @@ public void orNotWithSparseBitmaps() { rb.add(0); rb.add(1 << 16); // 65 536 - rb.add(3 << 16); //196 608 + rb.add(3 << 16); // 196 608 - rb2.add((4 << 16) - 1); //262 143 + rb2.add((4 << 16) - 1); // 262 143 rb.orNot(rb2, 4 << 16); @@ -2462,8 +2473,8 @@ public void orNotWithOtherBiggerThanOriginal() { rb.add(1); MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(1 << 14); //16 384 - rb2.add(3 << 16); //196 608 + rb2.add(1 << 14); // 16 384 + rb2.add(3 << 16); // 196 608 rb.orNot(rb2, (5 << 16)); assertEquals((5 << 16) - 2, rb.getCardinality()); @@ -2484,9 +2495,9 @@ public void orNotWithOtherBiggerThanOriginalAndEndRange() { rb.add(1); final MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); - rb2.add(3 << 16); //196 608 + rb2.add(3 << 16); // 196 608 - rb.orNot(rb2, (2 << 16) + (2 << 14)); //131 072 + 32 768 = 163 840 + rb.orNot(rb2, (2 << 16) + (2 << 14)); // 131 072 + 32 768 = 163 840 assertEquals((2 << 16) + (2 << 14), rb.getCardinality()); final IntIterator iterator = rb.getIntIterator(); @@ -2503,8 +2514,8 @@ public void orNotWithOriginalBiggerThanOther() { rb.add(1); rb.add(1 << 16); // 65 536 - rb.add(2 << 16); //131 072 - rb.add(3 << 16); //196 608 + rb.add(2 << 16); // 131 072 + rb.add(3 << 16); // 196 608 MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); @@ -2526,8 +2537,8 @@ public void orNotWithOriginalBiggerThanOther2() { rb.add(1); rb.add((1 << 16) - 1); // 65 535 rb.add(1 << 16); // 65 536 - rb.add(2 << 16); //131 072 - rb.add(3 << 16); //196 608 + rb.add(2 << 16); // 131 072 + rb.add(3 << 16); // 196 608 MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); @@ -2566,7 +2577,6 @@ public void randomTest() { rTest(65536 * 16); } - public void rTest(final int N) { for (int gap = 1; gap <= 65536; gap *= 2) { final BitSet bs1 = new BitSet(); @@ -2609,10 +2619,14 @@ public void rTest(final int N) { throw new RuntimeException("bug inplace and"); } if (!t.equals(MutableRoaringBitmap.and(rb1, rb2))) { - System.out - .println(t.highLowContainer.getContainerAtIndex(0).getClass().getCanonicalName()); - System.out.println(MutableRoaringBitmap.and(rb1, rb2).highLowContainer - .getContainerAtIndex(0).getClass().getCanonicalName()); + System.out.println( + t.highLowContainer.getContainerAtIndex(0).getClass().getCanonicalName()); + System.out.println( + MutableRoaringBitmap.and(rb1, rb2) + .highLowContainer + .getContainerAtIndex(0) + .getClass() + .getCanonicalName()); throw new RuntimeException("bug inplace and"); } @@ -2637,7 +2651,6 @@ public void rTest(final int N) { if (!t.toString().equals(MutableRoaringBitmap.or(rb1, rb2).toString())) { throw new RuntimeException("bug or"); } - } // testing XOR clonebs1 = (BitSet) bs1.clone(); @@ -2655,8 +2668,8 @@ public void rTest(final int N) { if (!t.equals(MutableRoaringBitmap.xor(rb1, rb2))) { System.out.println(t); System.out.println(MutableRoaringBitmap.xor(rb1, rb2)); - System.out - .println(Arrays.equals(t.toArray(), MutableRoaringBitmap.xor(rb1, rb2).toArray())); + System.out.println( + Arrays.equals(t.toArray(), MutableRoaringBitmap.xor(rb1, rb2).toArray())); throw new RuntimeException("bug xor"); } } @@ -2705,7 +2718,6 @@ public void rTest(final int N) { } } } - } } @@ -2724,7 +2736,6 @@ public void simplecardinalityTest() { rb.add(k * gap); assertEquals(rb.getCardinality(), N); } - } @Test @@ -2759,12 +2770,11 @@ public void testSerialization() throws IOException, ClassNotFoundException { assertTrue(rr.equals(rrback)); } - @Test public void testSerializationBigInts() throws IOException, ClassNotFoundException { final MutableRoaringBitmap rr = new MutableRoaringBitmap(); for (int k = 65000; k < 2 * 65000; ++k) { - rr.add((1<<31)+k); + rr.add((1 << 31) + k); } final ByteArrayOutputStream bos = new ByteArrayOutputStream(); // Note: you could use a file output steam instead of @@ -2841,7 +2851,6 @@ public void testSerialization4() throws IOException, ClassNotFoundException { assertTrue(rr.equals(rrback)); } - @Test public void sparseXor() { final MutableRoaringBitmap rr1 = new MutableRoaringBitmap(); @@ -2857,7 +2866,6 @@ public void sparseXor() { assertTrue(xor.contains(1)); } - @Test public void XORtest() { final MutableRoaringBitmap rr = new MutableRoaringBitmap(); @@ -2941,15 +2949,14 @@ public void testIterator() { assertTrue(copy2.equals(rb)); } - @Test public void testIteratorBigInts() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); for (int k = 0; k < 4000; ++k) { - rb.add((1<<31)+k); + rb.add((1 << 31) + k); } for (int k = 0; k < 1000; ++k) { - rb.add((1<<31)+k * 100); + rb.add((1 << 31) + k * 100); } MutableRoaringBitmap copy1 = new MutableRoaringBitmap(); for (int x : rb) { @@ -2976,10 +2983,6 @@ public void testIteratorBigInts() { assertTrue(copy2.equals(rb)); } - - - - @Test public void testIteratorMapped() { MutableRoaringBitmap orb = new MutableRoaringBitmap(); @@ -3014,8 +3017,7 @@ public void testIteratorMapped() { assertTrue(copy2.equals(toMapped(orb))); } - - @Test + @Test public void testIteratorMappedBigInts() { MutableRoaringBitmap orb = new MutableRoaringBitmap(); for (int k = 0; k < 4000; ++k) { @@ -3049,9 +3051,7 @@ public void testIteratorMappedBigInts() { assertTrue(copy2.equals(toMapped(orb))); } - - - @Test + @Test public void xortest1() { final HashSet V1 = new HashSet(); final HashSet V2 = new HashSet(); @@ -3175,7 +3175,6 @@ public void xortest4() { assertEquals(rb2.getCardinality() + rb.getCardinality(), xorresult2.getCardinality()); rb.xor(rb2); assertTrue(xorresult2.equals(rb)); - } boolean validate(MappeableBitmapContainer bc, MappeableArrayContainer ac) { @@ -3213,8 +3212,6 @@ public static boolean equals(BitSet bs, MutableRoaringBitmap rr) { return Arrays.equals(rr.toArray(), a); } - - /** * Test massive and. */ @@ -3229,7 +3226,7 @@ public void testMassiveAnd() { ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); } for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip(13L, (long) howmany / 2); + ewah[k].flip(13L, (long) howmany / 2); } for (int N = 2; N < ewah.length; ++N) { MutableRoaringBitmap answer = ewah[0]; @@ -3245,13 +3242,10 @@ public void testMassiveAnd() { MutableRoaringBitmap answer2b = BufferFastAggregation.and(z); assertTrue(answer.equals(answer2b)); assertTrue(answer.getCardinality() == answer2b.getCardinality()); - } } - - - @Test + @Test public void testMassiveAndBigInts() { MutableRoaringBitmap[] ewah = new MutableRoaringBitmap[1024]; for (int k = 0; k < ewah.length; ++k) { @@ -3259,10 +3253,10 @@ public void testMassiveAndBigInts() { } int howmany = 1000000; for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1<<31)+k); + ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); } for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip( (1L<<31)+13L, (1L<<31)+(long) howmany / 2); + ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); } for (int N = 2; N < ewah.length; ++N) { MutableRoaringBitmap answer = ewah[0]; @@ -3278,11 +3272,9 @@ public void testMassiveAndBigInts() { MutableRoaringBitmap answer2b = BufferFastAggregation.and(z); assertTrue(answer.equals(answer2b)); assertTrue(answer.getCardinality() == answer2b.getCardinality()); - } } - private static Iterator toIterator(final T[] x) { return new Iterator() { int pos = 0; @@ -3295,7 +3287,6 @@ public boolean hasNext() { @Override public void remove() {} - @Override public T next() { return x[pos++]; @@ -3303,7 +3294,6 @@ public T next() { }; } - /** * Test massive or. */ @@ -3338,7 +3328,7 @@ public void testMassiveOr() { } } -@Test + @Test public void testMassiveOrBigInts() { final int N = 128; for (int howmany = 512; howmany <= 1000000; howmany *= 2) { @@ -3347,10 +3337,10 @@ public void testMassiveOrBigInts() { ewah[k] = new MutableRoaringBitmap(); } for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add( (1<<31)+k); + ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); } for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip( (1L<<31)+13L, (1L<<31)+(long) howmany / 2); + ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); } MutableRoaringBitmap answer = ewah[0]; for (int k = 1; k < ewah.length; ++k) { @@ -3369,7 +3359,6 @@ public void testMassiveOrBigInts() { } } - /** * Test massive xor. */ @@ -3385,7 +3374,7 @@ public void testMassiveXOr() { ewah[Math.abs(k + 2 * k * k) % ewah.length].add(k); } for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip(13L, (long)howmany / 2); + ewah[k].flip(13L, (long) howmany / 2); } MutableRoaringBitmap answer = ewah[0]; @@ -3408,10 +3397,10 @@ public void testMassiveXOrBigInts() { ewah[k] = new MutableRoaringBitmap(); } for (int k = 0; k < howmany; ++k) { - ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1<<31)+k); + ewah[Math.abs(k + 2 * k * k) % ewah.length].add((1 << 31) + k); } for (int k = 3; k < ewah.length; k += 3) { - ewah[k].flip((1L<<31)+13L, (1L<<31)+(long)howmany / 2); + ewah[k].flip((1L << 31) + 13L, (1L << 31) + (long) howmany / 2); } MutableRoaringBitmap answer = ewah[0]; @@ -3425,7 +3414,6 @@ public void testMassiveXOrBigInts() { } } - @Test public void intersecttestWithRange() { MutableRoaringBitmap rr1 = new MutableRoaringBitmap(); @@ -3436,7 +3424,6 @@ public void intersecttestWithRange() { rr1.add(1L, 4L); rr1.add(6L, 10L); - // This one will be Array Containers rr2.add(0); rr2.add(2); @@ -3465,9 +3452,6 @@ public void intersecttestWithRange() { assertTrue(rr3.intersects(5, 10)); } - - - @Test public void testRandomLists() { MutableRoaringBitmap rb1 = @@ -3478,8 +3462,6 @@ public void testRandomLists() { assertTrue(rbor.equals(BufferFastAggregation.horizontal_or(rb1, rb2))); } - - @Test public void intersecttest() { final MutableRoaringBitmap rr1 = new MutableRoaringBitmap(); @@ -3506,30 +3488,33 @@ public void intersecttest() { // this had created an array out of bounds error @Test public void fliptest_Karpenske() { - long[] array = new long[] {343798, 343799, 343800, 343801, 343803, 343804, 343805, 343807, 343809, - 343811, 343812, 343815, 343816, 343817, 343818, 343819, 343821, 343825, 343827, 343828, - 343830, 343831, 343832, 343833, 343835, 343836, 343837, 343838, 343839, 343840, 343841, - 343842, 343843, 343844, 343845, 343847, 343848, 343849, 343850, 343851, 343853, 343854, - 343855, 343856, 343858, 343859, 343860, 343861, 343862, 343863, 343864, 343865, 343866, - 343868, 343869, 343874, 343875, 343877, 343879, 343880, 343881, 343882, 343883, 343887, - 343889, 343890, 343891, 343894, 343895, 343898, 343899, 343900, 343901, 343902, 343904, - 343906, 343907, 343908, 343909, 343910, 343911, 343912, 343913, 343914, 343915, 343916, - 343917, 343918, 343919, 343921, 343922, 343923, 343924, 343927, 343928, 343929, 343930, - 343931, 343932, 343933, 343934, 343935, 343938, 343939, 343941, 343942, 343943, 343944, - 343945, 343946, 343949, 343951, 343953, 343954, 343955, 343956, 343958, 343959, 343961, - 343962, 343964, 343965, 343966, 343967, 343968, 343969, 343971, 343972, 343973, 343974, - 343976, 343978, 343979, 343981, 343982, 343983, 343985, 343987, 343988, 343989, 343992, - 343993, 343994, 343995, 343996, 343997, 343998, 344000, 344001, 344002, 344003, 344004, - 344006, 344008, 344009, 344011, 344012, 344013, 344015, 344017, 344019, 344020, 344021, - 344023, 344025, 344026, 344027, 344028, 344029, 344030, 344031, 344034, 344035, 344036, - 344037, 344038, 344039, 344040, 344042, 344043, 344046, 344047}; + long[] array = + new long[] { + 343798, 343799, 343800, 343801, 343803, 343804, 343805, 343807, 343809, 343811, 343812, + 343815, 343816, 343817, 343818, 343819, 343821, 343825, 343827, 343828, 343830, 343831, + 343832, 343833, 343835, 343836, 343837, 343838, 343839, 343840, 343841, 343842, 343843, + 343844, 343845, 343847, 343848, 343849, 343850, 343851, 343853, 343854, 343855, 343856, + 343858, 343859, 343860, 343861, 343862, 343863, 343864, 343865, 343866, 343868, 343869, + 343874, 343875, 343877, 343879, 343880, 343881, 343882, 343883, 343887, 343889, 343890, + 343891, 343894, 343895, 343898, 343899, 343900, 343901, 343902, 343904, 343906, 343907, + 343908, 343909, 343910, 343911, 343912, 343913, 343914, 343915, 343916, 343917, 343918, + 343919, 343921, 343922, 343923, 343924, 343927, 343928, 343929, 343930, 343931, 343932, + 343933, 343934, 343935, 343938, 343939, 343941, 343942, 343943, 343944, 343945, 343946, + 343949, 343951, 343953, 343954, 343955, 343956, 343958, 343959, 343961, 343962, 343964, + 343965, 343966, 343967, 343968, 343969, 343971, 343972, 343973, 343974, 343976, 343978, + 343979, 343981, 343982, 343983, 343985, 343987, 343988, 343989, 343992, 343993, 343994, + 343995, 343996, 343997, 343998, 344000, 344001, 344002, 344003, 344004, 344006, 344008, + 344009, 344011, 344012, 344013, 344015, 344017, 344019, 344020, 344021, 344023, 344025, + 344026, 344027, 344028, 344029, 344030, 344031, 344034, 344035, 344036, 344037, 344038, + 344039, 344040, 344042, 344043, 344046, 344047 + }; MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); long[] indexes = array; int rangeStart = 0; for (int rangeEnd = 1; rangeEnd < indexes.length; rangeEnd++) { if (indexes[rangeEnd - 1] + 1 != indexes[rangeEnd]) { if (rangeStart == rangeEnd - 1) { - bitmap.add((int)indexes[rangeStart]); + bitmap.add((int) indexes[rangeStart]); } else { bitmap.flip(indexes[rangeStart], indexes[rangeEnd - 1] + 1); } @@ -3537,7 +3522,7 @@ public void fliptest_Karpenske() { } } if (rangeStart == indexes.length - 1) { - bitmap.add((int)indexes[rangeStart]); + bitmap.add((int) indexes[rangeStart]); } else { bitmap.flip(indexes[rangeStart], indexes[indexes.length - 1] + 1); } @@ -3607,7 +3592,6 @@ public void andCounttest3() { assertEquals(rrand.getCardinality(), rrandCount); final int rrandCountm = ImmutableRoaringBitmap.andCardinality(toMapped(rr), toMapped(rr2)); assertEquals(rrand.getCardinality(), rrandCountm); - } @Test @@ -3649,15 +3633,14 @@ public void orcount() { final MutableRoaringBitmap rror = ImmutableRoaringBitmap.or(rr, rr2); assertEquals(rror.getCardinality(), ImmutableRoaringBitmap.orCardinality(rr, rr2)); - } @Test public void testLazyOr() { MutableRoaringBitmap rb1 = new MutableRoaringBitmap(); - rb1.add(1<<16); - rb1.add(1<<18); - rb1.add(1<<19); + rb1.add(1 << 16); + rb1.add(1 << 18); + rb1.add(1 << 19); MutableRoaringBitmap rb2 = new MutableRoaringBitmap(); rb2.add(4); rb2.add(7); @@ -3669,9 +3652,9 @@ public void testLazyOr() { rb3.add(3); rb3.add(4); rb3.add(5); - rb3.add(1<<16); - rb3.add(1<<17); - rb3.add(1<<20); + rb3.add(1 << 16); + rb3.add(1 << 17); + rb3.add(1 << 20); rb1.lazyor(rb2); rb1.lazyor(rb3); MutableRoaringBitmap rb4 = new MutableRoaringBitmap(); @@ -3683,11 +3666,11 @@ public void testLazyOr() { rb4.add(7); rb4.add(8); rb4.add(9); - rb4.add(1<<16); - rb4.add(1<<17); - rb4.add(1<<18); - rb4.add(1<<19); - rb4.add(1<<20); + rb4.add(1 << 16); + rb4.add(1 << 17); + rb4.add(1 << 18); + rb4.add(1 << 19); + rb4.add(1 << 20); assertEquals(rb4, rb1); } @@ -3695,7 +3678,7 @@ public void testLazyOr() { public void testFirstLast_CreateSparseContainersAfterRun() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); rb.add(1L, 1 << 14); - for(int i = 18; i < 31; ++i) { + for (int i = 18; i < 31; ++i) { int x = 1 << i; rb.add(x); assertEquals(1, rb.first()); @@ -3727,7 +3710,7 @@ public void testFirstLast() { assertEquals(2, rb.first()); assertEquals((1 << 14) - 1, rb.last()); - rb.add(1L<< 15, 1L << 30); + rb.add(1L << 15, 1L << 30); assertEquals(2, rb.first()); assertEquals((1L << 30) - 1, rb.last()); } @@ -3741,7 +3724,8 @@ public void testAndCardinality() { baseline.add((1 << 21) + 3); baseline.add((1 << 21) + 5); assertEquals(baseline, MutableRoaringBitmap.and(baseline, baseline)); - assertEquals(baseline.getCardinality(), MutableRoaringBitmap.andCardinality(baseline, baseline)); + assertEquals( + baseline.getCardinality(), MutableRoaringBitmap.andCardinality(baseline, baseline)); } @Test @@ -3751,50 +3735,50 @@ public void addoffset() { rb.add(0xFFFF); rb.add(0x010101); for (int i = 100000; i < 200000; i += 4) { - rb.add(i); + rb.add(i); } rb.add(400000L, 1400000L); - for(int offset = 3; offset < 1000000; offset *= 3) { + for (int offset = 3; offset < 1000000; offset *= 3) { MutableRoaringBitmap rboff = MutableRoaringBitmap.addOffset(rb, offset); IntIterator i = rb.getIntIterator(); IntIterator j = rboff.getIntIterator(); - while(i.hasNext() && j.hasNext()) { - assertTrue(i.next() + offset == j.next()); - }System.out.println("offset = "+offset); - assertTrue(i.hasNext() == j.hasNext()); + while (i.hasNext() && j.hasNext()) { + assertTrue(i.next() + offset == j.next()); + } + System.out.println("offset = " + offset); + assertTrue(i.hasNext() == j.hasNext()); } - for(int offset = 1024; offset < 1000000; offset *= 2) { + for (int offset = 1024; offset < 1000000; offset *= 2) { MutableRoaringBitmap rboff = MutableRoaringBitmap.addOffset(rb, offset); IntIterator i = rb.getIntIterator(); IntIterator j = rboff.getIntIterator(); - while(i.hasNext() && j.hasNext()) { - assertTrue(i.next() + offset == j.next()); + while (i.hasNext() && j.hasNext()) { + assertTrue(i.next() + offset == j.next()); } - assertTrue(i.hasNext() == j.hasNext()); + assertTrue(i.hasNext() == j.hasNext()); } } - @Test public void issue418() { - final MutableRoaringBitmap rb = new MutableRoaringBitmap(); - rb.add(0); - assertEquals(rb.contains(0), true); - assertEquals(rb.getCardinality(), 1); - long vals[] = { 100, 0xFFFF0000L, 0xFFFF0001L }; - for(long s : vals) { - MutableRoaringBitmap shifted = MutableRoaringBitmap.addOffset(rb, s); - System.out.println("moved "+shifted); - assertEquals(shifted.contains((int)s), true); - assertEquals(shifted.getCardinality(), 1); - System.out.println("moving back by "+(-s)); + final MutableRoaringBitmap rb = new MutableRoaringBitmap(); + rb.add(0); + assertEquals(rb.contains(0), true); + assertEquals(rb.getCardinality(), 1); + long vals[] = {100, 0xFFFF0000L, 0xFFFF0001L}; + for (long s : vals) { + MutableRoaringBitmap shifted = MutableRoaringBitmap.addOffset(rb, s); + System.out.println("moved " + shifted); + assertEquals(shifted.contains((int) s), true); + assertEquals(shifted.getCardinality(), 1); + System.out.println("moving back by " + (-s)); - shifted = MutableRoaringBitmap.addOffset(shifted, -s); - System.out.println("back "+shifted); + shifted = MutableRoaringBitmap.addOffset(shifted, -s); + System.out.println("back " + shifted); - assertEquals(shifted.contains(0), true); - assertEquals(shifted.getCardinality(), 1); - } + assertEquals(shifted.contains(0), true); + assertEquals(shifted.getCardinality(), 1); + } } @Test @@ -3807,41 +3791,40 @@ public void addNegativeOffset() { rb.add(i); } rb.add(400000L, 1400000L); - for(int offset = 3; offset < 1000000; offset *= 3) { + for (int offset = 3; offset < 1000000; offset *= 3) { MutableRoaringBitmap rbposoff = MutableRoaringBitmap.addOffset(rb, offset); - if(rb.getLongCardinality() != rbposoff.getLongCardinality()) { + if (rb.getLongCardinality() != rbposoff.getLongCardinality()) { throw new RuntimeException("data loss"); } MutableRoaringBitmap rboff = MutableRoaringBitmap.addOffset(rbposoff, -offset); - if(rb.getLongCardinality() != rboff.getLongCardinality()) { + if (rb.getLongCardinality() != rboff.getLongCardinality()) { throw new RuntimeException("data loss"); } IntIterator i = rb.getIntIterator(); IntIterator j = rboff.getIntIterator(); - while(i.hasNext() && j.hasNext()) { - assertTrue(i.next() == j.next()); + while (i.hasNext() && j.hasNext()) { + assertTrue(i.next() == j.next()); } - assertTrue(i.hasNext() == j.hasNext()); + assertTrue(i.hasNext() == j.hasNext()); } - for(int offset = 1024; offset < 1000000; offset *= 2) { + for (int offset = 1024; offset < 1000000; offset *= 2) { MutableRoaringBitmap rbposoff = MutableRoaringBitmap.addOffset(rb, offset); - if(rb.getLongCardinality() != rbposoff.getLongCardinality()) { + if (rb.getLongCardinality() != rbposoff.getLongCardinality()) { throw new RuntimeException("data loss"); } MutableRoaringBitmap rboff = MutableRoaringBitmap.addOffset(rbposoff, -offset); - if(rb.getLongCardinality() != rboff.getLongCardinality()) { + if (rb.getLongCardinality() != rboff.getLongCardinality()) { throw new RuntimeException("data loss"); } IntIterator i = rb.getIntIterator(); IntIterator j = rboff.getIntIterator(); - while(i.hasNext() && j.hasNext()) { - assertTrue(i.next() == j.next()); + while (i.hasNext() && j.hasNext()) { + assertTrue(i.next() == j.next()); } - assertTrue(i.hasNext() == j.hasNext()); + assertTrue(i.hasNext() == j.hasNext()); } } - @Test public void testNextValueArray() { MutableRoaringBitmap r = new MutableRoaringBitmap(); @@ -3852,8 +3835,24 @@ public void testNextValueArray() { @Test public void regressionTestEquals370() { // see https://github.com/RoaringBitmap/RoaringBitmap/issues/370 - int[] a = {239,240,241,242,243,244,259,260,261,262,263,264,265,266,267,268,269,270,273,274,275,276,277,278,398,399,400,401,402,403,404,405,406,408,409,410,411,412,413,420,421,422,509,510,511,512,513,514,539,540,541,542,543,544,547,548,549,550,551,552,553,554,555,556,557,558,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,624,625,634,635,636,649,650,651,652,653,654,714,715,716,718,719,720,721,722,723,724,725,726,728,729,730,731,732,733,734,735,736,739,740,741,742,743,744,771,772,773}; - int[] b = {239,240,241,242,243,244,259,260,261,262,263,264,265,266,267,268,269,270,273,274,275,276,277,278,398,399,400,401,402,403,404,405,406,408,409,410,411,412,413,420,421,422,509,510,511,512,513,514,539,540,541,542,543,544,547,548,549,550,551,552,553,554,555,556,557,558,578,579,580,581,582,583,584,585,586,607,608,634,635,636,649,650,651,652,653,654,714,715,716,718,719,720,721,722,723,724,725,726,728,729,730,731,732,733,734,735,736,739,740,741,742,743,744,771,772,773}; + int[] a = { + 239, 240, 241, 242, 243, 244, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 273, + 274, 275, 276, 277, 278, 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, + 413, 420, 421, 422, 509, 510, 511, 512, 513, 514, 539, 540, 541, 542, 543, 544, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, + 588, 589, 590, 591, 592, 593, 594, 595, 624, 625, 634, 635, 636, 649, 650, 651, 652, 653, 654, + 714, 715, 716, 718, 719, 720, 721, 722, 723, 724, 725, 726, 728, 729, 730, 731, 732, 733, 734, + 735, 736, 739, 740, 741, 742, 743, 744, 771, 772, 773 + }; + int[] b = { + 239, 240, 241, 242, 243, 244, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 273, + 274, 275, 276, 277, 278, 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, + 413, 420, 421, 422, 509, 510, 511, 512, 513, 514, 539, 540, 541, 542, 543, 544, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 578, 579, 580, 581, 582, 583, 584, 585, 586, 607, + 608, 634, 635, 636, 649, 650, 651, 652, 653, 654, 714, 715, 716, 718, 719, 720, 721, 722, 723, + 724, 725, 726, 728, 729, 730, 731, 732, 733, 734, 735, 736, 739, 740, 741, 742, 743, 744, 771, + 772, 773 + }; MutableRoaringBitmap rbA = MutableRoaringBitmap.bitmapOf(a); MutableRoaringBitmap rbB = MutableRoaringBitmap.bitmapOf(b); @@ -3867,33 +3866,37 @@ public void regressionTestEquals370() { @Test public void regressionTestRemove377() { - // https://github.com/RoaringBitmap/RoaringBitmap/issues/377 - MutableRoaringBitmap map = new MutableRoaringBitmap(); - map.add(0L, 64L); - for (int i = 0; i < 64; i++) { - if (i != 30 && i != 32) { - map.remove(i); - } - } - map.remove(0L, 31L); - assertFalse(map.contains(30)); - assertTrue(map.contains(32)); + // https://github.com/RoaringBitmap/RoaringBitmap/issues/377 + MutableRoaringBitmap map = new MutableRoaringBitmap(); + map.add(0L, 64L); + for (int i = 0; i < 64; i++) { + if (i != 30 && i != 32) { + map.remove(i); + } + } + map.remove(0L, 31L); + assertFalse(map.contains(30)); + assertTrue(map.contains(32)); } @Test public void invalidCookieBuffer() { - assertThrows(IOException.class, () -> { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.deserialize(ByteBuffer.allocate(4)); - }); + assertThrows( + IOException.class, + () -> { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.deserialize(ByteBuffer.allocate(4)); + }); } @Test public void invalidCookieDataInput() { - assertThrows(IOException.class, () -> { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.deserialize(new DataInputStream(new ByteArrayInputStream(new byte[4]))); - }); + assertThrows( + IOException.class, + () -> { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.deserialize(new DataInputStream(new ByteArrayInputStream(new byte[4]))); + }); } @Test @@ -3901,7 +3904,7 @@ public void testCardinalityExceeds() { MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); long runLength = 20_000L; bitmap.add(0L, runLength); - for (int i = (1 << 16) + 1; i < 1 << 17; i+= 2) { + for (int i = (1 << 16) + 1; i < 1 << 17; i += 2) { bitmap.add(i); } long bitmapCount = 1 << 15; @@ -3919,15 +3922,15 @@ public void testCardinalityExceeds() { @Test public void testWithYourself() { - MutableRoaringBitmap b1 = MutableRoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10); + MutableRoaringBitmap b1 = MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); b1.runOptimize(); b1.or(b1); - assertTrue(b1.equals(MutableRoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10))); + assertTrue(b1.equals(MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))); b1.xor(b1); assertTrue(b1.isEmpty()); - b1 = MutableRoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10); + b1 = MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); b1.and(b1); - assertTrue(b1.equals(MutableRoaringBitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10))); + assertTrue(b1.equals(MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))); b1.andNot(b1); assertTrue(b1.isEmpty()); } @@ -3942,18 +3945,19 @@ public void testPreviousValueRegression() { @Test public void testRangeExtremeEnd() { MutableRoaringBitmap x = new MutableRoaringBitmap(); - long rangeStart = (1L << 32) - 2; + long rangeStart = (1L << 32) - 2; long rangeEnd = (1L << 32); x.add(rangeStart, rangeEnd); Assertions.assertEquals(2L, x.getLongCardinality()); Assertions.assertArrayEquals(new int[] {-2, -1}, x.toArray()); } + @Test public void issue623() { MutableRoaringBitmap r = new MutableRoaringBitmap(); r.add(65535); - r.add(65535+1); + r.add(65535 + 1); assertTrue(r.contains(65535)); assertTrue(r.contains(65535 + 1)); assertTrue(r.contains(65535L, 65535L + 1)); @@ -3965,58 +3969,56 @@ public void issue623() { } } + @Test + public void test1235() { + MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(1, 2, 3, 5); + r.flip(4); + assertEquals(r, MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5)); + } + @Test + public void test2345() { + MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5); + r.flip(1); + assertEquals(r, MutableRoaringBitmap.bitmapOf(2, 3, 4, 5)); + } - @Test - public void test1235() { - MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(1, 2, 3, 5); - r.flip(4); - assertEquals(r, MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5)); - } - - @Test - public void test2345() { - MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(1, 2, 3, 4, 5); - r.flip(1); - assertEquals(r, MutableRoaringBitmap.bitmapOf(2, 3, 4, 5)); - } - - @Test - public void testPreviousValueLimit() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(1); - assertEquals(-1l, bitmap.previousValue(0)); - } + @Test + public void testPreviousValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(1); + assertEquals(-1l, bitmap.previousValue(0)); + } - @Test - public void testPreviousAbsentValueLimit() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(0); - assertEquals(-1L, bitmap.previousAbsentValue(0)); - } + @Test + public void testPreviousAbsentValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(0); + assertEquals(-1L, bitmap.previousAbsentValue(0)); + } - @Test - public void testNextValueLimit() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(0xffffffff-1); - assertEquals(-1L, bitmap.nextValue(0xffffffff)); - } + @Test + public void testNextValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(0xffffffff - 1); + assertEquals(-1L, bitmap.nextValue(0xffffffff)); + } - @Test - public void testNextAbsentValueLimit() { - MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); - bitmap.add(-1); - assertEquals(-1L, bitmap.nextAbsentValue(-1)); - } + @Test + public void testNextAbsentValueLimit() { + MutableRoaringBitmap bitmap = new MutableRoaringBitmap(); + bitmap.add(-1); + assertEquals(-1L, bitmap.nextAbsentValue(-1)); + } - @Test - public void testSelectRange() { - MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOfRange(1, 1000000); - for(int i = 1; i <= 1000000; i+= 1000) { - for(int j = i; j <= 1000000; j+= 1000) { - MutableRoaringBitmap rr = r.selectRange(i, j); - assertEquals(rr, MutableRoaringBitmap.bitmapOfRange(i, j)); - } - } + @Test + public void testSelectRange() { + MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOfRange(1, 1000000); + for (int i = 1; i <= 1000000; i += 1000) { + for (int j = i; j <= 1000000; j += 1000) { + MutableRoaringBitmap rr = r.selectRange(i, j); + assertEquals(rr, MutableRoaringBitmap.bitmapOfRange(i, j)); + } } + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java index 97b4fc705..cea078161 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestRunContainer.java @@ -1,22 +1,33 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.buffer.MappeableArrayContainer.DEFAULT_MAX_SIZE; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; import org.roaringbitmap.CharIterator; import org.roaringbitmap.IntIterator; import org.roaringbitmap.RunContainer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.buffer.MappeableArrayContainer.DEFAULT_MAX_SIZE; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Random; +import java.util.Set; @Execution(ExecutionMode.CONCURRENT) public class TestRunContainer { @@ -36,25 +47,25 @@ private static ImmutableRoaringBitmap toMapped(MutableRoaringBitmap r) { @Test public void testToString() { MappeableRunContainer rc = new MappeableRunContainer(32200, 35000); - rc.add((char)-1); + rc.add((char) -1); assertEquals("[32200,34999][65535,65535]", rc.toString()); } @Test public void testRunOpti() { MutableRoaringBitmap mrb = new MutableRoaringBitmap(); - for(int r = 0; r< 100000; r+=3 ) { + for (int r = 0; r < 100000; r += 3) { mrb.add(r); } mrb.add(1000000); - for(int r = 2000000; r < 3000000; ++r) { + for (int r = 2000000; r < 3000000; ++r) { mrb.add(r); } MutableRoaringBitmap m2 = mrb.clone(); m2.runOptimize(); IntIterator x = m2.getReverseIntIterator(); int count = 0; - while(x.hasNext()) { + while (x.hasNext()) { x.next(); count++; } @@ -104,8 +115,8 @@ static int[] generateUniformHash(Random rand, int N, int Max) { return ans; } - private static void getSetOfMappeableRunContainers(ArrayList set, - ArrayList setb) { + private static void getSetOfMappeableRunContainers( + ArrayList set, ArrayList setb) { MappeableRunContainer r1 = new MappeableRunContainer(); r1 = (MappeableRunContainer) r1.iadd(0, (1 << 16)); MappeableContainer b1 = new MappeableArrayContainer(); @@ -163,7 +174,6 @@ private static void getSetOfMappeableRunContainers(ArrayList { - MappeableContainer rc = new MappeableRunContainer(); - rc.iadd(10, 9); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer rc = new MappeableRunContainer(); + rc.iadd(10, 9); + }); } @Test public void iaddInvalidRange2() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer rc = new MappeableRunContainer(); - rc.iadd(0, 1 << 20); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer rc = new MappeableRunContainer(); + rc.iadd(0, 1 << 20); + }); } @Test @@ -737,7 +750,6 @@ public void iaddRange5() { assertEquals(16, rc.getSizeInBytes()); } - @Test public void iaddRange6() { MappeableContainer rc = new MappeableRunContainer(); @@ -864,8 +876,6 @@ public void intersectionTest1() { assertEquals(ac, rc.and(ac)); } - - @Test public void intersectionTest2() { MappeableContainer ac = new MappeableArrayContainer(); @@ -940,8 +950,6 @@ public void iremove10() { assertEquals(8, rc.getSizeInBytes()); } - - @Test public void iremove11() { MappeableContainer rc = new MappeableRunContainer(); @@ -951,7 +959,6 @@ public void iremove11() { assertEquals(0, rc.getCardinality()); } - @Test public void iremove12() { MappeableContainer rc = new MappeableRunContainer(); @@ -977,7 +984,6 @@ public void iremove13() { assertEquals(12, rc.getSizeInBytes()); } - @Test public void iremove14() { MappeableContainer rc = new MappeableRunContainer(); @@ -1134,18 +1140,22 @@ public void iremove9() { @Test public void iremoveInvalidRange1() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer rc = new MappeableRunContainer(); - rc.iremove(10, 9); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer rc = new MappeableRunContainer(); + rc.iremove(10, 9); + }); } @Test public void iremoveInvalidRange2() { - assertThrows(IllegalArgumentException.class, () -> { - MappeableContainer rc = new MappeableRunContainer(); - rc.remove(0, 1 << 20); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + MappeableContainer rc = new MappeableRunContainer(); + rc.remove(0, 1 << 20); + }); } @Test @@ -1315,22 +1325,28 @@ public void MappeableRunContainerArg_ArrayANDNOT() { @Test public void RunContainerArg_ArrayANDNOT2() { - MappeableArrayContainer ac = new MappeableArrayContainer(CharBuffer.wrap(new char[]{0, 2, 4, 8, 10, 15, 16, 48, 50, 61, 80, (char)-2}), 12); - MappeableContainer rc = new MappeableRunContainer(CharBuffer.wrap(new char[]{7, 3, 17, 2, 20, 3, 30, 3, 36, 6, 60, 5, (char)-3, 2}), 7); - assertEquals(new MappeableArrayContainer(CharBuffer.wrap(new char[]{0, 2, 4, 15, 16, 48, 50, 80}), 8), ac.andNot(rc)); + MappeableArrayContainer ac = + new MappeableArrayContainer( + CharBuffer.wrap(new char[] {0, 2, 4, 8, 10, 15, 16, 48, 50, 61, 80, (char) -2}), 12); + MappeableContainer rc = + new MappeableRunContainer( + CharBuffer.wrap(new char[] {7, 3, 17, 2, 20, 3, 30, 3, 36, 6, 60, 5, (char) -3, 2}), 7); + assertEquals( + new MappeableArrayContainer(CharBuffer.wrap(new char[] {0, 2, 4, 15, 16, 48, 50, 80}), 8), + ac.andNot(rc)); } @Test public void FullRunContainerArg_ArrayANDNOT2() { - MappeableArrayContainer ac = new MappeableArrayContainer(CharBuffer.wrap(new char[]{3}), 1); + MappeableArrayContainer ac = new MappeableArrayContainer(CharBuffer.wrap(new char[] {3}), 1); MappeableContainer rc = MappeableRunContainer.full(); assertEquals(new MappeableArrayContainer(), ac.andNot(rc)); } @Test public void RunContainerArg_ArrayANDNOT3() { - MappeableArrayContainer ac = new MappeableArrayContainer(CharBuffer.wrap(new char[]{5}), 1); - MappeableContainer rc = new MappeableRunContainer(CharBuffer.wrap(new char[]{3, 10}), 1); + MappeableArrayContainer ac = new MappeableArrayContainer(CharBuffer.wrap(new char[] {5}), 1); + MappeableContainer rc = new MappeableRunContainer(CharBuffer.wrap(new char[] {3, 10}), 1); assertEquals(new MappeableArrayContainer(), ac.andNot(rc)); } @@ -1483,7 +1499,6 @@ public void not10() { } } - /* * @Test public void safeSerialization() throws Exception { MappeableRunContainer container = new * MappeableRunContainer(); container.add((char) 0); container.add((char) 2); @@ -1498,7 +1513,6 @@ public void not10() { * assertEquals(container.serializedSizeInBytes(), newContainer.serializedSizeInBytes()); } */ - @Test public void not11() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1521,7 +1535,6 @@ public void not11() { } } - @Test public void not12() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1622,7 +1635,6 @@ public void not3() { } } - @Test public void not4() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1673,7 +1685,6 @@ public void not6() { } } - @Test public void not7() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1684,7 +1695,6 @@ public void not7() { container.add((char) 504); container.add((char) 505); - // one run, spans the range MappeableContainer result = container.not(502, 504); @@ -1694,7 +1704,6 @@ public void not7() { } } - @Test public void not8() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1715,7 +1724,6 @@ public void not8() { } } - @Test public void not9() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1735,7 +1743,6 @@ public void not9() { } } - @Test public void randomFun() { final int bitsetperword1 = 32; @@ -1748,7 +1755,6 @@ public void randomFun() { int[] values1 = generateUniformHash(rand, bitsetperword1 * howmanywords, max); int[] values2 = generateUniformHash(rand, bitsetperword2 * howmanywords, max); - rc1 = new MappeableRunContainer(); rc1 = fillMeUp(rc1, values1); @@ -1769,7 +1775,6 @@ public void randomFun() { throw new RuntimeException("second containers do not match"); } - if (!rc1.or(rc2).equals(ac1.or(ac2))) { throw new RuntimeException("ors do not match"); } @@ -1785,10 +1790,8 @@ public void randomFun() { if (!rc1.xor(rc2).equals(ac1.xor(ac2))) { throw new RuntimeException("xors do not match"); } - } - @Test public void rank() { MappeableRunContainer container = new MappeableRunContainer(); @@ -1821,7 +1824,6 @@ public void remove() { assertEquals(0, newContainer.getCardinality()); } - @Test public void safeor() { MappeableContainer rc1 = new MappeableRunContainer(); @@ -1837,8 +1839,6 @@ public void safeor() { } } - - @Test public void safeSerialization() throws Exception { System.out.println("write safeSerialization"); /******************************/ @@ -1859,8 +1859,6 @@ public void select() { assertEquals(256, container.select(4)); } - - @Test public void simpleIterator() { MappeableContainer x = new MappeableRunContainer(); @@ -1875,12 +1873,12 @@ public void simpleIterator() { assertFalse(i.hasNext()); } - - @Test public void testAndNot() { - int[] array1 = {39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, - 39184, 39185, 39186, 39187, 39188}; + int[] array1 = { + 39173, 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, 39184, 39185, + 39186, 39187, 39188 + }; int[] array2 = {14205}; MutableRoaringBitmap rb1 = MutableRoaringBitmap.bitmapOf(array1); rb1.runOptimize(); @@ -1889,8 +1887,6 @@ public void testAndNot() { assertEquals(answer.getCardinality(), array1.length); } - - @Test public void testRoaringWithOptimize() { // create the same bitmap over and over again, with optimizing it @@ -1908,7 +1904,6 @@ public void testRoaringWithOptimize() { assertEquals(1, setWithOptimize.size()); } - @Test public void testRoaringWithoutOptimize() { // create the same bitmap over and over again, without optimizing it @@ -1925,7 +1920,6 @@ public void testRoaringWithoutOptimize() { assertEquals(1, setWithoutOptimize.size()); } - @Test public void toBitmapOrArrayContainer() { MappeableRunContainer rc = new MappeableRunContainer(); @@ -1986,7 +1980,6 @@ public void union2() { assertEquals(N, rc.getCardinality()); } - @Test public void xor() { MappeableContainer bc = new MappeableBitmapContainer(); @@ -2007,7 +2000,6 @@ public void xor() { assertEquals(4 * DEFAULT_MAX_SIZE, rc.getCardinality()); } - @Test public void xor_array() { MappeableContainer bc = new MappeableArrayContainer(); @@ -2028,7 +2020,6 @@ public void xor_array() { assertEquals(4 * DEFAULT_MAX_SIZE, rc.getCardinality()); } - @Test public void xor1() { MappeableContainer bc = new MappeableBitmapContainer(); @@ -2039,8 +2030,6 @@ public void xor1() { assertTrue(result.contains((char) 1)); } - - @Test public void xor1a() { MappeableContainer bc = new MappeableArrayContainer(); @@ -2051,7 +2040,6 @@ public void xor1a() { assertTrue(result.contains((char) 1)); } - @Test public void xor2() { MappeableContainer bc = new MappeableBitmapContainer(); @@ -2062,7 +2050,6 @@ public void xor2() { assertTrue(result.contains((char) 1)); } - @Test public void xor2a() { MappeableContainer bc = new MappeableArrayContainer(); @@ -2093,7 +2080,6 @@ public void xor3a() { assertEquals(0, result.getCardinality()); } - @Test public void xor4() { MappeableContainer bc = new MappeableArrayContainer(); @@ -2125,9 +2111,9 @@ public void iorArray() { assertEquals(13, rc.getCardinality()); rc = new MappeableRunContainer(); - rc = rc.add(0, 1<<16); + rc = rc.add(0, 1 << 16); rc = rc.ior(ac); - assertEquals(1<<16, rc.getCardinality()); + assertEquals(1 << 16, rc.getCardinality()); } @Test @@ -2140,9 +2126,9 @@ public void iorBitmap() { assertEquals(1, rc.getCardinality()); rc = new MappeableRunContainer(); - rc = rc.add(0, 1<<16); + rc = rc.add(0, 1 << 16); rc = rc.ior(bc); - assertEquals(1<<16, rc.getCardinality()); + assertEquals(1 << 16, rc.getCardinality()); } @Test @@ -2160,12 +2146,11 @@ public void iorRun() { assertEquals(13, rc1.getCardinality()); rc1 = new MappeableRunContainer(); - rc1 = rc1.add(0, 1<<16); + rc1 = rc1.add(0, 1 << 16); rc1 = rc1.ior(rc2); - assertEquals(1<<16, rc1.getCardinality()); + assertEquals(1 << 16, rc1.getCardinality()); } - @Test public void intersectsRun() { MappeableContainer rc1 = new MappeableRunContainer(); @@ -2223,50 +2208,49 @@ public void testContainsMappeableBitmapContainer_EmptyContainsEmpty() { @Test public void testContainsMappeableBitmapContainer_IncludeProperSubset() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableBitmapContainer().add(0,9); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableBitmapContainer().add(0, 9); assertTrue(rc.contains(subset)); } - @Test public void testContainsMappeableBitmapContainer_IncludeProperSubsetDifferentStart() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableBitmapContainer().add(1,9); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableBitmapContainer().add(1, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsBitmapContainer_IncludeProperSubsetMultiWordRun() { - MappeableContainer rc = new MappeableRunContainer().add(0,80); - MappeableContainer subset = new MappeableBitmapContainer().add(0,79); + MappeableContainer rc = new MappeableRunContainer().add(0, 80); + MappeableContainer subset = new MappeableBitmapContainer().add(0, 79); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableBitmapContainer_ExcludeShiftedSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableBitmapContainer().add(2,12); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableBitmapContainer().add(2, 12); assertFalse(rc.contains(subset)); } @Test public void testContainsMappeableBitmapContainer_IncludeSelf() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableBitmapContainer().add(0,10); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableBitmapContainer().add(0, 10); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableBitmapContainer_ExcludeSuperSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer superset = new MappeableBitmapContainer().add(0,20); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer superset = new MappeableBitmapContainer().add(0, 20); assertFalse(rc.contains(superset)); } @Test public void testContainsMappeableBitmapContainer_ExcludeDisJointSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); MappeableContainer disjoint = new MappeableBitmapContainer().add(20, 40); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); @@ -2274,15 +2258,15 @@ public void testContainsMappeableBitmapContainer_ExcludeDisJointSet() { @Test public void testContainsMappeableBitmapContainer_Issue721Case1() { - MappeableContainer rc = new MappeableRunContainer().add(0,60).add(63,64).add(66,67); - MappeableContainer subset = new MappeableBitmapContainer().add(63,64); + MappeableContainer rc = new MappeableRunContainer().add(0, 60).add(63, 64).add(66, 67); + MappeableContainer subset = new MappeableBitmapContainer().add(63, 64); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableBitmapContainer_Issue721Case2() { - MappeableContainer rc = new MappeableRunContainer().add(0,10).add(12,13); - MappeableContainer disjoint = new MappeableBitmapContainer().add(11,12); + MappeableContainer rc = new MappeableRunContainer().add(0, 10).add(12, 13); + MappeableContainer disjoint = new MappeableBitmapContainer().add(11, 12); assertFalse(rc.contains(disjoint)); } @@ -2302,42 +2286,42 @@ public void testContainsMappeableRunContainer_EmptyContainsEmpty() { @Test public void testContainsMappeableRunContainer_IncludeProperSubset() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableRunContainer().add(0,9); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableRunContainer().add(0, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableRunContainer_IncludeSelf() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableRunContainer().add(0,10); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableRunContainer().add(0, 10); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableRunContainer_ExcludeSuperSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer superset = new MappeableRunContainer().add(0,20); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer superset = new MappeableRunContainer().add(0, 20); assertFalse(rc.contains(superset)); } @Test public void testContainsMappeableRunContainer_IncludeProperSubsetDifferentStart() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableRunContainer().add(1,9); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableRunContainer().add(1, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableRunContainer_ExcludeShiftedSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableRunContainer().add(2,12); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableRunContainer().add(2, 12); assertFalse(rc.contains(subset)); } @Test public void testContainsMappeableRunContainer_ExcludeDisJointSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); MappeableContainer disjoint = new MappeableRunContainer().add(20, 40); assertFalse(rc.contains(disjoint)); assertFalse(disjoint.contains(rc)); @@ -2352,36 +2336,36 @@ public void testContainsMappeableArrayContainer_EmptyContainsEmpty() { @Test public void testContainsMappeableArrayContainer_IncludeProperSubset() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableArrayContainer().add(0,9); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableArrayContainer().add(0, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableArrayContainer_IncludeProperSubsetDifferentStart() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableArrayContainer().add(2,9); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableArrayContainer().add(2, 9); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableArrayContainer_ExcludeShiftedSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer shifted = new MappeableArrayContainer().add(2,12); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer shifted = new MappeableArrayContainer().add(2, 12); assertFalse(rc.contains(shifted)); } @Test public void testContainsMappeableArrayContainer_IncludeSelf() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer subset = new MappeableArrayContainer().add(0,10); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer subset = new MappeableArrayContainer().add(0, 10); assertTrue(rc.contains(subset)); } @Test public void testContainsMappeableArrayContainer_ExcludeSuperSet() { - MappeableContainer rc = new MappeableRunContainer().add(0,10); - MappeableContainer superset = new MappeableArrayContainer().add(0,20); + MappeableContainer rc = new MappeableRunContainer().add(0, 10); + MappeableContainer superset = new MappeableArrayContainer().add(0, 20); assertFalse(rc.contains(superset)); } @@ -2429,7 +2413,7 @@ public void testEqualsMappeableArrayContainer_NotEqual_ArrayShifted() { public void testEqualsMappeableArrayContainer_NotEqual_ArrayDiscontiguous() { MappeableContainer rc = new MappeableRunContainer().add(0, 10); MappeableContainer ac = new MappeableArrayContainer().add(0, 11); - ac.flip((char)9); + ac.flip((char) 9); assertNotEquals(rc, ac); assertNotEquals(ac, rc); } @@ -2489,21 +2473,21 @@ public void testIntersectsWithRange() { assertFalse(container.intersects(11, 1 << 16)); } - @Test public void testIntersectsWithRangeUnsigned() { - MappeableContainer container = new MappeableRunContainer().add(lower16Bits(-50), lower16Bits(-10)); + MappeableContainer container = + new MappeableRunContainer().add(lower16Bits(-50), lower16Bits(-10)); assertFalse(container.intersects(0, 1)); assertTrue(container.intersects(0, lower16Bits(-40))); assertFalse(container.intersects(lower16Bits(-100), lower16Bits(-55))); - //assertFalse(container.intersects(-9, 1 << 16));// forbidden + // assertFalse(container.intersects(-9, 1 << 16));// forbidden assertTrue(container.intersects(11, 1 << 16)); } - @Test public void testIntersectsWithRangeManyRuns() { - MappeableContainer container = new MappeableRunContainer().add(0, 10).add(lower16Bits(-50), lower16Bits(-10)); + MappeableContainer container = + new MappeableRunContainer().add(0, 10).add(lower16Bits(-50), lower16Bits(-10)); assertTrue(container.intersects(0, 1)); assertTrue(container.intersects(0, 101)); assertTrue(container.intersects(0, lower16Bits(-1))); @@ -2517,7 +2501,7 @@ public void testIntersectsWithRangeManyRuns() { @Test public void testContainsFull() { assertTrue(MappeableRunContainer.full().contains(0, 1 << 16)); - assertFalse(MappeableRunContainer.full().flip((char)(1 << 15)).contains(0, 1 << 16)); + assertFalse(MappeableRunContainer.full().flip((char) (1 << 15)).contains(0, 1 << 16)); } @Test @@ -2540,9 +2524,7 @@ public void testContainsRange() { @Test public void testContainsRange2() { - MappeableContainer rc = new MappeableRunContainer().add(1, 100) - .add(300, 400) - .add(5000, 10000); + MappeableContainer rc = new MappeableRunContainer().add(1, 100).add(300, 400).add(5000, 10000); assertFalse(rc.contains(0, 100)); assertFalse(rc.contains(0, 100000)); assertTrue(rc.contains(1, 100)); @@ -2559,10 +2541,11 @@ public void testContainsRange2() { assertFalse(rc.contains(10001, 20000)); } - @Test public void testContainsRange3() { - MappeableContainer rc = new MappeableRunContainer().add(1, 100) + MappeableContainer rc = + new MappeableRunContainer() + .add(1, 100) .add(300, 300) .add(400, 500) .add(502, 600) @@ -2578,142 +2561,146 @@ public void testContainsRange3() { @Test public void testNextValue() { - MappeableContainer container = new RunContainer(new char[] { 64, 64 }, 1).toMappeableContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(-1, container.nextValue((char)129)); + MappeableContainer container = new RunContainer(new char[] {64, 64}, 1).toMappeableContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(-1, container.nextValue((char) 129)); } @Test public void testNextValueBetweenRuns() { - MappeableContainer container = new RunContainer(new char[] { 64, 64, 256, 64 }, 2) - .toMappeableContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(256, container.nextValue((char)129)); - assertEquals(-1, container.nextValue((char)512)); + MappeableContainer container = + new RunContainer(new char[] {64, 64, 256, 64}, 2).toMappeableContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(256, container.nextValue((char) 129)); + assertEquals(-1, container.nextValue((char) 512)); } @Test public void testNextValue2() { - MappeableContainer container = new RunContainer(new char[] { 64, 64, 200, 300, 5000, 200 }, 3) - .toMappeableContainer(); - assertEquals(64, container.nextValue((char)0)); - assertEquals(64, container.nextValue((char)63)); - assertEquals(64, container.nextValue((char)64)); - assertEquals(65, container.nextValue((char)65)); - assertEquals(128, container.nextValue((char)128)); - assertEquals(200, container.nextValue((char)129)); - assertEquals(200, container.nextValue((char)199)); - assertEquals(200, container.nextValue((char)200)); - assertEquals(250, container.nextValue((char)250)); - assertEquals(5000, container.nextValue((char)2500)); - assertEquals(5000, container.nextValue((char)5000)); - assertEquals(5200, container.nextValue((char)5200)); - assertEquals(-1, container.nextValue((char)5201)); + MappeableContainer container = + new RunContainer(new char[] {64, 64, 200, 300, 5000, 200}, 3).toMappeableContainer(); + assertEquals(64, container.nextValue((char) 0)); + assertEquals(64, container.nextValue((char) 63)); + assertEquals(64, container.nextValue((char) 64)); + assertEquals(65, container.nextValue((char) 65)); + assertEquals(128, container.nextValue((char) 128)); + assertEquals(200, container.nextValue((char) 129)); + assertEquals(200, container.nextValue((char) 199)); + assertEquals(200, container.nextValue((char) 200)); + assertEquals(250, container.nextValue((char) 250)); + assertEquals(5000, container.nextValue((char) 2500)); + assertEquals(5000, container.nextValue((char) 5000)); + assertEquals(5200, container.nextValue((char) 5200)); + assertEquals(-1, container.nextValue((char) 5201)); } @Test public void testPreviousValue1() { - MappeableContainer container = new RunContainer(new char[] { 64, 64 }, 1) - .toMappeableContainer(); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); + MappeableContainer container = new RunContainer(new char[] {64, 64}, 1).toMappeableContainer(); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); } @Test public void testPreviousValue2() { - MappeableContainer container = new RunContainer(new char[] { 64, 64, 200, 300, 5000, 200 }, 3) - .toMappeableContainer(); - assertEquals(-1, container.previousValue((char)0)); - assertEquals(-1, container.previousValue((char)63)); - assertEquals(64, container.previousValue((char)64)); - assertEquals(65, container.previousValue((char)65)); - assertEquals(128, container.previousValue((char)128)); - assertEquals(128, container.previousValue((char)129)); - assertEquals(128, container.previousValue((char)199)); - assertEquals(200, container.previousValue((char)200)); - assertEquals(250, container.previousValue((char)250)); - assertEquals(500, container.previousValue((char)2500)); - assertEquals(5000, container.previousValue((char)5000)); - assertEquals(5200, container.previousValue((char)5200)); + MappeableContainer container = + new RunContainer(new char[] {64, 64, 200, 300, 5000, 200}, 3).toMappeableContainer(); + assertEquals(-1, container.previousValue((char) 0)); + assertEquals(-1, container.previousValue((char) 63)); + assertEquals(64, container.previousValue((char) 64)); + assertEquals(65, container.previousValue((char) 65)); + assertEquals(128, container.previousValue((char) 128)); + assertEquals(128, container.previousValue((char) 129)); + assertEquals(128, container.previousValue((char) 199)); + assertEquals(200, container.previousValue((char) 200)); + assertEquals(250, container.previousValue((char) 250)); + assertEquals(500, container.previousValue((char) 2500)); + assertEquals(5000, container.previousValue((char) 5000)); + assertEquals(5200, container.previousValue((char) 5200)); } @Test public void testPreviousValueUnsigned() { - MappeableContainer container = new RunContainer(new char[] { (char)((1 << 15) | 5), (char)0, (char)((1 << 15) | 7), (char)0}, 2) + MappeableContainer container = + new RunContainer( + new char[] {(char) ((1 << 15) | 5), (char) 0, (char) ((1 << 15) | 7), (char) 0}, 2) .toMappeableContainer(); - assertEquals(-1, container.previousValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 5), container.previousValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 7), container.previousValue((char)((1 << 15) | 8))); + assertEquals(-1, container.previousValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 5), container.previousValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 7), container.previousValue((char) ((1 << 15) | 8))); } @Test public void testNextValueUnsigned() { - MappeableContainer container = new RunContainer(new char[] { (char)((1 << 15) | 5), (char)0, (char)((1 << 15) | 7), (char)0}, 2) + MappeableContainer container = + new RunContainer( + new char[] {(char) ((1 << 15) | 5), (char) 0, (char) ((1 << 15) | 7), (char) 0}, 2) .toMappeableContainer(); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 5), container.nextValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 7), container.nextValue((char)((1 << 15) | 7))); - assertEquals(-1, container.nextValue((char)((1 << 15) | 8))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 5), container.nextValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 7), container.nextValue((char) ((1 << 15) | 7))); + assertEquals(-1, container.nextValue((char) ((1 << 15) | 8))); } - @Test public void testPreviousAbsentValue1() { MappeableContainer container = new MappeableRunContainer().iadd(64, 129); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); } @Test public void testPreviousAbsentValue2() { - MappeableContainer container = new MappeableRunContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.previousAbsentValue((char)0)); - assertEquals(63, container.previousAbsentValue((char)63)); - assertEquals(63, container.previousAbsentValue((char)64)); - assertEquals(63, container.previousAbsentValue((char)65)); - assertEquals(63, container.previousAbsentValue((char)128)); - assertEquals(129, container.previousAbsentValue((char)129)); - assertEquals(199, container.previousAbsentValue((char)199)); - assertEquals(199, container.previousAbsentValue((char)200)); - assertEquals(199, container.previousAbsentValue((char)250)); - assertEquals(2500, container.previousAbsentValue((char)2500)); - assertEquals(4999, container.previousAbsentValue((char)5000)); - assertEquals(4999, container.previousAbsentValue((char)5200)); + MappeableContainer container = + new MappeableRunContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertEquals(0, container.previousAbsentValue((char) 0)); + assertEquals(63, container.previousAbsentValue((char) 63)); + assertEquals(63, container.previousAbsentValue((char) 64)); + assertEquals(63, container.previousAbsentValue((char) 65)); + assertEquals(63, container.previousAbsentValue((char) 128)); + assertEquals(129, container.previousAbsentValue((char) 129)); + assertEquals(199, container.previousAbsentValue((char) 199)); + assertEquals(199, container.previousAbsentValue((char) 200)); + assertEquals(199, container.previousAbsentValue((char) 250)); + assertEquals(2500, container.previousAbsentValue((char) 2500)); + assertEquals(4999, container.previousAbsentValue((char) 5000)); + assertEquals(4999, container.previousAbsentValue((char) 5200)); } @Test public void testPreviousAbsentValueEmpty() { MappeableRunContainer container = new MappeableRunContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.previousAbsentValue((char)i)); + assertEquals(i, container.previousAbsentValue((char) i)); } } @Test public void testPreviousAbsentValueSparse() { - MappeableRunContainer container = new MappeableRunContainer(CharBuffer.wrap(new char[] { 10, 0, 20, 0, 30, 0}), 3); - assertEquals(9, container.previousAbsentValue((char)9)); - assertEquals(9, container.previousAbsentValue((char)10)); - assertEquals(11, container.previousAbsentValue((char)11)); - assertEquals(21, container.previousAbsentValue((char)21)); - assertEquals(29, container.previousAbsentValue((char)30)); + MappeableRunContainer container = + new MappeableRunContainer(CharBuffer.wrap(new char[] {10, 0, 20, 0, 30, 0}), 3); + assertEquals(9, container.previousAbsentValue((char) 9)); + assertEquals(9, container.previousAbsentValue((char) 10)); + assertEquals(11, container.previousAbsentValue((char) 11)); + assertEquals(21, container.previousAbsentValue((char) 21)); + assertEquals(29, container.previousAbsentValue((char) 30)); } @Test @@ -2725,9 +2712,9 @@ public void testPreviousAbsentEvenBits() { } MappeableRunContainer container = new MappeableRunContainer(CharBuffer.wrap(evenBits), 1 << 14); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i - 1, container.previousAbsentValue((char)i)); - assertEquals(i + 1, container.previousAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i - 1, container.previousAbsentValue((char) i)); + assertEquals(i + 1, container.previousAbsentValue((char) (i + 1))); } } @@ -2735,58 +2722,59 @@ public void testPreviousAbsentEvenBits() { public void testPreviousAbsentValueUnsigned() { char[] array = {(char) ((1 << 15) | 5), 0, (char) ((1 << 15) | 7), 0}; MappeableRunContainer container = new MappeableRunContainer(CharBuffer.wrap(array), 2); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 4), container.previousAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 6), container.previousAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.previousAbsentValue((char)((1 << 15) | 8))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 4), container.previousAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 6), container.previousAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.previousAbsentValue((char) ((1 << 15) | 8))); } - @Test public void testNextAbsentValue1() { MappeableContainer container = new MappeableRunContainer().iadd(64, 129); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); } @Test public void testNextAbsentValue2() { - MappeableContainer container = new MappeableRunContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); - assertEquals(0, container.nextAbsentValue((char)0)); - assertEquals(63, container.nextAbsentValue((char)63)); - assertEquals(129, container.nextAbsentValue((char)64)); - assertEquals(129, container.nextAbsentValue((char)65)); - assertEquals(129, container.nextAbsentValue((char)128)); - assertEquals(129, container.nextAbsentValue((char)129)); - assertEquals(199, container.nextAbsentValue((char)199)); - assertEquals(501, container.nextAbsentValue((char)200)); - assertEquals(501, container.nextAbsentValue((char)250)); - assertEquals(2500, container.nextAbsentValue((char)2500)); - assertEquals(5201, container.nextAbsentValue((char)5000)); - assertEquals(5201, container.nextAbsentValue((char)5200)); + MappeableContainer container = + new MappeableRunContainer().iadd(64, 129).iadd(200, 501).iadd(5000, 5201); + assertEquals(0, container.nextAbsentValue((char) 0)); + assertEquals(63, container.nextAbsentValue((char) 63)); + assertEquals(129, container.nextAbsentValue((char) 64)); + assertEquals(129, container.nextAbsentValue((char) 65)); + assertEquals(129, container.nextAbsentValue((char) 128)); + assertEquals(129, container.nextAbsentValue((char) 129)); + assertEquals(199, container.nextAbsentValue((char) 199)); + assertEquals(501, container.nextAbsentValue((char) 200)); + assertEquals(501, container.nextAbsentValue((char) 250)); + assertEquals(2500, container.nextAbsentValue((char) 2500)); + assertEquals(5201, container.nextAbsentValue((char) 5000)); + assertEquals(5201, container.nextAbsentValue((char) 5200)); } @Test public void testNextAbsentValueEmpty() { MappeableRunContainer container = new MappeableRunContainer(); for (int i = 0; i < 1000; i++) { - assertEquals(i, container.nextAbsentValue((char)i)); + assertEquals(i, container.nextAbsentValue((char) i)); } } @Test public void testNextAbsentValueSparse() { - MappeableContainer container = new MappeableRunContainer(CharBuffer.wrap(new char[] { 10, 0, 20, 0, 30, 0}), 3); - assertEquals(9, container.nextAbsentValue((char)9)); - assertEquals(11, container.nextAbsentValue((char)10)); - assertEquals(11, container.nextAbsentValue((char)11)); - assertEquals(21, container.nextAbsentValue((char)21)); - assertEquals(31, container.nextAbsentValue((char)30)); + MappeableContainer container = + new MappeableRunContainer(CharBuffer.wrap(new char[] {10, 0, 20, 0, 30, 0}), 3); + assertEquals(9, container.nextAbsentValue((char) 9)); + assertEquals(11, container.nextAbsentValue((char) 10)); + assertEquals(11, container.nextAbsentValue((char) 11)); + assertEquals(21, container.nextAbsentValue((char) 21)); + assertEquals(31, container.nextAbsentValue((char) 30)); } @Test @@ -2798,9 +2786,9 @@ public void testNextAbsentEvenBits() { } MappeableRunContainer container = new MappeableRunContainer(CharBuffer.wrap(evenBits), 1 << 14); - for (int i = 0; i < 1 << 10; i+=2) { - assertEquals(i + 1, container.nextAbsentValue((char)i)); - assertEquals(i + 1, container.nextAbsentValue((char)(i+1))); + for (int i = 0; i < 1 << 10; i += 2) { + assertEquals(i + 1, container.nextAbsentValue((char) i)); + assertEquals(i + 1, container.nextAbsentValue((char) (i + 1))); } } @@ -2808,21 +2796,20 @@ public void testNextAbsentEvenBits() { public void testNextAbsentValueUnsigned() { char[] array = {(char) ((1 << 15) | 5), 0, (char) ((1 << 15) | 7), 0}; MappeableRunContainer container = new MappeableRunContainer(CharBuffer.wrap(array), 2); - assertEquals(((1 << 15) | 4), container.nextAbsentValue((char)((1 << 15) | 4))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 5))); - assertEquals(((1 << 15) | 6), container.nextAbsentValue((char)((1 << 15) | 6))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 7))); - assertEquals(((1 << 15) | 8), container.nextAbsentValue((char)((1 << 15) | 8))); + assertEquals(((1 << 15) | 4), container.nextAbsentValue((char) ((1 << 15) | 4))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 5))); + assertEquals(((1 << 15) | 6), container.nextAbsentValue((char) ((1 << 15) | 6))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 7))); + assertEquals(((1 << 15) | 8), container.nextAbsentValue((char) ((1 << 15) | 8))); } @Test public void testContains() { - MappeableRunContainer rc = new MappeableRunContainer(CharBuffer.wrap(new char[]{23, 24}), 1); + MappeableRunContainer rc = new MappeableRunContainer(CharBuffer.wrap(new char[] {23, 24}), 1); assertFalse(rc.contains(48, 49)); } - private static int lower16Bits(int x) { - return ((char)x) & 0xFFFF; + return ((char) x) & 0xFFFF; } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java index a948aa83f..5dc82d1d5 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializationViaByteBuffer.java @@ -1,5 +1,11 @@ package org.roaringbitmap.buffer; +import static java.nio.channels.FileChannel.MapMode.READ_WRITE; +import static java.nio.file.Files.delete; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.roaringbitmap.SeededTestData; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -9,9 +15,13 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.SeededTestData; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.FileChannel; @@ -20,10 +30,6 @@ import java.util.UUID; import java.util.stream.Stream; -import static java.nio.channels.FileChannel.MapMode.READ_WRITE; -import static java.nio.file.Files.delete; -import static org.junit.jupiter.api.Assertions.assertEquals; - @Execution(ExecutionMode.CONCURRENT) public class TestSerializationViaByteBuffer { @@ -34,63 +40,62 @@ public static void cleanup() { public static Stream params() { return Stream.of( - Arguments.of(2, ByteOrder.BIG_ENDIAN, true), - Arguments.of(2, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(3, ByteOrder.BIG_ENDIAN, true), - Arguments.of(3, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(4, ByteOrder.BIG_ENDIAN, true), - Arguments.of(4, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(5, ByteOrder.BIG_ENDIAN, true), - Arguments.of(5, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(6, ByteOrder.BIG_ENDIAN, true), - Arguments.of(6, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(7, ByteOrder.BIG_ENDIAN, true), - Arguments.of(7, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(8, ByteOrder.BIG_ENDIAN, true), - Arguments.of(8, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(9, ByteOrder.BIG_ENDIAN, true), - Arguments.of(9, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(10, ByteOrder.BIG_ENDIAN, true), - Arguments.of(10, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(11, ByteOrder.BIG_ENDIAN, true), - Arguments.of(11, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(12, ByteOrder.BIG_ENDIAN, true), - Arguments.of(12, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(13, ByteOrder.BIG_ENDIAN, true), - Arguments.of(13, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(14, ByteOrder.BIG_ENDIAN, true), - Arguments.of(14, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(15, ByteOrder.BIG_ENDIAN, true), - Arguments.of(15, ByteOrder.LITTLE_ENDIAN, true), - Arguments.of(2, ByteOrder.BIG_ENDIAN, false), - Arguments.of(2, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(3, ByteOrder.BIG_ENDIAN, false), - Arguments.of(3, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(4, ByteOrder.BIG_ENDIAN, false), - Arguments.of(4, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(5, ByteOrder.BIG_ENDIAN, false), - Arguments.of(5, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(6, ByteOrder.BIG_ENDIAN, false), - Arguments.of(6, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(7, ByteOrder.BIG_ENDIAN, false), - Arguments.of(7, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(8, ByteOrder.BIG_ENDIAN, false), - Arguments.of(8, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(9, ByteOrder.BIG_ENDIAN, false), - Arguments.of(9, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(10, ByteOrder.BIG_ENDIAN, false), - Arguments.of(10, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(11, ByteOrder.BIG_ENDIAN, false), - Arguments.of(11, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(12, ByteOrder.BIG_ENDIAN, false), - Arguments.of(12, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(13, ByteOrder.BIG_ENDIAN, false), - Arguments.of(13, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(14, ByteOrder.BIG_ENDIAN, false), - Arguments.of(14, ByteOrder.LITTLE_ENDIAN, false), - Arguments.of(15, ByteOrder.BIG_ENDIAN, false), - Arguments.of(15, ByteOrder.LITTLE_ENDIAN, false) - ); + Arguments.of(2, ByteOrder.BIG_ENDIAN, true), + Arguments.of(2, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(3, ByteOrder.BIG_ENDIAN, true), + Arguments.of(3, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(4, ByteOrder.BIG_ENDIAN, true), + Arguments.of(4, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(5, ByteOrder.BIG_ENDIAN, true), + Arguments.of(5, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(6, ByteOrder.BIG_ENDIAN, true), + Arguments.of(6, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(7, ByteOrder.BIG_ENDIAN, true), + Arguments.of(7, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(8, ByteOrder.BIG_ENDIAN, true), + Arguments.of(8, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(9, ByteOrder.BIG_ENDIAN, true), + Arguments.of(9, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(10, ByteOrder.BIG_ENDIAN, true), + Arguments.of(10, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(11, ByteOrder.BIG_ENDIAN, true), + Arguments.of(11, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(12, ByteOrder.BIG_ENDIAN, true), + Arguments.of(12, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(13, ByteOrder.BIG_ENDIAN, true), + Arguments.of(13, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(14, ByteOrder.BIG_ENDIAN, true), + Arguments.of(14, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(15, ByteOrder.BIG_ENDIAN, true), + Arguments.of(15, ByteOrder.LITTLE_ENDIAN, true), + Arguments.of(2, ByteOrder.BIG_ENDIAN, false), + Arguments.of(2, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(3, ByteOrder.BIG_ENDIAN, false), + Arguments.of(3, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(4, ByteOrder.BIG_ENDIAN, false), + Arguments.of(4, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(5, ByteOrder.BIG_ENDIAN, false), + Arguments.of(5, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(6, ByteOrder.BIG_ENDIAN, false), + Arguments.of(6, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(7, ByteOrder.BIG_ENDIAN, false), + Arguments.of(7, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(8, ByteOrder.BIG_ENDIAN, false), + Arguments.of(8, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(9, ByteOrder.BIG_ENDIAN, false), + Arguments.of(9, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(10, ByteOrder.BIG_ENDIAN, false), + Arguments.of(10, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(11, ByteOrder.BIG_ENDIAN, false), + Arguments.of(11, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(12, ByteOrder.BIG_ENDIAN, false), + Arguments.of(12, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(13, ByteOrder.BIG_ENDIAN, false), + Arguments.of(13, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(14, ByteOrder.BIG_ENDIAN, false), + Arguments.of(14, ByteOrder.LITTLE_ENDIAN, false), + Arguments.of(15, ByteOrder.BIG_ENDIAN, false), + Arguments.of(15, ByteOrder.LITTLE_ENDIAN, false)); } private Path file; @@ -114,11 +119,12 @@ public void after() throws IOException { @ParameterizedTest @MethodSource("params") - public void testDeserializeFromMappedFile(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromMappedFile(int keys, ByteOrder order, boolean runOptimise) + throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); try (RandomAccessFile raf = new RandomAccessFile(file.toFile(), "rw"); - FileChannel channel = raf.getChannel()) { + FileChannel channel = raf.getChannel()) { ByteBuffer buffer = channel.map(READ_WRITE, 0, serialised.length); buffer.put(serialised); buffer.flip(); @@ -129,14 +135,14 @@ public void testDeserializeFromMappedFile(int keys, ByteOrder order, boolean run } } - @ParameterizedTest @MethodSource("params") - public void testSerializeMappedBitmap(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeMappedBitmap(int keys, ByteOrder order, boolean runOptimise) + throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); try (RandomAccessFile raf = new RandomAccessFile(file.toFile(), "rw"); - FileChannel channel = raf.getChannel()) { + FileChannel channel = raf.getChannel()) { ByteBuffer buffer = channel.map(READ_WRITE, 0, serialised.length); buffer.put(serialised); buffer.flip(); @@ -151,7 +157,8 @@ public void testSerializeMappedBitmap(int keys, ByteOrder order, boolean runOpti @ParameterizedTest @MethodSource("params") - public void testDeserializeFromHeap(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromHeap(int keys, ByteOrder order, boolean runOptimise) + throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.wrap(serialised).order(order); @@ -162,7 +169,8 @@ public void testDeserializeFromHeap(int keys, ByteOrder order, boolean runOptimi @ParameterizedTest @MethodSource("params") - public void testDeserializeFromDirect(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromDirect(int keys, ByteOrder order, boolean runOptimise) + throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocateDirect(serialised.length).order(order); @@ -175,7 +183,8 @@ public void testDeserializeFromDirect(int keys, ByteOrder order, boolean runOpti @ParameterizedTest @MethodSource("params") - public void testDeserializeFromDirectWithOffset(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testDeserializeFromDirectWithOffset(int keys, ByteOrder order, boolean runOptimise) + throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocateDirect(10 + serialised.length).order(order); @@ -189,7 +198,8 @@ public void testDeserializeFromDirectWithOffset(int keys, ByteOrder order, boole @ParameterizedTest @MethodSource("params") - public void testSerializeCorrectOffset(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeCorrectOffset(int keys, ByteOrder order, boolean runOptimise) + throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocateDirect(10 + serialised.length).order(order); @@ -201,7 +211,8 @@ public void testSerializeCorrectOffset(int keys, ByteOrder order, boolean runOpt @ParameterizedTest @MethodSource("params") - public void testSerializeToByteBufferDeserializeViaStream(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeToByteBufferDeserializeViaStream( + int keys, ByteOrder order, boolean runOptimise) throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocate(serialised.length).order(order); @@ -216,7 +227,8 @@ public void testSerializeToByteBufferDeserializeViaStream(int keys, ByteOrder or @ParameterizedTest @MethodSource("params") - public void testSerializeToByteBufferDeserializeByteBuffer(int keys, ByteOrder order, boolean runOptimise) throws IOException { + public void testSerializeToByteBufferDeserializeByteBuffer( + int keys, ByteOrder order, boolean runOptimise) throws IOException { MutableRoaringBitmap input = SeededTestData.randomBitmap(keys).toMutableRoaringBitmap(); byte[] serialised = serialise(input, runOptimise); ByteBuffer buffer = ByteBuffer.allocate(serialised.length).order(order); @@ -228,12 +240,13 @@ public void testSerializeToByteBufferDeserializeByteBuffer(int keys, ByteOrder o assertEquals(input, roundtrip); } - private static byte[] serialise(MutableRoaringBitmap input, boolean runOptimise) throws IOException { + private static byte[] serialise(MutableRoaringBitmap input, boolean runOptimise) + throws IOException { if (runOptimise) { input.runOptimize(); } try (ByteArrayOutputStream bos = new ByteArrayOutputStream(input.serializedSizeInBytes()); - DataOutputStream dos = new DataOutputStream(bos)) { + DataOutputStream dos = new DataOutputStream(bos)) { input.serialize(dos); return bos.toByteArray(); } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java index 9a3f727b0..a68ff0116 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestSerializedSize.java @@ -1,13 +1,11 @@ package org.roaringbitmap.buffer; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; public class TestSerializedSize { - @Test public void testEmpty() { MutableRoaringBitmap rb = new MutableRoaringBitmap(); @@ -19,8 +17,6 @@ public void testEmpty() { assertTrue(rac <= c); } - - @Test public void testOne() { for (int k = 0; k < 100000; k += 100) { @@ -35,7 +31,6 @@ public void testOne() { } } - @Test public void testRange() { for (int k = 0; k < 100000; k += 100) { @@ -50,7 +45,6 @@ public void testRange() { } } - @Test public void testLarge() { for (long scale = 15; scale < 2048; scale *= 15) { @@ -59,8 +53,7 @@ public void testLarge() { int universe_size = 0; for (int k = 0; k < N; ++k) { int val = (int) (scale * k); - if (val > universe_size) - universe_size = val; + if (val > universe_size) universe_size = val; rb.add((int) (scale * k)); } universe_size++; @@ -83,10 +76,9 @@ public void testManyRanges() { for (int i = 0; i < step; ++i) { final int maxv = i * (1 << 16) + stepsize; rb.add(i * (1L << 16), i * (1L << 16) + stepsize); - if (maxv > universe_size) - universe_size = maxv; + if (maxv > universe_size) universe_size = maxv; } - long c = MutableRoaringBitmap.maximumSerializedSize(rb.getCardinality(),universe_size); + long c = MutableRoaringBitmap.maximumSerializedSize(rb.getCardinality(), universe_size); long ac = rb.serializedSizeInBytes(); assertTrue(ac <= c); rb.runOptimize(); @@ -94,5 +86,4 @@ public void testManyRanges() { assertTrue(rac <= c); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java index b0103b5c1..3fd5ed9b5 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestUtil.java @@ -1,5 +1,12 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.SeededTestData.denseRegion; +import static org.roaringbitmap.SeededTestData.rleRegion; +import static org.roaringbitmap.SeededTestData.sparseRegion; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -7,7 +14,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.roaringbitmap.Util; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -15,121 +21,124 @@ import java.util.Arrays; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; -import static org.roaringbitmap.SeededTestData.*; -import static org.roaringbitmap.SeededTestData.sparseRegion; - @Execution(ExecutionMode.CONCURRENT) public class TestUtil { - @Test - public void testCopy() { - CharBuffer sb = CharBuffer.allocate(64); - sb.position(32); - CharBuffer slice = sb.slice(); - CharBuffer dest = CharBuffer.allocate(64); - for(int k = 0; k < 32; ++k) - slice.put(k, (char) k); - BufferUtil.arraycopy(slice, 16, dest, 16, 16); - for(int k = 16; k < 32; ++k) - assertEquals((char)k,dest.get(k)); - BufferUtil.arraycopy(slice, 0, dest, 16, 16); - for(int k = 16; k < 32; ++k) - assertEquals((char)(k-16),dest.get(k)); - BufferUtil.arraycopy(slice, 16, dest, 0, 16); - for(int k = 0; k < 16; ++k) - assertEquals((char)(k+16),dest.get(k)); - - } + @Test + public void testCopy() { + CharBuffer sb = CharBuffer.allocate(64); + sb.position(32); + CharBuffer slice = sb.slice(); + CharBuffer dest = CharBuffer.allocate(64); + for (int k = 0; k < 32; ++k) slice.put(k, (char) k); + BufferUtil.arraycopy(slice, 16, dest, 16, 16); + for (int k = 16; k < 32; ++k) assertEquals((char) k, dest.get(k)); + BufferUtil.arraycopy(slice, 0, dest, 16, 16); + for (int k = 16; k < 32; ++k) assertEquals((char) (k - 16), dest.get(k)); + BufferUtil.arraycopy(slice, 16, dest, 0, 16); + for (int k = 0; k < 16; ++k) assertEquals((char) (k + 16), dest.get(k)); + } - @Test - public void testFillArrayANDNOT() { - LongBuffer data1 = LongBuffer.wrap(new long[]{1, 2, 4, 8, 16}); - LongBuffer data2 = LongBuffer.wrap(new long[]{2, 1, 3, 7, 15}); - char[] content = new char[5]; - char[] result = {0, 65, 130, 195, 260}; - BufferUtil.fillArrayANDNOT(content, data1, data2); - assertTrue(Arrays.equals(content, result)); - } + @Test + public void testFillArrayANDNOT() { + LongBuffer data1 = LongBuffer.wrap(new long[] {1, 2, 4, 8, 16}); + LongBuffer data2 = LongBuffer.wrap(new long[] {2, 1, 3, 7, 15}); + char[] content = new char[5]; + char[] result = {0, 65, 130, 195, 260}; + BufferUtil.fillArrayANDNOT(content, data1, data2); + assertTrue(Arrays.equals(content, result)); + } - @Test - public void testFillArrayANDNOTException() { - assertThrows(IllegalArgumentException.class, () -> { - LongBuffer data1 = LongBuffer.wrap(new long[]{1, 2, 4, 8, 16}); - LongBuffer data2 = LongBuffer.wrap(new long[]{2, 1, 3, 7}); - char[] content = new char[5]; - BufferUtil.fillArrayANDNOT(content, data1, data2); + @Test + public void testFillArrayANDNOTException() { + assertThrows( + IllegalArgumentException.class, + () -> { + LongBuffer data1 = LongBuffer.wrap(new long[] {1, 2, 4, 8, 16}); + LongBuffer data2 = LongBuffer.wrap(new long[] {2, 1, 3, 7}); + char[] content = new char[5]; + BufferUtil.fillArrayANDNOT(content, data1, data2); }); - } - - + } - @Test - public void testUnsignedIntersects() { - CharBuffer data1 = CharBuffer.wrap(fromShorts(new short[]{-100, -98, -96, -94, -92, -90, -88, -86, -84, -82, -80})); - CharBuffer data2 = CharBuffer.wrap(fromShorts(new short[]{-99, -97, -95, -93, -91, -89, -87, -85, -83, -81, -79})); - CharBuffer data3 = CharBuffer.wrap(fromShorts(new short[]{-99, -97, -95, -93, -91, -89, -87, -85, -83, -81, -80})); - CharBuffer data4 = CharBuffer.wrap(new char[]{}); - CharBuffer data5 = CharBuffer.wrap(new char[]{}); - assertFalse(BufferUtil.unsignedIntersects(data1, data1.limit(), data2, data2.limit())); - assertTrue(BufferUtil.unsignedIntersects(data1, data1.limit(), data3, data3.limit())); - assertFalse(BufferUtil.unsignedIntersects(data4, data4.limit(), data5, data5.limit())); - } + @Test + public void testUnsignedIntersects() { + CharBuffer data1 = + CharBuffer.wrap( + fromShorts(new short[] {-100, -98, -96, -94, -92, -90, -88, -86, -84, -82, -80})); + CharBuffer data2 = + CharBuffer.wrap( + fromShorts(new short[] {-99, -97, -95, -93, -91, -89, -87, -85, -83, -81, -79})); + CharBuffer data3 = + CharBuffer.wrap( + fromShorts(new short[] {-99, -97, -95, -93, -91, -89, -87, -85, -83, -81, -80})); + CharBuffer data4 = CharBuffer.wrap(new char[] {}); + CharBuffer data5 = CharBuffer.wrap(new char[] {}); + assertFalse(BufferUtil.unsignedIntersects(data1, data1.limit(), data2, data2.limit())); + assertTrue(BufferUtil.unsignedIntersects(data1, data1.limit(), data3, data3.limit())); + assertFalse(BufferUtil.unsignedIntersects(data4, data4.limit(), data5, data5.limit())); + } @Test - public void testAdvanceUntil() { - CharBuffer data = CharBuffer.wrap(fromShorts(new short[] {0, 3, 16, 18, 21, 29, 30, -342})); - assertEquals(1, BufferUtil.advanceUntil(data, -1, data.limit(), (char) 3)); - assertEquals(5, BufferUtil.advanceUntil(data, -1, data.limit(), (char) 28)); - assertEquals(5, BufferUtil.advanceUntil(data, -1, data.limit(), (char) 29)); - assertEquals(7, BufferUtil.advanceUntil(data, -1, data.limit(), (char) -342)); - } + public void testAdvanceUntil() { + CharBuffer data = CharBuffer.wrap(fromShorts(new short[] {0, 3, 16, 18, 21, 29, 30, -342})); + assertEquals(1, BufferUtil.advanceUntil(data, -1, data.limit(), (char) 3)); + assertEquals(5, BufferUtil.advanceUntil(data, -1, data.limit(), (char) 28)); + assertEquals(5, BufferUtil.advanceUntil(data, -1, data.limit(), (char) 29)); + assertEquals(7, BufferUtil.advanceUntil(data, -1, data.limit(), (char) -342)); + } - @Test - public void testIterateUntil() { - CharBuffer data = CharBuffer.wrap(fromShorts(new short[] {0, 3, 16, 18, 21, 29, 30, -342})); - assertEquals(1, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) 3))); - assertEquals(5, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) 28))); - assertEquals(5, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) 29))); - assertEquals(7, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) -342))); - } + @Test + public void testIterateUntil() { + CharBuffer data = CharBuffer.wrap(fromShorts(new short[] {0, 3, 16, 18, 21, 29, 30, -342})); + assertEquals(1, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) 3))); + assertEquals(5, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) 28))); + assertEquals(5, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) 29))); + assertEquals(7, BufferUtil.iterateUntil(data, 0, data.limit(), ((char) -342))); + } static char[] fromShorts(short[] array) { char[] result = new char[array.length]; - for (int i = 0 ; i < array.length; ++i) { - result[i] = (char)(array[i] & 0xFFFF); + for (int i = 0; i < array.length; ++i) { + result[i] = (char) (array[i] & 0xFFFF); } return result; } public static Stream sets() { - return Stream.of(true, false) - .flatMap(direct -> Stream.of( - Arguments.of(direct, rleRegion().toArray(), rleRegion().toArray()), - Arguments.of(direct, denseRegion().toArray(), rleRegion().toArray()), - Arguments.of(direct, sparseRegion().toArray(), rleRegion().toArray()), - Arguments.of(direct, rleRegion().toArray(), denseRegion().toArray()), - Arguments.of(direct, denseRegion().toArray(), denseRegion().toArray()), - Arguments.of(direct, sparseRegion().toArray(), denseRegion().toArray()), - Arguments.of(direct, rleRegion().toArray(), sparseRegion().toArray()), - Arguments.of(direct, denseRegion().toArray(), sparseRegion().toArray()), - Arguments.of(direct, sparseRegion().toArray(), sparseRegion().toArray()))); + return Stream.of(true, false) + .flatMap( + direct -> + Stream.of( + Arguments.of(direct, rleRegion().toArray(), rleRegion().toArray()), + Arguments.of(direct, denseRegion().toArray(), rleRegion().toArray()), + Arguments.of(direct, sparseRegion().toArray(), rleRegion().toArray()), + Arguments.of(direct, rleRegion().toArray(), denseRegion().toArray()), + Arguments.of(direct, denseRegion().toArray(), denseRegion().toArray()), + Arguments.of(direct, sparseRegion().toArray(), denseRegion().toArray()), + Arguments.of(direct, rleRegion().toArray(), sparseRegion().toArray()), + Arguments.of(direct, denseRegion().toArray(), sparseRegion().toArray()), + Arguments.of(direct, sparseRegion().toArray(), sparseRegion().toArray()))); } - @MethodSource("sets") @ParameterizedTest(name = "direct={0}") public void testIntersectBitmapWithArray(boolean direct, int[] set1, int[] set2) { - LongBuffer bitmap = direct ? ByteBuffer.allocateDirect(8192).asLongBuffer() : LongBuffer.allocate(1024); + LongBuffer bitmap = + direct ? ByteBuffer.allocateDirect(8192).asLongBuffer() : LongBuffer.allocate(1024); for (int i : set1) { bitmap.put(i >>> 6, bitmap.get(i >>> 6) | (1L << i)); } - LongBuffer referenceBitmap = direct ? ByteBuffer.allocateDirect(8192).asLongBuffer() : LongBuffer.allocate(1024); - CharBuffer array = direct ? ByteBuffer.allocateDirect(2 * set2.length).asCharBuffer() : CharBuffer.allocate(set2.length); + LongBuffer referenceBitmap = + direct ? ByteBuffer.allocateDirect(8192).asLongBuffer() : LongBuffer.allocate(1024); + CharBuffer array = + direct + ? ByteBuffer.allocateDirect(2 * set2.length).asCharBuffer() + : CharBuffer.allocate(set2.length); int pos = 0; for (int i : set2) { referenceBitmap.put(i >>> 6, referenceBitmap.get(i >>> 6) | (1L << i)); - array.put(pos++, (char)i); + array.put(pos++, (char) i); } int expectedCardinality = 0; for (int i = 0; i < 1024; ++i) { @@ -145,17 +154,17 @@ public void testIntersectBitmapWithArray(boolean direct, int[] set1, int[] set2) @Test public void bitmapOfRange() { - assertBitmapRange(0, 10);// begin of first container - assertBitmapRange(0, 1 << 16 - 1);// early full container - assertBitmapRange(0, 1 << 16);// full first container - assertBitmapRange(0, 1 << 16 + 1);// full first container + one value the second - assertBitmapRange(10, 1 << 16);// without first several integers - assertBitmapRange(1 << 16, (1 << 16) * 2);// full second container - assertBitmapRange(10, 100);// some integers inside interval + assertBitmapRange(0, 10); // begin of first container + assertBitmapRange(0, 1 << 16 - 1); // early full container + assertBitmapRange(0, 1 << 16); // full first container + assertBitmapRange(0, 1 << 16 + 1); // full first container + one value the second + assertBitmapRange(10, 1 << 16); // without first several integers + assertBitmapRange(1 << 16, (1 << 16) * 2); // full second container + assertBitmapRange(10, 100); // some integers inside interval assertBitmapRange((1 << 16) - 5, (1 << 16) + 7); // first to second container assertBitmapRange(0, 100_000); // more than one container - assertBitmapRange(100_000, 200_000);// second to third container - assertBitmapRange(200_000, 400_000);// more containers inside + assertBitmapRange(100_000, 200_000); // second to third container + assertBitmapRange(200_000, 400_000); // more containers inside } private static void assertBitmapRange(int start, int end) { diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java index a6430366a..700798020 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/buffer/TestVeryLargeBitmap.java @@ -1,10 +1,9 @@ package org.roaringbitmap.buffer; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class TestVeryLargeBitmap { @Test public void testSelect() { @@ -32,5 +31,4 @@ public void stupidlyLarge() { ome.printStackTrace(); } } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java index 82fc80009..2fc0cbdce 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapAnalyserTest.java @@ -1,18 +1,17 @@ package org.roaringbitmap.insights; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.roaringbitmap.RoaringBitmap; +import org.roaringbitmap.SeededTestData; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.roaringbitmap.RoaringBitmap; -import org.roaringbitmap.SeededTestData; import java.util.ArrayList; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; - - @Execution(ExecutionMode.CONCURRENT) public class BitmapAnalyserTest { @@ -25,7 +24,8 @@ public void analyseSingleBitmap() { rb.add(i); } BitmapStatistics result = BitmapAnalyser.analyse(rb); - BitmapStatistics expected = new BitmapStatistics(new BitmapStatistics.ArrayContainersStats(1, 6), 1, 1); + BitmapStatistics expected = + new BitmapStatistics(new BitmapStatistics.ArrayContainersStats(1, 6), 1, 1); assertEquals(expected, result); } @@ -41,7 +41,10 @@ public void analyseRandomBitmap() { assertEquals(runFraction, result.containerFraction(result.getRunContainerCount()), delta); assertEquals(bitmapFraction, result.containerFraction(result.getBitmapContainerCount()), delta); - assertEquals(arrayFraction, result.containerFraction(result.getArrayContainersStats().getContainersCount()), delta); + assertEquals( + arrayFraction, + result.containerFraction(result.getArrayContainersStats().getContainersCount()), + delta); } @Test @@ -62,8 +65,10 @@ public void analyseRandomBitmaps() { assertEquals(runFraction, result.containerFraction(result.getRunContainerCount()), delta); assertEquals(bitmapFraction, result.containerFraction(result.getBitmapContainerCount()), delta); - assertEquals(arrayFraction, result.containerFraction(result.getArrayContainersStats().getContainersCount()), delta); + assertEquals( + arrayFraction, + result.containerFraction(result.getArrayContainersStats().getContainersCount()), + delta); assertEquals(totalBitmaps, result.getBitmapsCount()); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java index e75b78ea9..1b34c1f04 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/insights/BitmapStatisticsTest.java @@ -1,19 +1,16 @@ package org.roaringbitmap.insights; - -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + public class BitmapStatisticsTest { @Test public void toStringWorks() { - BitmapStatistics statistics = new BitmapStatistics( - new BitmapStatistics.ArrayContainersStats(10, 50), - 2, - 1); + BitmapStatistics statistics = + new BitmapStatistics(new BitmapStatistics.ArrayContainersStats(10, 50), 2, 1); String string = statistics.toString(); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java index 97df7d22e..bb9ec30d4 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/insights/NaiveWriterRecommenderTest.java @@ -1,11 +1,10 @@ package org.roaringbitmap.insights; - -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + public class NaiveWriterRecommenderTest { @Test @@ -15,15 +14,17 @@ public void recommendForArrays() { int bitmapContainerCount = 2; int runContainerCount = 50; int bitmapsCount = 10; - BitmapStatistics stats = new BitmapStatistics( - new BitmapStatistics.ArrayContainersStats(arrayContainerCount, arrayContainerCount * averagePerArrayContaier), - bitmapContainerCount, - runContainerCount, - bitmapsCount); + BitmapStatistics stats = + new BitmapStatistics( + new BitmapStatistics.ArrayContainersStats( + arrayContainerCount, arrayContainerCount * averagePerArrayContaier), + bitmapContainerCount, + runContainerCount, + bitmapsCount); String recommendation = NaiveWriterRecommender.recommend(stats); - //System.out.println(recommendation); + // System.out.println(recommendation); assertTrue(recommendation.contains(".initialCapacity(2005)")); assertTrue(recommendation.contains(".optimiseForArrays()")); assertTrue(recommendation.contains(".expectedContainerSize(10)")); @@ -36,29 +37,33 @@ public void recommendForDenseArrays() { int bitmapContainerCount = 2; int runContainerCount = 50; int bitmapsCount = 10; - BitmapStatistics stats = new BitmapStatistics( - new BitmapStatistics.ArrayContainersStats(arrayContainerCount, arrayContainerCount * denseAveragePerArrayContaier), - bitmapContainerCount, - runContainerCount, - bitmapsCount); + BitmapStatistics stats = + new BitmapStatistics( + new BitmapStatistics.ArrayContainersStats( + arrayContainerCount, arrayContainerCount * denseAveragePerArrayContaier), + bitmapContainerCount, + runContainerCount, + bitmapsCount); String recommendation = NaiveWriterRecommender.recommend(stats); assertTrue(recommendation.contains(".constantMemory()")); } - @Test + @Test public void recommendForRuns() { int arrayContainerCount = 100; int averagePerArrayContaier = 10; int bitmapContainerCount = 200; int runContainerCount = 50000; int bitmapsCount = 70; - BitmapStatistics stats = new BitmapStatistics( - new BitmapStatistics.ArrayContainersStats(arrayContainerCount, arrayContainerCount * averagePerArrayContaier), - bitmapContainerCount, - runContainerCount, - bitmapsCount); + BitmapStatistics stats = + new BitmapStatistics( + new BitmapStatistics.ArrayContainersStats( + arrayContainerCount, arrayContainerCount * averagePerArrayContaier), + bitmapContainerCount, + runContainerCount, + bitmapsCount); String recommendation = NaiveWriterRecommender.recommend(stats); @@ -66,7 +71,6 @@ public void recommendForRuns() { assertTrue(recommendation.contains(".optimiseForRuns()")); } - @Test public void recommendForUniform() { int arrayContainerCount = 10000; @@ -74,11 +78,13 @@ public void recommendForUniform() { int bitmapContainerCount = 10000; int runContainerCount = 10000; int bitmapsCount = 120; - BitmapStatistics stats = new BitmapStatistics( - new BitmapStatistics.ArrayContainersStats(arrayContainerCount, arrayContainerCount * averagePerArrayContaier), - bitmapContainerCount, - runContainerCount, - bitmapsCount); + BitmapStatistics stats = + new BitmapStatistics( + new BitmapStatistics.ArrayContainersStats( + arrayContainerCount, arrayContainerCount * averagePerArrayContaier), + bitmapContainerCount, + runContainerCount, + bitmapsCount); String recommendation = NaiveWriterRecommender.recommend(stats); @@ -93,11 +99,13 @@ public void recommendForBitmaps() { int bitmapContainerCount = 100000; int runContainerCount = 40; int bitmapsCount = 190; - BitmapStatistics stats = new BitmapStatistics( - new BitmapStatistics.ArrayContainersStats(arrayContainerCount, arrayContainerCount * averagePerArrayContaier), - bitmapContainerCount, - runContainerCount, - bitmapsCount); + BitmapStatistics stats = + new BitmapStatistics( + new BitmapStatistics.ArrayContainersStats( + arrayContainerCount, arrayContainerCount * averagePerArrayContaier), + bitmapContainerCount, + runContainerCount, + bitmapsCount); String recommendation = NaiveWriterRecommender.recommend(stats); @@ -106,9 +114,8 @@ public void recommendForBitmaps() { } @Test - public void notRecommendForEmptyStats(){ + public void notRecommendForEmptyStats() { String recommendation = NaiveWriterRecommender.recommend(BitmapStatistics.empty); assertFalse(recommendation.contains(".initialCapacity")); } - } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java index 0a8bd6d75..661dd0ee8 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ArtTest.java @@ -1,5 +1,13 @@ package org.roaringbitmap.longlong; +import org.roaringbitmap.art.Art; +import org.roaringbitmap.art.LeafNode; +import org.roaringbitmap.art.LeafNodeIterator; +import org.roaringbitmap.art.Node; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -7,19 +15,13 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.roaringbitmap.art.Art; -import org.roaringbitmap.art.LeafNode; -import org.roaringbitmap.art.LeafNodeIterator; -import org.roaringbitmap.art.Node; public class ArtTest { - //one leaf node + // one leaf node @Test public void testLeafNode() { - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 0}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 0}; Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 1); LeafNodeIterator leafNodeIterator = art.leafNodeIterator(false, null); @@ -34,11 +36,11 @@ public void testLeafNode() { Assertions.assertTrue(art.findByKey(key1) == Node.ILLEGAL_IDX); } - //one node4 with two leaf nodes + // one node4 with two leaf nodes @Test public void testNode4() { - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 0}; - byte[] key2 = new byte[]{1, 2, 3, 4, 5, 1}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 0}; + byte[] key2 = new byte[] {1, 2, 3, 4, 5, 1}; Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 2); LeafNodeIterator leafNodeIterator = art.leafNodeIterator(false, null); @@ -55,19 +57,19 @@ public void testNode4() { hasNext = leafNodeIterator.hasNext(); Assertions.assertTrue(!hasNext); art.remove(key1); - //shrink to leaf node + // shrink to leaf node long containerIdx2 = art.findByKey(key2); Assertions.assertEquals(1, containerIdx2); } - //1 node16 + // 1 node16 @Test public void testNode16() throws Exception { - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 0}; - byte[] key2 = new byte[]{1, 2, 3, 4, 5, 1}; - byte[] key3 = new byte[]{1, 2, 3, 4, 5, 2}; - byte[] key4 = new byte[]{1, 2, 3, 4, 5, 3}; - byte[] key5 = new byte[]{1, 2, 3, 4, 5, 4}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 0}; + byte[] key2 = new byte[] {1, 2, 3, 4, 5, 1}; + byte[] key3 = new byte[] {1, 2, 3, 4, 5, 2}; + byte[] key4 = new byte[] {1, 2, 3, 4, 5, 3}; + byte[] key5 = new byte[] {1, 2, 3, 4, 5, 4}; Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 5); LeafNodeIterator leafNodeIterator = art.leafNodeIterator(false, null); @@ -87,13 +89,13 @@ public void testNode16() throws Exception { Assertions.assertEquals(3, containerIdx); containerIdx = art.findByKey(key5); Assertions.assertEquals(4, containerIdx); - //ser/deser + // ser/deser int sizeInBytes = (int) art.serializeSizeInBytes(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); art.serializeArt(dataOutputStream); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( - byteArrayOutputStream.toByteArray()); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); Art deserArt = new Art(); deserArt.deserializeArt(dataInputStream); @@ -107,33 +109,33 @@ public void testNode16() throws Exception { art.remove(key5); art.remove(key4); - //shrink to node4 + // shrink to node4 long containerIdx4 = art.findByKey(key3); Assertions.assertEquals(2, containerIdx4); } - //node48 + // node48 @Test public void testNode48() throws Exception { Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 17); - byte[] key = new byte[]{1, 2, 3, 4, 5, 0}; + byte[] key = new byte[] {1, 2, 3, 4, 5, 0}; long containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == 0); - key = new byte[]{1, 2, 3, 4, 5, 10}; + key = new byte[] {1, 2, 3, 4, 5, 10}; containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == 10); - key = new byte[]{1, 2, 3, 4, 5, 12}; + key = new byte[] {1, 2, 3, 4, 5, 12}; containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == 12); - byte[] key13 = new byte[]{1, 2, 3, 4, 5, 12}; - //ser/deser + byte[] key13 = new byte[] {1, 2, 3, 4, 5, 12}; + // ser/deser int sizeInBytes = (int) art.serializeSizeInBytes(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(sizeInBytes); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); art.serializeArt(dataOutputStream); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( - byteArrayOutputStream.toByteArray()); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); Art deserArt = new Art(); deserArt.deserializeArt(dataInputStream); @@ -146,34 +148,34 @@ public void testNode48() throws Exception { Assertions.assertEquals(art.findByKey(key13), deserArt.findByKey(key13)); Assertions.assertEquals(art.getKeySize(), deserArt.getKeySize()); - //shrink to node16 + // shrink to node16 for (int i = 0; i < 6; i++) { key13[5] = (byte) (12 + i); art.remove(key13); } - byte[] key12 = new byte[]{1, 2, 3, 4, 5, 11}; + byte[] key12 = new byte[] {1, 2, 3, 4, 5, 11}; long containerIdx12 = art.findByKey(key12); Assertions.assertEquals(11, containerIdx12); } - //node256 + // node256 @Test public void testNode256() throws IOException { Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 50); - byte[] key = new byte[]{1, 2, 3, 4, 5, 0}; + byte[] key = new byte[] {1, 2, 3, 4, 5, 0}; long containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == 0); - key = new byte[]{1, 2, 3, 4, 5, 10}; + key = new byte[] {1, 2, 3, 4, 5, 10}; containerIdx = art.findByKey(key); Assertions.assertEquals(10, containerIdx); - key = new byte[]{1, 2, 3, 4, 5, 16}; + key = new byte[] {1, 2, 3, 4, 5, 16}; containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == 16); - key = new byte[]{1, 2, 3, 4, 5, 36}; + key = new byte[] {1, 2, 3, 4, 5, 36}; containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == 36); - key = new byte[]{1, 2, 3, 4, 5, 51}; + key = new byte[] {1, 2, 3, 4, 5, 51}; containerIdx = art.findByKey(key); Assertions.assertTrue(containerIdx == Node.ILLEGAL_IDX); long sizeInBytesL = art.serializeSizeInBytes(); @@ -183,10 +185,10 @@ public void testNode256() throws IOException { art.serializeArt(dataOutputStream); Assertions.assertEquals(sizeInBytesI, byteArrayOutputStream.toByteArray().length); Art deserArt = new Art(); - DataInputStream dataInputStream = new DataInputStream( - new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); + DataInputStream dataInputStream = + new DataInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); deserArt.deserializeArt(dataInputStream); - key = new byte[]{1, 2, 3, 4, 5, 36}; + key = new byte[] {1, 2, 3, 4, 5, 36}; containerIdx = deserArt.findByKey(key); Assertions.assertEquals(36, containerIdx); @@ -198,18 +200,18 @@ public void testNode256() throws IOException { containerIdx = deserBBOne.findByKey(key); Assertions.assertEquals(36, containerIdx); - //shrink to node48 + // shrink to node48 deserArt.remove(key); - key = new byte[]{1, 2, 3, 4, 5, 10}; + key = new byte[] {1, 2, 3, 4, 5, 10}; containerIdx = deserArt.findByKey(key); Assertions.assertTrue(containerIdx == 10); } @Test public void testNodeSeek() { - byte[] key0 = new byte[]{1, 2, 3, 4, 5, 0}; - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 1}; - byte[] key2 = new byte[]{1, 2, 3, 4, 5, 2}; + byte[] key0 = new byte[] {1, 2, 3, 4, 5, 0}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 1}; + byte[] key2 = new byte[] {1, 2, 3, 4, 5, 2}; Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 3); LeafNodeIterator lnIt = art.leafNodeIterator(false, null); @@ -236,7 +238,8 @@ public void testNodeSeek() { Assertions.assertTrue(BytesUtil.same(lnIt.next().getKeyBytes(), key2)); Assertions.assertFalse(lnIt.hasNext()); - // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher levels + // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher + // levels // (as it is) lnIt.seek(LongUtils.toLong(key1, (char) 0)); Assertions.assertTrue(lnIt.hasNext()); @@ -245,9 +248,9 @@ public void testNodeSeek() { @Test public void testNodeSeekReverse() { - byte[] key0 = new byte[]{1, 2, 3, 4, 5, 0}; - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 1}; - byte[] key2 = new byte[]{1, 2, 3, 4, 5, 2}; + byte[] key0 = new byte[] {1, 2, 3, 4, 5, 0}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 1}; + byte[] key2 = new byte[] {1, 2, 3, 4, 5, 2}; Art art = new Art(); insert5PrefixCommonBytesIntoArt(art, 3); LeafNodeIterator lnIt = art.leafNodeIterator(true, null); @@ -274,7 +277,8 @@ public void testNodeSeekReverse() { Assertions.assertTrue(BytesUtil.same(lnIt.next().getKeyBytes(), key0)); Assertions.assertFalse(lnIt.hasNext()); - // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher levels + // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher + // levels // (as it is) lnIt.seek(LongUtils.toLong(key1, (char) 0)); Assertions.assertTrue(lnIt.hasNext()); @@ -283,13 +287,13 @@ public void testNodeSeekReverse() { @Test public void testNodeSeekOverGaps() { - byte[] start0 = new byte[]{0, 2, 3, 4, 5, 0}; - byte[] key0 = new byte[]{1, 2, 3, 4, 5, 0}; - byte[] gap1 = new byte[]{1, 2, 3, 4, 5, 1}; - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 2}; - byte[] gap2 = new byte[]{1, 2, 3, 4, 5, 3}; - byte[] key2 = new byte[]{1, 2, 3, 4, 5, 4}; - byte[] end1 = new byte[]{2, 2, 3, 4, 5, 4}; + byte[] start0 = new byte[] {0, 2, 3, 4, 5, 0}; + byte[] key0 = new byte[] {1, 2, 3, 4, 5, 0}; + byte[] gap1 = new byte[] {1, 2, 3, 4, 5, 1}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 2}; + byte[] gap2 = new byte[] {1, 2, 3, 4, 5, 3}; + byte[] key2 = new byte[] {1, 2, 3, 4, 5, 4}; + byte[] end1 = new byte[] {2, 2, 3, 4, 5, 4}; Art art = new Art(); insert5PrefixCommonWithGapBytesIntoArt(art, 3); @@ -317,7 +321,8 @@ public void testNodeSeekOverGaps() { Assertions.assertTrue(BytesUtil.same(lnIt.next().getKeyBytes(), key2)); Assertions.assertFalse(lnIt.hasNext()); - // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher levels + // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher + // levels // (as it is) lnIt.seek(LongUtils.toLong(key0, (char) 0)); Assertions.assertTrue(lnIt.hasNext()); @@ -342,21 +347,20 @@ public void testNodeSeekOverGaps() { Assertions.assertFalse(lnIt.hasNext()); // going the before the first should "return" the first - lnIt.seek(LongUtils.toLong(start0, (char)0)); + lnIt.seek(LongUtils.toLong(start0, (char) 0)); Assertions.assertTrue(lnIt.hasNext()); Assertions.assertTrue(BytesUtil.same(lnIt.peekNext().getKeyBytes(), key0)); - } @Test public void testNodeSeekOverGapsReverse() { - byte[] start0 = new byte[]{2, 2, 3, 4, 5, 0}; - byte[] key0 = new byte[]{1, 2, 3, 4, 5, 4}; - byte[] gap1 = new byte[]{1, 2, 3, 4, 5, 3}; - byte[] key1 = new byte[]{1, 2, 3, 4, 5, 2}; - byte[] gap2 = new byte[]{1, 2, 3, 4, 5, 1}; - byte[] key2 = new byte[]{1, 2, 3, 4, 5, 0}; - byte[] end1 = new byte[]{0, 2, 3, 4, 5, 0}; + byte[] start0 = new byte[] {2, 2, 3, 4, 5, 0}; + byte[] key0 = new byte[] {1, 2, 3, 4, 5, 4}; + byte[] gap1 = new byte[] {1, 2, 3, 4, 5, 3}; + byte[] key1 = new byte[] {1, 2, 3, 4, 5, 2}; + byte[] gap2 = new byte[] {1, 2, 3, 4, 5, 1}; + byte[] key2 = new byte[] {1, 2, 3, 4, 5, 0}; + byte[] end1 = new byte[] {0, 2, 3, 4, 5, 0}; Art art = new Art(); insert5PrefixCommonWithGapBytesIntoArt(art, 3); @@ -384,7 +388,8 @@ public void testNodeSeekOverGapsReverse() { Assertions.assertTrue(BytesUtil.same(lnIt.next().getKeyBytes(), key2)); Assertions.assertFalse(lnIt.hasNext()); - // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher levels + // seeking to the prior "1" takes you there.. so this needs to be guarded against, in higher + // levels // (as it is) lnIt.seek(LongUtils.toLong(key0, (char) 0)); Assertions.assertTrue(lnIt.hasNext()); @@ -409,32 +414,32 @@ public void testNodeSeekOverGapsReverse() { Assertions.assertFalse(lnIt.hasNext()); // going the before the first should "return" the first - lnIt.seek(LongUtils.toLong(start0, (char)0)); + lnIt.seek(LongUtils.toLong(start0, (char) 0)); Assertions.assertTrue(lnIt.hasNext()); Assertions.assertTrue(BytesUtil.same(lnIt.peekNext().getKeyBytes(), key0)); } private void insert5PrefixCommonBytesIntoArt(Art art, int keyNum) { - byte[] key = new byte[]{1, 2, 3, 4, 5, 0}; + byte[] key = new byte[] {1, 2, 3, 4, 5, 0}; byte b = 0; long containerIdx = 0; for (int i = 0; i < keyNum; i++) { key[5] = b; art.insert(key, containerIdx); - key = new byte[]{1, 2, 3, 4, 5, 0}; + key = new byte[] {1, 2, 3, 4, 5, 0}; b++; containerIdx++; } } private void insert5PrefixCommonWithGapBytesIntoArt(Art art, int keyNum) { - byte[] key = new byte[]{1, 2, 3, 4, 5, 0}; + byte[] key = new byte[] {1, 2, 3, 4, 5, 0}; byte b = 0; long containerIdx = 0; for (int i = 0; i < keyNum; i++) { key[5] = b; art.insert(key, containerIdx); - key = new byte[]{1, 2, 3, 4, 5, 0}; + key = new byte[] {1, 2, 3, 4, 5, 0}; b += 2; containerIdx++; } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java index 1342d6e2f..162959ec2 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/ContainersTest.java @@ -1,5 +1,15 @@ package org.roaringbitmap.longlong; +import org.roaringbitmap.ArrayContainer; +import org.roaringbitmap.BitmapContainer; +import org.roaringbitmap.Container; +import org.roaringbitmap.RunContainer; +import org.roaringbitmap.art.ContainerIterator; +import org.roaringbitmap.art.Containers; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -7,14 +17,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.roaringbitmap.ArrayContainer; -import org.roaringbitmap.BitmapContainer; -import org.roaringbitmap.Container; -import org.roaringbitmap.RunContainer; -import org.roaringbitmap.art.ContainerIterator; -import org.roaringbitmap.art.Containers; public class ContainersTest { @@ -49,7 +51,7 @@ public void test1() { if (i == 0) { long currentContainerIdx = containerIterator.getCurrentContainerIdx(); Assertions.assertEquals(cidx0, currentContainerIdx); - RunContainer rc = new RunContainer(new char[]{23, 24}, 1); + RunContainer rc = new RunContainer(new char[] {23, 24}, 1); containerIterator.replace(rc); } i++; @@ -57,7 +59,7 @@ public void test1() { Assertions.assertTrue(i == 3); Container replacedContainer = containers.getContainer(cidx0); Assertions.assertEquals(23, replacedContainer.select(0)); - ArrayContainer arrayContainer1 = new ArrayContainer(new char[]{10, 20, 30}); + ArrayContainer arrayContainer1 = new ArrayContainer(new char[] {10, 20, 30}); containers.replace(cidx1, arrayContainer1); replacedContainer = containers.getContainer(cidx1); Assertions.assertTrue(replacedContainer == arrayContainer1); @@ -77,8 +79,8 @@ public void test2() throws IOException { DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); containers.serialize(dataOutputStream); Containers deseredOne = new Containers(); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( - byteArrayOutputStream.toByteArray()); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); deseredOne.deserialize(dataInputStream); long containerSize = deseredOne.getContainerSize(); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java index f74c682d1..94ead800d 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/IntegerUtilTest.java @@ -1,9 +1,9 @@ package org.roaringbitmap.longlong; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + public class IntegerUtilTest { @Test @@ -25,10 +25,10 @@ public void testConvertIntToBytes() { @Test public void testSetByte() { for (int i = 0; i < 4; ++i) { - int value = IntegerUtil.setByte(0x55555555, (byte)0xAA, i); + int value = IntegerUtil.setByte(0x55555555, (byte) 0xAA, i); byte[] bytes = IntegerUtil.toBDBytes(value); for (int j = 0; j < 4; ++j) { - byte expected = i == j ? (byte)0xAA : (byte)0x55; + byte expected = i == j ? (byte) 0xAA : (byte) 0x55; assertEquals(expected, bytes[j]); } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java index 8eab5a8d1..f3473994d 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/Issue319.java @@ -12,8 +12,7 @@ public class Issue319 { public static void main(String[] args) throws IOException { RoaringBitmap mrb = RoaringBitmap.bitmapOf(1, 2, 3, 1000); - for (int k = 0; k < 1000000000; k += 13) - mrb.add(k); + for (int k = 0; k < 1000000000; k += 13) mrb.add(k); mrb.runOptimize(); int count = 30; byte[] array = serialize(mrb); @@ -25,26 +24,28 @@ public static void main(String[] args) throws IOException { bef = System.currentTimeMillis(); RoaringBitmap ret = new RoaringBitmap(); try { - ret.deserialize(new java.io.DataInputStream(new java.io.InputStream() { - int c = 0; - - @Override - public int read() { - return array[c++] & 0xff; - } - - @Override - public int read(byte b[]) { - return read(b, 0, b.length); - } - - @Override - public int read(byte[] b, int off, int l) { - System.arraycopy(array, c, b, off, l); - c += l; - return l; - } - })); + ret.deserialize( + new java.io.DataInputStream( + new java.io.InputStream() { + int c = 0; + + @Override + public int read() { + return array[c++] & 0xff; + } + + @Override + public int read(byte b[]) { + return read(b, 0, b.length); + } + + @Override + public int read(byte[] b, int off, int l) { + System.arraycopy(array, c, b, off, l); + c += l; + return l; + } + })); } catch (IOException ioe) { // should never happen because we read from a byte array throw new RuntimeException("unexpected error while deserializing from a byte array"); @@ -52,12 +53,10 @@ public int read(byte[] b, int off, int l) { aft = System.currentTimeMillis(); System.out.print(aft - bef + " ms "); sum += aft - bef; - if (!ret.equals(mrb)) - throw new RuntimeException("bug"); + if (!ret.equals(mrb)) throw new RuntimeException("bug"); } System.out.println("\naverage: " + sum / count); - System.out.println("via ByteArrayInputStream: "); sum = 0; for (int k = 0; k < count; k++) { @@ -67,8 +66,7 @@ public int read(byte[] b, int off, int l) { aft = System.currentTimeMillis(); System.out.print(aft - bef + " ms "); sum += aft - bef; - if (!ret.equals(mrb)) - throw new RuntimeException("bug"); + if (!ret.equals(mrb)) throw new RuntimeException("bug"); } System.out.println("\naverage: " + sum / count); @@ -80,8 +78,7 @@ public int read(byte[] b, int off, int l) { aft = System.currentTimeMillis(); System.out.print(aft - bef + " ms "); sum += aft - bef; - if (!ret.equals(mrb)) - throw new RuntimeException("bug"); + if (!ret.equals(mrb)) throw new RuntimeException("bug"); } System.out.println("\naverage: " + sum / count); @@ -94,41 +91,41 @@ public int read(byte[] b, int off, int l) { aft = System.currentTimeMillis(); System.out.print(aft - bef + " ms "); sum += aft - bef; - if (!ret.equals(mrb)) - throw new RuntimeException("bug"); + if (!ret.equals(mrb)) throw new RuntimeException("bug"); } System.out.println("\naverage: " + sum / count); - } private static byte[] serialize(RoaringBitmap mrb) { byte[] array = new byte[mrb.serializedSizeInBytes()]; try { - mrb.serialize(new java.io.DataOutputStream(new java.io.OutputStream() { - int c = 0; - - @Override - public void close() {} - - @Override - public void flush() {} - - @Override - public void write(int b) { - array[c++] = (byte) b; - } - - @Override - public void write(byte[] b) { - write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int off, int l) { - System.arraycopy(b, off, array, c, l); - c += l; - } - })); + mrb.serialize( + new java.io.DataOutputStream( + new java.io.OutputStream() { + int c = 0; + + @Override + public void close() {} + + @Override + public void flush() {} + + @Override + public void write(int b) { + array[c++] = (byte) b; + } + + @Override + public void write(byte[] b) { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int l) { + System.arraycopy(b, off, array, c, l); + c += l; + } + })); } catch (IOException ioe) { // should never happen because we write to a byte array throw new RuntimeException("unexpected error while serializing to a byte array"); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java index 3e2c0b46b..635563b00 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/JolBenchmarksTest.java @@ -16,118 +16,124 @@ // https://github.com/RoaringBitmap/RoaringBitmap/issues/346 public class JolBenchmarksTest { - @SuppressWarnings("restriction") - public static void main(String[] args) { - // distinctHigherRadices(); - // sameHigherRadix(); - statisticsWithGrowingSizes(); - } - - private static void distinctHigherRadices() { - int valuesPerRadix = 1 << 16; - int distance = 2000; - Roaring64NavigableMap bitmapMap = new Roaring64NavigableMap(); - long[] radices = new long[1024]; - for (int i = 0; i < radices.length; ++i) { - radices[i] = ((long) i) << 48; - } - for (int i = 0; i < radices.length; i++) { - for (int j = 0; j < valuesPerRadix; ++j) { - bitmapMap.addLong(radices[i] | (j * distance)); - } - } - - long[] bitmapArray = bitmapMap.toArray(); - - Roaring64Bitmap bitmapArt = new Roaring64Bitmap(); - bitmapArt.add(bitmapArray); - - System.out.println("---distinctHigherRadices---"); - System.out.println(GraphLayout.parseInstance(bitmapArray).toFootprint()); - - System.out.println("---"); - System.out.println(GraphLayout.parseInstance(bitmapMap).toFootprint()); - System.out.println(bitmapMap.getLongSizeInBytes()); - bitmapMap.runOptimize(); - System.out.println(GraphLayout.parseInstance(bitmapMap).toFootprint()); - System.out.println(bitmapMap.getLongSizeInBytes()); - - System.out.println("---"); - System.out.println(GraphLayout.parseInstance(bitmapArt).toFootprint()); - System.out.println(bitmapArt.getLongSizeInBytes()); - bitmapArt.runOptimize(); - System.out.println(GraphLayout.parseInstance(bitmapArt).toFootprint()); - System.out.println(bitmapArt.getLongSizeInBytes()); - } - - private static void sameHigherRadix() { - int numValues = (1 << 16) * 1024; - int distance = 2000; - Roaring64NavigableMap bitmap = new Roaring64NavigableMap(); - - long x = 0L; - for (int i = 0; i < numValues; i++) { - bitmap.addLong(x); - x += distance; - } - - long[] array = bitmap.toArray(); - - Roaring64Bitmap bitmapOpt = new Roaring64Bitmap(); - bitmapOpt.add(array); - - System.out.println("---sameHigherRadix---"); - System.out.println(GraphLayout.parseInstance(array).toFootprint()); - - System.out.println("---"); - System.out.println(GraphLayout.parseInstance(bitmap).toFootprint()); - bitmap.runOptimize(); - System.out.println(GraphLayout.parseInstance(bitmap).toFootprint()); - - System.out.println("---"); - System.out.println(GraphLayout.parseInstance(bitmapOpt).toFootprint()); - bitmapOpt.runOptimize(); - System.out.println(GraphLayout.parseInstance(bitmapOpt).toFootprint()); - } - - public static void statisticsWithGrowingSizes() { - Random r = new Random(); - - // We re-use the bitmaps so that we accumulate the longs into them - // We then expect to have denser buckets (around 0) - Roaring64Bitmap bitmap64Art = new Roaring64Bitmap(); - Roaring64NavigableMap bitmap64Map = new Roaring64NavigableMap(); - - for (long size = 0 ; size < 1024 ; size++) { - long max = (1L + size*size*size*size*size); - System.out.println(size + " in [-" + max + ", " + max + "["); - - long fSize = size; - long[] array = IntStream.range(0, Ints.checkedCast(size)) - .mapToLong(i -> i) - .flatMap(i -> LongStream.generate(() -> r.nextLong() % max).limit(fSize)) - .toArray(); - - reportBitmapsMemory(array, bitmap64Art, bitmap64Map); - } - } - - private static void reportBitmapsMemory(long[] array, LongBitmapDataProvider bitmap, LongBitmapDataProvider bitmap2) { - reportBitmapsMemory(array, bitmap); - reportBitmapsMemory(array, bitmap2); - - if (!Arrays.equals(bitmap.toArray(), bitmap.toArray())) { - throw new IllegalStateException("Issue with: " + Arrays.toString(array)); - } - } - - private static void reportBitmapsMemory(long[] array, LongBitmapDataProvider bitmap) { - LongStream.of(array).forEach(bitmap::addLong); - long jolSize = GraphLayout.parseInstance(bitmap).totalSize(); - long ownEstimation = bitmap.getLongSizeInBytes(); - System.out.println(bitmap.getClass().getSimpleName() - + ": " + String.format("%,d", jolSize) + "(real) vs " - + String.format("%,d", ownEstimation) + "(estimated) " - + (ownEstimation < jolSize ? "optimistic" : "pessimistic")); - } + @SuppressWarnings("restriction") + public static void main(String[] args) { + // distinctHigherRadices(); + // sameHigherRadix(); + statisticsWithGrowingSizes(); + } + + private static void distinctHigherRadices() { + int valuesPerRadix = 1 << 16; + int distance = 2000; + Roaring64NavigableMap bitmapMap = new Roaring64NavigableMap(); + long[] radices = new long[1024]; + for (int i = 0; i < radices.length; ++i) { + radices[i] = ((long) i) << 48; + } + for (int i = 0; i < radices.length; i++) { + for (int j = 0; j < valuesPerRadix; ++j) { + bitmapMap.addLong(radices[i] | (j * distance)); + } + } + + long[] bitmapArray = bitmapMap.toArray(); + + Roaring64Bitmap bitmapArt = new Roaring64Bitmap(); + bitmapArt.add(bitmapArray); + + System.out.println("---distinctHigherRadices---"); + System.out.println(GraphLayout.parseInstance(bitmapArray).toFootprint()); + + System.out.println("---"); + System.out.println(GraphLayout.parseInstance(bitmapMap).toFootprint()); + System.out.println(bitmapMap.getLongSizeInBytes()); + bitmapMap.runOptimize(); + System.out.println(GraphLayout.parseInstance(bitmapMap).toFootprint()); + System.out.println(bitmapMap.getLongSizeInBytes()); + + System.out.println("---"); + System.out.println(GraphLayout.parseInstance(bitmapArt).toFootprint()); + System.out.println(bitmapArt.getLongSizeInBytes()); + bitmapArt.runOptimize(); + System.out.println(GraphLayout.parseInstance(bitmapArt).toFootprint()); + System.out.println(bitmapArt.getLongSizeInBytes()); + } + + private static void sameHigherRadix() { + int numValues = (1 << 16) * 1024; + int distance = 2000; + Roaring64NavigableMap bitmap = new Roaring64NavigableMap(); + + long x = 0L; + for (int i = 0; i < numValues; i++) { + bitmap.addLong(x); + x += distance; + } + + long[] array = bitmap.toArray(); + + Roaring64Bitmap bitmapOpt = new Roaring64Bitmap(); + bitmapOpt.add(array); + + System.out.println("---sameHigherRadix---"); + System.out.println(GraphLayout.parseInstance(array).toFootprint()); + + System.out.println("---"); + System.out.println(GraphLayout.parseInstance(bitmap).toFootprint()); + bitmap.runOptimize(); + System.out.println(GraphLayout.parseInstance(bitmap).toFootprint()); + + System.out.println("---"); + System.out.println(GraphLayout.parseInstance(bitmapOpt).toFootprint()); + bitmapOpt.runOptimize(); + System.out.println(GraphLayout.parseInstance(bitmapOpt).toFootprint()); + } + + public static void statisticsWithGrowingSizes() { + Random r = new Random(); + + // We re-use the bitmaps so that we accumulate the longs into them + // We then expect to have denser buckets (around 0) + Roaring64Bitmap bitmap64Art = new Roaring64Bitmap(); + Roaring64NavigableMap bitmap64Map = new Roaring64NavigableMap(); + + for (long size = 0; size < 1024; size++) { + long max = (1L + size * size * size * size * size); + System.out.println(size + " in [-" + max + ", " + max + "["); + + long fSize = size; + long[] array = + IntStream.range(0, Ints.checkedCast(size)) + .mapToLong(i -> i) + .flatMap(i -> LongStream.generate(() -> r.nextLong() % max).limit(fSize)) + .toArray(); + + reportBitmapsMemory(array, bitmap64Art, bitmap64Map); + } + } + + private static void reportBitmapsMemory( + long[] array, LongBitmapDataProvider bitmap, LongBitmapDataProvider bitmap2) { + reportBitmapsMemory(array, bitmap); + reportBitmapsMemory(array, bitmap2); + + if (!Arrays.equals(bitmap.toArray(), bitmap.toArray())) { + throw new IllegalStateException("Issue with: " + Arrays.toString(array)); + } + } + + private static void reportBitmapsMemory(long[] array, LongBitmapDataProvider bitmap) { + LongStream.of(array).forEach(bitmap::addLong); + long jolSize = GraphLayout.parseInstance(bitmap).totalSize(); + long ownEstimation = bitmap.getLongSizeInBytes(); + System.out.println( + bitmap.getClass().getSimpleName() + + ": " + + String.format("%,d", jolSize) + + "(real) vs " + + String.format("%,d", ownEstimation) + + "(estimated) " + + (ownEstimation < jolSize ? "optimistic" : "pessimistic")); + } } diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java index 54ed486d2..eeba403d7 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java @@ -1,7 +1,5 @@ package org.roaringbitmap.longlong; -import org.apache.commons.lang3.SerializationUtils; - import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -11,9 +9,20 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.roaringbitmap.Util.toUnsignedLong; +import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; +import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; + +import org.roaringbitmap.RoaringBitmap; +import org.roaringbitmap.ValidationRangeConsumer; +import org.roaringbitmap.art.LeafNode; +import org.roaringbitmap.art.LeafNodeIterator; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; +import org.apache.commons.lang3.SerializationUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -21,16 +30,15 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.*; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.roaringbitmap.RoaringBitmap; -import org.roaringbitmap.ValidationRangeConsumer; -import static org.roaringbitmap.ValidationRangeConsumer.Value.ABSENT; -import static org.roaringbitmap.ValidationRangeConsumer.Value.PRESENT; -import org.roaringbitmap.art.LeafNode; -import org.roaringbitmap.art.LeafNodeIterator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; public class TestRoaring64Bitmap { @@ -98,7 +106,7 @@ public void testAllKindOfNodeTypesSerDeser() throws Exception { i++; } Assertions.assertEquals(source.size(), i); - //test all kind of nodes's serialization/deserialization + // test all kind of nodes's serialization/deserialization long sizeL = roaring64Bitmap.serializedSizeInBytes(); if (sizeL > Integer.MAX_VALUE) { return; @@ -108,8 +116,8 @@ public void testAllKindOfNodeTypesSerDeser() throws Exception { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(sizeInt); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); roaring64Bitmap.serialize(dataOutputStream); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( - byteArrayOutputStream.toByteArray()); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); Roaring64Bitmap deserStreamOne = new Roaring64Bitmap(); deserStreamOne.deserialize(dataInputStream); @@ -165,7 +173,6 @@ public void testZero() { assertEquals(1, map.rankLong(Long.MAX_VALUE)); } - @Test public void testMinusOne_Unsigned() { Roaring64Bitmap map = newDefaultCtor(); @@ -187,7 +194,7 @@ public void testMinusOne_Unsigned() { assertEquals(0, map.rankLong(Long.MAX_VALUE)); assertEquals(0, map.rankLong(-2)); assertEquals(1, map.rankLong(-1)); - assertArrayEquals(new long[]{-1L}, map.toArray()); + assertArrayEquals(new long[] {-1L}, map.toArray()); } @Test @@ -215,16 +222,18 @@ public void testSimpleIntegers() { assertEquals(2, map.rankLong(235)); assertEquals(2, map.rankLong(Integer.MAX_VALUE + 1L)); assertEquals(2, map.rankLong(Long.MAX_VALUE)); - assertArrayEquals(new long[]{123L, 234L}, map.toArray()); + assertArrayEquals(new long[] {123L, 234L}, map.toArray()); } @Test public void testAddOneSelect2() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64Bitmap map = newDefaultCtor(); - map.addLong(123); - map.select(1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64Bitmap map = newDefaultCtor(); + map.addLong(123); + map.select(1); + }); } @Test @@ -244,10 +253,12 @@ public void testIterator_NextWithoutHasNext_Filled() { @Test public void testIterator_NextWithoutHasNext_Empty() { - assertThrows(IllegalStateException.class, () -> { - Roaring64Bitmap map = newDefaultCtor(); - map.getLongIterator().next(); - }); + assertThrows( + IllegalStateException.class, + () -> { + Roaring64Bitmap map = newDefaultCtor(); + map.getLongIterator().next(); + }); } @Test @@ -267,7 +278,7 @@ public void testLongMaxValue() { assertEquals(0, map.rankLong(1)); assertEquals(0, map.rankLong(Long.MAX_VALUE - 1)); assertEquals(1, map.rankLong(Long.MAX_VALUE)); - assertArrayEquals(new long[]{Long.MAX_VALUE}, map.toArray()); + assertArrayEquals(new long[] {Long.MAX_VALUE}, map.toArray()); } @Test @@ -318,13 +329,14 @@ public void testLongMinValueZeroOneMaxValue() { assertEquals(3, map.rankLong(Long.MAX_VALUE)); final List foreach = new ArrayList<>(); - map.forEach(new LongConsumer() { - - @Override - public void accept(long value) { - foreach.add(value); - } - }); + map.forEach( + new LongConsumer() { + + @Override + public void accept(long value) { + foreach.add(value); + } + }); assertEquals(Arrays.asList(0L, 1L, Long.MAX_VALUE, Long.MIN_VALUE), foreach); } @@ -472,7 +484,6 @@ public void testLargeSelectLong() { assertEquals(negative, last); } - @Test public void testLargeRankLong() { long positive = 1; @@ -483,7 +494,6 @@ public void testLargeRankLong() { assertEquals(2, map.rankLong(negative)); } - @Test public void testIterationOrder() { long positive = 1; @@ -525,8 +535,8 @@ public void testSerializationEmpty() throws IOException, ClassNotFoundException public void testSerialization_ToBigEndianBuffer() throws IOException { final Roaring64Bitmap map = newDefaultCtor(); map.addLong(123); - ByteBuffer buffer = ByteBuffer.allocate((int) map.serializedSizeInBytes()) - .order(ByteOrder.BIG_ENDIAN); + ByteBuffer buffer = + ByteBuffer.allocate((int) map.serializedSizeInBytes()).order(ByteOrder.BIG_ENDIAN); map.serialize(buffer); assertEquals(map.serializedSizeInBytes(), buffer.position()); } @@ -546,7 +556,6 @@ public void testSerialization_OneValue() throws IOException, ClassNotFoundExcept assertEquals(123, clone.select(0)); } - @Test public void testSerialization() throws IOException, ClassNotFoundException { final Roaring64Bitmap map = newDefaultCtor(); @@ -562,10 +571,8 @@ public void testSerialization() throws IOException, ClassNotFoundException { assertEquals(123, clone.select(0)); } - @Test - public void testSerializationMultipleBuckets() - throws IOException, ClassNotFoundException { + public void testSerializationMultipleBuckets() throws IOException, ClassNotFoundException { final Roaring64Bitmap map = newDefaultCtor(); map.addLong(-123); map.addLong(123); @@ -593,7 +600,6 @@ public void testSerializationMultipleBuckets() assertEquals(-123, anotherDeserMap.select(2)); } - @Test public void testOrSameBucket() { Roaring64Bitmap left = newDefaultCtor(); @@ -663,7 +669,6 @@ public void testOrDifferentBucket() { assertEquals(Long.MAX_VALUE / 2, orNotInPlace.select(1)); } - @Test public void testOrDifferentBucket2() { Roaring64Bitmap left = newDefaultCtor(); @@ -707,7 +712,6 @@ public void testOrCloneInput() { assertEquals(123, right.select(0)); } - @Test public void testXorBucket() { Roaring64Bitmap left = newDefaultCtor(); @@ -794,7 +798,6 @@ public void testXor_MultipleBucket() { assertEquals(123, xorNotInPlace.select(0)); } - @Test public void testAndSingleBucket() { Roaring64Bitmap left = newDefaultCtor(); @@ -838,8 +841,9 @@ public void testAnd() { @Test public void testAndDisjoint() { // There are no shared values between these maps. - final long[] leftData = new long[]{1076595327100L, 1074755534972L, 5060192403580L, 5060308664444L}; - final long[] rightData = new long[]{3470563844L}; + final long[] leftData = + new long[] {1076595327100L, 1074755534972L, 5060192403580L, 5060308664444L}; + final long[] rightData = new long[] {3470563844L}; Roaring64Bitmap left = Roaring64Bitmap.bitmapOf(leftData); Roaring64Bitmap right = Roaring64Bitmap.bitmapOf(rightData); @@ -871,10 +875,10 @@ void testToArrayAfterAndOptHasEmptyContainer() { Roaring64Bitmap bitmap2 = new Roaring64Bitmap(); bitmap2.addLong(1); - //bit and + // bit and Roaring64Bitmap andNotInPlace = Roaring64Bitmap.and(bitmap, bitmap2); bitmap.and(bitmap2); - //to array + // to array Assertions.assertDoesNotThrow(bitmap::toArray); Assertions.assertDoesNotThrow(andNotInPlace::toArray); } @@ -1100,7 +1104,7 @@ public void testFlipSameContainer() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(1,2); + map.flip(1, 2); assertEquals(2, map.getLongCardinality()); assertEquals(1, map.select(1)); @@ -1113,7 +1117,7 @@ public void testFlipMiddleContainer() { map.addLong(0); map.addLong(0x20001); - map.flip(0x10001,0x10002); + map.flip(0x10001, 0x10002); assertEquals(3, map.getLongCardinality()); assertEquals(0x10001, map.select(1)); @@ -1124,7 +1128,7 @@ public void testFlipNextContainer() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(0x10001,0x10002); + map.flip(0x10001, 0x10002); assertEquals(2, map.getLongCardinality()); assertEquals(0x10001, map.select(1)); @@ -1135,7 +1139,7 @@ public void testFlipToEdgeContainer() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(0xFFFF,0x10000); + map.flip(0xFFFF, 0x10000); assertEquals(2, map.getLongCardinality()); assertEquals(0xFFFF, map.select(1)); @@ -1146,7 +1150,7 @@ public void testFlipOverEdgeContainer() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(0xFFFF,0x10002); + map.flip(0xFFFF, 0x10002); assertEquals(4, map.getLongCardinality()); assertEquals(0x10001, map.select(3)); @@ -1157,7 +1161,7 @@ public void testFlipPriorContainer() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0x10001); - map.flip(1L,2L); + map.flip(1L, 2L); assertEquals(2, map.getLongCardinality()); assertEquals(1, map.select(0)); @@ -1169,7 +1173,7 @@ public void testFlipSameNonZeroValuesNoChange() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(1L,1L); + map.flip(1L, 1L); assertEquals(1, map.getLongCardinality()); assertEquals(0, map.select(0)); @@ -1180,7 +1184,7 @@ public void testFlipPositiveStartGreaterThanEndNoChange() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(2L,1L); + map.flip(2L, 1L); assertEquals(1, map.getLongCardinality()); assertEquals(0, map.select(0)); @@ -1191,7 +1195,7 @@ public void testFlipNegStartGreaterThanEndNoChange() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(-1L,-3L); + map.flip(-1L, -3L); assertEquals(1, map.getLongCardinality()); assertEquals(0, map.select(0)); @@ -1202,7 +1206,7 @@ public void testFlipNegStartGreaterThanPosEndNoChange() { Roaring64Bitmap map = newDefaultCtor(); map.addLong(0); - map.flip(-1L,0x7FffFFffFFffFFffL); + map.flip(-1L, 0x7FffFFffFFffFFffL); assertEquals(1, map.getLongCardinality()); assertEquals(0, map.select(0)); @@ -1272,7 +1276,7 @@ public void testToString() { @Test public void testInvalidIntMask() { Roaring64Bitmap map = new Roaring64Bitmap(); - int a = 0xFFFFFFFF; // -1 in two's compliment + int a = 0xFFFFFFFF; // -1 in two's compliment map.addInt(a); assertEquals(map.getIntCardinality(), 1); long addedInt = map.getLongIterator().next(); @@ -1291,7 +1295,8 @@ public void testAddInvalidRange() { // Different higher parts assertThrows(IllegalArgumentException.class, () -> map.addRange(Long.MAX_VALUE, 0L)); - assertThrows(IllegalArgumentException.class, () -> map.addRange(Long.MIN_VALUE, Long.MAX_VALUE)); + assertThrows( + IllegalArgumentException.class, () -> map.addRange(Long.MIN_VALUE, Long.MAX_VALUE)); } @Test @@ -1320,7 +1325,6 @@ public void testAddRangeEndExcludingNextBitmapFirstLow() { assertEquals(end - 1, map.select(1)); } - @Test public void testAddRangeMultipleBuckets() { Roaring64Bitmap map = newDefaultCtor(); @@ -1337,17 +1341,18 @@ public void testAddRangeMultipleBuckets() { assertEquals(to - 1, map.select(nbItems - 1)); } - public static final long outOfRoaringBitmapRange = 2L * Integer.MAX_VALUE + 3L; // Check this range is not handled by RoaringBitmap @Test public void testCardinalityAboveIntegerMaxValue_RoaringBitmap() { - assertThrows(IllegalArgumentException.class, () -> { - RoaringBitmap map = new RoaringBitmap(); + assertThrows( + IllegalArgumentException.class, + () -> { + RoaringBitmap map = new RoaringBitmap(); - map.add(0L, outOfRoaringBitmapRange); - }); + map.add(0L, outOfRoaringBitmapRange); + }); } @Test @@ -1364,7 +1369,6 @@ public void testCardinalityAboveIntegerMaxValue() { assertEquals(0, map.select(0)); assertEquals(outOfSingleRoaring - 1, map.select(outOfSingleRoaring - 1)); - } @Test @@ -1378,7 +1382,6 @@ public void testRoaringBitmapSelectAboveIntegerMaxValue() { assertEquals(-1, map.select(-1)); } - @Test public void testTrim() { Roaring64Bitmap map = newDefaultCtor(); @@ -1417,22 +1420,23 @@ public void testAutoboxedIterator() { @Test public void testAutoboxedIteratorCanNotRemove() { - assertThrows(UnsupportedOperationException.class, () -> { - Roaring64Bitmap map = newDefaultCtor(); + assertThrows( + UnsupportedOperationException.class, + () -> { + Roaring64Bitmap map = newDefaultCtor(); - map.addLong(123); - map.addLong(234); + map.addLong(123); + map.addLong(234); - Iterator it = map.iterator(); + Iterator it = map.iterator(); - assertTrue(it.hasNext()); + assertTrue(it.hasNext()); - // Should throw a UnsupportedOperationException - it.remove(); - }); + // Should throw a UnsupportedOperationException + it.remove(); + }); } - @Test public void testSelectMultipleBuckets() { Roaring64Bitmap map = newDefaultCtor(); @@ -1446,33 +1450,37 @@ public void testSelectMultipleBuckets() { @Test public void testSelectEmpty() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64Bitmap map = newDefaultCtor(); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64Bitmap map = newDefaultCtor(); - map.select(0); - }); + map.select(0); + }); } - @Test public void testSelectOutOfBoundsMatchCardinality() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64Bitmap map = newDefaultCtor(); - map.addLong(123); - map.select(1); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64Bitmap map = newDefaultCtor(); + map.addLong(123); + map.select(1); + }); } @Test public void testSelectOutOfBoundsOtherCardinality() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64Bitmap map = newDefaultCtor(); - map.addLong(123); - map.select(2); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64Bitmap map = newDefaultCtor(); + map.addLong(123); + map.select(2); + }); } - @Test public void testRankMultipleBuckets() { Roaring64Bitmap map = newDefaultCtor(); @@ -1610,21 +1618,22 @@ public void testHashCodeEquals() { public void testIssue428() { long input = 1353768194141061120L; - long[] compare = new long[]{ - 5192650370358181888L, - 5193776270265024512L, - 5194532734264934400L, - 5194544828892839936L, - 5194545653526560768L, - 5194545688960040960L, - 5194545692181266432L, - 5194545705066168320L, - 5194545722246037504L, - 5194545928404467712L, - 5194550326450978816L, - 5194620695195156480L, - 5206161169240293376L - }; + long[] compare = + new long[] { + 5192650370358181888L, + 5193776270265024512L, + 5194532734264934400L, + 5194544828892839936L, + 5194545653526560768L, + 5194545688960040960L, + 5194545692181266432L, + 5194545705066168320L, + 5194545722246037504L, + 5194545928404467712L, + 5194550326450978816L, + 5194620695195156480L, + 5206161169240293376L + }; Roaring64Bitmap inputRB = new Roaring64Bitmap(); inputRB.add(input); @@ -1648,11 +1657,23 @@ public void testIssue428() { @Test public void shouldNotThrowNPE() { - long[] inputs = new long[]{5183829215128059904L}; - long[] crossers = new long[]{4413527634823086080L, 4418031234450456576L, 4421408934170984448L, - 4421690409147695104L, 4421479302915162112L, 4421426526357028864L, 4421413332217495552L, - 4421416630752378880L, 4421416905630285824L, 4421417111788716032L, 4421417128968585216L, - 4421417133263552512L, 4421417134337294336L}; + long[] inputs = new long[] {5183829215128059904L}; + long[] crossers = + new long[] { + 4413527634823086080L, + 4418031234450456576L, + 4421408934170984448L, + 4421690409147695104L, + 4421479302915162112L, + 4421426526357028864L, + 4421413332217495552L, + 4421416630752378880L, + 4421416905630285824L, + 4421417111788716032L, + 4421417128968585216L, + 4421417133263552512L, + 4421417134337294336L + }; Roaring64Bitmap refRB = new Roaring64Bitmap(); refRB.add(inputs); @@ -1664,11 +1685,23 @@ public void shouldNotThrowNPE() { @Test public void shouldNotThrowAIOOB() { - long[] inputs = new long[]{5183829215128059904L}; - long[] crossers = new long[]{4413527634823086080L, 4418031234450456576L, 4421408934170984448L, - 4421127459194273792L, 4420916352961740800L, 4420863576403607552L, 4420850382264074240L, - 4420847083729190912L, 4420847358607097856L, 4420847564765528064L, 4420847616305135616L, - 4420847620600102912L, 4420847623821328384L}; + long[] inputs = new long[] {5183829215128059904L}; + long[] crossers = + new long[] { + 4413527634823086080L, + 4418031234450456576L, + 4421408934170984448L, + 4421127459194273792L, + 4420916352961740800L, + 4420863576403607552L, + 4420850382264074240L, + 4420847083729190912L, + 4420847358607097856L, + 4420847564765528064L, + 4420847616305135616L, + 4420847620600102912L, + 4420847623821328384L + }; Roaring64Bitmap referenceRB = new Roaring64Bitmap(); referenceRB.add(inputs); Roaring64Bitmap crossRB = new Roaring64Bitmap(); @@ -1680,8 +1713,8 @@ public void shouldNotThrowAIOOB() { @Test public void shouldNotThrowIAE() { - long[] inputs = new long[]{5183829215128059904L}; - long[] crossers = new long[]{4421416447812311717L, 4420658333523655893L, 4420658332008999025L}; + long[] inputs = new long[] {5183829215128059904L}; + long[] crossers = new long[] {4421416447812311717L, 4420658333523655893L, 4420658332008999025L}; Roaring64Bitmap referenceRB = new Roaring64Bitmap(); referenceRB.add(inputs); @@ -1691,28 +1724,25 @@ public void shouldNotThrowIAE() { assertEquals(0, crossRB.getIntCardinality()); } - - - @Test public void testSkips() { final Random source = new Random(0xcb000a2b9b5bdfb6l); final long[] data = takeSortedAndDistinct(source, 45000); Roaring64Bitmap bitmap = Roaring64Bitmap.bitmapOf(data); PeekableLongIterator pii = bitmap.getLongIterator(); - for(int i = 0; i < data.length; ++i) { + for (int i = 0; i < data.length; ++i) { pii.advanceIfNeeded(data[i]); assertEquals(data[i], pii.peekNext()); } pii = bitmap.getLongIterator(); - for(int i = 0; i < data.length; ++i) { + for (int i = 0; i < data.length; ++i) { pii.advanceIfNeeded(data[i]); assertEquals(data[i], pii.next()); } pii = bitmap.getLongIterator(); - for(int i = 1; i < data.length; ++i) { - pii.advanceIfNeeded(data[i-1]); - assertEquals(data[i-1], pii.next()); + for (int i = 1; i < data.length; ++i) { + pii.advanceIfNeeded(data[i - 1]); + assertEquals(data[i - 1], pii.next()); assertEquals(data[i], pii.peekNext()); } bitmap.getLongIterator().advanceIfNeeded(-1); // should not crash @@ -1723,12 +1753,12 @@ public void testSkips() { public void testSkipsDense() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); int n = 100000; - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { bitmap.add(2 * i + Integer.MAX_VALUE); } // use advance - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { PeekableLongIterator pii = bitmap.getLongIterator(); long expected = 2 * i + Integer.MAX_VALUE; pii.advanceIfNeeded(expected); @@ -1737,7 +1767,7 @@ public void testSkipsDense() { } // use iterator from - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { long expected = 2 * i + Integer.MAX_VALUE; PeekableLongIterator pii = bitmap.getLongIteratorFrom(expected); assertEquals(expected, pii.peekNext()); @@ -1751,17 +1781,17 @@ public void testSkipsMultipleHighPoints() { int n = 100000; int numHighPoints = 10; - for(long h = 0; h < numHighPoints; ++h) { + for (long h = 0; h < numHighPoints; ++h) { long base = h << 16; - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { bitmap.add(2 * i + base); } } - for(long h = 0; h < numHighPoints; ++h) { + for (long h = 0; h < numHighPoints; ++h) { long base = h << 16; // use advance - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { PeekableLongIterator pii = bitmap.getLongIterator(); long expected = 2 * i + base; pii.advanceIfNeeded(expected); @@ -1770,7 +1800,7 @@ public void testSkipsMultipleHighPoints() { } // use iterator from - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { long expected = 2 * i + base; PeekableLongIterator pii = bitmap.getLongIteratorFrom(expected); assertEquals(expected, pii.peekNext()); @@ -1779,21 +1809,20 @@ public void testSkipsMultipleHighPoints() { } } - @Test public void testSkipsRun() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); bitmap.addRange(4L, 100000L); bitmap.runOptimize(); // use advance - for(int i = 4; i < 100000; ++i) { + for (int i = 4; i < 100000; ++i) { PeekableLongIterator pii = bitmap.getLongIterator(); pii.advanceIfNeeded(i); assertEquals(i, pii.peekNext()); assertEquals(i, pii.next()); } // use iterator from - for(int i = 4; i < 100000; ++i) { + for (int i = 4; i < 100000; ++i) { PeekableLongIterator pii = bitmap.getLongIteratorFrom(i); assertEquals(i, pii.peekNext()); assertEquals(i, pii.next()); @@ -1809,41 +1838,40 @@ public void testEmptySkips() { bitmap.getLongIteratorFrom(0); } - @Test public void testSkipsReverse() { final Random source = new Random(0xcb000a2b9b5bdfb6l); final long[] data = takeSortedAndDistinct(source, 45000); Roaring64Bitmap bitmap = Roaring64Bitmap.bitmapOf(data); PeekableLongIterator pii = bitmap.getReverseLongIterator(); - for(int i = data.length -1; i >= 0 ; --i) { + for (int i = data.length - 1; i >= 0; --i) { pii.advanceIfNeeded(data[i]); assertEquals(data[i], pii.peekNext()); } pii = bitmap.getReverseLongIterator(); - for(int i = data.length -1; i >= 0 ; --i) { + for (int i = data.length - 1; i >= 0; --i) { pii.advanceIfNeeded(data[i]); assertEquals(data[i], pii.next()); } pii = bitmap.getReverseLongIterator(); - for(int i = data.length -2; i >= 0 ; --i) { - pii.advanceIfNeeded(data[i+1]); + for (int i = data.length - 2; i >= 0; --i) { + pii.advanceIfNeeded(data[i + 1]); pii.next(); - assertEquals(data[i],pii.peekNext() ); + assertEquals(data[i], pii.peekNext()); } - bitmap.getReverseLongIterator().advanceIfNeeded(-1);// should not crash - bitmap.getReverseLongIteratorFrom(-1);// should not crash + bitmap.getReverseLongIterator().advanceIfNeeded(-1); // should not crash + bitmap.getReverseLongIteratorFrom(-1); // should not crash } @Test public void testSkipsDenseReverse() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); int n = 100000; - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { bitmap.add(2 * i + Integer.MAX_VALUE); } // use advance - for(long i = n - 1; i >= 0; --i) { + for (long i = n - 1; i >= 0; --i) { long expected = 2 * i + Integer.MAX_VALUE; PeekableLongIterator pii = bitmap.getReverseLongIterator(); pii.advanceIfNeeded(expected); @@ -1852,7 +1880,7 @@ public void testSkipsDenseReverse() { } // use iterator from - for(long i = n - 1; i >= 0; --i) { + for (long i = n - 1; i >= 0; --i) { long expected = 2 * i + Integer.MAX_VALUE; PeekableLongIterator pii = bitmap.getReverseLongIteratorFrom(expected); assertEquals(expected, pii.peekNext()); @@ -1866,17 +1894,17 @@ public void testSkipsMultipleHighPointsReverse() { int n = 100000; int numHighPoints = 10; - for(long h = 0; h < numHighPoints; ++h) { + for (long h = 0; h < numHighPoints; ++h) { long base = h << 16; - for(long i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { bitmap.add(2 * i + base); } } - for(long h = 0; h < numHighPoints; ++h) { + for (long h = 0; h < numHighPoints; ++h) { long base = h << 16; // use advance - for(long i = n - 1; i >= 0 ; --i) { + for (long i = n - 1; i >= 0; --i) { PeekableLongIterator pii = bitmap.getReverseLongIterator(); long expected = 2 * i + base; pii.advanceIfNeeded(expected); @@ -1885,7 +1913,7 @@ public void testSkipsMultipleHighPointsReverse() { } // use iterator from - for(long i = n - 1; i >= 0 ; --i) { + for (long i = n - 1; i >= 0; --i) { long expected = 2 * i + base; PeekableLongIterator pii = bitmap.getReverseLongIteratorFrom(expected); assertEquals(expected, pii.peekNext()); @@ -1901,7 +1929,7 @@ public void testSkipsRunReverse() { bitmap.runOptimize(); // use advance - for(int i = 99999; i >= 4; --i) { + for (int i = 99999; i >= 4; --i) { PeekableLongIterator pii = bitmap.getReverseLongIterator(); pii.advanceIfNeeded(i); assertEquals(i, pii.peekNext()); @@ -1909,7 +1937,7 @@ public void testSkipsRunReverse() { } // use iterator from - for(int i = 99999; i >= 4; --i) { + for (int i = 99999; i >= 4; --i) { PeekableLongIterator pii = bitmap.getReverseLongIteratorFrom(i); assertEquals(i, pii.peekNext()); assertEquals(i, pii.next()); @@ -1967,7 +1995,7 @@ public void testSkipIntoGaps() { @Test public void testSkipIntoFarAwayGaps() { Roaring64Bitmap bitset = new Roaring64Bitmap(); - //long runLength = 18500L; + // long runLength = 18500L; long runLength = 4 << 20; // ~ 4mio long b1 = 2000000000L; long b1e = b1 + runLength; @@ -2066,7 +2094,7 @@ public void testSkipIntoGapsReverse() { @Test public void testSkipIntoFarAwayGapsReverse() { Roaring64Bitmap bitset = new Roaring64Bitmap(); - //long runLength = 18500L; + // long runLength = 18500L; long runLength = 4 << 20; // ~ 4mio long b1 = 2000000000L; long b1e = b1 + runLength; @@ -2193,15 +2221,15 @@ public void testForAllInRangeContinuous() { bitmap.forAllInRange(10001, 1000, consumer2); assertEquals(1000, consumer2.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[]{ - ABSENT, ABSENT, PRESENT, PRESENT, PRESENT - }); + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] {ABSENT, ABSENT, PRESENT, PRESENT, PRESENT}); bitmap.forAllInRange(98, 5, consumer3); assertEquals(5, consumer3.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer4 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[]{ - PRESENT, PRESENT, ABSENT, ABSENT, ABSENT - }); + ValidationRangeConsumer consumer4 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] {PRESENT, PRESENT, ABSENT, ABSENT, ABSENT}); bitmap.forAllInRange(9998, 5, consumer4); assertEquals(5, consumer4.getNumberOfValuesConsumed()); } @@ -2220,19 +2248,20 @@ public void testForAllInRangeDense() { bitmap.forAllInRange(0, 100000, consumer); assertEquals(100000, consumer.getNumberOfValuesConsumed()); - ValidationRangeConsumer.Value[] expectedSubRange = Arrays.copyOfRange(expected,2500, 6000); + ValidationRangeConsumer.Value[] expectedSubRange = Arrays.copyOfRange(expected, 2500, 6000); ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(expectedSubRange); bitmap.forAllInRange(2500, 3500, consumer2); assertEquals(3500, consumer2.getNumberOfValuesConsumed()); - ValidationRangeConsumer consumer3 = ValidationRangeConsumer.validate(new ValidationRangeConsumer.Value[]{ - expected[99997], expected[99998], expected[99999], ABSENT, ABSENT, ABSENT - }); + ValidationRangeConsumer consumer3 = + ValidationRangeConsumer.validate( + new ValidationRangeConsumer.Value[] { + expected[99997], expected[99998], expected[99999], ABSENT, ABSENT, ABSENT + }); bitmap.forAllInRange(99997, 6, consumer3); assertEquals(6, consumer3.getNumberOfValuesConsumed()); } - @Test public void testForAllInRangeSparse() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); @@ -2247,7 +2276,7 @@ public void testForAllInRangeSparse() { bitmap.forAllInRange(0, 100000, consumer); assertEquals(100000, consumer.getNumberOfValuesConsumed()); - ValidationRangeConsumer.Value[] expectedSubRange = Arrays.copyOfRange(expected,2500, 6001); + ValidationRangeConsumer.Value[] expectedSubRange = Arrays.copyOfRange(expected, 2500, 6001); ValidationRangeConsumer consumer2 = ValidationRangeConsumer.validate(expectedSubRange); bitmap.forAllInRange(2500, 3500, consumer2); assertEquals(3500, consumer2.getNumberOfValuesConsumed()); @@ -2262,25 +2291,82 @@ public void testForAllInRangeSparse() { public void testIssue537() { Roaring64Bitmap a = Roaring64Bitmap.bitmapOf(275846320L); Roaring64Bitmap b = Roaring64Bitmap.bitmapOf(275846320L); - Roaring64Bitmap c = Roaring64Bitmap.bitmapOf(275845652L,275845746L,275846148L,275847372L,275847380L,275847388L,275847459L,275847528L,275847586L, - 275847588L,275847600L,275847607L,275847610L,275847613L,275847631L,275847664L,275847672L,275847677L, - 275847680L,275847742L,275847808L,275847811L,275847824L,275847830L,275847856L,275847861L,275847863L, - 275847872L,275847896L,275847923L,275847924L,275847975L,275847990L,275847995L,275848003L,275848080L, - 275848081L,275848084L,275848095L,275848100L,275848120L,275848129L,275848134L,275848163L,275848174L, - 275848206L,275848218L,275848231L,275848272L,275848281L,275848308L,275848344L,275848376L,275848382L, - 275848395L,275848400L,275848411L,275848426L,275848445L,275848449L,275848451L,275848454L,275848469L); + Roaring64Bitmap c = + Roaring64Bitmap.bitmapOf( + 275845652L, + 275845746L, + 275846148L, + 275847372L, + 275847380L, + 275847388L, + 275847459L, + 275847528L, + 275847586L, + 275847588L, + 275847600L, + 275847607L, + 275847610L, + 275847613L, + 275847631L, + 275847664L, + 275847672L, + 275847677L, + 275847680L, + 275847742L, + 275847808L, + 275847811L, + 275847824L, + 275847830L, + 275847856L, + 275847861L, + 275847863L, + 275847872L, + 275847896L, + 275847923L, + 275847924L, + 275847975L, + 275847990L, + 275847995L, + 275848003L, + 275848080L, + 275848081L, + 275848084L, + 275848095L, + 275848100L, + 275848120L, + 275848129L, + 275848134L, + 275848163L, + 275848174L, + 275848206L, + 275848218L, + 275848231L, + 275848272L, + 275848281L, + 275848308L, + 275848344L, + 275848376L, + 275848382L, + 275848395L, + 275848400L, + 275848411L, + 275848426L, + 275848445L, + 275848449L, + 275848451L, + 275848454L, + 275848469L); c.and(b); assertFalse(c.contains(275846320L)); c.and(a); assertFalse(c.contains(275846320L)); } - @Test public void testIssue558() { Roaring64Bitmap rb = new Roaring64Bitmap(); Random random = new Random(1234); - for (int i = 0 ; i < 1000000; i++) { + for (int i = 0; i < 1000000; i++) { rb.addLong(random.nextLong()); rb.removeLong(random.nextLong()); } @@ -2290,71 +2376,84 @@ public void testIssue558() { public void testIssue577Case1() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); bitmap.add( - 45011744312L, 45008074636L, 41842920068L, 41829418930L, 40860008694L, 40232297287L, - 40182908832L, 40171852270L, 39933922233L, 39794107638L); + 45011744312L, + 45008074636L, + 41842920068L, + 41829418930L, + 40860008694L, + 40232297287L, + 40182908832L, + 40171852270L, + 39933922233L, + 39794107638L); long maxLong = bitmap.getReverseLongIterator().peekNext(); assertEquals(maxLong, 45011744312L); - bitmap.forEachInRange(46000000000L, 1000000000, - value -> fail("No values in this range, but got: " + value)); + bitmap.forEachInRange( + 46000000000L, 1000000000, value -> fail("No values in this range, but got: " + value)); } @Test public void testIssue577Case2() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); - bitmap.add( - 30385375409L, 30399869293L, 34362979339L, 35541844320L, 36637965094L); + bitmap.add(30385375409L, 30399869293L, 34362979339L, 35541844320L, 36637965094L); - bitmap.forEachInRange(33000000000L, 1000000000, - value -> assertEquals(34362979339L, value)); + bitmap.forEachInRange(33000000000L, 1000000000, value -> assertEquals(34362979339L, value)); } @Test public void testIssue577Case3() { Roaring64Bitmap bitmap = new Roaring64Bitmap(); - bitmap.add( - 14510802367L, 26338197481L, 32716744974L, 32725817880L, 35679129730L); + bitmap.add(14510802367L, 26338197481L, 32716744974L, 32725817880L, 35679129730L); - final long[] expected = new long[]{32716744974L, 32725817880L}; + final long[] expected = new long[] {32716744974L, 32725817880L}; - bitmap.forEachInRange(32000000000L, 1000000000, new LongConsumer() { + bitmap.forEachInRange( + 32000000000L, + 1000000000, + new LongConsumer() { - int offset = 0; + int offset = 0; - @Override - public void accept(long value) { - assertEquals(expected[offset], value); - offset++; - } - }); + @Override + public void accept(long value) { + assertEquals(expected[offset], value); + offset++; + } + }); } - @Test public void testWithYourself() { - Roaring64Bitmap b1 = Roaring64Bitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10); + Roaring64Bitmap b1 = Roaring64Bitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); b1.runOptimize(); b1.or(b1); - assertTrue(b1.equals(Roaring64Bitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10))); + assertTrue(b1.equals(Roaring64Bitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))); b1.xor(b1); assertTrue(b1.isEmpty()); - b1 = Roaring64Bitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10); + b1 = Roaring64Bitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); b1.and(b1); - assertTrue(b1.equals(Roaring64Bitmap.bitmapOf(1,2,3,4,5,6,7,8,9,10))); + assertTrue(b1.equals(Roaring64Bitmap.bitmapOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))); b1.andNot(b1); assertTrue(b1.isEmpty()); } @Test public void testIssue580() { - Roaring64Bitmap rb = Roaring64Bitmap.bitmapOf(3242766498713841665L, 3492544636360507394L, - 3418218112527884289L, 3220956490660966402L, 3495344165583036418L, 3495023214002368514L, - 3485108231289675778L); + Roaring64Bitmap rb = + Roaring64Bitmap.bitmapOf( + 3242766498713841665L, + 3492544636360507394L, + 3418218112527884289L, + 3220956490660966402L, + 3495344165583036418L, + 3495023214002368514L, + 3485108231289675778L); LongIterator it = rb.getLongIterator(); int count = 0; - while(it.hasNext()) { - it.next(); - count++; + while (it.hasNext()) { + it.next(); + count++; } assertEquals(count, 7); } @@ -2376,7 +2475,9 @@ public void testRangeAroundLongMax() { x.addRange(Long.MAX_VALUE - 1L, Long.MAX_VALUE + 3L); Assertions.assertEquals(4L, x.getLongCardinality()); - Assertions.assertArrayEquals(x.toArray(), new long[] {Long.MAX_VALUE - 1L, Long.MAX_VALUE, Long.MIN_VALUE, Long.MIN_VALUE + 1L}); + Assertions.assertArrayEquals( + x.toArray(), + new long[] {Long.MAX_VALUE - 1L, Long.MAX_VALUE, Long.MIN_VALUE, Long.MIN_VALUE + 1L}); } @Test @@ -2440,11 +2541,11 @@ public void testFirstLast_AllKindsOfNodeTypes() { Set source = getSourceForAllKindsOfNodeTypes(); source.forEach(rb::addLong); - assertEquals(source.stream().min((l,r) -> Long.compareUnsigned(l, r)).get(), rb.first()); - assertEquals(source.stream().max((l,r) -> Long.compareUnsigned(l, r)).get(), rb.last()); + assertEquals(source.stream().min((l, r) -> Long.compareUnsigned(l, r)).get(), rb.first()); + assertEquals(source.stream().max((l, r) -> Long.compareUnsigned(l, r)).get(), rb.last()); } - @Test + @Test public void testIssue619() { long[] CLEANER_VALUES = {140664568792144l}; long[] ADDRESS_SPACE_VALUES = {140662937752432l}; @@ -2456,7 +2557,7 @@ public void testIssue619() { addressSpace.add(ADDRESS_SPACE_VALUES); addressSpace.add(CLEANER_VALUES); if (iteration == 33) { - //This test case can safely break here. + // This test case can safely break here. break; } addressSpace.andNot(cleaner); diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java index 2ae20577f..2a7244765 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java @@ -1,5 +1,22 @@ package org.roaringbitmap.longlong; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.roaringbitmap.BitmapDataProvider; +import org.roaringbitmap.RoaringBitmap; +import org.roaringbitmap.RoaringBitmapSupplier; +import org.roaringbitmap.TestAdversarialInputs; +import org.roaringbitmap.Util; +import org.roaringbitmap.buffer.MutableRoaringBitmap; +import org.roaringbitmap.buffer.MutableRoaringBitmapSupplier; + import com.google.common.io.ByteStreams; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; @@ -7,15 +24,20 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.roaringbitmap.*; -import org.roaringbitmap.buffer.MutableRoaringBitmap; -import org.roaringbitmap.buffer.MutableRoaringBitmapSupplier; - -import java.io.*; -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.NavigableMap; +import java.util.NoSuchElementException; +import java.util.Random; public class TestRoaring64NavigableMap { @@ -59,11 +81,13 @@ protected void checkCardinalities(Roaring64NavigableMap bitmap) { index++; } - assertArrayEquals(expectedCardinalities, + assertArrayEquals( + expectedCardinalities, Arrays.copyOf(bitmap.getSortedCumulatedCardinality(), expectedCardinalities.length)); } - public static void checkSerializeBytes(ImmutableLongBitmapDataProvider bitmap) throws IOException { + public static void checkSerializeBytes(ImmutableLongBitmapDataProvider bitmap) + throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (DataOutputStream oos = new DataOutputStream(baos)) { bitmap.serialize(oos); @@ -126,7 +150,6 @@ public void testZero() { assertEquals(1, map.rankLong(Long.MAX_VALUE)); } - @Test public void testMinusOne_Unsigned() { Roaring64NavigableMap map = newUnsignedHeap(); @@ -156,11 +179,9 @@ public void testMinusOne_Unsigned() { assertEquals(0, map.rankLong(-2)); assertEquals(1, map.rankLong(-1)); - assertArrayEquals(new long[] {-1L}, map.toArray()); } - @Test public void testAddNotAddLong() { Roaring64NavigableMap map = newSignedBuffered(); @@ -229,8 +250,6 @@ public void testSimpleIntegers() { assertArrayEquals(new long[] {123L, 234L}, map.toArray()); } - - @Test public void testHashCodeEquals() { Roaring64NavigableMap left = newDefaultCtor(); @@ -247,16 +266,17 @@ public void testHashCodeEquals() { @Test public void testAddOneSelect2() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64NavigableMap map = newDefaultCtor(); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64NavigableMap map = newDefaultCtor(); - map.addLong(123); + map.addLong(123); - map.select(1); - }); + map.select(1); + }); } - @Test public void testAddInt() { Roaring64NavigableMap map = newDefaultCtor(); @@ -278,11 +298,13 @@ public void testIterator_NextWithoutHasNext_Filled() { @Test public void testIterator_NextWithoutHasNext_Empty() { - assertThrows(IllegalStateException.class, () -> { - Roaring64NavigableMap map = newDefaultCtor(); + assertThrows( + IllegalStateException.class, + () -> { + Roaring64NavigableMap map = newDefaultCtor(); - map.getLongIterator().next(); - }); + map.getLongIterator().next(); + }); } @Test @@ -372,13 +394,14 @@ public void testLongMinValueZeroOneMaxValue() { assertEquals(4, map.rankLong(Long.MAX_VALUE)); final List foreach = new ArrayList<>(); - map.forEach(new LongConsumer() { - - @Override - public void accept(long value) { - foreach.add(value); - } - }); + map.forEach( + new LongConsumer() { + + @Override + public void accept(long value) { + foreach.add(value); + } + }); assertEquals(Arrays.asList(Long.MIN_VALUE, 0L, 1L, Long.MAX_VALUE), foreach); } @@ -585,13 +608,14 @@ public void testPerfManyDifferentBuckets_NoCache() { @Test public void testComparator() { - Comparator natural = new Comparator() { - - @Override - public int compare(Integer o1, Integer o2) { - return Integer.compare(o1, o2); - } - }; + Comparator natural = + new Comparator() { + + @Override + public int compare(Integer o1, Integer o2) { + return Integer.compare(o1, o2); + } + }; Comparator unsigned = RoaringIntPacking.unsignedComparator(); // Comparator a negative and a positive differs from natural comparison @@ -694,7 +718,8 @@ public void testAddingLowValueAfterHighValue() { assertEquals(Long.MAX_VALUE, map.select(1)); } - private Roaring64NavigableMap clone(Roaring64NavigableMap map) throws IOException, ClassNotFoundException { + private Roaring64NavigableMap clone(Roaring64NavigableMap map) + throws IOException, ClassNotFoundException { return SerializationUtils.clone(map); } @@ -722,7 +747,6 @@ public void testSerialization_OneValue() throws IOException, ClassNotFoundExcept assertEquals(123, clone.select(0)); } - @Test public void testSerialization_Unsigned() throws IOException, ClassNotFoundException { final Roaring64NavigableMap map = newUnsignedHeap(); @@ -736,9 +760,9 @@ public void testSerialization_Unsigned() throws IOException, ClassNotFoundExcept assertEquals(123, clone.select(0)); } - @Test - public void testSerialization_MultipleBuckets_Signed() throws IOException, ClassNotFoundException { + public void testSerialization_MultipleBuckets_Signed() + throws IOException, ClassNotFoundException { final Roaring64NavigableMap map = newSignedBuffered(); map.addLong(-123); map.addLong(123); @@ -755,7 +779,8 @@ public void testSerialization_MultipleBuckets_Signed() throws IOException, Class } @Test - public void testSerialization_MultipleBuckets_Unsigned() throws IOException, ClassNotFoundException { + public void testSerialization_MultipleBuckets_Unsigned() + throws IOException, ClassNotFoundException { final Roaring64NavigableMap map = newUnsignedHeap(); map.addLong(-123); map.addLong(123); @@ -772,7 +797,8 @@ public void testSerialization_MultipleBuckets_Unsigned() throws IOException, Cla } @Test - public void testSerializationSizeInBytes_singleBucket() throws IOException, ClassNotFoundException { + public void testSerializationSizeInBytes_singleBucket() + throws IOException, ClassNotFoundException { final Roaring64NavigableMap map = newDefaultCtor(); map.addLong(123); @@ -780,7 +806,8 @@ public void testSerializationSizeInBytes_singleBucket() throws IOException, Clas } @Test - public void testSerializationSizeInBytes_multipleBuckets() throws IOException, ClassNotFoundException { + public void testSerializationSizeInBytes_multipleBuckets() + throws IOException, ClassNotFoundException { final Roaring64NavigableMap map = newDefaultCtor(); map.addLong(123); map.addLong(Long.MAX_VALUE); @@ -789,14 +816,16 @@ public void testSerializationSizeInBytes_multipleBuckets() throws IOException, C } @Test - public void testSupplierIsTransient_defaultIsImmutable() throws IOException, ClassNotFoundException, NoSuchFieldException { + public void testSupplierIsTransient_defaultIsImmutable() + throws IOException, ClassNotFoundException, NoSuchFieldException { Roaring64NavigableMap map = new Roaring64NavigableMap(new MutableRoaringBitmapSupplier()); map.add(0); final Roaring64NavigableMap clone = clone(map); // Demonstrate we fallback to RoaringBitmapSupplier as default - Assertions.assertTrue(map.getHighToBitmap().firstEntry().getValue() instanceof MutableRoaringBitmap); + Assertions.assertTrue( + map.getHighToBitmap().firstEntry().getValue() instanceof MutableRoaringBitmap); Assertions.assertTrue(clone.getHighToBitmap().firstEntry().getValue() instanceof RoaringBitmap); } @@ -850,7 +879,6 @@ public void testOr_DifferentBucket_NotBuffer() { assertEquals(Long.MAX_VALUE / 2, left.select(1)); } - @Test public void testOr_SameBucket_NotBuffer() { Roaring64NavigableMap left = new Roaring64NavigableMap(true, new RoaringBitmapSupplier()); @@ -920,7 +948,6 @@ public void testOr_CloneInput() { assertEquals(123, right.select(0)); } - @Test public void testXor_SingleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -988,7 +1015,6 @@ public void testXor_MultipleBucket() { assertEquals(123, left.select(0)); } - @Test public void testAnd_SingleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1051,7 +1077,6 @@ public void testAnd_MultipleBucket() { assertEquals(Long.MAX_VALUE, left.select(0)); } - @Test public void testAndNot_SingleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1148,7 +1173,6 @@ public void testAddRange_SingleBucket_NotBuffer() { assertEquals(11L, map.select(6L)); } - @Test public void testAddRange_SingleBucket_Buffer() { Roaring64NavigableMap map = newSignedBuffered(); @@ -1175,7 +1199,6 @@ public void testAddRange_EndExcludingNextBitmapFirstLow() { assertEquals(end - 1, map.select(1)); } - @Test public void testAddRange_MultipleBuckets() { Roaring64NavigableMap map = newDefaultCtor(); @@ -1192,17 +1215,18 @@ public void testAddRange_MultipleBuckets() { assertEquals(to - 1, map.select(nbItems - 1)); } - public static final long outOfRoaringBitmapRange = 2L * Integer.MAX_VALUE + 3L; // Check this range is not handled by RoaringBitmap @Test public void testCardinalityAboveIntegerMaxValue_RoaringBitmap() { - assertThrows(IllegalArgumentException.class, () -> { - RoaringBitmap map = new RoaringBitmap(); + assertThrows( + IllegalArgumentException.class, + () -> { + RoaringBitmap map = new RoaringBitmap(); - map.add(0L, outOfRoaringBitmapRange); - }); + map.add(0L, outOfRoaringBitmapRange); + }); } @Test @@ -1219,7 +1243,6 @@ public void testCardinalityAboveIntegerMaxValue() { assertEquals(0, map.select(0)); assertEquals(outOfSingleRoaring - 1, map.select(outOfSingleRoaring - 1)); - } @Test @@ -1282,23 +1305,23 @@ public void testAutoboxedIterator() { @Test public void testAutoboxedIterator_CanNotRemove() { - assertThrows(UnsupportedOperationException.class, () -> { - Roaring64NavigableMap map = newUnsignedHeap(); + assertThrows( + UnsupportedOperationException.class, + () -> { + Roaring64NavigableMap map = newUnsignedHeap(); - map.addLong(123); - map.addLong(234); + map.addLong(123); + map.addLong(234); - Iterator it = map.iterator(); + Iterator it = map.iterator(); - assertTrue(it.hasNext()); + assertTrue(it.hasNext()); - // Should throw a UnsupportedOperationException - it.remove(); - }); + // Should throw a UnsupportedOperationException + it.remove(); + }); } - - @Test public void testSelect_NoCache_MultipleBuckets() { Roaring64NavigableMap map = newNoCache(); @@ -1312,37 +1335,41 @@ public void testSelect_NoCache_MultipleBuckets() { @Test public void testSelect_Empty() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64NavigableMap map = newUnsignedHeap(); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64NavigableMap map = newUnsignedHeap(); - map.select(0); - }); + map.select(0); + }); } - @Test public void testSelect_OutOfBounds_MatchCardinality() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64NavigableMap map = newUnsignedHeap(); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64NavigableMap map = newUnsignedHeap(); - map.addLong(123); + map.addLong(123); - map.select(1); - }); + map.select(1); + }); } @Test public void testSelect_OutOfBounds_OtherCardinality() { - assertThrows(IllegalArgumentException.class, () -> { - Roaring64NavigableMap map = newUnsignedHeap(); + assertThrows( + IllegalArgumentException.class, + () -> { + Roaring64NavigableMap map = newUnsignedHeap(); - map.addLong(123); + map.addLong(123); - map.select(2); - }); + map.select(2); + }); } - @Test public void testRank_NoCache_MultipleBuckets() { Roaring64NavigableMap map = newNoCache(); @@ -1516,11 +1543,14 @@ public void testLongSizeInBytes() { @Test public void testLazyOr() { - Roaring64NavigableMap map1 = Roaring64NavigableMap.bitmapOf(1 << 16, 1 << 18, 1 << 19, 1L << 33); + Roaring64NavigableMap map1 = + Roaring64NavigableMap.bitmapOf(1 << 16, 1 << 18, 1 << 19, 1L << 33); map1.naivelazyor(Roaring64NavigableMap.bitmapOf(4, 7, 8, 9)); map1.naivelazyor(Roaring64NavigableMap.bitmapOf(1, 2, 3, 4, 5, 1 << 16, 1 << 17, 1 << 20)); map1.repairAfterLazy(); - Roaring64NavigableMap map2 = Roaring64NavigableMap.bitmapOf(1, 2, 3, 4, 5, 7, 8, 9, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20 , 1L << 33); + Roaring64NavigableMap map2 = + Roaring64NavigableMap.bitmapOf( + 1, 2, 3, 4, 5, 7, 8, 9, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, 1L << 33); assertEquals(map2, map1); } @@ -1631,7 +1661,8 @@ public void testNaivelazyor_ImplicitRoaringBitmap() { } } - private void checkConsistencyWithResource(String resourceName, Roaring64NavigableMap bitmap) throws IOException { + private void checkConsistencyWithResource(String resourceName, Roaring64NavigableMap bitmap) + throws IOException { byte[] reference = ByteStreams.toByteArray(TestAdversarialInputs.openInputstream(resourceName)); Assertions.assertEquals(reference.length, bitmap.serializedSizeInBytes()); @@ -1643,7 +1674,8 @@ private void checkConsistencyWithResource(String resourceName, Roaring64Navigabl @Test public void testSerialization_empty() throws IOException, ClassNotFoundException { - // This example binary comes from https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata + // This example binary comes from + // https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata String resourceName = "/testdata/64mapempty.bin"; InputStream inputStream = TestAdversarialInputs.openInputstream(resourceName); @@ -1661,7 +1693,8 @@ public void testSerialization_empty() throws IOException, ClassNotFoundException @Test public void testSerialization_64map32bitvals() throws IOException, ClassNotFoundException { - // This example binary comes from https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata + // This example binary comes from + // https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata String resourceName = "/testdata/64map32bitvals.bin"; InputStream inputStream = TestAdversarialInputs.openInputstream(resourceName); @@ -1681,7 +1714,8 @@ public void testSerialization_64map32bitvals() throws IOException, ClassNotFound @Test public void testSerialization_spreadvals() throws IOException, ClassNotFoundException { - // This example binary comes from https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata + // This example binary comes from + // https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata String resourceName = "/testdata/64mapspreadvals.bin"; InputStream inputStream = TestAdversarialInputs.openInputstream(resourceName); @@ -1704,7 +1738,8 @@ public void testSerialization_spreadvals() throws IOException, ClassNotFoundExce @Test public void testSerialization_highvals() throws IOException, ClassNotFoundException { - // This example binary comes from https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata + // This example binary comes from + // https://github.com/RoaringBitmap/CRoaring/tree/master/tests/testdata String resourceName = "/testdata/64maphighvals.bin"; InputStream inputStream = TestAdversarialInputs.openInputstream(resourceName); @@ -1774,7 +1809,11 @@ public void testRangeAroundIntegerMax() { Assertions.assertEquals(4L, x.getLongCardinality()); Assertions.assertEquals(1L, x.getHighToBitmap().size()); - Assertions.assertArrayEquals(new long[] {Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L, Integer.MAX_VALUE + 2L}, x.toArray()); + Assertions.assertArrayEquals( + new long[] { + Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L, Integer.MAX_VALUE + 2L + }, + x.toArray()); } @Test @@ -1785,7 +1824,8 @@ public void testRangeAround2TimesIntegerMax() { Assertions.assertEquals(4L, x.getLongCardinality()); Assertions.assertEquals(2L, x.getHighToBitmap().size()); - Assertions.assertArrayEquals(new long[] {rangeStart, rangeStart+1L, rangeStart+2L, rangeStart+3L}, x.toArray()); + Assertions.assertArrayEquals( + new long[] {rangeStart, rangeStart + 1L, rangeStart + 2L, rangeStart + 3L}, x.toArray()); } @Test @@ -1794,16 +1834,20 @@ public void testRangeAroundLongMax() { x.addRange(Long.MAX_VALUE - 1L, Long.MAX_VALUE + 3L); Assertions.assertEquals(4L, x.getLongCardinality()); - Assertions.assertArrayEquals(new long[] {Long.MAX_VALUE - 1L, Long.MAX_VALUE, Long.MIN_VALUE, Long.MIN_VALUE + 1L}, x.toArray()); + Assertions.assertArrayEquals( + new long[] {Long.MAX_VALUE - 1L, Long.MAX_VALUE, Long.MIN_VALUE, Long.MIN_VALUE + 1L}, + x.toArray()); } @Test() public void testRangeAroundLongMax_signed() { Roaring64NavigableMap x = newSignedBuffered(); - Assertions.assertThrows(IllegalArgumentException.class, () -> { - x.addRange(Long.MAX_VALUE - 1L, Long.MAX_VALUE + 3L); - }); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> { + x.addRange(Long.MAX_VALUE - 1L, Long.MAX_VALUE + 3L); + }); } @Test @@ -1816,7 +1860,6 @@ public void testEmptyLast() { assertThrows(NoSuchElementException.class, () -> newDefaultCtor().last()); } - @Test public void testFirstLast_32b() { Roaring64NavigableMap rb = newDefaultCtor(); diff --git a/simplebenchmark/src/main/java/simplebenchmark.java b/simplebenchmark/src/main/java/simplebenchmark.java index 810e94f3a..d87280acd 100644 --- a/simplebenchmark/src/main/java/simplebenchmark.java +++ b/simplebenchmark/src/main/java/simplebenchmark.java @@ -1,266 +1,270 @@ - -import java.io.*; -import java.net.*; -import java.text.*; -import java.util.*; -import java.util.zip.*; -import org.roaringbitmap.*; -import org.roaringbitmap.buffer.*; +import org.roaringbitmap.RoaringBitmap; +import org.roaringbitmap.buffer.ImmutableRoaringBitmap; +import org.roaringbitmap.buffer.MutableRoaringBitmap; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; public class simplebenchmark { - public static final String CENSUS_INCOME = "census-income"; - public static final String CENSUS1881 = "census1881"; - public static final String DIMENSION_008 = "dimension_008"; - public static final String DIMENSION_003 = "dimension_003"; - public static final String DIMENSION_033 = "dimension_033"; - public static final String USCENSUS2000 = "uscensus2000"; - public static final String WEATHER_SEPT_85 = "weather_sept_85"; - public static final String WIKILEAKS_NOQUOTES = "wikileaks-noquotes"; - public static final String CENSUS_INCOME_SRT = "census-income_srt"; - public static final String CENSUS1881_SRT = "census1881_srt"; - public static final String WEATHER_SEPT_85_SRT = "weather_sept_85_srt"; - public static final String WIKILEAKS_NOQUOTES_SRT = "wikileaks-noquotes_srt"; - public static int rep = 100; - static List toBitmaps(ZipRealDataRetriever zip) throws IOException, URISyntaxException { - ArrayList answer = new ArrayList(); - for(int[] data : zip.fetchBitPositions()) { - RoaringBitmap r = RoaringBitmap.bitmapOf(data); - r.runOptimize(); - answer.add(r); - } - return answer; + public static final String CENSUS_INCOME = "census-income"; + public static final String CENSUS1881 = "census1881"; + public static final String DIMENSION_008 = "dimension_008"; + public static final String DIMENSION_003 = "dimension_003"; + public static final String DIMENSION_033 = "dimension_033"; + public static final String USCENSUS2000 = "uscensus2000"; + public static final String WEATHER_SEPT_85 = "weather_sept_85"; + public static final String WIKILEAKS_NOQUOTES = "wikileaks-noquotes"; + public static final String CENSUS_INCOME_SRT = "census-income_srt"; + public static final String CENSUS1881_SRT = "census1881_srt"; + public static final String WEATHER_SEPT_85_SRT = "weather_sept_85_srt"; + public static final String WIKILEAKS_NOQUOTES_SRT = "wikileaks-noquotes_srt"; + public static int rep = 100; + + static List toBitmaps(ZipRealDataRetriever zip) + throws IOException, URISyntaxException { + ArrayList answer = new ArrayList(); + for (int[] data : zip.fetchBitPositions()) { + RoaringBitmap r = RoaringBitmap.bitmapOf(data); + r.runOptimize(); + answer.add(r); } - static List toBufferBitmaps(ZipRealDataRetriever zip) throws IOException, URISyntaxException { - ArrayList answer = new ArrayList(); - for(int[] data : zip.fetchBitPositions()) { - MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(data); - r.runOptimize(); - answer.add(r); - } - return answer; + return answer; + } + + static List toBufferBitmaps(ZipRealDataRetriever zip) + throws IOException, URISyntaxException { + ArrayList answer = new ArrayList(); + for (int[] data : zip.fetchBitPositions()) { + MutableRoaringBitmap r = MutableRoaringBitmap.bitmapOf(data); + r.runOptimize(); + answer.add(r); } + return answer; + } - static int universeSize(ZipRealDataRetriever zip) throws IOException, URISyntaxException { - int answer = 0; - for(int[] data : zip.fetchBitPositions()) { - if(data[data.length - 1] > answer) answer = data[data.length - 1]; - } - return answer; + static int universeSize(ZipRealDataRetriever zip) throws IOException, URISyntaxException { + int answer = 0; + for (int[] data : zip.fetchBitPositions()) { + if (data[data.length - 1] > answer) answer = data[data.length - 1]; } - - public static void benchmark(ZipRealDataRetriever zip) throws IOException,URISyntaxException { - int maxvalue = universeSize(zip); - // bitspervalue nanotimefor2by2and nanotimefor2by2or nanotimeforwideor nanotimeforcontains (first normal then buffer) - System.out.print(String.format("%1$-25s", zip.getName())+"\t\t"); - List bitmaps = toBitmaps(zip); - display(bitmaps,maxvalue); - // - System.out.print("\t"); - List bufferbitmaps = toBufferBitmaps(zip); - bufferdisplay(bufferbitmaps,maxvalue); - System.out.println(); - - + return answer; + } + + public static void benchmark(ZipRealDataRetriever zip) throws IOException, URISyntaxException { + int maxvalue = universeSize(zip); + // bitspervalue nanotimefor2by2and nanotimefor2by2or nanotimeforwideor nanotimeforcontains + // (first normal then buffer) + System.out.print(String.format("%1$-25s", zip.getName()) + "\t\t"); + List bitmaps = toBitmaps(zip); + display(bitmaps, maxvalue); + // + System.out.print("\t"); + List bufferbitmaps = toBufferBitmaps(zip); + bufferdisplay(bufferbitmaps, maxvalue); + System.out.println(); + } + + static void display(List bitmaps, int maxvalue) { + long totalcard = 0; + long totalbytes = 0; + DecimalFormat dfbitsperval = new DecimalFormat("0.00"); + + for (RoaringBitmap r : bitmaps) { + totalcard += r.getCardinality(); + totalbytes += r.getSizeInBytes(); } - static void display(List bitmaps, int maxvalue) { - long totalcard = 0; - long totalbytes = 0; - DecimalFormat dfbitsperval = new DecimalFormat("0.00"); - - for(RoaringBitmap r : bitmaps) { - totalcard += r.getCardinality(); - totalbytes += r.getSizeInBytes(); - } - - List timings = timings(bitmaps,maxvalue); - for(int repeat = 0; repeat < rep; ++ repeat) { - List newtime = timings(bitmaps,maxvalue); - for(int i = 0 ; i < newtime.size() ; ++i) { - if(newtime.get(i) < timings.get(i)) timings.set(i,newtime.get(i)); - } - } - - System.out.print(String.format("%1$-10s",dfbitsperval.format(totalbytes * 8.0 / totalcard))); - System.out.flush(); - for(long time : timings) { - System.out.print(String.format("%1$10s",time)); - } - + List timings = timings(bitmaps, maxvalue); + for (int repeat = 0; repeat < rep; ++repeat) { + List newtime = timings(bitmaps, maxvalue); + for (int i = 0; i < newtime.size(); ++i) { + if (newtime.get(i) < timings.get(i)) timings.set(i, newtime.get(i)); + } } - static void bufferdisplay(List bitmaps, int maxvalue) { - long totalcard = 0; - long totalbytes = 0; - DecimalFormat dfbitsperval = new DecimalFormat("0.00"); - - for(ImmutableRoaringBitmap r : bitmaps) { - totalcard += r.getCardinality(); - totalbytes += r.getSizeInBytes(); - } - - List timings = buffertimings(bitmaps,maxvalue); - for(int repeat = 0; repeat < rep; ++ repeat) { - List newtime = buffertimings(bitmaps,maxvalue); - for(int i = 0 ; i < newtime.size() ; ++i) { - if(newtime.get(i) < timings.get(i)) timings.set(i,newtime.get(i)); - } - } - - for(long time : timings) { - System.out.print(String.format("%1$10s",time)); - } + System.out.print(String.format("%1$-10s", dfbitsperval.format(totalbytes * 8.0 / totalcard))); + System.out.flush(); + for (long time : timings) { + System.out.print(String.format("%1$10s", time)); } + } - static ArrayList timings(List bitmaps, int maxvalue) { - long successive_and = 0; - long successive_or = 0; - long total_or = 0; - long start, stop; - ArrayList timings = new ArrayList(); - - start = System.nanoTime(); - for (int i = 0; i < bitmaps.size() - 1; ++i) { - successive_and += RoaringBitmap.and(bitmaps.get(i),bitmaps.get(i + 1)).getCardinality(); - } - if(successive_and == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - - start = System.nanoTime(); - for (int i = 0; i < bitmaps.size() - 1; ++i) { - successive_or += RoaringBitmap.or(bitmaps.get(i),bitmaps.get(i + 1)).getCardinality(); - } - if(successive_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - - timings.add(stop - start); - - start = System.nanoTime(); - total_or = RoaringBitmap.or(bitmaps.iterator()).getCardinality(); - if(total_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - int quartcount = 0; - start = System.nanoTime(); - for(RoaringBitmap rb : bitmaps) { - if(rb.contains(maxvalue / 4 )) ++ quartcount; - if(rb.contains(maxvalue / 2 )) ++ quartcount; - if(rb.contains(3 * maxvalue / 4 )) ++ quartcount; - } - if(quartcount == 0) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - return timings; + static void bufferdisplay(List bitmaps, int maxvalue) { + long totalcard = 0; + long totalbytes = 0; + DecimalFormat dfbitsperval = new DecimalFormat("0.00"); + for (ImmutableRoaringBitmap r : bitmaps) { + totalcard += r.getCardinality(); + totalbytes += r.getSizeInBytes(); } - static ArrayList buffertimings(List bitmaps, int maxvalue) { - long successive_and = 0; - long successive_or = 0; - long total_or = 0; - long start, stop; - ArrayList timings = new ArrayList(); - - start = System.nanoTime(); - for (int i = 0; i < bitmaps.size() - 1; ++i) { - successive_and += ImmutableRoaringBitmap.and(bitmaps.get(i),bitmaps.get(i + 1)).getCardinality(); - } - if(successive_and == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - - start = System.nanoTime(); - for (int i = 0; i < bitmaps.size() - 1; ++i) { - successive_or += ImmutableRoaringBitmap.or(bitmaps.get(i),bitmaps.get(i + 1)).getCardinality(); - } - if(successive_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - - start = System.nanoTime(); - total_or = ImmutableRoaringBitmap.or(bitmaps.iterator()).getCardinality(); - if(total_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - int quartcount = 0; - start = System.nanoTime(); - for(ImmutableRoaringBitmap rb : bitmaps) { - if(rb.contains(maxvalue / 4 )) ++ quartcount; - if(rb.contains(maxvalue / 2 )) ++ quartcount; - if(rb.contains(3 * maxvalue / 4 )) ++ quartcount; - } - if(quartcount == 0) System.out.println(); // to defeat clever compilers - stop = System.nanoTime(); - timings.add(stop - start); - return timings; - + List timings = buffertimings(bitmaps, maxvalue); + for (int repeat = 0; repeat < rep; ++repeat) { + List newtime = buffertimings(bitmaps, maxvalue); + for (int i = 0; i < newtime.size(); ++i) { + if (newtime.get(i) < timings.get(i)) timings.set(i, newtime.get(i)); + } } + for (long time : timings) { + System.out.print(String.format("%1$10s", time)); + } + } + + static ArrayList timings(List bitmaps, int maxvalue) { + long successive_and = 0; + long successive_or = 0; + long total_or = 0; + long start, stop; + ArrayList timings = new ArrayList(); + + start = System.nanoTime(); + for (int i = 0; i < bitmaps.size() - 1; ++i) { + successive_and += RoaringBitmap.and(bitmaps.get(i), bitmaps.get(i + 1)).getCardinality(); + } + if (successive_and == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); - - - public static void main(String[] args) throws IOException, URISyntaxException { - if(args.length != 1) { - System.out.println("You need to provide exactly one parameter."); - System.out.println("E.g., java simplebenchmark ../real-roaring-dataset/src/main/resources/real-roaring-dataset/census1881.zip"); - return; - } - try { - benchmark(new ZipRealDataRetriever(args[0])); - } catch(FileNotFoundException fnf) { - System.err.println("I can't find the file "+ args[0]); - } + start = System.nanoTime(); + for (int i = 0; i < bitmaps.size() - 1; ++i) { + successive_or += RoaringBitmap.or(bitmaps.get(i), bitmaps.get(i + 1)).getCardinality(); + } + if (successive_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + + timings.add(stop - start); + + start = System.nanoTime(); + total_or = RoaringBitmap.or(bitmaps.iterator()).getCardinality(); + if (total_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); + int quartcount = 0; + start = System.nanoTime(); + for (RoaringBitmap rb : bitmaps) { + if (rb.contains(maxvalue / 4)) ++quartcount; + if (rb.contains(maxvalue / 2)) ++quartcount; + if (rb.contains(3 * maxvalue / 4)) ++quartcount; + } + if (quartcount == 0) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); + return timings; + } + + static ArrayList buffertimings(List bitmaps, int maxvalue) { + long successive_and = 0; + long successive_or = 0; + long total_or = 0; + long start, stop; + ArrayList timings = new ArrayList(); + + start = System.nanoTime(); + for (int i = 0; i < bitmaps.size() - 1; ++i) { + successive_and += + ImmutableRoaringBitmap.and(bitmaps.get(i), bitmaps.get(i + 1)).getCardinality(); } + if (successive_and == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); + + start = System.nanoTime(); + for (int i = 0; i < bitmaps.size() - 1; ++i) { + successive_or += + ImmutableRoaringBitmap.or(bitmaps.get(i), bitmaps.get(i + 1)).getCardinality(); + } + if (successive_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); + + start = System.nanoTime(); + total_or = ImmutableRoaringBitmap.or(bitmaps.iterator()).getCardinality(); + if (total_or == 0xFFFFFFFF) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); + int quartcount = 0; + start = System.nanoTime(); + for (ImmutableRoaringBitmap rb : bitmaps) { + if (rb.contains(maxvalue / 4)) ++quartcount; + if (rb.contains(maxvalue / 2)) ++quartcount; + if (rb.contains(3 * maxvalue / 4)) ++quartcount; + } + if (quartcount == 0) System.out.println(); // to defeat clever compilers + stop = System.nanoTime(); + timings.add(stop - start); + return timings; + } + + public static void main(String[] args) throws IOException, URISyntaxException { + if (args.length != 1) { + System.out.println("You need to provide exactly one parameter."); + System.out.println( + "E.g., java simplebenchmark" + + " ../real-roaring-dataset/src/main/resources/real-roaring-dataset/census1881.zip"); + return; + } + try { + benchmark(new ZipRealDataRetriever(args[0])); + } catch (FileNotFoundException fnf) { + System.err.println("I can't find the file " + args[0]); + } + } } - class ZipRealDataRetriever { - private final String dataset; + private final String dataset; - public ZipRealDataRetriever(String dataset) throws IOException, URISyntaxException { - this.dataset = dataset; - } + public ZipRealDataRetriever(String dataset) throws IOException, URISyntaxException { + this.dataset = dataset; + } - public List fetchBitPositions() throws IOException { - List bitPositions = new ArrayList<>(); - - try ( - final ZipInputStream zis = getResourceAsStream(); - final BufferedReader buf = new BufferedReader(new InputStreamReader(zis)); - ) { - - - while (true) { - ZipEntry nextEntry = zis.getNextEntry(); - if (nextEntry == null) { - break; - } - - try { - String oneLine = buf.readLine(); // a single, perhaps very long, line - String[] positions = oneLine.split(","); - int[] ans = new int[positions.length]; - for (int i = 0; i < positions.length; i++) { - ans[i] = Integer.parseInt(positions[i]); - } - bitPositions.add(ans); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + public List fetchBitPositions() throws IOException { + List bitPositions = new ArrayList<>(); + + try (final ZipInputStream zis = getResourceAsStream(); + final BufferedReader buf = new BufferedReader(new InputStreamReader(zis)); ) { + + while (true) { + ZipEntry nextEntry = zis.getNextEntry(); + if (nextEntry == null) { + break; } - return bitPositions; - } - public String getName() { - return new File(dataset).getName(); + try { + String oneLine = buf.readLine(); // a single, perhaps very long, line + String[] positions = oneLine.split(","); + int[] ans = new int[positions.length]; + for (int i = 0; i < positions.length; i++) { + ans[i] = Integer.parseInt(positions[i]); + } + bitPositions.add(ans); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } + return bitPositions; + } - private ZipInputStream getResourceAsStream() throws FileNotFoundException { - return new ZipInputStream(new FileInputStream(dataset)); - } + public String getName() { + return new File(dataset).getName(); + } + private ZipInputStream getResourceAsStream() throws FileNotFoundException { + return new ZipInputStream(new FileInputStream(dataset)); + } } From cca90c986d5c0096bbeabb5f968833bf12c28c0e Mon Sep 17 00:00:00 2001 From: fanson Date: Tue, 26 Nov 2024 01:16:10 +0800 Subject: [PATCH 167/167] add Roaring64NavigableMapSliceIndex support (serialization format is compatible with roaring(Go)) (#760) * add NavigableMapSliceIndex support * close datainputstream after deserialize * small changes * 1. code fix for CR; 2. add serializationMode local variable; 3. support legecy/portable(default) serialization mode for Roaring64NavigableMapSliceIndex * 1. add more documents 2. keep Roaring64NavigableMap.SERIALIZATION_MODE public & static 3. remove ser/deser using bytebuffer * 1. keep SERIALIZATION_MODE in Roaring64NavigableMap 2. add 'DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE' in Roaring64NavigableMapSliceIndex 3. add a go-compatable serialization format in Roaring64NavigableMapSliceIndex, leave others unimplemented * --author=haiyang.zhou 1. add sanity checks in test 2. add documents about limit of Roaring64NavigableMap.clone * tiny modification of javadoc * set minValue and maxValue when deserialize & clone * make minValue() and maxValue() public, and and some assertions in unittests * add some assertions in unittests --------- Co-authored-by: haiyang.zhou Co-authored-by: haiyang.zhou --- .../Roaring64NavigableMapSliceIndex.java | 731 ++++++++++++++++++ .../bsi/R64NavigableBSITest.java | 450 +++++++++++ .../longlong/Roaring64NavigableMap.java | 335 ++++++++ .../longlong/TestRoaring64Bitmap.java | 2 +- .../longlong/TestRoaring64NavigableMap.java | 434 ++++++++++- 5 files changed, 1950 insertions(+), 2 deletions(-) create mode 100644 bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64NavigableMapSliceIndex.java create mode 100644 bsi/src/test/java/org/roaringbitmap/bsi/R64NavigableBSITest.java diff --git a/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64NavigableMapSliceIndex.java b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64NavigableMapSliceIndex.java new file mode 100644 index 000000000..ffbcf1cad --- /dev/null +++ b/bsi/src/main/java/org/roaringbitmap/bsi/longlong/Roaring64NavigableMapSliceIndex.java @@ -0,0 +1,731 @@ +package org.roaringbitmap.bsi.longlong; + +import org.roaringbitmap.bsi.BitmapSliceIndex; +import org.roaringbitmap.bsi.Pair; +import org.roaringbitmap.longlong.Roaring64NavigableMap; + +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.stream.IntStream; + +/** + * Roaring64NavigableMap based bsi implementation.
+ * + * See {@link #serialize} for more information for serialization format} + */ +public class Roaring64NavigableMapSliceIndex { + /** + * the maxValue of this bsi + */ + private long maxValue; + + /** + * the minValue of this bsi + */ + private long minValue; + + /** + * the bit component slice Array of this bsi + */ + private Roaring64NavigableMap[] bA; + + /** + * the exist bitmap of this bsi which means the columnId have value in this bsi + */ + private Roaring64NavigableMap ebM; + + private Boolean runOptimized = false; + + /** + * bsi serialization mode compatible with roaring(go) + */ + public static int BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO = 0; + + /** + * The serialization format for Roaring64NavigableMapSliceIndex.
+ * Currently, {@link #BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO} is supported.
+ * Other serialization formats maybe added in the future, and the serialization formats may change. + * See {@link #serialize} for more information for serialization format} + */ + public static int DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE = + BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO; + + /** + * NewDefaultBSI constructs an auto-sized BSI. + */ + public Roaring64NavigableMapSliceIndex() { + this(0L, 0L); + } + + /** + * NewBSI constructs a new BSI. Min/Max values are optional. If set to 0 + * then the underlying BSI will be automatically sized. + */ + public Roaring64NavigableMapSliceIndex(long minValue, long maxValue) { + if (minValue < 0) { + throw new IllegalArgumentException("Values should be non-negative"); + } + if (maxValue < minValue) { + throw new IllegalArgumentException("maxValue should GE minValue"); + } + + this.bA = new Roaring64NavigableMap[64 - Long.numberOfLeadingZeros(maxValue)]; + for (int i = 0; i < bA.length; i++) { + this.bA[i] = new Roaring64NavigableMap(); + } + + this.ebM = new Roaring64NavigableMap(); + } + + /** + * add all content from another BSI instance, current bsi is modified + */ + public void add(Roaring64NavigableMapSliceIndex otherBsi) { + if (null == otherBsi || otherBsi.ebM.isEmpty()) { + return; + } + + this.ebM.or(otherBsi.ebM); + if (otherBsi.bitCount() > this.bitCount()) { + grow(otherBsi.bitCount()); + } + + for (int i = 0; i < otherBsi.bitCount(); i++) { + this.addDigit(otherBsi.bA[i], i); + } + + // update min and max after adding + this.minValue = minValue(); + this.maxValue = maxValue(); + } + + /** + * add the specify slice to current 'bA[]' at index 'i', and 'carry' will be processed automatically + */ + private void addDigit(Roaring64NavigableMap foundSet, int i) { + Roaring64NavigableMap carry = Roaring64NavigableMap.and(this.bA[i], foundSet); + this.bA[i].xor(foundSet); + if (!carry.isEmpty()) { + if (i + 1 >= this.bitCount()) { + grow(this.bitCount() + 1); + } + this.addDigit(carry, i + 1); + } + } + + /** + * get the min value from the bsi + */ + public long minValue() { + if (ebM.isEmpty()) { + return 0; + } + + Roaring64NavigableMap minValuesId = ebM; + for (int i = bA.length - 1; i >= 0; i -= 1) { + Roaring64NavigableMap tmp = Roaring64NavigableMap.andNot(minValuesId, bA[i]); + if (!tmp.isEmpty()) { + minValuesId = tmp; + } + } + + return valueAt(minValuesId.first()); + } + + /** + * get the max value from the bsi + */ + public long maxValue() { + if (ebM.isEmpty()) { + return 0; + } + + Roaring64NavigableMap maxValuesId = ebM; + for (int i = bA.length - 1; i >= 0; i -= 1) { + Roaring64NavigableMap tmp = Roaring64NavigableMap.and(maxValuesId, bA[i]); + if (!tmp.isEmpty()) { + maxValuesId = tmp; + } + } + + return valueAt(maxValuesId.first()); + } + + /** + * return the value associated with the input columnId + * @param columnId the column id + * @return the value associated with the input columnId + */ + private long valueAt(long columnId) { + long value = 0; + for (int i = 0; i < this.bitCount(); i += 1) { + if (this.bA[i].contains(columnId)) { + value |= (1L << i); + } + } + + return value; + } + + /** + * RunOptimize attempts to further compress the runs of consecutive values found in the bitmap + */ + public void runOptimize() { + this.ebM.runOptimize(); + + for (Roaring64NavigableMap integers : this.bA) { + integers.runOptimize(); + } + this.runOptimized = true; + } + + /** + * hasRunCompression returns true if the bitmap benefits from run compression + */ + public boolean hasRunCompression() { + return this.runOptimized; + } + + /** + * GetExistenceBitmap returns a pointer to the underlying existence bitmap of the BSI + */ + public Roaring64NavigableMap getExistenceBitmap() { + return this.ebM; + } + + /** + * the number of slice + */ + public int bitCount() { + return this.bA.length; + } + + /** + * get the cardinality of the bsi (the number of distinct values added to the ebM) + */ + public long getLongCardinality() { + return this.ebM.getLongCardinality(); + } + + /** + * get the value at the column ID. + */ + public Pair getValue(long columnId) { + boolean exists = this.ebM.contains(columnId); + if (!exists) { + return Pair.newPair(0L, false); + } + + return Pair.newPair(valueAt(columnId), true); + } + + private void clear() { + this.maxValue = 0; + this.minValue = 0; + this.ebM = null; + this.bA = null; + } + + /** + * Serialize the BSI. + *

+ * Currently, only {@link #BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO} is supported.
+ * *NOTE* Other serialization formats maybe added in the future, and the serialization formats may change. + *

+ * The serialization format for underlying Roaring64NavigableMap depends on + * {@link Roaring64NavigableMap#SERIALIZATION_MODE}.
+ * NOTE: if {@link Roaring64NavigableMap#SERIALIZATION_MODE} = {@link Roaring64NavigableMap#SERIALIZATION_MODE_PORTABLE} + * and {@link #DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE} = {@link #BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO}, + * then the bsi serialization is compatible with bsi implementation of roaring(Go). + *

+ * Current serialization format:
+ * --- + *

+   * ebM as standard Roaring64NavigableMap format (with specify legacy/portable format)
+   * loop over bA[]  as standard Roaring64NavigableMap format (with specify legacy/portable format)
+   * 
+ * --- + *
+ * Consider calling {@link #runOptimize} before serialization to improve compression. + * The current bsi is not modified. + *

+ * @see bsi64.WriteTo + * @param output the DataOutput stream + * @throws IOException Signals that an I/O exception has occurred. + */ + public void serialize(DataOutput output) throws IOException { + if (DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE == BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO) { + // write ebm + this.ebM.serialize(output); + for (Roaring64NavigableMap rb : this.bA) { + rb.serialize(output); + } + } else { + throw new UnsupportedOperationException( + "unsupported serialization mode " + DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE); + } + } + + /** + * Deserialize (retrieve) the BSI.
+ * See {@link #serialize(DataOutput)} for the serialization format. + * The current bsi is overwritten. + *

+ * *NOTE*
+ * 1. multiple bsi objects in one {@code DataInput} not supported for current serialization format.
+ * 2. for proper deserialization, {@link Roaring64NavigableMap#SERIALIZATION_MODE} should be set + * to the value as serialization
+ * @param in the DataInput stream + * @throws IOException Signals that an I/O exception has occurred. + */ + public void deserialize(DataInput in) throws IOException { + if (DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE == BSI64_SERIALIZATION_MODE_COMPATIBLE_WITH_GO) { + this.clear(); + // read ebm + Roaring64NavigableMap ebm = new Roaring64NavigableMap(); + ebm.deserialize(in); + this.ebM = ebm; + + List baList = new ArrayList<>(); + try (DataInputStream is = new DataInputStream((InputStream) in); ) { + while (is.available() > 0) { + Roaring64NavigableMap rb = new Roaring64NavigableMap(); + rb.deserialize(in); + baList.add(rb); + } + } + this.bA = baList.toArray(new Roaring64NavigableMap[0]); + this.minValue = minValue(); + this.maxValue = maxValue(); + } else { + throw new UnsupportedOperationException( + "unsupported serialization mode " + DEFAULT_BSI64_NAVIGABLE_SERIALIZATION_MODE); + } + } + + /* + * get the serialized size in bytes + */ + public long serializedSizeInBytes() { + long size = 0; + for (Roaring64NavigableMap rb : this.bA) { + size += rb.serializedSizeInBytes(); + } + return this.ebM.serializedSizeInBytes() + size; + } + + /** + * valueExists tests whether the value exists. + */ + public boolean valueExist(long columnId) { + return this.ebM.contains(columnId); + } + + /** + * SetValue sets a value for a given columnID. + */ + public void setValue(long columnId, long value) { + ensureCapacityInternal(value, value); + setValueInternal(columnId, value); + } + + private void setValueInternal(long columnId, long value) { + for (int i = 0; i < this.bitCount(); i += 1) { + if ((value & (1L << i)) > 0) { + this.bA[i].add(columnId); + } else { + this.bA[i].removeLong(columnId); + } + } + this.ebM.add(columnId); + } + + private void ensureCapacityInternal(long minValue, long maxValue) { + if (ebM.isEmpty()) { + this.minValue = minValue; + this.maxValue = maxValue; + grow(Long.toBinaryString(maxValue).length()); + } else if (this.minValue > minValue) { + this.minValue = minValue; + } else if (this.maxValue < maxValue) { + this.maxValue = maxValue; + grow(Long.toBinaryString(maxValue).length()); + } + } + + private void grow(int newBitDepth) { + int oldBitDepth = this.bA.length; + + if (oldBitDepth >= newBitDepth) { + return; + } + + Roaring64NavigableMap[] newBA = new Roaring64NavigableMap[newBitDepth]; + if (oldBitDepth != 0) { + System.arraycopy(this.bA, 0, newBA, 0, oldBitDepth); + } + + for (int i = newBitDepth - 1; i >= oldBitDepth; i--) { + newBA[i] = new Roaring64NavigableMap(); + if (this.runOptimized) { + newBA[i].runOptimize(); + } + } + this.bA = newBA; + } + + /** + * set list of values + * @param values list of value pairs + */ + public void setValues(List> values) { + if (values == null || values.isEmpty()) return; + long maxValue = + values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).max().getAsLong(); + long minValue = + values.stream().mapToLong(Pair::getRight).filter(Objects::nonNull).min().getAsLong(); + ensureCapacityInternal(minValue, maxValue); + for (Pair pair : values) { + setValueInternal(pair.getKey(), pair.getValue()); + } + } + + /** + * merge will merge 2 bsi into current + * merge API was designed for distributed computing + * note: current and other bsi has no intersection + * + * @param otherBsi other bsi we need merge + */ + public void merge(Roaring64NavigableMapSliceIndex otherBsi) { + + if (null == otherBsi || otherBsi.ebM.isEmpty()) { + return; + } + + // todo whether we need this + if (Roaring64NavigableMap.intersects(this.ebM, otherBsi.ebM)) { + throw new IllegalArgumentException("merge can be used only in bsiA bsiB is null"); + } + + int bitDepth = Integer.max(this.bitCount(), otherBsi.bitCount()); + Roaring64NavigableMap[] newBA = new Roaring64NavigableMap[bitDepth]; + for (int i = 0; i < bitDepth; i++) { + Roaring64NavigableMap current = i < this.bA.length ? this.bA[i] : new Roaring64NavigableMap(); + Roaring64NavigableMap other = + i < otherBsi.bA.length ? otherBsi.bA[i] : new Roaring64NavigableMap(); + newBA[i] = Roaring64NavigableMap.or(current, other); + if (this.runOptimized || otherBsi.runOptimized) { + newBA[i].runOptimize(); + } + } + this.bA = newBA; + this.ebM.or(otherBsi.ebM); + this.runOptimized = this.runOptimized || otherBsi.runOptimized; + this.maxValue = Long.max(this.maxValue, otherBsi.maxValue); + this.minValue = Long.min(this.minValue, otherBsi.minValue); + } + + /** + * clone a bsi instance + */ + @Override + public Roaring64NavigableMapSliceIndex clone() { + Roaring64NavigableMapSliceIndex bitSliceIndex = new Roaring64NavigableMapSliceIndex(); + bitSliceIndex.minValue = this.minValue; + bitSliceIndex.maxValue = this.maxValue; + bitSliceIndex.ebM = this.ebM.clone(); + Roaring64NavigableMap[] cloneBA = new Roaring64NavigableMap[this.bitCount()]; + for (int i = 0; i < cloneBA.length; i++) { + cloneBA[i] = this.bA[i].clone(); + } + bitSliceIndex.bA = cloneBA; + bitSliceIndex.runOptimized = this.runOptimized; + return bitSliceIndex; + } + + /** + * O'Neil range using a bit-sliced index + * + * @param operation compare operation + * @param predicate the value we found filter + * @param foundSet columnId set we want compare,using RoaringBitmap to express + * @return columnId set we found in this bsi with giving conditions, using RoaringBitmap to express + * see https://github.com/lemire/BitSliceIndex/blob/master/src/main/java/org/roaringbitmap/circuits/comparator/BasicComparator.java + */ + private Roaring64NavigableMap oNeilCompare( + BitmapSliceIndex.Operation operation, long predicate, Roaring64NavigableMap foundSet) { + Roaring64NavigableMap fixedFoundSet = foundSet == null ? this.ebM : foundSet; + + Roaring64NavigableMap GT = new Roaring64NavigableMap(); + Roaring64NavigableMap LT = new Roaring64NavigableMap(); + Roaring64NavigableMap EQ = this.ebM; + + for (int i = this.bitCount() - 1; i >= 0; i--) { + int bit = (int) ((predicate >> i) & 1); + if (bit == 1) { + LT = Roaring64NavigableMap.or(LT, Roaring64NavigableMap.andNot(EQ, this.bA[i])); + EQ = Roaring64NavigableMap.and(EQ, this.bA[i]); + } else { + GT = Roaring64NavigableMap.or(GT, Roaring64NavigableMap.and(EQ, this.bA[i])); + EQ = Roaring64NavigableMap.andNot(EQ, this.bA[i]); + } + } + EQ = Roaring64NavigableMap.and(fixedFoundSet, EQ); + switch (operation) { + case EQ: + return EQ; + case NEQ: + return Roaring64NavigableMap.andNot(fixedFoundSet, EQ); + case GT: + return Roaring64NavigableMap.and(GT, fixedFoundSet); + case LT: + return Roaring64NavigableMap.and(LT, fixedFoundSet); + case LE: + return Roaring64NavigableMap.and(Roaring64NavigableMap.or(LT, EQ), fixedFoundSet); + case GE: + return Roaring64NavigableMap.and(Roaring64NavigableMap.or(GT, EQ), fixedFoundSet); + default: + throw new IllegalArgumentException(""); + } + } + + /** + * BSI Compare using single thread + * this Function compose algorithm from O'Neil and Owen Kaser + * the GE algorithm is from Owen since the performance is better. others are from O'Neil + * + * @param operation the operation of BitmapSliceIndex.Operation + * @param startOrValue the start or value of comparison, when the comparison operation is range, it's start, + * when others,it's value. + * @param end the end value of comparison. when the comparison operation is not range,the end = 0 + * @param foundSet columnId set we want compare,using RoaringBitmap to express + * @return columnId set we found in this bsi with giving conditions, using Roaring64NavigableMap to express + */ + public Roaring64NavigableMap compare( + BitmapSliceIndex.Operation operation, + long startOrValue, + long end, + Roaring64NavigableMap foundSet) { + Roaring64NavigableMap result = compareUsingMinMax(operation, startOrValue, end, foundSet); + if (result != null) { + return result; + } + + switch (operation) { + case EQ: + return oNeilCompare(BitmapSliceIndex.Operation.EQ, startOrValue, foundSet); + case NEQ: + return oNeilCompare(BitmapSliceIndex.Operation.NEQ, startOrValue, foundSet); + case GE: + return oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet); + case GT: + { + return oNeilCompare(BitmapSliceIndex.Operation.GT, startOrValue, foundSet); + } + case LT: + return oNeilCompare(BitmapSliceIndex.Operation.LT, startOrValue, foundSet); + + case LE: + return oNeilCompare(BitmapSliceIndex.Operation.LE, startOrValue, foundSet); + + case RANGE: + { + if (startOrValue < minValue) { + startOrValue = minValue; + } + if (end > maxValue) { + end = maxValue; + } + Roaring64NavigableMap left = + oNeilCompare(BitmapSliceIndex.Operation.GE, startOrValue, foundSet); + Roaring64NavigableMap right = oNeilCompare(BitmapSliceIndex.Operation.LE, end, foundSet); + + return Roaring64NavigableMap.and(left, right); + } + default: + throw new IllegalArgumentException("not support operation!"); + } + } + + private Roaring64NavigableMap compareUsingMinMax( + BitmapSliceIndex.Operation operation, + long startOrValue, + long end, + Roaring64NavigableMap foundSet) { + Roaring64NavigableMap all = + foundSet == null ? ebM.clone() : Roaring64NavigableMap.and(ebM, foundSet); + Roaring64NavigableMap empty = new Roaring64NavigableMap(); + + switch (operation) { + case LT: + if (startOrValue > maxValue) { + return all; + } else if (startOrValue <= minValue) { + return empty; + } + + break; + case LE: + if (startOrValue >= maxValue) { + return all; + } else if (startOrValue < minValue) { + return empty; + } + + break; + case GT: + if (startOrValue < minValue) { + return all; + } else if (startOrValue >= maxValue) { + return empty; + } + + break; + case GE: + if (startOrValue <= minValue) { + return all; + } else if (startOrValue > maxValue) { + return empty; + } + + break; + case EQ: + if (minValue == maxValue && minValue == startOrValue) { + return all; + } else if (startOrValue < minValue || startOrValue > maxValue) { + return empty; + } + + break; + case NEQ: + if (minValue == maxValue) { + return minValue == startOrValue ? empty : all; + } + + break; + case RANGE: + if (startOrValue <= minValue && end >= maxValue) { + return all; + } else if (startOrValue > maxValue || end < minValue) { + return empty; + } + + break; + default: + return null; + } + + return null; + } + + /** + * given columns in foundSet, return the count and sum of values found in BSI + * @param foundSet given columnIds (represent as Roaring64NavigableMap) + * @return the <sum, count> pair + */ + public Pair sum(Roaring64NavigableMap foundSet) { + if (null == foundSet || foundSet.isEmpty()) { + return Pair.newPair(0L, 0L); + } + long count = foundSet.getLongCardinality(); + + long sum = + IntStream.range(0, this.bitCount()) + .mapToLong(x -> (1L << x) * Roaring64NavigableMap.andCardinality(this.bA[x], foundSet)) + .sum(); + + return Pair.newPair(sum, count); + } + + /** + * given columns in foundSet, return the top k columnId found in BSI + * @param foundSet the columnIds needs to be checked (represent as Roaring64NavigableMap) + * @param k top k + * @return the top k columnIds found in BSI + */ + public Roaring64NavigableMap topK(Roaring64NavigableMap foundSet, long k) { + if (null == foundSet || foundSet.isEmpty()) { + return new Roaring64NavigableMap(); + } + if (k >= foundSet.getLongCardinality()) { + return foundSet; + } + Roaring64NavigableMap re = new Roaring64NavigableMap(); + Roaring64NavigableMap candidates = foundSet.clone(); + // keep target K value + long originalTargetTopK = k; + + for (int x = this.bitCount() - 1; x >= 0 && !candidates.isEmpty() && k > 0; x--) { + Roaring64NavigableMap X = Roaring64NavigableMap.and(candidates, this.bA[x]); + long cardinality = X.getLongCardinality(); + if (cardinality > k) { + candidates.and(this.bA[x]); + } else { + re.or(X); + candidates.andNot(this.bA[x]); + k -= cardinality; + } + } + + // check whether we get enough items in 're' + long reCardinality = re.getLongCardinality(); + long candidatesCardinality = candidates.getLongCardinality(); + if (reCardinality < originalTargetTopK) { + // 're' has not enough items, pick some items from candidates, then merge re&candidates + long dismissCandidatesCnt = candidatesCardinality + reCardinality - originalTargetTopK; + Iterator iterator = candidates.iterator(); + while (iterator.hasNext() && dismissCandidatesCnt > 0) { + // remove some items from candidates + candidates.removeLong(iterator.next()); + dismissCandidatesCnt--; + } + } else { + candidates = null; + } + return Roaring64NavigableMap.or(re, candidates); + } + + /** + * given columns in foundSet, + * 1. if one columnId of foundSet is in the bsi, then get the associated value + * 2. then return all the values as a Roaring64NavigableMap. + * @param foundSet the columnIds needs to be checked, null if all columnIds needs to be checked + */ + public Roaring64NavigableMap transpose(Roaring64NavigableMap foundSet) { + Roaring64NavigableMap re = new Roaring64NavigableMap(); + Roaring64NavigableMap fixedFoundSet = + foundSet == null ? this.ebM : Roaring64NavigableMap.and(foundSet, this.ebM); + fixedFoundSet.forEach((long x) -> re.add(this.getValue(x).getKey())); + return re; + } + + /** + * given columns in foundSet, + * 1. if one columnId of foundSet is in the bsi, then get the associated value in the bsi + * 2. then return all the <value, # of columnIds> as a bsi. + * @param foundSet the columnIds needs to be checked, null if all columnIds needs to be checked + */ + public Roaring64NavigableMapSliceIndex transposeWithCount(Roaring64NavigableMap foundSet) { + Roaring64NavigableMapSliceIndex re = new Roaring64NavigableMapSliceIndex(); + Roaring64NavigableMap fixedFoundSet = + foundSet == null ? this.ebM : Roaring64NavigableMap.and(foundSet, this.ebM); + fixedFoundSet.forEach( + (long x) -> { + long nk = this.getValue(x).getKey(); + if (re.valueExist(nk)) { + re.setValue(nk, re.getValue(nk).getKey() + 1); + } else { + re.setValue(nk, 1); + } + }); + return re; + } +} diff --git a/bsi/src/test/java/org/roaringbitmap/bsi/R64NavigableBSITest.java b/bsi/src/test/java/org/roaringbitmap/bsi/R64NavigableBSITest.java new file mode 100644 index 000000000..3d1d51f25 --- /dev/null +++ b/bsi/src/test/java/org/roaringbitmap/bsi/R64NavigableBSITest.java @@ -0,0 +1,450 @@ +package org.roaringbitmap.bsi; + +import org.roaringbitmap.bsi.longlong.Roaring64NavigableMapSliceIndex; +import org.roaringbitmap.longlong.Roaring64NavigableMap; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.LongStream; + +public class R64NavigableBSITest { + private Map testDataSet = new HashMap<>(); + + private Roaring64NavigableMapSliceIndex bsi; + + @BeforeEach + public void setup() { + LongStream.range(1, 100).forEach(x -> testDataSet.put(x, x)); + bsi = new Roaring64NavigableMapSliceIndex(1, 99); + testDataSet.forEach( + (k, v) -> { + bsi.setValue(k, v); + }); + } + + @Test + public void testSetAndGet() { + LongStream.range(1, 100) + .forEach( + x -> { + Pair pair = bsi.getValue(x); + Assertions.assertTrue(pair.getRight()); + Assertions.assertEquals((long) pair.getKey(), x); + }); + + IntStream.range(1, 100) + .forEach( + x -> { + Pair pair = bsi.getValue(x); + Assertions.assertTrue(pair.getRight()); + Assertions.assertEquals((long) pair.getKey(), x); + }); + } + + @Test + public void testMerge() { + Roaring64NavigableMapSliceIndex bsiA = new Roaring64NavigableMapSliceIndex(); + IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x)); + Roaring64NavigableMapSliceIndex bsiB = new Roaring64NavigableMapSliceIndex(); + IntStream.range(100, 199).forEach(x -> bsiB.setValue(x, x)); + Assertions.assertEquals(bsiA.getExistenceBitmap().getLongCardinality(), 99); + Assertions.assertEquals(bsiB.getExistenceBitmap().getLongCardinality(), 99); + bsiA.merge(bsiB); + IntStream.range(1, 199) + .forEach( + x -> { + Pair bsiValue = bsiA.getValue(x); + Assertions.assertTrue(bsiValue.getRight()); + Assertions.assertEquals((long) bsiValue.getKey(), x); + }); + } + + @Test + public void testCloneLegacy() { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(1, 99); + List> collect = + testDataSet.entrySet().stream() + .map(x -> Pair.newPair(x.getKey(), x.getValue())) + .collect(Collectors.toList()); + + bsi.setValues(collect); + + Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99); + final Roaring64NavigableMapSliceIndex clone = bsi.clone(); + Assertions.assertEquals(clone.minValue(), 1); + Assertions.assertEquals(clone.maxValue(), 99); + + IntStream.range(1, 100) + .forEach( + x -> { + Pair bsiValue = clone.getValue(x); + Assertions.assertTrue(bsiValue.getRight()); + Assertions.assertEquals((long) bsiValue.getKey(), x); + }); + } + + @Test + public void testClonePortable() { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(1, 99); + List> collect = + testDataSet.entrySet().stream() + .map(x -> Pair.newPair(x.getKey(), x.getValue())) + .collect(Collectors.toList()); + + bsi.setValues(collect); + + Assertions.assertEquals(bsi.getExistenceBitmap().getLongCardinality(), 99); + final Roaring64NavigableMapSliceIndex clone = bsi.clone(); + Assertions.assertEquals(clone.minValue(), 1); + Assertions.assertEquals(clone.maxValue(), 99); + + IntStream.range(1, 100) + .forEach( + x -> { + Pair bsiValue = clone.getValue(x); + Assertions.assertTrue(bsiValue.getRight()); + Assertions.assertEquals((long) bsiValue.getKey(), x); + }); + } + + @Test + public void testAdd() { + Roaring64NavigableMapSliceIndex bsiA = new Roaring64NavigableMapSliceIndex(); + LongStream.range(1, 100).forEach(x -> bsiA.setValue(x, x)); + Roaring64NavigableMapSliceIndex bsiB = new Roaring64NavigableMapSliceIndex(); + LongStream.range(1, 120).forEach(x -> bsiB.setValue(x, x)); + + bsiA.add(bsiB); + + LongStream.range(1, 120) + .forEach( + x -> { + Pair bsiValue = bsiA.getValue(x); + Assertions.assertTrue(bsiValue.getRight()); + if (x < 100) { + Assertions.assertEquals((long) bsiValue.getKey(), x * 2); + } else { + Assertions.assertEquals((long) bsiValue.getKey(), x); + } + }); + } + + @Test + public void testAddAndEvaluate() { + Roaring64NavigableMapSliceIndex bsiA = new Roaring64NavigableMapSliceIndex(); + IntStream.range(1, 100).forEach(x -> bsiA.setValue(x, x)); + Roaring64NavigableMapSliceIndex bsiB = new Roaring64NavigableMapSliceIndex(); + IntStream.range(1, 120).forEach(x -> bsiB.setValue(120 - x, x)); + + bsiA.add(bsiB); + + Roaring64NavigableMap result = bsiA.compare(BitmapSliceIndex.Operation.EQ, 120, 0, null); + Assertions.assertEquals(99, result.getLongCardinality()); + Assertions.assertArrayEquals(result.toArray(), LongStream.range(1, 100).toArray()); + + result = bsiA.compare(BitmapSliceIndex.Operation.RANGE, 1, 20, null); + Assertions.assertEquals(20, result.getLongCardinality()); + Assertions.assertArrayEquals(result.toArray(), LongStream.range(100, 120).toArray()); + } + + @Test + public void TestIO4Stream() throws IOException { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(1, 99); + LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x)); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream bdo = new DataOutputStream(bos); + bsi.serialize(bdo); + byte[] data = bos.toByteArray(); + + Roaring64NavigableMapSliceIndex newBsi = new Roaring64NavigableMapSliceIndex(); + + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream bdi = new DataInputStream(bis); + newBsi.deserialize(bdi); + + Assertions.assertEquals(newBsi.getExistenceBitmap().getLongCardinality(), 99); + Assertions.assertEquals(newBsi.minValue(), 1); + Assertions.assertEquals(newBsi.maxValue(), 99); + + LongStream.range(1, 100) + .forEach( + x -> { + Pair bsiValue = newBsi.getValue(x); + Assertions.assertTrue(bsiValue.getRight()); + Assertions.assertEquals((long) bsiValue.getKey(), x); + }); + } + + @Test + public void testIOFromExternal() { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(1, 99); + LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x)); + + LongStream.range(1, 100) + .forEach( + x -> { + Pair bsiValue = bsi.getValue(x); + Assertions.assertTrue(bsiValue.getRight()); + Assertions.assertEquals((long) bsiValue.getKey(), x); + }); + } + + @Test + public void testEQ() { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(1, 99); + LongStream.range(1, 100) + .forEach( + x -> { + if (x <= 50) { + bsi.setValue(x, 1); + } else { + bsi.setValue(x, x); + } + }); + + Roaring64NavigableMap bitmap = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null); + Assertions.assertEquals(50L, bitmap.getLongCardinality()); + } + + @Test + public void testNotEQ() { + bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(1, 99); + bsi.setValue(2, 1); + bsi.setValue(3, 50); + + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null); + Assertions.assertEquals(2, result.getLongCardinality()); + Assertions.assertArrayEquals(new long[] {2, 3}, result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 100, 0, null); + Assertions.assertEquals(3, result.getLongCardinality()); + Assertions.assertArrayEquals(new long[] {1, 2, 3}, result.toArray()); + + bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(1, 99); + bsi.setValue(2, 99); + bsi.setValue(3, 99); + + result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 99, 0, null); + Assertions.assertTrue(result.isEmpty()); + + result = bsi.compare(BitmapSliceIndex.Operation.NEQ, 1, 0, null); + Assertions.assertEquals(3, result.getLongCardinality()); + Assertions.assertArrayEquals(new long[] {1, 2, 3}, result.toArray()); + } + + // parallel operation test + @Test + public void testGT() { + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.GT, 50, 0, null); + Assertions.assertEquals(49, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(51, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.GT, 0, 0, null); + Assertions.assertEquals(99, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.GT, 99, 0, null); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + public void testGE() { + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.GE, 50, 0, null); + Assertions.assertEquals(50, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(50, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.GE, 1, 0, null); + Assertions.assertEquals(99, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.GE, 100, 0, null); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + public void testLT() { + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.LT, 50, 0, null); + Assertions.assertEquals(49, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 50).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.LT, Integer.MAX_VALUE, 0, null); + Assertions.assertEquals(99, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.LT, 1, 0, null); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + public void testLE() { + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.LE, 50, 0, null); + Assertions.assertEquals(50, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 51).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.LE, Integer.MAX_VALUE, 0, null); + Assertions.assertEquals(99, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.LE, 0, 0, null); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + public void testRANGE() { + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 10, 20, null); + Assertions.assertEquals(11, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(10, 21).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1, 200, null); + Assertions.assertEquals(99, result.getLongCardinality()); + Assertions.assertArrayEquals(LongStream.range(1, 100).toArray(), result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.RANGE, 1000, 2000, null); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + public void testSum() { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(1, 99); + LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x)); + + Roaring64NavigableMap foundSet = + Roaring64NavigableMap.bitmapOf(LongStream.range(1, 51).toArray()); + + Pair sumPair = bsi.sum(foundSet); + + long sum = LongStream.range(1, 51).sum(); + long count = LongStream.range(1, 51).count(); + + Assertions.assertTrue(sumPair.getLeft().intValue() == sum && sumPair.getRight() == count); + } + + @Test + public void testValueZero() { + bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(0, 0); + bsi.setValue(1, 0); + bsi.setValue(2, 1); + + Roaring64NavigableMap result = bsi.compare(BitmapSliceIndex.Operation.EQ, 0, 0, null); + Assertions.assertEquals(2, result.getLongCardinality()); + Assertions.assertArrayEquals(new long[] {0, 1}, result.toArray()); + + result = bsi.compare(BitmapSliceIndex.Operation.EQ, 1, 0, null); + Assertions.assertEquals(1, result.getLongCardinality()); + Assertions.assertArrayEquals(new long[] {2}, result.toArray()); + } + + @Test + public void testTopK() { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(0, 7); + bsi.setValue(1, 6); + bsi.setValue(2, 1); + bsi.setValue(3, 7); + bsi.setValue(4, 0); + bsi.setValue(5, 9); + bsi.setValue(6, 9); + bsi.setValue(7, 8); + bsi.setValue(8, 9); + bsi.setValue(9, 8); + + Assertions.assertEquals( + bsi.topK(bsi.getExistenceBitmap(), 4), Roaring64NavigableMap.bitmapOf(5, 6, 8, 9)); + Assertions.assertEquals( + bsi.topK(bsi.getExistenceBitmap(), 5), Roaring64NavigableMap.bitmapOf(5, 6, 7, 8, 9)); + Assertions.assertEquals( + bsi.topK(bsi.getExistenceBitmap(), 2), Roaring64NavigableMap.bitmapOf(6, 8)); + } + + @Test + public void testTranspose() { + bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(1, 2); + bsi.setValue(2, 4); + bsi.setValue(3, 4); + bsi.setValue(4, 8); + bsi.setValue(5, 8); + Roaring64NavigableMap re = bsi.transpose(null); + Assertions.assertEquals(re, Roaring64NavigableMap.bitmapOf(2, 4, 8)); + } + + @Test + public void testTransposeWithCount() { + bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(1, 2); + bsi.setValue(2, 4); + bsi.setValue(3, 4); + bsi.setValue(4, 8); + bsi.setValue(5, 8); + Roaring64NavigableMapSliceIndex re = bsi.transposeWithCount(null); + Assertions.assertEquals(re.getExistenceBitmap(), Roaring64NavigableMap.bitmapOf(2, 4, 8)); + Assertions.assertEquals(re.getValue(2).getKey(), 1); + Assertions.assertEquals(re.getValue(4).getKey(), 2); + Assertions.assertEquals(re.getValue(8).getKey(), 2); + } + + @Test + public void testIssue753() throws IOException { + bsi = new Roaring64NavigableMapSliceIndex(); + LongStream.range(1, 100).forEach(x -> bsi.setValue(x, x)); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 56, null).getLongCardinality(), 56); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 129, null).getLongCardinality(), 99); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 200, null).getLongCardinality(), 99); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, 20000, null).getLongCardinality(), 99); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -129, null).getLongCardinality(), 0); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -4, -2, null).getLongCardinality(), 0); + + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 56, null).getLongCardinality(), 53); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 129, null).getLongCardinality(), 96); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 200, null).getLongCardinality(), 96); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 20000, null).getLongCardinality(), 96); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, -129, null).getLongCardinality(), 0); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 4, 2, null).getLongCardinality(), 0); + + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, -129, -14, null).getLongCardinality(), 0); + Assertions.assertEquals( + bsi.compare(BitmapSliceIndex.Operation.RANGE, 129, 2000, null).getLongCardinality(), 0); + } + + @Test + public void testIssue755() throws IOException { + Roaring64NavigableMapSliceIndex bsi = new Roaring64NavigableMapSliceIndex(); + bsi.setValue(100L, 3L); + bsi.setValue(1L, (long) Integer.MAX_VALUE * 2 + 23456); + bsi.setValue(2L, (long) Integer.MAX_VALUE + 23456); + Assertions.assertEquals(bsi.getValue(100L).getKey(), 3L); // {{3,true}} + Assertions.assertEquals( + bsi.getValue(1L).getKey(), (long) Integer.MAX_VALUE * 2 + 23456); // {23455,true} + Assertions.assertEquals( + bsi.getValue(2L).getKey(), (long) Integer.MAX_VALUE + 23456); // {-2147460193,true} + } +} diff --git a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java index 6aa014e1f..a2864ff0d 100644 --- a/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java +++ b/roaringbitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java @@ -14,8 +14,12 @@ import org.roaringbitmap.buffer.MutableRoaringBitmap; import org.roaringbitmap.buffer.MutableRoaringBitmapPrivate; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.DataInput; +import java.io.DataInputStream; import java.io.DataOutput; +import java.io.DataOutputStream; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; @@ -854,6 +858,99 @@ public void or(final Roaring64NavigableMap x2) { } } + /** + * Bitwise OR (union) operation. The provided bitmaps are *not* modified. This operation is + * thread-safe as long as the provided bitmaps remain unchanged. + * + * @param x1 first bitmap + * @param x2 other bitmap + * @return result of the operation + */ + public static Roaring64NavigableMap or( + final Roaring64NavigableMap x1, final Roaring64NavigableMap x2) { + Roaring64NavigableMap result = new Roaring64NavigableMap(); + if (x1 == x2) { + return x1; + } + if (x1 == null) { + return x2; + } + if (x2 == null) { + return x1; + } + + Iterator> x1Iterator = + x1.getHighToBitmap().entrySet().iterator(); + Iterator> x2Iterator = + x2.getHighToBitmap().entrySet().iterator(); + Entry x1Entry = x1Iterator.hasNext() ? x1Iterator.next() : null; + Entry x2Entry = x2Iterator.hasNext() ? x2Iterator.next() : null; + + while (x1Entry != null || x2Entry != null) { + if (x1Entry == null) { + pushClonedEntry(x2Entry, result); + x2Entry = x2Iterator.hasNext() ? x2Iterator.next() : null; + } else if (x2Entry == null) { + pushClonedEntry(x1Entry, result); + x1Entry = x1Iterator.hasNext() ? x1Iterator.next() : null; + } else { + // compare & merge + int compare = Integer.compareUnsigned(x1Entry.getKey(), x2Entry.getKey()); + if (compare == 0) { + if (x1Entry.getValue() instanceof RoaringBitmap + && x2Entry.getValue() instanceof RoaringBitmap) { + result.pushBitmapForHigh( + x1Entry.getKey(), + RoaringBitmap.or( + (RoaringBitmap) x1Entry.getValue(), (RoaringBitmap) x2Entry.getValue())); + } else if (x1Entry.getValue() instanceof MutableRoaringBitmap + && x2Entry.getValue() instanceof MutableRoaringBitmap) { + result.pushBitmapForHigh( + x1Entry.getKey(), + MutableRoaringBitmap.or( + (MutableRoaringBitmap) x1Entry.getValue(), + (MutableRoaringBitmap) x2Entry.getValue())); + } else { + throw new UnsupportedOperationException( + ".or(...) over " + + getClassName(x1Entry.getValue()) + + " and " + + getClassName(x2Entry.getValue())); + } + x1Entry = x1Iterator.hasNext() ? x1Iterator.next() : null; + x2Entry = x2Iterator.hasNext() ? x2Iterator.next() : null; + } else if (compare < 0) { + pushClonedEntry(x1Entry, result); + x1Entry = x1Iterator.hasNext() ? x1Iterator.next() : null; + } else { + pushClonedEntry(x2Entry, result); + x2Entry = x2Iterator.hasNext() ? x2Iterator.next() : null; + } + } + } + + result.resetPerfHelpers(); + return result; + } + + /** + * static method for push a new entry(cloned) into target Roaring64NavigableMap + * + * @param entry the original entry item of a Roaring64NavigableMap instance + * @param result the target Roaring64NavigableMap + */ + private static void pushClonedEntry( + Entry entry, Roaring64NavigableMap result) { + if (entry.getValue() instanceof RoaringBitmap) { + result.pushBitmapForHigh(entry.getKey(), ((RoaringBitmap) (entry.getValue())).clone()); + } else if (entry.getValue() instanceof MutableRoaringBitmap) { + result.pushBitmapForHigh(entry.getKey(), ((MutableRoaringBitmap) (entry.getValue())).clone()); + } else { + throw new UnsupportedOperationException( + ". Unsupported type for pushClonedEntry: " + getClassName(entry.getValue())); + } + } + /** * In-place bitwise XOR (symmetric difference) operation. The current bitmap is modified. * @@ -913,6 +1010,55 @@ public void xor(final Roaring64NavigableMap x2) { } } + /** + * Checks whether the two bitmaps intersect. This can be much faster than calling "and" and + * checking the cardinality of the result. + * + * @param x1 first bitmap + * @param x2 other bitmap + * @return true if they intersect + */ + public static boolean intersects(final Roaring64NavigableMap x1, final Roaring64NavigableMap x2) { + if (x2 == x1) { + return true; + } + if (x1 == null || x2 == null) { + return false; + } + + // find the one with smaller entries cnt + long x1HighCnt = x1.getHighToBitmap().size(); + long x2HighCnt = x2.getHighToBitmap().size(); + Roaring64NavigableMap outer = x1HighCnt < x2HighCnt ? x1 : x2; + Roaring64NavigableMap inner = x1HighCnt < x2HighCnt ? x2 : x1; + for (Entry entry : outer.getHighToBitmap().entrySet()) { + BitmapDataProvider lowBitmap1 = entry.getValue(); + BitmapDataProvider lowBitmap2 = inner.getHighToBitmap().get(entry.getKey()); + if (lowBitmap2 == null) { + continue; + } + if (lowBitmap1 instanceof RoaringBitmap && lowBitmap2 instanceof RoaringBitmap) { + if (RoaringBitmap.intersects((RoaringBitmap) lowBitmap1, (RoaringBitmap) lowBitmap2)) { + return true; + } + } else if (lowBitmap1 instanceof MutableRoaringBitmap + && lowBitmap2 instanceof MutableRoaringBitmap) { + if (MutableRoaringBitmap.intersects( + (MutableRoaringBitmap) lowBitmap1, (MutableRoaringBitmap) lowBitmap2)) { + return true; + } + } else { + throw new UnsupportedOperationException( + ".intersects(...) over " + + getClassName(lowBitmap1) + + " and " + + getClassName(lowBitmap2)); + } + } + + return false; + } + /** * In-place bitwise AND (intersection) operation. The current bitmap is modified. * @@ -960,6 +1106,116 @@ public void and(final Roaring64NavigableMap x2) { } } + /** + * Bitwise AND (intersection) operation. The provided bitmaps are *not* modified. This operation + * is thread-safe as long as the provided bitmaps remain unchanged. + * + * @param x1 first bitmap + * @param x2 other bitmap + * @return result of the operation + */ + public static Roaring64NavigableMap and( + final Roaring64NavigableMap x1, final Roaring64NavigableMap x2) { + Roaring64NavigableMap result = new Roaring64NavigableMap(); + if (x2 == x1) { + return x1; + } + if (x1 == null || x2 == null) { + return result; + } + Iterator> x1Iterator = + x1.getHighToBitmap().entrySet().iterator(); + while (x1Iterator.hasNext()) { + Entry e1 = x1Iterator.next(); + // Keep object to prevent auto-boxing + Integer high = e1.getKey(); + + BitmapDataProvider lowBitmap1 = e1.getValue(); + BitmapDataProvider lowBitmap2 = x2.getHighToBitmap().get(high); + if (lowBitmap2 != null) { + if (lowBitmap2 instanceof RoaringBitmap && lowBitmap1 instanceof RoaringBitmap) { + RoaringBitmap andResult = + RoaringBitmap.and((RoaringBitmap) lowBitmap1, (RoaringBitmap) lowBitmap2); + result.pushBitmapForHigh(high, andResult); + } else if (lowBitmap2 instanceof MutableRoaringBitmap + && lowBitmap1 instanceof MutableRoaringBitmap) { + MutableRoaringBitmap andResult = + MutableRoaringBitmap.and( + (MutableRoaringBitmap) lowBitmap1, (MutableRoaringBitmap) lowBitmap2); + result.pushBitmapForHigh(high, andResult); + } else { + throw new UnsupportedOperationException( + ".and(...) over " + getClassName(lowBitmap1) + " and " + getClassName(lowBitmap2)); + } + } + } + result.resetPerfHelpers(); + return result; + } + + /** + * Cardinality of Bitwise AND (intersection) operation. The provided bitmaps are *not* modified. + * This operation is thread-safe as long as the provided bitmaps remain unchanged. + * + * @param x1 first bitmap + * @param x2 other bitmap + * @return as if you did and(x1,x2).getCardinality() + */ + public static long andCardinality( + final Roaring64NavigableMap x1, final Roaring64NavigableMap x2) { + long cardinality = 0; + if (x1 == null || x2 == null) { + return cardinality; + } + if (x1.getHighToBitmap().isEmpty() || x2.getHighToBitmap().isEmpty()) { + return cardinality; + } + if (x2 == x1) { + return x1.getLongCardinality(); + } + + Iterator> x1Iterator = + x1.getHighToBitmap().entrySet().iterator(); + Iterator> x2Iterator = + x2.getHighToBitmap().entrySet().iterator(); + Entry x1Entry = x1Iterator.next(); + Entry x2Entry = x2Iterator.next(); + + while (x1Entry != null && x2Entry != null) { + int highKey1 = x1Entry.getKey(); + int highKey2 = x2Entry.getKey(); + BitmapDataProvider lowBitmap1 = x1Entry.getValue(); + BitmapDataProvider lowBitmap2 = x2Entry.getValue(); + + int compare = Integer.compareUnsigned(highKey1, highKey2); + if (compare == 0) { + if (lowBitmap2 instanceof RoaringBitmap && lowBitmap1 instanceof RoaringBitmap) { + cardinality += + RoaringBitmap.andCardinality((RoaringBitmap) lowBitmap1, (RoaringBitmap) lowBitmap2); + } else if (lowBitmap2 instanceof MutableRoaringBitmap + && lowBitmap1 instanceof MutableRoaringBitmap) { + cardinality += + MutableRoaringBitmap.andCardinality( + (MutableRoaringBitmap) lowBitmap1, (MutableRoaringBitmap) lowBitmap2); + } else { + throw new UnsupportedOperationException( + ".andCardinality(...) over " + + getClassName(lowBitmap1) + + " and " + + getClassName(lowBitmap2)); + } + x1Entry = x1Iterator.hasNext() ? x1Iterator.next() : null; + x2Entry = x2Iterator.hasNext() ? x2Iterator.next() : null; + } else if (compare < 0) { + x1Entry = x1Iterator.hasNext() ? x1Iterator.next() : null; + } else { + x2Entry = x2Iterator.hasNext() ? x2Iterator.next() : null; + } + } + + return cardinality; + } + /** * In-place bitwise ANDNOT (difference) operation. The current bitmap is modified. * @@ -1005,6 +1261,56 @@ public void andNot(final Roaring64NavigableMap x2) { } } + /** + * Bitwise ANDNOT (difference) operation. The provided bitmaps are *not* modified. This operation + * is thread-safe as long as the provided bitmaps remain unchanged. + * + * @param x1 first bitmap + * @param x2 other bitmap + * @return result of the operation + */ + public static Roaring64NavigableMap andNot( + final Roaring64NavigableMap x1, final Roaring64NavigableMap x2) { + Roaring64NavigableMap result = new Roaring64NavigableMap(); + if (x1 == x2 || x1 == null || x1.getHighToBitmap() == null) { + return result; + } + if (x2 == null || x2.getHighToBitmap() == null) { + return x1; + } + + Iterator> x1Iterator = + x1.getHighToBitmap().entrySet().iterator(); + while (x1Iterator.hasNext()) { + Entry e1 = x1Iterator.next(); + + // Keep object to prevent auto-boxing + Integer high = e1.getKey(); + BitmapDataProvider lowBitmap1 = e1.getValue(); + BitmapDataProvider lowBitmap2 = x2.getHighToBitmap().get(high); + if (lowBitmap2 != null) { + if (lowBitmap2 instanceof RoaringBitmap && lowBitmap1 instanceof RoaringBitmap) { + RoaringBitmap andNotResult = + RoaringBitmap.andNot((RoaringBitmap) lowBitmap1, (RoaringBitmap) lowBitmap2); + result.pushBitmapForHigh(high, andNotResult); + } else if (lowBitmap2 instanceof MutableRoaringBitmap + && lowBitmap1 instanceof MutableRoaringBitmap) { + MutableRoaringBitmap andNotResult = + MutableRoaringBitmap.andNot( + (MutableRoaringBitmap) lowBitmap1, (MutableRoaringBitmap) lowBitmap2); + result.pushBitmapForHigh(high, andNotResult); + } else { + throw new UnsupportedOperationException( + ".andNot(...) over " + getClassName(lowBitmap1) + " and " + getClassName(lowBitmap2)); + } + } else { + result.pushBitmapForHigh(high, lowBitmap1); + } + } + result.resetPerfHelpers(); + return result; + } + /** * {@link Roaring64NavigableMap} are serializable. However, contrary to RoaringBitmap, the * serialization format is not well-defined: for now, it is strongly coupled with Java standard @@ -1602,6 +1908,35 @@ public boolean equals(Object obj) { return Objects.equals(highToBitmap, other.highToBitmap); } + /** + * clone current Roaring64NavigableMap instance, the new cloned instance will have + * the same serialization mode with this one. + *

+ * *NOTE* This can only handle instances where {@link #serializedSizeInBytes} < Integer.MAX_VALUE, + * otherwise an UnsupportedOperationException will be thrown. + */ + @Override + public Roaring64NavigableMap clone() { + long sizeInBytesL = this.serializedSizeInBytes(); + if (sizeInBytesL >= Integer.MAX_VALUE) { + throw new UnsupportedOperationException(); + } + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dataOutput = new DataOutputStream(baos)) { + serialize(dataOutput); + Roaring64NavigableMap freshOne = new Roaring64NavigableMap(); + try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + DataInputStream dataInput = new DataInputStream(bais)) { + freshOne.deserialize(dataInput); + return freshOne; + } catch (Exception e) { + throw new RuntimeException("fail to deserialize", e); + } + } catch (Exception e) { + throw new RuntimeException("fail to clone through the ser/deser", e); + } + } + /** * Add the value if it is not already present, otherwise remove it. * diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java index eeba403d7..046a6ec91 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java @@ -46,7 +46,7 @@ private Roaring64Bitmap newDefaultCtor() { return new Roaring64Bitmap(); } - private Set getSourceForAllKindsOfNodeTypes() { + public static Set getSourceForAllKindsOfNodeTypes() { Random random = new Random(1234); Set source = new HashSet<>(); int total = 10000; diff --git a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java index 2a7244765..169cefd34 100644 --- a/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java +++ b/roaringbitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64NavigableMap.java @@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.roaringbitmap.longlong.TestRoaring64Bitmap.getSourceForAllKindsOfNodeTypes; import org.roaringbitmap.BitmapDataProvider; import org.roaringbitmap.RoaringBitmap; @@ -25,6 +26,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -38,6 +40,7 @@ import java.util.NavigableMap; import java.util.NoSuchElementException; import java.util.Random; +import java.util.Set; public class TestRoaring64NavigableMap { @@ -46,7 +49,6 @@ private Roaring64NavigableMap newDefaultCtor() { return new Roaring64NavigableMap(); } - // Testing the nocache behavior should not depends on bitmap being on-heap of buffered private Roaring64NavigableMap newNoCache() { return new Roaring64NavigableMap(true, false); } @@ -845,6 +847,27 @@ public void testOr_SameBucket() { assertEquals(234, left.select(1)); } + @Test + public void testOr_Static_SameBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + right.addLong(234); + + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(234, right.select(0)); + + assertEquals(2, result.getLongCardinality()); + + assertEquals(123, result.select(0)); + assertEquals(234, result.select(1)); + } + @Test public void testOr_MultipleBuckets() { Roaring64NavigableMap left = newDefaultCtor(); @@ -863,6 +886,30 @@ public void testOr_MultipleBuckets() { assertEquals(Long.MAX_VALUE, left.select(2)); } + @Test + public void testOr_Static_MultipleBuckets() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + left.addLong(Long.MAX_VALUE); + right.addLong(234); + + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(2, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(Long.MAX_VALUE, left.select(1)); + assertEquals(1, right.getLongCardinality()); + assertEquals(234, right.select(0)); + + assertEquals(3, result.getLongCardinality()); + + assertEquals(123, result.select(0)); + assertEquals(234, result.select(1)); + assertEquals(Long.MAX_VALUE, result.select(2)); + } + @Test public void testOr_DifferentBucket_NotBuffer() { Roaring64NavigableMap left = newSignedBuffered(); @@ -879,6 +926,27 @@ public void testOr_DifferentBucket_NotBuffer() { assertEquals(Long.MAX_VALUE / 2, left.select(1)); } + @Test + public void testOr_Static_DifferentBucket_NotBuffer() { + Roaring64NavigableMap left = newSignedBuffered(); + Roaring64NavigableMap right = newSignedBuffered(); + + left.addLong(123); + right.addLong(Long.MAX_VALUE / 2); + + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(Long.MAX_VALUE / 2, right.select(0)); + + assertEquals(2, result.getLongCardinality()); + + assertEquals(123, result.select(0)); + assertEquals(Long.MAX_VALUE / 2, result.select(1)); + } + @Test public void testOr_SameBucket_NotBuffer() { Roaring64NavigableMap left = new Roaring64NavigableMap(true, new RoaringBitmapSupplier()); @@ -895,6 +963,27 @@ public void testOr_SameBucket_NotBuffer() { assertEquals(234, left.select(1)); } + @Test + public void testOr_Static_SameBucket_NotBuffer() { + Roaring64NavigableMap left = new Roaring64NavigableMap(true, new RoaringBitmapSupplier()); + Roaring64NavigableMap right = new Roaring64NavigableMap(true, new RoaringBitmapSupplier()); + + left.addLong(123); + right.addLong(234); + + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(234, right.select(0)); + + assertEquals(2, result.getLongCardinality()); + + assertEquals(123, result.select(0)); + assertEquals(234, result.select(1)); + } + @Test public void testOr_DifferentBucket_Buffer() { Roaring64NavigableMap left = newSignedBuffered(); @@ -911,6 +1000,27 @@ public void testOr_DifferentBucket_Buffer() { assertEquals(Long.MAX_VALUE, left.select(1)); } + @Test + public void testOr_Static_DifferentBucket_Buffer() { + Roaring64NavigableMap left = newSignedBuffered(); + Roaring64NavigableMap right = newSignedBuffered(); + + left.addLong(123); + right.addLong(Long.MAX_VALUE); + + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(Long.MAX_VALUE, right.select(0)); + + assertEquals(2, result.getLongCardinality()); + + assertEquals(123, result.select(0)); + assertEquals(Long.MAX_VALUE, result.select(1)); + } + @Test public void testOr_SameBucket_Buffer() { Roaring64NavigableMap left = newSignedBuffered(); @@ -927,6 +1037,27 @@ public void testOr_SameBucket_Buffer() { assertEquals(234, left.select(1)); } + @Test + public void testOr_Static_SameBucket_Buffer() { + Roaring64NavigableMap left = newSignedBuffered(); + Roaring64NavigableMap right = newSignedBuffered(); + + left.addLong(123); + right.addLong(234); + + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(234, right.select(0)); + + assertEquals(2, result.getLongCardinality()); + + assertEquals(123, result.select(0)); + assertEquals(234, result.select(1)); + } + @Test public void testOr_CloneInput() { Roaring64NavigableMap left = newDefaultCtor(); @@ -948,6 +1079,31 @@ public void testOr_CloneInput() { assertEquals(123, right.select(0)); } + @Test + public void testOr_Static_CloneInput() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + right.addLong(123); + + // We push in left a bucket which does not exist + Roaring64NavigableMap result = Roaring64NavigableMap.or(left, right); + // check that inputs have not changed + assertEquals(0, left.getLongCardinality()); + assertEquals(1, right.getLongCardinality()); + assertEquals(123, right.select(0)); + + // Then we mutate left: ensure it does not impact right as it should remain unchanged + result.addLong(234); + + assertEquals(2, result.getLongCardinality()); + assertEquals(123, result.select(0)); + assertEquals(234, result.select(1)); + + assertEquals(1, right.getLongCardinality()); + assertEquals(123, right.select(0)); + } + @Test public void testXor_SingleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1032,6 +1188,30 @@ public void testAnd_SingleBucket() { assertEquals(234, left.select(0)); } + @Test + public void testAnd_Static_SingleBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + left.addLong(234); + right.addLong(234); + right.addLong(345); + + // We have 1 shared value: 234 + Roaring64NavigableMap result = Roaring64NavigableMap.and(left, right); + // check that inputs have not changed + assertEquals(2, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(234, left.select(1)); + assertEquals(2, right.getLongCardinality()); + assertEquals(234, right.select(0)); + assertEquals(345, right.select(1)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(234, result.select(0)); + } + @Test public void testAnd_Buffer() { Roaring64NavigableMap left = newSignedBuffered(); @@ -1047,6 +1227,26 @@ public void testAnd_Buffer() { assertEquals(123, left.select(0)); } + @Test + public void testAnd_Static_Buffer() { + Roaring64NavigableMap left = newSignedBuffered(); + Roaring64NavigableMap right = newSignedBuffered(); + + left.addLong(123); + right.addLong(123); + + // We have 1 shared value: 234 + Roaring64NavigableMap result = Roaring64NavigableMap.and(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(123, right.select(0)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(123, result.select(0)); + } + @Test public void testAnd_DifferentBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1061,6 +1261,25 @@ public void testAnd_DifferentBucket() { assertEquals(0, left.getLongCardinality()); } + @Test + public void testAnd_Static_DifferentBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + right.addLong(Long.MAX_VALUE); + + // We have 1 shared value: 234 + Roaring64NavigableMap result = Roaring64NavigableMap.and(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(Long.MAX_VALUE, right.select(0)); + + assertEquals(0, result.getLongCardinality()); + } + @Test public void testAnd_MultipleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1077,6 +1296,28 @@ public void testAnd_MultipleBucket() { assertEquals(Long.MAX_VALUE, left.select(0)); } + @Test + public void testAnd_Static_MultipleBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + left.addLong(Long.MAX_VALUE); + right.addLong(Long.MAX_VALUE); + + // We have 1 shared value: 234 + Roaring64NavigableMap result = Roaring64NavigableMap.and(left, right); + // check that inputs have not changed + assertEquals(2, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(Long.MAX_VALUE, left.select(1)); + assertEquals(1, right.getLongCardinality()); + assertEquals(Long.MAX_VALUE, right.select(0)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(Long.MAX_VALUE, result.select(0)); + } + @Test public void testAndNot_SingleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1094,6 +1335,30 @@ public void testAndNot_SingleBucket() { assertEquals(123, left.select(0)); } + @Test + public void testAndNot_Static_SingleBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + left.addLong(234); + right.addLong(234); + right.addLong(345); + + // We have 1 shared value: 234 + Roaring64NavigableMap result = Roaring64NavigableMap.andNot(left, right); + // check that inputs have not changed + assertEquals(2, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(234, left.select(1)); + assertEquals(2, right.getLongCardinality()); + assertEquals(234, right.select(0)); + assertEquals(345, right.select(1)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(123, result.select(0)); + } + @Test public void testAndNot_Buffer() { Roaring64NavigableMap left = newSignedBuffered(); @@ -1109,6 +1374,25 @@ public void testAndNot_Buffer() { assertEquals(123, left.select(0)); } + @Test + public void testAndNot_Static_Buffer() { + Roaring64NavigableMap left = newSignedBuffered(); + Roaring64NavigableMap right = newSignedBuffered(); + + left.addLong(123); + right.addLong(234); + + Roaring64NavigableMap result = Roaring64NavigableMap.andNot(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(234, right.select(0)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(123, result.select(0)); + } + @Test public void testAndNot_DifferentBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1124,6 +1408,26 @@ public void testAndNot_DifferentBucket() { assertEquals(123, left.select(0)); } + @Test + public void testAndNot_Static_DifferentBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + right.addLong(Long.MAX_VALUE); + + // We have 1 shared value: 234 + Roaring64NavigableMap result = Roaring64NavigableMap.andNot(left, right); + // check that inputs have not changed + assertEquals(1, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(1, right.getLongCardinality()); + assertEquals(Long.MAX_VALUE, right.select(0)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(123, result.select(0)); + } + @Test public void testAndNot_MultipleBucket() { Roaring64NavigableMap left = newDefaultCtor(); @@ -1140,6 +1444,28 @@ public void testAndNot_MultipleBucket() { assertEquals(123, left.select(0)); } + @Test + public void testAndNot_Static_MultipleBucket() { + Roaring64NavigableMap left = newDefaultCtor(); + Roaring64NavigableMap right = newDefaultCtor(); + + left.addLong(123); + left.addLong(Long.MAX_VALUE); + right.addLong(Long.MAX_VALUE); + + // We have 1 shared value: Long.MAX_VALUE + Roaring64NavigableMap result = Roaring64NavigableMap.andNot(left, right); + // check that inputs have not changed + assertEquals(2, left.getLongCardinality()); + assertEquals(123, left.select(0)); + assertEquals(Long.MAX_VALUE, left.select(1)); + assertEquals(1, right.getLongCardinality()); + assertEquals(Long.MAX_VALUE, right.select(0)); + + assertEquals(1, result.getLongCardinality()); + assertEquals(123, result.select(0)); + } + @Test public void testToString_signed() { Roaring64NavigableMap map = new Roaring64NavigableMap(true); @@ -1575,6 +1901,26 @@ public void testAnd_ImplicitRoaringBitmap() { } } + @Test + public void testAnd_Static_ImplicitRoaringBitmap() { + // Based on RoaringBitmap + Roaring64NavigableMap x = new Roaring64NavigableMap(); + x.addRange(123, 124); + Assertions.assertTrue(x.getHighToBitmap().values().iterator().next() instanceof RoaringBitmap); + + // Based on MutableRoaringBitmap + Roaring64NavigableMap y = Roaring64NavigableMap.bitmapOf(4L); + Assertions.assertTrue(y.getHighToBitmap().values().iterator().next() instanceof RoaringBitmap); + + { + Roaring64NavigableMap result = Roaring64NavigableMap.and(x, y); + + BitmapDataProvider singleBitmap = result.getHighToBitmap().values().iterator().next(); + Assertions.assertTrue(singleBitmap instanceof RoaringBitmap); + Assertions.assertTrue(singleBitmap.isEmpty()); + } + } + @Test public void testAnd_MutableRoaringBitmap() { // Based on RoaringBitmap @@ -1590,6 +1936,21 @@ public void testAnd_MutableRoaringBitmap() { Assertions.assertEquals(8L, x.getLongCardinality()); } + @Test + public void testAnd_Static_MutableRoaringBitmap() { + // Based on RoaringBitmap + Roaring64NavigableMap x = new Roaring64NavigableMap(new MutableRoaringBitmapSupplier()); + x.addRange(0, 16); + + // Based on MutableRoaringBitmap + Roaring64NavigableMap y = new Roaring64NavigableMap(new MutableRoaringBitmapSupplier()); + y.addRange(8, 32); + + Assertions.assertEquals(16L, x.getLongCardinality()); + Roaring64NavigableMap result = Roaring64NavigableMap.and(x, y); + Assertions.assertEquals(8L, result.getLongCardinality()); + } + @Test public void testAnd_IncompatibleImplementations() { // Based on RoaringBitmap @@ -1603,6 +1964,20 @@ public void testAnd_IncompatibleImplementations() { Assertions.assertThrows(UnsupportedOperationException.class, () -> x.and(y)); } + @Test + public void testAnd_Static_IncompatibleImplementations() { + // Based on RoaringBitmap + Roaring64NavigableMap x = new Roaring64NavigableMap(new RoaringBitmapSupplier()); + x.addRange(0, 16); + + // Based on MutableRoaringBitmap + Roaring64NavigableMap y = new Roaring64NavigableMap(new MutableRoaringBitmapSupplier()); + y.addRange(8, 32); + + Assertions.assertThrows( + UnsupportedOperationException.class, () -> Roaring64NavigableMap.and(x, y)); + } + @Test public void testAndNot_ImplicitRoaringBitmap() { // Based on RoaringBitmap @@ -1624,6 +1999,27 @@ public void testAndNot_ImplicitRoaringBitmap() { } } + @Test + public void testAndNot_Static_ImplicitRoaringBitmap() { + // Based on RoaringBitmap + Roaring64NavigableMap x = new Roaring64NavigableMap(); + x.addRange(8, 16); + + // Based on MutableRoaringBitmap + Roaring64NavigableMap y = new Roaring64NavigableMap(); + y.addRange(12, 32); + + { + Roaring64NavigableMap result = Roaring64NavigableMap.andNot(x, y); + + BitmapDataProvider singleBitmap = result.getHighToBitmap().values().iterator().next(); + Assertions.assertTrue(singleBitmap instanceof RoaringBitmap); + Assertions.assertEquals(4L, singleBitmap.getLongCardinality()); + Assertions.assertEquals(8L, singleBitmap.select(0)); + Assertions.assertEquals(11L, singleBitmap.select(3)); + } + } + @Test public void testOr_ImplicitRoaringBitmap() { // Based on RoaringBitmap @@ -1712,6 +2108,42 @@ public void testSerialization_64map32bitvals() throws IOException, ClassNotFound checkConsistencyWithResource(resourceName, bitmap); } + @Test + public void testAllKindOfNodeTypesSerDeser() throws Exception { + Set source = getSourceForAllKindsOfNodeTypes(); + + Roaring64NavigableMap map = new Roaring64NavigableMap(); + for (long x : source) { + map.addLong(x); + } + + LongIterator longIterator = map.getLongIterator(); + int i = 0; + while (longIterator.hasNext()) { + long actual = longIterator.next(); + Assertions.assertTrue(source.contains(actual)); + i++; + } + Assertions.assertEquals(source.size(), i); + // test all kind of nodes' serialization/deserialization + long sizeL = map.serializedSizeInBytes(); + if (sizeL > Integer.MAX_VALUE) { + return; + } + + int sizeInt = (int) sizeL; + long select2 = map.select(2); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(sizeInt); + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + map.serialize(dataOutputStream); + ByteArrayInputStream byteArrayInputStream = + new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); + Roaring64NavigableMap deserStreamOne = new Roaring64NavigableMap(); + deserStreamOne.deserialize(dataInputStream); + Assertions.assertEquals(select2, deserStreamOne.select(2)); + } + @Test public void testSerialization_spreadvals() throws IOException, ClassNotFoundException { // This example binary comes from