comparison src/main/gov/nasa/jpf/util/BitSet256.java @ 0:61d41facf527

initial v8 import (history reset)
author Peter Mehlitz <Peter.C.Mehlitz@nasa.gov>
date Fri, 23 Jan 2015 10:14:01 -0800
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:61d41facf527
1 /*
2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
4 * All rights reserved.
5 *
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0.
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package gov.nasa.jpf.util;
20
21
22 /**
23 * a fixed size BitSet with 256 bits.
24 *
25 * The main motivation for this class is to minimize memory size while maximizing
26 * performance and keeping a java.util.BitSet compatible interface. The only
27 * deviation from the standard BitSet is that we assume more cardinality() calls
28 * than set()/clear() calls, i.e. we want to cache this value
29 *
30 * Instances of this class do not allocate any additional memory, we keep all
31 * data in builtin type fields
32 */
33 public class BitSet256 extends AbstractFixedBitSet {
34
35 public static final int INDEX_MASK = 0xffffff00;
36
37 long l0, l1, l2, l3;
38
39 public BitSet256 (){
40 // nothing in here
41 }
42
43 public BitSet256 (int i){
44 set(i);
45 }
46
47 public BitSet256 (int... idx){
48 for (int i : idx){
49 set(i);
50 }
51 }
52
53 private final int computeCardinality (){
54 int n= Long.bitCount(l0);
55 n += Long.bitCount(l1);
56 n += Long.bitCount(l2);
57 n += Long.bitCount(l3);
58 return n;
59 }
60
61 //--- public interface (much like java.util.BitSet)
62
63 @Override
64 public void set (int i){
65 if ((i & INDEX_MASK) == 0) {
66 long bitPattern = (1L << i);
67
68 switch (i >> 6) {
69 case 0:
70 if ((l0 & bitPattern) == 0L) {
71 cardinality++;
72 l0 |= bitPattern;
73 }
74 break;
75 case 1:
76 if ((l1 & bitPattern) == 0L) {
77 cardinality++;
78 l1 |= bitPattern;
79 }
80 break;
81 case 2:
82 if ((l2 & bitPattern) == 0L) {
83 cardinality++;
84 l2 |= bitPattern;
85 }
86 break;
87 case 3:
88 if ((l3 & bitPattern) == 0L) {
89 cardinality++;
90 l3 |= bitPattern;
91 }
92 }
93 } else {
94 throw new IndexOutOfBoundsException("BitSet256 index out of range: " + i);
95 }
96 }
97
98 @Override
99 public void clear (int i){
100 if ((i & INDEX_MASK) == 0) {
101 long bitPattern = (1L << i);
102
103 switch (i >> 6) {
104 case 0:
105 if ((l0 & bitPattern) != 0L) {
106 cardinality--;
107 l0 &= ~bitPattern;
108 }
109 break;
110 case 1:
111 if ((l1 & bitPattern) != 0L) {
112 cardinality--;
113 l1 &= ~bitPattern;
114 }
115 break;
116 case 2:
117 if ((l2 & bitPattern) != 0L) {
118 cardinality--;
119 l2 &= ~bitPattern;
120 }
121 break;
122 case 3:
123 if ((l3 & bitPattern) != 0L) {
124 cardinality--;
125 l3 &= ~bitPattern;
126 }
127 }
128 } else {
129 throw new IndexOutOfBoundsException("BitSet256 index out of range: " + i);
130 }
131 }
132
133 @Override
134 public boolean get (int i){
135 if ((i & INDEX_MASK) == 0) {
136 long bitPattern = (1L << i);
137
138 switch (i >> 6) {
139 case 0:
140 return ((l0 & bitPattern) != 0);
141 case 1:
142 return ((l1 & bitPattern) != 0);
143 case 2:
144 return ((l2 & bitPattern) != 0);
145 case 3:
146 return ((l3 & bitPattern) != 0);
147 }
148 }
149
150 throw new IndexOutOfBoundsException("BitSet256 index out of range: " + i);
151 }
152
153 @Override
154 public int size() {
155 return 256;
156 }
157
158
159 /**
160 * number of bits we can store
161 */
162 @Override
163 public int capacity() {
164 return 256;
165 }
166
167 /**
168 * index of highest set bit + 1
169 */
170 @Override
171 public int length() {
172 if (l3 != 0){
173 return 256 - Long.numberOfLeadingZeros(l3);
174 } else if (l2 != 0){
175 return 192 - Long.numberOfLeadingZeros(l2);
176 } else if (l1 != 0){
177 return 128 - Long.numberOfLeadingZeros(l1);
178 } else if (l1 != 0){
179 return 64 - Long.numberOfLeadingZeros(l0);
180 } else {
181 return 0;
182 }
183 }
184
185 @Override
186 public void clear() {
187 l0 = l1 = l2 = l3 = 0L;
188 cardinality = 0;
189 }
190
191
192 @Override
193 public int nextSetBit (int fromIdx){
194 if ((fromIdx & INDEX_MASK) == 0) {
195 int i;
196 int i0 = fromIdx & 0x3f;
197 switch (fromIdx >> 6){
198 case 0:
199 if ((i=Long.numberOfTrailingZeros(l0 & (0xffffffffffffffffL << i0))) <64) return i;
200 if ((i=Long.numberOfTrailingZeros(l1)) <64) return i + 64;
201 if ((i=Long.numberOfTrailingZeros(l2)) <64) return i + 128;
202 if ((i=Long.numberOfTrailingZeros(l3)) <64) return i + 192;
203 break;
204 case 1:
205 if ((i=Long.numberOfTrailingZeros(l1 & (0xffffffffffffffffL << i0))) <64) return i + 64;
206 if ((i=Long.numberOfTrailingZeros(l2)) <64) return i + 128;
207 if ((i=Long.numberOfTrailingZeros(l3)) <64) return i + 192;
208 break;
209 case 2:
210 if ((i=Long.numberOfTrailingZeros(l2 & (0xffffffffffffffffL << i0))) <64) return i + 128;
211 if ((i=Long.numberOfTrailingZeros(l3)) <64) return i + 192;
212 break;
213 case 3:
214 if ((i=Long.numberOfTrailingZeros(l3 & (0xffffffffffffffffL << i0))) <64) return i + 192;
215 }
216
217 return -1;
218
219 } else {
220 //throw new IndexOutOfBoundsException("BitSet256 index out of range: " + fromIdx);
221 return -1;
222 }
223 }
224
225 @Override
226 public int nextClearBit (int fromIdx){
227 if ((fromIdx & INDEX_MASK) == 0) {
228 int i;
229 int i0 = fromIdx & 0x3f;
230 switch (fromIdx >> 6){
231 case 0:
232 if ((i=Long.numberOfTrailingZeros(~l0 & (0xffffffffffffffffL << i0))) <64) return i;
233 if ((i=Long.numberOfTrailingZeros(~l1)) <64) return i + 64;
234 if ((i=Long.numberOfTrailingZeros(~l2)) <64) return i + 128;
235 if ((i=Long.numberOfTrailingZeros(~l3)) <64) return i + 192;
236 break;
237 case 1:
238 if ((i=Long.numberOfTrailingZeros(~l1 & (0xffffffffffffffffL << i0))) <64) return i + 64;
239 if ((i=Long.numberOfTrailingZeros(~l2)) <64) return i + 128;
240 if ((i=Long.numberOfTrailingZeros(~l3)) <64) return i + 192;
241 break;
242 case 2:
243 if ((i=Long.numberOfTrailingZeros(~l2 & (0xffffffffffffffffL << i0))) <64) return i + 128;
244 if ((i=Long.numberOfTrailingZeros(~l3)) <64) return i + 192;
245 break;
246 case 3:
247 if ((i=Long.numberOfTrailingZeros(~l3 & (0xffffffffffffffffL << i0))) <64) return i + 192;
248 }
249
250 return -1;
251
252 } else {
253 //throw new IndexOutOfBoundsException("BitSet256 index out of range: " + fromIdx);
254 return -1;
255 }
256 }
257
258 public void and (BitSet256 other){
259 l0 &= other.l0;
260 l1 &= other.l1;
261 l2 &= other.l2;
262 l3 &= other.l3;
263
264 cardinality = computeCardinality();
265 }
266
267 public void andNot (BitSet256 other){
268 l0 &= ~other.l0;
269 l1 &= ~other.l1;
270 l2 &= ~other.l2;
271 l3 &= ~other.l3;
272
273 cardinality = computeCardinality();
274 }
275
276 public void or (BitSet256 other){
277 l0 |= other.l0;
278 l1 |= other.l1;
279 l2 |= other.l2;
280 l3 |= other.l3;
281
282 cardinality = computeCardinality();
283 }
284
285 @Override
286 public boolean equals (Object o){
287 if (o instanceof BitSet256){
288 BitSet256 other = (BitSet256)o;
289 if (l0 != other.l0) return false;
290 if (l1 != other.l1) return false;
291 if (l2 != other.l2) return false;
292 if (l3 != other.l3) return false;
293 return true;
294 } else {
295 // <2do> we could compare to a normal java.util.BitSet here
296 return false;
297 }
298 }
299
300 /**
301 * answer the same hashCodes as java.util.BitSet
302 */
303 @Override
304 public int hashCode() {
305 long hc = 1234;
306 hc ^= l0;
307 hc ^= l1*2;
308 hc ^= l2*3;
309 hc ^= l3*4;
310 return (int) ((hc >>32) ^ hc);
311 }
312
313 @Override
314 public void hash (HashData hd){
315 hd.add(l0);
316 hd.add(l1);
317 hd.add(l2);
318 hd.add(l3);
319 }
320
321 @Override
322 public String toString() {
323 StringBuilder sb = new StringBuilder();
324 sb.append('{');
325
326 boolean first = true;
327 for (int i=nextSetBit(0); i>= 0; i = nextSetBit(i+1)){
328 if (!first){
329 sb.append(',');
330 } else {
331 first = false;
332 }
333 sb.append(i);
334 }
335
336 sb.append('}');
337
338 return sb.toString();
339 }
340 }