@Test
 public void testHash() {
   MutableRoaringBitmap rbm1 = new MutableRoaringBitmap();
   rbm1.add(17);
   MutableRoaringBitmap rbm2 = new MutableRoaringBitmap();
   rbm2.add(17);
   Assert.assertTrue(rbm1.hashCode() == rbm2.hashCode());
   rbm2 = rbm1.clone();
   Assert.assertTrue(rbm1.hashCode() == rbm2.hashCode());
 }
  @Test
  public void ANDNOTtestA() {
    // both have run containers
    final MutableRoaringBitmap rr = new MutableRoaringBitmap();
    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);
    }

    rr.runOptimize();

    final MutableRoaringBitmap rr2 = new MutableRoaringBitmap();
    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);
    }
    rr2.runOptimize();
    final MutableRoaringBitmap correct = MutableRoaringBitmap.andNot(rr, rr2);
    rr.andNot(rr2);
    Assert.assertTrue(correct.equals(rr));
    Assert.assertTrue(correct.hashCode() == rr.hashCode());
  }
  @SuppressWarnings("resource")
  @Test
  public void testProperSerializationA() throws IOException {
    // denser, so we should have run containers
    final int SIZE = 500;
    final Random rand = new Random(0);
    for (int i = 0; i < SIZE; ++i) {
      MutableRoaringBitmap r = new MutableRoaringBitmap();
      for (int k = 0; k < 500000; ++k) {
        if (rand.nextDouble() < .9) {
          r.add(k);
        }
      }
      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)));
      b.flip();
      ImmutableRoaringBitmap irb = new ImmutableRoaringBitmap(b);
      Assert.assertTrue(irb.hashCode() == r.hashCode());
      Assert.assertTrue(irb.getCardinality() == r.getCardinality());
    }
  }