3232 * in the set can be quite large, reaching over 100000 in extreme cases. Since lifetime analysis
3333 * uses 4 bitsets per block and the number of blocks can also be very large, space efficiency can
3434 * play a major role in performance. A simple sorted list of integers performs significantly better
35- * for large numbers of intervals and blocks while only modestly affecting the perform for small
36- * values .
35+ * for large numbers of intervals and blocks while having no measurable performance impact for small
36+ * numbers of intervals when compared to {@link java.util.BitSet} .
3737 */
3838public class SparseBitSet {
3939
@@ -52,8 +52,14 @@ public class SparseBitSet {
5252 */
5353 private int iterator = 0 ;
5454
55+ /**
56+ * The sets are almost never empty and commonly contain just a few elements so start at a small
57+ * initial size.
58+ */
59+ static final int INITIAL_SIZE = 4 ;
60+
5561 public SparseBitSet () {
56- elements = new int [4 ];
62+ elements = new int [INITIAL_SIZE ];
5763 }
5864
5965 public SparseBitSet (SparseBitSet other ) {
@@ -75,9 +81,10 @@ public void addAll(SparseBitSet other) {
7581 size = other .size ;
7682 } else {
7783 ensureCapacity (other .size );
78- int otherIndex = 0 ;
7984 int originalSize = size ;
80- for (int index = 0 ; index < originalSize && otherIndex < other .size ;) {
85+ int index = 0 ;
86+ int otherIndex = 0 ;
87+ while (index < originalSize && otherIndex < other .size ) {
8188 int value = elements [index ];
8289 int otherValue = other .elements [otherIndex ];
8390 if (value == otherValue ) {
@@ -108,17 +115,13 @@ public void addAll(SparseBitSet other) {
108115
109116 private void ensureCapacity (int minCapacity ) {
110117 if (minCapacity > elements .length ) {
111- grow (minCapacity );
118+ int oldCapacity = elements .length ;
119+ elements = Arrays .copyOf (elements , oldCapacity + Math .max (minCapacity - oldCapacity , oldCapacity >> 1 ));
112120 }
113121 }
114122
115- private void grow (int minCapacity ) {
116- int oldCapacity = elements .length ;
117- elements = Arrays .copyOf (elements , oldCapacity + Math .max (minCapacity - oldCapacity , oldCapacity >> 1 ));
118- }
119-
120123 /**
121- * Remove all the value that are seting {@ocde other} from this set.
124+ * Remove all the values that are set in {@ocde other} from this set.
122125 */
123126 public void removeAll (SparseBitSet other ) {
124127 int otherIndex = 0 ;
@@ -173,12 +176,17 @@ public boolean get(int bitIndex) {
173176 * Sets the bit at the specified index to {@code true}.
174177 */
175178 public void set (int bitIndex ) {
179+ if (bitIndex < 0 ) {
180+ throw new IllegalArgumentException ("negative values are not permitted" );
181+ }
176182 int location = Arrays .binarySearch (elements , 0 , size , bitIndex );
177183 if (location < 0 ) {
184+ /*
185+ * If an element isn't found, binarySearch returns the proper insertion location as
186+ * (-(insertion point) - 1 so reverse this computation and insert it.
187+ */
178188 int insertPoint = -(location + 1 );
179- if (size == elements .length ) {
180- grow (size + 1 );
181- }
189+ ensureCapacity (size + 1 );
182190 System .arraycopy (elements , insertPoint , elements , insertPoint + 1 , size - insertPoint );
183191 elements [insertPoint ] = bitIndex ;
184192 size ++;
0 commit comments