mirror of https://github.com/apache/lucene.git
implement OpenBitSet.set(from,to) and clear(from,to)
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@549909 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
02cadd8bb0
commit
aa705c5f14
|
@ -246,6 +246,35 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
bits[wordNum] |= bitmask;
|
||||
}
|
||||
|
||||
/** Sets a range of bits, expanding the set size if necessary
|
||||
*
|
||||
* @param startIndex lower index
|
||||
* @param endIndex one-past the last bit to set
|
||||
*/
|
||||
public void set(long startIndex, long endIndex) {
|
||||
if (endIndex <= startIndex) return;
|
||||
|
||||
int startWord = (int)(startIndex>>6);
|
||||
|
||||
// since endIndex is one past the end, this is index of the last
|
||||
// word to be changed.
|
||||
int endWord = expandingWordNum(endIndex-1);
|
||||
|
||||
long startmask = -1L << startIndex;
|
||||
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
|
||||
|
||||
if (startWord == endWord) {
|
||||
bits[startWord] |= (startmask & endmask);
|
||||
return;
|
||||
}
|
||||
|
||||
bits[startWord] |= startmask;
|
||||
Arrays.fill(bits, startWord+1, endWord, -1L);
|
||||
bits[endWord] |= endmask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected int expandingWordNum(long index) {
|
||||
int wordNum = (int)(index >> 6);
|
||||
if (wordNum>=wlen) {
|
||||
|
@ -283,7 +312,7 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
bits[wordNum] &= ~bitmask;
|
||||
}
|
||||
|
||||
/** clears a bit, allowing access beyond the current set size */
|
||||
/** clears a bit, allowing access beyond the current set size without changing the size.*/
|
||||
public void clear(long index) {
|
||||
int wordNum = (int)(index >> 6); // div 64
|
||||
if (wordNum>=wlen) return;
|
||||
|
@ -292,6 +321,43 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
bits[wordNum] &= ~bitmask;
|
||||
}
|
||||
|
||||
/** Clears a range of bits. Clearing past the end does not change the size of the set.
|
||||
*
|
||||
* @param startIndex lower index
|
||||
* @param endIndex one-past the last bit to clear
|
||||
*/
|
||||
public void clear(long startIndex, long endIndex) {
|
||||
if (endIndex <= startIndex) return;
|
||||
|
||||
int startWord = (int)(startIndex>>6);
|
||||
|
||||
// since endIndex is one past the end, this is index of the last
|
||||
// word to be changed.
|
||||
int endWord = (int)((endIndex-1)>>6);
|
||||
|
||||
long startmask = -1L << startIndex;
|
||||
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
|
||||
|
||||
// invert masks since we are clearing
|
||||
startmask = ~startmask;
|
||||
endmask = ~endmask;
|
||||
|
||||
if (startWord == endWord) {
|
||||
bits[startWord] &= (startmask | endmask);
|
||||
return;
|
||||
}
|
||||
|
||||
bits[startWord] &= startmask;
|
||||
|
||||
int middle = Math.min(wlen, endWord);
|
||||
Arrays.fill(bits, startWord+1, middle, 0L);
|
||||
if (endWord < wlen) {
|
||||
bits[endWord] &= endmask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Sets a bit and returns the previous value.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
|
@ -375,22 +441,21 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
if (endIndex <= startIndex) return;
|
||||
|
||||
int oldlen = wlen;
|
||||
ensureCapacity(endIndex);
|
||||
int startWord = (int)(startIndex>>6);
|
||||
int endWord = (int)(endIndex>>6);
|
||||
|
||||
/*** Grrr, java shifting wraps around so -1L>>64 == -1
|
||||
// since endIndex is one past the end, this is index of the last
|
||||
// word to be changed.
|
||||
int endWord = expandingWordNum(endIndex-1);
|
||||
|
||||
/*** Grrr, java shifting wraps around so -1L>>>64 == -1
|
||||
* for that reason, make sure not to use endmask if the bits to flip will
|
||||
* be zero in the last word (redefine endWord to be the last changed...)
|
||||
long startmask = -1L << (startIndex & 0x3f); // example: 11111...111000
|
||||
long endmask = -1L >>> (64-(endIndex & 0x3f)); // example: 00111...111111
|
||||
***/
|
||||
|
||||
long startmask = -1L << startIndex;
|
||||
long endmask = (endIndex&0x3f)==0 ? 0 : -1L >>> (64-endIndex);
|
||||
|
||||
if (this.wlen <= endWord) {
|
||||
this.wlen = endWord;
|
||||
if (endmask!=0) this.wlen++;
|
||||
}
|
||||
long endmask = -1L >>> -endIndex; // 64-endIndex is the same as -endIndex due to wrap
|
||||
|
||||
if (startWord == endWord) {
|
||||
bits[startWord] ^= (startmask & endmask);
|
||||
|
@ -399,7 +464,7 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
|
||||
bits[startWord] ^= startmask;
|
||||
|
||||
int middle = Math.min(oldlen,endWord);
|
||||
int middle = Math.min(oldlen, endWord);
|
||||
for (int i=startWord+1; i<middle; i++) {
|
||||
bits[i] = ~bits[i];
|
||||
}
|
||||
|
@ -408,9 +473,7 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
Arrays.fill(bits,middle,endWord,-1L);
|
||||
}
|
||||
|
||||
if (endmask!=0) {
|
||||
bits[endWord] ^= endmask;
|
||||
}
|
||||
bits[endWord] ^= endmask;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,7 +75,28 @@ public class TestOpenBitSet extends TestCase {
|
|||
if (sz>0) {
|
||||
int nOper = rand.nextInt(sz);
|
||||
for (int j=0; j<nOper; j++) {
|
||||
int idx;
|
||||
int idx;
|
||||
int idx1,idx2;
|
||||
|
||||
idx1 = rand.nextInt(sz);
|
||||
idx2 = rand.nextInt(sz);
|
||||
if (idx1>idx2) { idx=idx1; idx1=idx2; idx2=idx; }
|
||||
a.set(idx1,idx2);
|
||||
b.set(idx1,idx2);
|
||||
|
||||
idx1 = rand.nextInt(sz);
|
||||
idx2 = rand.nextInt(sz);
|
||||
if (idx1>idx2) { idx=idx1; idx1=idx2; idx2=idx; }
|
||||
a.clear(idx1,idx2);
|
||||
b.clear(idx1,idx2);
|
||||
|
||||
idx1 = rand.nextInt(sz);
|
||||
idx2 = rand.nextInt(sz);
|
||||
if (idx1>idx2) { idx=idx1; idx1=idx2; idx2=idx; }
|
||||
a.flip(idx1,idx2);
|
||||
b.flip(idx1,idx2);
|
||||
|
||||
|
||||
idx = rand.nextInt(sz);
|
||||
a.set(idx);
|
||||
b.fastSet(idx);
|
||||
|
@ -85,11 +106,6 @@ public class TestOpenBitSet extends TestCase {
|
|||
idx = rand.nextInt(sz);
|
||||
a.flip(idx);
|
||||
b.fastFlip(idx);
|
||||
int idx1 = rand.nextInt(sz);
|
||||
int idx2 = rand.nextInt(sz);
|
||||
if (idx1>idx2) { idx=idx1; idx1=idx2; idx2=idx; }
|
||||
a.flip(idx1,idx2);
|
||||
b.flip(idx1,idx2);
|
||||
|
||||
boolean val = b.flipAndGet(idx);
|
||||
boolean val2 = b.flipAndGet(idx);
|
||||
|
@ -98,6 +114,7 @@ public class TestOpenBitSet extends TestCase {
|
|||
val = b.getAndSet(idx);
|
||||
assertTrue(val2 == val);
|
||||
assertTrue(b.get(idx));
|
||||
|
||||
if (!val) b.fastClear(idx);
|
||||
assertTrue(b.get(idx) == val);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue