@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 MutableRoaringBitmap rb1 = new MutableRoaringBitmap();
      final MutableRoaringBitmap rb2 = new MutableRoaringBitmap();
      Set<Integer> set1 = new HashSet<>();
      Set<Integer> 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<Integer> xorSet = new TreeSet<>();
      xorSet.addAll(set1);
      xorSet.addAll(set2);
      Set<Integer> 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<Integer> expectedResultSet = new TreeSet<>();
        for (int i = rangeStart; i < rangeEnd; i++) {
          if (xorSet.contains(i)) {
            expectedResultSet.add(i);
          }
        }
        List<ImmutableRoaringBitmap> list = new ArrayList<>();
        list.add(rb1);
        list.add(rb2);
        MutableRoaringBitmap result =
            ImmutableRoaringBitmap.xor(list.iterator(), rangeStart, rangeEnd);
        Set<Integer> actualResultSet = new TreeSet<>();
        IntIterator intIterator = result.getIntIterator();
        while (intIterator.hasNext()) {
          actualResultSet.add(intIterator.next());
        }
        Assert.assertEquals(expectedResultSet, actualResultSet);
      }
    }
  }
 @Test
 public void testIterator() {
   MutableRoaringBitmap rb = new MutableRoaringBitmap();
   for (int k = 0; k < 4000; ++k) rb.add(k);
   for (int k = 0; k < 1000; ++k) rb.add(k * 100);
   MutableRoaringBitmap copy1 = new MutableRoaringBitmap();
   for (int x : rb) {
     copy1.add(x);
   }
   Assert.assertTrue(copy1.equals(rb));
   MutableRoaringBitmap copy2 = new MutableRoaringBitmap();
   IntIterator i = rb.getIntIterator();
   Iterator<Integer> is = rb.iterator();
   while (i.hasNext()) {
     if (!is.hasNext()) throw new RuntimeException("bug");
     int x = i.next();
     copy2.add(x);
     int xs = is.next();
     if (x != xs) throw new RuntimeException("values differ " + x + " " + xs);
   }
   if (is.hasNext()) throw new RuntimeException("bug: more data available");
   Assert.assertTrue(copy2.equals(rb));
 }
 private static final int[] toDocArray(ReaderLocal reader, DocumentsRequest request)
     throws IOException {
   SchemaField schemaField = null;
   Schema schema = request.getConfig().getSchema();
   String field = request.getField();
   if (!StringUtils.isEmpty(field)) {
     schemaField = schema.getField(field);
     if (schemaField == null) throw new IOException("Field not found: " + field);
   } else {
     schemaField = schema.getFieldList().getUniqueField();
     if (schemaField == null) throw new IOException("No unique field");
   }
   int higher = -1;
   RoaringBitmap bitSet = new RoaringBitmap();
   String fieldName = schemaField.getName();
   for (String uniqueKey : request.getUniqueKeyList()) {
     TermDocs termDocs = reader.getTermDocs(new Term(fieldName, uniqueKey));
     if (termDocs != null) {
       while (termDocs.next()) {
         int doc = termDocs.doc();
         if (doc > higher) higher = doc;
         bitSet.add(doc);
       }
     }
     termDocs.close();
   }
   if (request.isReverse()) bitSet.flip(0, higher + 1);
   IntBufferedArrayInterface intBufferArray =
       IntBufferedArrayFactory.INSTANCE.newInstance(bitSet.getCardinality());
   IntIterator iterator = bitSet.getIntIterator();
   while (iterator.hasNext()) {
     int docId = iterator.next();
     if (!reader.isDeletedNoLock(docId)) intBufferArray.add(docId);
   }
   return intBufferArray.getFinalArray();
 }