Skip to content

Commit 001b377

Browse files
committed
adds 32-bit java.util.BitSet extends javajs.util.BS
1 parent ea586be commit 001b377

File tree

2 files changed

+138
-8
lines changed

2 files changed

+138
-8
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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+
18+
package java.util;
19+
20+
import javajs.util.BS;
21+
22+
public class BitSet extends BS {
23+
public BitSet() {
24+
super();
25+
}
26+
27+
public BitSet(int nbits) {
28+
super();
29+
init(nbits);
30+
}
31+
32+
public void flip(int bitIndex) {
33+
if (bitIndex < 0)
34+
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
35+
int wordIndex = wordIndex(bitIndex);
36+
expandTo(wordIndex);
37+
words[wordIndex] ^= (1 << bitIndex); // Restores invariants
38+
}
39+
public void flip(int fromIndex, int toIndex) {
40+
if (fromIndex == toIndex)
41+
return;
42+
43+
// Increase capacity if necessary
44+
int startWordIndex = wordIndex(fromIndex);
45+
int endWordIndex = wordIndex(toIndex - 1);
46+
expandTo(endWordIndex);
47+
48+
int firstWordMask = WORD_MASK << fromIndex;
49+
int lastWordMask = WORD_MASK >>> -toIndex;
50+
if (startWordIndex == endWordIndex) {
51+
// Case 1: One word
52+
words[startWordIndex] ^= (firstWordMask & lastWordMask);
53+
} else {
54+
// Case 2: Multiple words
55+
// Handle first word
56+
words[startWordIndex] ^= firstWordMask;
57+
58+
// Handle intermediate words, if any
59+
for (int i = startWordIndex + 1; i < endWordIndex; i++)
60+
words[i] ^= WORD_MASK;
61+
62+
// Handle last word (restores invariants)
63+
words[endWordIndex] ^= lastWordMask;
64+
}
65+
}
66+
public void set(int bitIndex, boolean value) {
67+
setBitTo(bitIndex, value);
68+
}
69+
public void set(int fromIndex, int toIndex) {
70+
setBits(fromIndex, toIndex);
71+
}
72+
public void set(int fromIndex, int toIndex, boolean value) {
73+
if (value)
74+
set(fromIndex, toIndex);
75+
else
76+
clear(fromIndex, toIndex);
77+
}
78+
public void clear(int fromIndex, int toIndex) {
79+
clearBits(fromIndex, toIndex);
80+
}
81+
public void clear() {
82+
clearAll();
83+
}
84+
public BitSet get(int fromIndex, int toIndex) {
85+
//checkRange(fromIndex, toIndex);
86+
87+
//checkInvariants();
88+
89+
int len = length();
90+
91+
// If no set bits in range return empty bitset
92+
if (len <= fromIndex || fromIndex == toIndex)
93+
return new BitSet(0);
94+
95+
// An optimization
96+
if (toIndex > len)
97+
toIndex = len;
98+
99+
BitSet result = new BitSet(toIndex - fromIndex);
100+
int targetWords = wordIndex(toIndex - fromIndex - 1) + 1;
101+
int sourceIndex = wordIndex(fromIndex);
102+
boolean wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0);
103+
104+
// Process all words but the last word
105+
for (int i = 0; i < targetWords - 1; i++, sourceIndex++)
106+
result.words[i] = wordAligned ? words[sourceIndex] :
107+
(words[sourceIndex] >>> fromIndex) |
108+
(words[sourceIndex+1] << -fromIndex);
109+
110+
// Process the last word
111+
int lastWordMask = WORD_MASK >>> -toIndex;
112+
result.words[targetWords - 1] =
113+
((toIndex-1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK)
114+
? /* straddles source words */
115+
((words[sourceIndex] >>> fromIndex) |
116+
(words[sourceIndex+1] & lastWordMask) << -fromIndex)
117+
:
118+
((words[sourceIndex] & lastWordMask) >>> fromIndex);
119+
120+
// Set wordsInUse correctly
121+
result.wordsInUse = targetWords;
122+
result.recalculateWordsInUse();
123+
//result.checkInvariants();
124+
125+
return result;
126+
}
127+
128+
129+
}

sources/net.sf.j2s.java.core/src/javajs/util/BS.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,28 @@
7979
*/
8080
public class BS implements Cloneable, JSONEncodable {
8181
/*
82-
* BitSets are packed into arrays of "words."
82+
* BitSets are packed into arrays of "wrangeords."
8383
*
8484
* An int, which consists of 32 bits, requiring 5 address bits, is used for
8585
* the JavaScript port.
8686
*/
8787
private final static int ADDRESS_BITS_PER_WORD = 5;
8888
private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
89+
protected final static int BIT_INDEX_MASK = BITS_PER_WORD - 1;
8990

9091
/* Used to shift left or right for a partial word mask */
91-
private static final int WORD_MASK = 0xffffffff;
92+
protected static final int WORD_MASK = 0xffffffff;
9293

9394

9495
/**
9596
* The internal field corresponding to the serialField "bits".
9697
*/
97-
private int[] words;
98+
protected int[] words;
9899

99100
/**
100101
* The number of words in the logical size of this BitSet.
101102
*/
102-
private transient int wordsInUse = 0;
103+
protected transient int wordsInUse = 0;
103104

104105
/**
105106
* Whether the size of "words" is user-specified. If so, we assume the user
@@ -115,7 +116,7 @@ public class BS implements Cloneable, JSONEncodable {
115116
* @param bitIndex
116117
* @return b
117118
*/
118-
private static int wordIndex(int bitIndex) {
119+
protected static int wordIndex(int bitIndex) {
119120
return bitIndex >> ADDRESS_BITS_PER_WORD;
120121
}
121122

@@ -124,7 +125,7 @@ private static int wordIndex(int bitIndex) {
124125
* WARNING:This method assumes that the number of words actually in use is
125126
* less than or equal to the current value of wordsInUse!
126127
*/
127-
private void recalculateWordsInUse() {
128+
protected void recalculateWordsInUse() {
128129
// Traverse the bitset until a used word is found
129130
int i;
130131
for (i = wordsInUse - 1; i >= 0; i--)
@@ -159,7 +160,7 @@ public static BS newN(int nbits) {
159160
return bs;
160161
}
161162

162-
private void init(int nbits) {
163+
protected void init(int nbits) {
163164
// nbits can't be negative; size 0 is OK
164165
if (nbits < 0)
165166
throw new NegativeArraySizeException("nbits < 0: " + nbits);
@@ -194,7 +195,7 @@ private void ensureCapacity(int wordsRequired) {
194195
* @param wordIndex
195196
* the index to be accommodated.
196197
*/
197-
private void expandTo(int wordIndex) {
198+
protected void expandTo(int wordIndex) {
198199
int wordsRequired = wordIndex + 1;
199200
if (wordsInUse < wordsRequired) {
200201
ensureCapacity(wordsRequired);

0 commit comments

Comments
 (0)