Repository: roaringbitmap/roaringbitmap
Issue: Result of Roaring64Bitmap::or is not right

**Describe the bug**
```java
public static void main(String[] args) throws IOException {

        String s1 = FileUtils.readFileToString(new File("D:\\\\Documents\\\\Pictures\\\\base64.txt"), StandardCharsets.UTF_8);
        byte[] decodedString = Base64.getDecoder().decode(new String(s1).getBytes(StandardCharsets.UTF_8));
        Roaring64Bitmap b1 = BitMapUtil.toBitMap(decodedString);
        Roaring64Bitmap b2 = BitMapUtil.toBitMap(decodedString);

        System.out.println("b1 length " + b1.getLongCardinality() + ", and b1 contains 22110666752 " + b1.contains(22110666752L));
        b1.or(b1);
        System.out.println("b1 length " + b1.getLongCardinality() + ", and b1 contains 22110666752 " + b1.contains(22110666752L));

    }

public static Roaring64Bitmap toBitMap(byte[] array){
        if (array == null){
            return new Roaring64Bitmap();
        }
        Roaring64Bitmap ret = new Roaring64Bitmap();
        try {
            ret.deserialize(ByteBuffer.wrap(array));
        } catch(IOException ioe) {
            ioe.printStackTrace(); // should not happen
        }
        return ret;
    }
```


result is :
```
b1 length 85243, and b1 contains 22110666752 false
b1 length 85297, and b1 contains 22110666752 true
```

base64.txt file is
[base64.txt](https://github.com/RoaringBitmap/RoaringBitmap/files/9961308/base64.txt)


Changed files:
RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java

diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
index 27af9afe..a9e93eec 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/RoaringBitmap.java
@@ -1212,6 +1212,7 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
    * @param x2 other bitmap
    */
   public void and(final RoaringBitmap x2) {
+    if(x2 == this) { return; }
     int pos1 = 0, pos2 = 0, intersectionSize = 0;
     final int length1 = highLowContainer.size(), length2 = x2.highLowContainer.size();
 
@@ -1285,6 +1286,10 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
    * @param x2 other bitmap
    */
   public void andNot(final RoaringBitmap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     int pos1 = 0, pos2 = 0, intersectionSize = 0;
     final int length1 = highLowContainer.size(), length2 = x2.highLowContainer.size();
 
@@ -1366,6 +1371,9 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
    * @param rangeEnd end point of the range (exclusive).
    */
   public void orNot(final RoaringBitmap other, long rangeEnd) {
+    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);
@@ -2211,6 +2219,7 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
   // 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; }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
@@ -2258,6 +2267,7 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
   // 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; }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
@@ -2333,6 +2343,7 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
    * @param x2 other bitmap
    */
   public void or(final RoaringBitmap x2) {
+    if(this == x2) { return; }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
@@ -3089,6 +3100,10 @@ public class RoaringBitmap implements Cloneable, Serializable, Iterable<Integer>
    * @param x2 other bitmap
    */
   public void xor(final RoaringBitmap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
index 878a0c42..7ef2ce04 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/buffer/MutableRoaringBitmap.java
@@ -850,6 +850,7 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
    * @param array other bitmap
    */
   public void and(final ImmutableRoaringBitmap array) {
+    if(array == this) { return; }
     int pos1 = 0, pos2 = 0, intersectionSize = 0;
     final int length1 = highLowContainer.size(), length2 = array.highLowContainer.size();
 
@@ -881,6 +882,10 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
    * @param x2 other bitmap
    */
   public void andNot(final ImmutableRoaringBitmap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     int pos1 = 0, pos2 = 0, intersectionSize = 0;
     final int length1 = highLowContainer.size(), length2 = x2.highLowContainer.size();
 
@@ -921,6 +926,9 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
    * @param rangeEnd end point of the range (exclusive).
    */
   public void orNot(ImmutableRoaringBitmap other, long rangeEnd) {
+    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);
@@ -1254,6 +1262,7 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
   // call repairAfterLazy on result, eventually
   // important: x2 should not have been computed lazily
   protected void lazyor(final ImmutableRoaringBitmap x2) {
+    if(this == x2) { return; }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
@@ -1301,6 +1310,7 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
   // 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; }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
@@ -1354,6 +1364,7 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
    * @param x2 other bitmap
    */
   public void or(final ImmutableRoaringBitmap x2) {
+    if(this == x2) { return; }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
@@ -1617,6 +1628,10 @@ public class MutableRoaringBitmap extends ImmutableRoaringBitmap
    * @param x2 other bitmap
    */
   public void xor(final ImmutableRoaringBitmap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     int pos1 = 0, pos2 = 0;
     int length1 = highLowContainer.size();
     final int length2 = x2.highLowContainer.size();
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
index 6f036d7f..36883093 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64Bitmap.java
@@ -294,6 +294,7 @@ public class Roaring64Bitmap implements Externalizable, LongBitmapDataProvider {
    * @param x2 other bitmap
    */
   public void or(final Roaring64Bitmap x2) {
+    if(this == x2) { return; }
     KeyIterator highIte2 = x2.highLowContainer.highKeyIterator();
     while (highIte2.hasNext()) {
       byte[] high = highIte2.next();
@@ -316,6 +317,10 @@ public class Roaring64Bitmap implements Externalizable, LongBitmapDataProvider {
    * @param x2 other bitmap
    */
   public void xor(final Roaring64Bitmap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     KeyIterator keyIterator = x2.highLowContainer.highKeyIterator();
     while (keyIterator.hasNext()) {
       byte[] high = keyIterator.next();
@@ -338,6 +343,7 @@ public class Roaring64Bitmap implements Externalizable, LongBitmapDataProvider {
    * @param x2 other bitmap
    */
   public void and(final Roaring64Bitmap x2) {
+    if(x2 == this) { return; }
     KeyIterator thisIterator = highLowContainer.highKeyIterator();
     while (thisIterator.hasNext()) {
       byte[] highKey = thisIterator.next();
@@ -364,6 +370,10 @@ public class Roaring64Bitmap implements Externalizable, LongBitmapDataProvider {
    * @param x2 other bitmap
    */
   public void andNot(final Roaring64Bitmap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     KeyIterator thisKeyIterator = highLowContainer.highKeyIterator();
     while (thisKeyIterator.hasNext()) {
       byte[] high = thisKeyIterator.next();
diff --git a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
index 187c9c13..0461576e 100644
--- a/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
+++ b/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java
@@ -708,6 +708,7 @@ public class Roaring64NavigableMap implements Externalizable, LongBitmapDataProv
    * @param x2 other bitmap
    */
   public void naivelazyor(final Roaring64NavigableMap x2) {
+    if(this == x2) { return; }
     for (Entry<Integer, BitmapDataProvider> e2 : x2.highToBitmap.entrySet()) {
       // Keep object to prevent auto-boxing
       Integer high = e2.getKey();
@@ -750,6 +751,7 @@ public class Roaring64NavigableMap implements Externalizable, LongBitmapDataProv
    * @param x2 other bitmap
    */
   public void or(final Roaring64NavigableMap x2) {
+    if(this == x2) { return; }
     boolean firstBucket = true;
 
     for (Entry<Integer, BitmapDataProvider> e2 : x2.highToBitmap.entrySet()) {
@@ -806,6 +808,10 @@ public class Roaring64NavigableMap implements Externalizable, LongBitmapDataProv
    * @param x2 other bitmap
    */
   public void xor(final Roaring64NavigableMap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     boolean firstBucket = true;
 
     for (Entry<Integer, BitmapDataProvider> e2 : x2.highToBitmap.entrySet()) {
@@ -861,6 +867,7 @@ public class Roaring64NavigableMap implements Externalizable, LongBitmapDataProv
    * @param x2 other bitmap
    */
   public void and(final Roaring64NavigableMap x2) {
+    if(x2 == this) { return; }
     boolean firstBucket = true;
 
     Iterator<Entry<Integer, BitmapDataProvider>> thisIterator = highToBitmap.entrySet().iterator();
@@ -906,6 +913,10 @@ public class Roaring64NavigableMap implements Externalizable, LongBitmapDataProv
    * @param x2 other bitmap
    */
   public void andNot(final Roaring64NavigableMap x2) {
+    if(x2 == this) {
+      clear();
+      return;
+    }
     boolean firstBucket = true;
 
     Iterator<Entry<Integer, BitmapDataProvider>> thisIterator = highToBitmap.entrySet().iterator();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
index 59e01b17..a1327195 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/TestRoaringBitmap.java
@@ -5406,6 +5406,22 @@ public class TestRoaringBitmap {
         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();
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
index 50cb2b22..f1371599 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/buffer/TestRoaringBitmap.java
@@ -3916,6 +3916,21 @@ public class TestRoaringBitmap {
     assertTrue(bitmap.cardinalityExceeds(runLength - 1));
   }
 
+  @Test
+  public void testWithYourself() {
+    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)));
+    b1.xor(b1);
+    assertTrue(b1.isEmpty());
+    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)));
+    b1.andNot(b1);
+    assertTrue(b1.isEmpty());
+  }
+
   @Test
   public void testPreviousValueRegression() {
     // see https://github.com/RoaringBitmap/RoaringBitmap/issues/564
diff --git a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
index f0d0d52c..eeff115f 100644
--- a/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
+++ b/RoaringBitmap/src/test/java/org/roaringbitmap/longlong/TestRoaring64Bitmap.java
@@ -2172,6 +2172,20 @@ public class TestRoaring64Bitmap {
   }
 
 
+  @Test
+  public void testWithYourself() {
+    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)));
+    b1.xor(b1);
+    assertTrue(b1.isEmpty());
+    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)));
+    b1.andNot(b1);
+    assertTrue(b1.isEmpty());
+  }
 
   @Test
   public void testIssue580() {