125 this(unassignedBits, BitsState.getState(unassignedBits, reset)); |
108 this(unassignedBits, BitsState.getState(unassignedBits, reset)); |
126 } |
109 } |
127 |
110 |
128 /** Construct a set consisting initially of given bit vector. |
111 /** Construct a set consisting initially of given bit vector. |
129 */ |
112 */ |
130 private Bits(int[] bits, BitsState initState) { |
113 protected Bits(int[] bits, BitsState initState) { |
131 this.bits = bits; |
114 this.bits = bits; |
132 this.currentState = initState; |
115 this.currentState = initState; |
133 switch (initState) { |
116 switch (initState) { |
134 case UNKNOWN: |
117 case UNKNOWN: |
135 reset(); //this will also set current state; |
118 this.bits = null; |
136 break; |
119 break; |
137 case NORMAL: |
120 case NORMAL: |
138 Assert.check(bits != unassignedBits); |
121 Assert.check(bits != unassignedBits); |
139 lastOperation = INIT; |
|
140 break; |
122 break; |
141 } |
123 } |
142 } |
124 } |
143 |
125 |
144 /** This method will be called after any operation that causes a change to |
126 protected void sizeTo(int len) { |
145 * the bits. Subclasses can thus override it in order to extract information |
|
146 * from the changes produced to the bits by the given operation. |
|
147 */ |
|
148 public void changed() {} |
|
149 |
|
150 private void sizeTo(int len) { |
|
151 if (bits.length < len) { |
127 if (bits.length < len) { |
152 bits = Arrays.copyOf(bits, len); |
128 bits = Arrays.copyOf(bits, len); |
153 } |
129 } |
154 } |
130 } |
155 |
131 |
156 /** This set = {}. |
132 /** This set = {}. |
157 */ |
133 */ |
158 public void clear() { |
134 public void clear() { |
159 Assert.check(currentState != BitsState.UNKNOWN); |
135 Assert.check(currentState != BitsState.UNKNOWN); |
160 oldBits = bits; |
136 for (int i = 0; i < bits.length; i++) { |
161 lastOperation = CLEAR; |
137 bits[i] = 0; |
162 for (int i = 0; i < bits.length; i++) bits[i] = 0; |
138 } |
163 changed(); |
|
164 currentState = BitsState.NORMAL; |
139 currentState = BitsState.NORMAL; |
165 } |
140 } |
166 |
141 |
167 public void reset() { |
142 public void reset() { |
|
143 internalReset(); |
|
144 } |
|
145 |
|
146 protected void internalReset() { |
168 bits = null; |
147 bits = null; |
169 oldBits = null; |
|
170 currentState = BitsState.UNKNOWN; |
148 currentState = BitsState.UNKNOWN; |
171 } |
149 } |
172 |
150 |
173 public boolean isReset() { |
151 public boolean isReset() { |
174 return currentState == BitsState.UNKNOWN; |
152 return currentState == BitsState.UNKNOWN; |
175 } |
153 } |
176 |
154 |
177 public Bits assign(Bits someBits) { |
155 public Bits assign(Bits someBits) { |
178 lastOperation = ASSIGN; |
|
179 oldBits = bits; |
|
180 bits = someBits.dup().bits; |
156 bits = someBits.dup().bits; |
181 changed(); |
|
182 currentState = BitsState.NORMAL; |
157 currentState = BitsState.NORMAL; |
183 return this; |
158 return this; |
184 } |
159 } |
185 |
160 |
186 /** Return a copy of this set. |
161 /** Return a copy of this set. |
187 */ |
162 */ |
188 private Bits dup() { |
163 public Bits dup() { |
189 Assert.check(currentState != BitsState.UNKNOWN); |
164 Assert.check(currentState != BitsState.UNKNOWN); |
190 Bits tmp = new Bits(); |
165 Bits tmp = new Bits(); |
|
166 tmp.bits = dupBits(); |
|
167 currentState = BitsState.NORMAL; |
|
168 return tmp; |
|
169 } |
|
170 |
|
171 protected int[] dupBits() { |
|
172 int [] result; |
191 if (currentState != BitsState.NORMAL) { |
173 if (currentState != BitsState.NORMAL) { |
192 tmp.bits = bits; |
174 result = bits; |
193 } else { |
175 } else { |
194 tmp.bits = new int[bits.length]; |
176 result = new int[bits.length]; |
195 System.arraycopy(bits, 0, tmp.bits, 0, bits.length); |
177 System.arraycopy(bits, 0, result, 0, bits.length); |
196 } |
178 } |
197 currentState = BitsState.NORMAL; |
179 return result; |
198 return tmp; |
|
199 } |
180 } |
200 |
181 |
201 /** Include x in this set. |
182 /** Include x in this set. |
202 */ |
183 */ |
203 public void incl(int x) { |
184 public void incl(int x) { |
204 Assert.check(currentState != BitsState.UNKNOWN); |
185 Assert.check(currentState != BitsState.UNKNOWN); |
205 Assert.check(x >= 0); |
186 Assert.check(x >= 0, "Value of x " + x); |
206 oldBits = bits; |
|
207 lastOperation = INCL_BIT; |
|
208 sizeTo((x >>> wordshift) + 1); |
187 sizeTo((x >>> wordshift) + 1); |
209 bits[x >>> wordshift] = bits[x >>> wordshift] | |
188 bits[x >>> wordshift] = bits[x >>> wordshift] | |
210 (1 << (x & wordmask)); |
189 (1 << (x & wordmask)); |
211 changed(); |
|
212 currentState = BitsState.NORMAL; |
190 currentState = BitsState.NORMAL; |
213 } |
191 } |
214 |
192 |
215 |
193 |
216 /** Include [start..limit) in this set. |
194 /** Include [start..limit) in this set. |
217 */ |
195 */ |
218 public void inclRange(int start, int limit) { |
196 public void inclRange(int start, int limit) { |
219 Assert.check(currentState != BitsState.UNKNOWN); |
197 Assert.check(currentState != BitsState.UNKNOWN); |
220 oldBits = bits; |
|
221 lastOperation = INCL_RANGE; |
|
222 sizeTo((limit >>> wordshift) + 1); |
198 sizeTo((limit >>> wordshift) + 1); |
223 for (int x = start; x < limit; x++) { |
199 for (int x = start; x < limit; x++) { |
224 bits[x >>> wordshift] = bits[x >>> wordshift] | |
200 bits[x >>> wordshift] = bits[x >>> wordshift] | |
225 (1 << (x & wordmask)); |
201 (1 << (x & wordmask)); |
226 } |
202 } |
227 changed(); |
|
228 currentState = BitsState.NORMAL; |
203 currentState = BitsState.NORMAL; |
229 } |
204 } |
230 |
205 |
231 /** Exclude [start...end] from this set. |
206 /** Exclude [start...end] from this set. |
232 */ |
207 */ |
233 public void excludeFrom(int start) { |
208 public void excludeFrom(int start) { |
234 Assert.check(currentState != BitsState.UNKNOWN); |
209 Assert.check(currentState != BitsState.UNKNOWN); |
235 oldBits = bits; |
|
236 lastOperation = EXCL_RANGE; |
|
237 Bits temp = new Bits(); |
210 Bits temp = new Bits(); |
238 temp.sizeTo(bits.length); |
211 temp.sizeTo(bits.length); |
239 temp.inclRange(0, start); |
212 temp.inclRange(0, start); |
240 internalAndSet(temp); |
213 internalAndSet(temp); |
241 changed(); |
|
242 currentState = BitsState.NORMAL; |
214 currentState = BitsState.NORMAL; |
243 } |
215 } |
244 |
216 |
245 /** Exclude x from this set. |
217 /** Exclude x from this set. |
246 */ |
218 */ |
247 public void excl(int x) { |
219 public void excl(int x) { |
248 Assert.check(currentState != BitsState.UNKNOWN); |
220 Assert.check(currentState != BitsState.UNKNOWN); |
249 Assert.check(x >= 0); |
221 Assert.check(x >= 0); |
250 oldBits = bits; |
|
251 lastOperation = EXCL_BIT; |
|
252 sizeTo((x >>> wordshift) + 1); |
222 sizeTo((x >>> wordshift) + 1); |
253 bits[x >>> wordshift] = bits[x >>> wordshift] & |
223 bits[x >>> wordshift] = bits[x >>> wordshift] & |
254 ~(1 << (x & wordmask)); |
224 ~(1 << (x & wordmask)); |
255 changed(); |
|
256 currentState = BitsState.NORMAL; |
225 currentState = BitsState.NORMAL; |
257 } |
226 } |
258 |
227 |
259 /** Is x an element of this set? |
228 /** Is x an element of this set? |
260 */ |
229 */ |
287 |
253 |
288 /** this set = this set | xs. |
254 /** this set = this set | xs. |
289 */ |
255 */ |
290 public Bits orSet(Bits xs) { |
256 public Bits orSet(Bits xs) { |
291 Assert.check(currentState != BitsState.UNKNOWN); |
257 Assert.check(currentState != BitsState.UNKNOWN); |
292 oldBits = bits; |
|
293 lastOperation = OR_SET; |
|
294 sizeTo(xs.bits.length); |
258 sizeTo(xs.bits.length); |
295 for (int i = 0; i < xs.bits.length; i++) { |
259 for (int i = 0; i < xs.bits.length; i++) { |
296 bits[i] = bits[i] | xs.bits[i]; |
260 bits[i] = bits[i] | xs.bits[i]; |
297 } |
261 } |
298 changed(); |
|
299 currentState = BitsState.NORMAL; |
262 currentState = BitsState.NORMAL; |
300 return this; |
263 return this; |
301 } |
264 } |
302 |
265 |
303 /** this set = this set \ xs. |
266 /** this set = this set \ xs. |
304 */ |
267 */ |
305 public Bits diffSet(Bits xs) { |
268 public Bits diffSet(Bits xs) { |
306 Assert.check(currentState != BitsState.UNKNOWN); |
269 Assert.check(currentState != BitsState.UNKNOWN); |
307 oldBits = bits; |
|
308 lastOperation = DIFF_SET; |
|
309 for (int i = 0; i < bits.length; i++) { |
270 for (int i = 0; i < bits.length; i++) { |
310 if (i < xs.bits.length) { |
271 if (i < xs.bits.length) { |
311 bits[i] = bits[i] & ~xs.bits[i]; |
272 bits[i] = bits[i] & ~xs.bits[i]; |
312 } |
273 } |
313 } |
274 } |
314 changed(); |
|
315 currentState = BitsState.NORMAL; |
275 currentState = BitsState.NORMAL; |
316 return this; |
276 return this; |
317 } |
277 } |
318 |
278 |
319 /** this set = this set ^ xs. |
279 /** this set = this set ^ xs. |
320 */ |
280 */ |
321 public Bits xorSet(Bits xs) { |
281 public Bits xorSet(Bits xs) { |
322 Assert.check(currentState != BitsState.UNKNOWN); |
282 Assert.check(currentState != BitsState.UNKNOWN); |
323 oldBits = bits; |
|
324 lastOperation = XOR_SET; |
|
325 sizeTo(xs.bits.length); |
283 sizeTo(xs.bits.length); |
326 for (int i = 0; i < xs.bits.length; i++) { |
284 for (int i = 0; i < xs.bits.length; i++) { |
327 bits[i] = bits[i] ^ xs.bits[i]; |
285 bits[i] = bits[i] ^ xs.bits[i]; |
328 } |
286 } |
329 changed(); |
|
330 currentState = BitsState.NORMAL; |
287 currentState = BitsState.NORMAL; |
331 return this; |
288 return this; |
332 } |
289 } |
333 |
290 |
334 /** Count trailing zero bits in an int. Algorithm from "Hacker's |
291 /** Count trailing zero bits in an int. Algorithm from "Hacker's |
335 * Delight" by Henry S. Warren Jr. (figure 5-13) |
292 * Delight" by Henry S. Warren Jr. (figure 5-13) |
336 */ |
293 */ |
337 private static int trailingZeroBits(int x) { |
294 private static int trailingZeroBits(int x) { |
338 Assert.check(wordlen == 32); |
295 Assert.check(wordlen == 32); |
339 if (x == 0) return 32; |
296 if (x == 0) { |
|
297 return 32; |
|
298 } |
340 int n = 1; |
299 int n = 1; |
341 if ((x & 0xffff) == 0) { n += 16; x >>>= 16; } |
300 if ((x & 0xffff) == 0) { n += 16; x >>>= 16; } |
342 if ((x & 0x00ff) == 0) { n += 8; x >>>= 8; } |
301 if ((x & 0x00ff) == 0) { n += 8; x >>>= 8; } |
343 if ((x & 0x000f) == 0) { n += 4; x >>>= 4; } |
302 if ((x & 0x000f) == 0) { n += 4; x >>>= 4; } |
344 if ((x & 0x0003) == 0) { n += 2; x >>>= 2; } |
303 if ((x & 0x0003) == 0) { n += 2; x >>>= 2; } |
353 * }</pre> |
312 * }</pre> |
354 */ |
313 */ |
355 public int nextBit(int x) { |
314 public int nextBit(int x) { |
356 Assert.check(currentState != BitsState.UNKNOWN); |
315 Assert.check(currentState != BitsState.UNKNOWN); |
357 int windex = x >>> wordshift; |
316 int windex = x >>> wordshift; |
358 if (windex >= bits.length) return -1; |
317 if (windex >= bits.length) { |
|
318 return -1; |
|
319 } |
359 int word = bits[windex] & ~((1 << (x & wordmask))-1); |
320 int word = bits[windex] & ~((1 << (x & wordmask))-1); |
360 while (true) { |
321 while (true) { |
361 if (word != 0) |
322 if (word != 0) { |
362 return (windex << wordshift) + trailingZeroBits(word); |
323 return (windex << wordshift) + trailingZeroBits(word); |
|
324 } |
363 windex++; |
325 windex++; |
364 if (windex >= bits.length) return -1; |
326 if (windex >= bits.length) { |
|
327 return -1; |
|
328 } |
365 word = bits[windex]; |
329 word = bits[windex]; |
366 } |
330 } |
367 } |
331 } |
368 |
332 |
369 /** a string representation of this set. |
333 /** a string representation of this set. |
370 */ |
334 */ |
|
335 @Override |
371 public String toString() { |
336 public String toString() { |
372 if (bits.length > 0) { |
337 if (bits != null && bits.length > 0) { |
373 char[] digits = new char[bits.length * wordlen]; |
338 char[] digits = new char[bits.length * wordlen]; |
374 for (int i = 0; i < bits.length * wordlen; i++) |
339 for (int i = 0; i < bits.length * wordlen; i++) { |
375 digits[i] = isMember(i) ? '1' : '0'; |
340 digits[i] = isMember(i) ? '1' : '0'; |
|
341 } |
376 return new String(digits); |
342 return new String(digits); |
377 } else { |
343 } else { |
378 return "[]"; |
344 return "[]"; |
379 } |
345 } |
380 } |
346 } |