View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.bloomfilter;
18  
19  import static org.junit.Assert.assertNotEquals;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import org.junit.jupiter.api.Test;
26  
27  public class BitMapTest {
28  
29      /**
30       * Assert the {@link BitMap#mod(long, int)} method functions as an unsigned modulus.
31       *
32       * @param dividend the dividend
33       * @param divisor the divisor
34       */
35      private void assertMod(final long dividend, final int divisor) {
36          assertTrue(divisor > 0 && divisor <= Integer.MAX_VALUE,
37              "Incorrect usage. Divisor must be strictly positive.");
38          assertEquals((int) Long.remainderUnsigned(dividend, divisor), BitMap.mod(dividend, divisor),
39              () -> String.format("failure with dividend=%s and divisor=%s.", dividend, divisor));
40      }
41  
42      @Test
43      public final void testContains() {
44          final long[] bitMaps = new long[1];
45  
46          for (int i = 0; i < 64; i++) {
47              bitMaps[0] = 0L;
48              BitMap.set(bitMaps, i);
49              for (int j = 0; j < 64; j++) {
50                  if (j == i) {
51                      assertTrue(BitMap.contains(bitMaps, j), String.format("Failed at index: %d for %d", i, j));
52                  } else {
53                      assertFalse(BitMap.contains(bitMaps, j), String.format("Failed at index %d for %d", i, j));
54                  }
55              }
56          }
57  
58          // test boundary conditions
59          long[] ary = new long[1];
60  
61          final long[] aryT = ary;
62          assertThrows(ArrayIndexOutOfBoundsException.class, () -> BitMap.contains(aryT, -1));
63          assertFalse(BitMap.contains(ary, 0));
64          ary[0] = 0x01;
65          assertTrue(BitMap.contains(ary, 0));
66  
67          assertFalse(BitMap.contains(ary, 63));
68          ary[0] = 1L << 63;
69          assertTrue(BitMap.contains(ary, 63));
70          assertThrows(ArrayIndexOutOfBoundsException.class, () -> BitMap.contains(aryT, 64));
71  
72          ary = new long[2];
73          assertFalse(BitMap.contains(ary, 64));
74          ary[1] = 1;
75          assertTrue(BitMap.contains(ary, 64));
76      }
77  
78      @Test
79      public final void testGetLongBit() {
80          assertEquals(1, BitMap.getLongBit(0));
81          assertEquals(0x8000000000000000L, BitMap.getLongBit(63));
82          assertEquals(1, BitMap.getLongBit(64));
83          assertEquals(0x8000000000000000L, BitMap.getLongBit(127));
84          assertEquals(1, BitMap.getLongBit(128));
85      }
86  
87      @Test
88      public final void testGetLongIndex() {
89          assertEquals(0, BitMap.getLongIndex(0));
90          assertEquals(0, BitMap.getLongIndex(63));
91          assertEquals(1, BitMap.getLongIndex(64));
92          assertEquals(1, BitMap.getLongIndex(127));
93          assertEquals(2, BitMap.getLongIndex(128));
94      }
95  
96      @Test
97      public void testMod() {
98          for (final long dividend : new long[] {0, -1, -2, -3, -6378683, -23567468136887892L,
99              Long.MIN_VALUE, 345, 678686, 67868768686878924L, Long.MAX_VALUE, Long.MAX_VALUE - 1}) {
100             for (final int divisor : new int[] {1, 2, 3, 5, 13, Integer.MAX_VALUE, Integer.MAX_VALUE - 1}) {
101                 assertMod(dividend, divisor);
102             }
103         }
104     }
105 
106     @Test
107     public void testModEdgeCases() {
108         for (final long dividend : new long[] {0, -1, 1, Long.MAX_VALUE}) {
109             assertThrows(ArithmeticException.class, () -> BitMap.mod(dividend, 0));
110         }
111         assertNotEquals(Math.floorMod(5, -1), BitMap.mod(5, -1));
112     }
113 
114     @Test
115     public final void testNumberOfBitMaps() {
116         assertEquals(0, BitMap.numberOfBitMaps(0), "Number of bits 0");
117         for (int i = 1; i < 65; i++) {
118             assertEquals(1, BitMap.numberOfBitMaps(i), String.format("Number of bits %d", i));
119         }
120         for (int i = 65; i < 129; i++) {
121             assertEquals(2, BitMap.numberOfBitMaps(i), String.format("Number of bits %d", i));
122         }
123         assertEquals(3, BitMap.numberOfBitMaps(129), "Number of bits 129");
124     }
125 
126     @Test
127     public final void testSet() {
128         final long[] bitMaps = new long[BitMap.numberOfBitMaps(129)];
129         for (int i = 0; i < 129; i++) {
130             BitMap.set(bitMaps, i);
131             assertTrue(BitMap.contains(bitMaps, i), String.format("Failed at index: %d", i));
132         }
133         assertEquals(0xFFFFFFFFFFFFFFFFL, bitMaps[0]);
134         assertEquals(0xFFFFFFFFFFFFFFFFL, bitMaps[1]);
135         assertEquals(1L, bitMaps[2]);
136     }
137 }