code: package zemberek.core.collections;
  
  import static org.junit.Assert.assertEquals;
  
  import com.google.common.base.Stopwatch;
  import java.util.Arrays;
  import java.util.Random;
  import java.util.concurrent.TimeUnit;
  import org.junit.Assert;
  import org.junit.Ignore;
  import org.junit.Test;
  
  
  public class LongBitVectorTest {
  
    @Test(expected = IllegalArgumentException.class)
    public void initializationNegative() {
      new LongBitVector(-1);
    }
  
    @Test(expected = IllegalArgumentException.class)
    public void initializationOutOfBOund() {
      new LongBitVector(Integer.MAX_VALUE * 64L + 1L);
    }
  
    @Test
    public void getSetTest() {
      long[] setBits = {1, 2, 3, 7, 9, 21, 35, 56, 63, 64, 88, 99, 101, 500, 700, 999};
      LongBitVector vector = new LongBitVector(1000);
      for (long setBit : setBits) {
        vector.set(setBit);
      }
  
      for (int i = 0; i < 1000; i++) {
        if (Arrays.binarySearch(setBits, i) >= 0) {
          Assert.assertTrue(vector.get(i));
        } else {
          Assert.assertFalse(vector.get(i));
        }
      }
    }
  
    @Test
    public void setTest2() {
      String s = "101100100 01110110 11001010 11111001 01001110 10111011 01111010 11010100";
      LongBitVector vector = LongBitVector.fromBinaryString(s);
      s = s.replaceAll(" ", "");
      for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '1') {
          Assert.assertTrue(vector.get(i));
        } else {
          Assert.assertFalse(vector.get(i));
        }
      }
    }
  
    @Test
    public void setGetLastBitIndex() {
      String s = "101100100 01110110 11001010 11111001 01001110 10111011 01111010 11010100";
      LongBitVector vector = LongBitVector.fromBinaryString(s);
      s = s.replaceAll(" ", "");
      assertEquals(s.length() - 3, vector.getLastBitIndex(true));
      assertEquals(s.length() - 1, vector.getLastBitIndex(false));
      vector = LongBitVector.fromBinaryString("000011");
      assertEquals(5, vector.getLastBitIndex(true));
      assertEquals(3, vector.getLastBitIndex(false));
      vector = LongBitVector.fromBinaryString("0000");
      assertEquals(-1, vector.getLastBitIndex(true));
      assertEquals(3, vector.getLastBitIndex(false));
      vector = LongBitVector.fromBinaryString("1111");
      assertEquals(-1, vector.getLastBitIndex(false));
      assertEquals(3, vector.getLastBitIndex(true));
    }
  
  
    @Test
    public void getResetTest() {
      long[] resetBits = {1, 2, 3, 7, 9, 21, 35, 56, 63, 64, 88, 99, 101, 500, 700, 999};
      LongBitVector vector = new LongBitVector(1000);
      vector.add(1000, true);
      for (long resetBit : resetBits) {
        vector.clear(resetBit);
      }
  
      for (int i = 0; i < 1000; i++) {
        if (Arrays.binarySearch(resetBits, i) >= 0) {
          Assert.assertFalse(vector.get(i));
        } else {
          Assert.assertTrue(vector.get(i));
        }
      }
    }
  
    @Test
    public void appendTestBoolean() {
      LongBitVector vector = new LongBitVector(0);
      vector.add(true);
      vector.add(true);
      vector.add(false);
      vector.add(true);
      assertEquals(4, vector.size());
      for (int i = 0; i < 1000; i++) {
        vector.add(true);
      }
      assertEquals(1004, vector.size());
    }
  
    @Test
    public void appendTestInteger() {
  
      LongBitVector vector = new LongBitVector(0);
      vector.add(0x0000ffff, 16);
      assertEquals(16, vector.size());
      vector.add(0x0000ffff, 32);
      assertEquals(48, vector.size());
  
      LongBitVector vector2 = new LongBitVector(64);
      vector2.add(64, false);
      vector2.add(0xff, 6);
      assertEquals(70, vector2.size());
      Assert.assertFalse(vector2.get(63));
      for (int i = 64; i < 70; i++) {
        Assert.assertTrue(vector2.get(i));
      }
    }
  
    @Test
    public void fillTest() {
      LongBitVector vector = new LongBitVector(128);
      vector.add(128, false);
      for (int i = 0; i < 128; i++) {
        Assert.assertTrue(!vector.get(i));
      }
      vector.fill(true);
      for (int i = 0; i < 128; i++) {
        Assert.assertTrue(vector.get(i));
      }
      vector.fill(false);
      for (int i = 0; i < 128; i++) {
        Assert.assertTrue(!vector.get(i));
      }
  
      // check filling with 1 does not effect the overflow smoothnlp.core.bits of the last long.
      vector = new LongBitVector(3);
      vector.add(3, false);
      vector.fill(true);
      assertEquals(vector.getLongArray()[0], 7);
  
    }
  
    @Test
    @Ignore("Not a test.")
    public void performanceTest() {
      int itCount = 5;
      Random rnd = new Random(0xbeefcafe);
      final int size = 20000000;
      int[] oneIndexes = new int[size];
      int k = 0;
      for (int i = 0; i < oneIndexes.length; i++) {
        if (rnd.nextDouble() > 0.33) {
          oneIndexes[k] = i;
          k++;
        }
      }
      Arrays.copyOf(oneIndexes, k);
      LongBitVector vector = new LongBitVector(size);
  
      for (int i = 0; i < itCount; i++) {
        Stopwatch sw = Stopwatch.createStarted();
        for (int oneIndex : oneIndexes) {
          vector.set(oneIndex);
        }
        for (int oneIndex : oneIndexes) {
          vector.clear(oneIndex);
        }
        System.out.println(sw.elapsed(TimeUnit.MILLISECONDS));
      }
    }
  
    @Test
    public void getLongPiece() {
      LongBitVector vector = new LongBitVector(128);
      vector.add(128, false);
      vector.set(new long[]{0, 2, 4, 7});
      Long result = vector.getLong(0, 5);
      assertEquals("10101", Long.toBinaryString(result));
      vector.set(new long[]{62, 64, 65});
      result = vector.getLong(62, 5);
      assertEquals("1101", Long.toBinaryString(result));
      vector.fill(true);
      vector.clear(new long[]{63, 68});
      assertEquals("101111011", Long.toBinaryString(vector.getLong(61, 9)));
      assertEquals("1", Long.toBinaryString(vector.getLong(61, 1)));
      assertEquals("0", Long.toBinaryString(vector.getLong(63, 1)));
      assertEquals(Long.toBinaryString(0xbfffffffffffffffL),
          Long.toBinaryString(vector.getLong(1, 64)));
    }
  }
  