Skip to content

Commit 4e1df43

Browse files
author
Petko Nikolov
committed
adding xor and and-not to BitSet; unit tests added
1 parent af7f2f1 commit 4e1df43

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

core/src/main/scala/org/apache/spark/util/collection/BitSet.scala

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class BitSet(numBits: Int) extends Serializable {
6464
}
6565

6666
/**
67-
* Compute the bit-wise OR of the two sets returning the
67+
* Compute the bit-wise OR of the two sets returning the
6868
* result.
6969
*/
7070
def |(other: BitSet): BitSet = {
@@ -88,6 +88,53 @@ class BitSet(numBits: Int) extends Serializable {
8888
newBS
8989
}
9090

91+
92+
/**
93+
* Compute the symmetric difference by performing bit-wise XOR of the two sets returning the
94+
* result.
95+
*/
96+
def ^(other: BitSet): BitSet = {
97+
val newBS = new BitSet(math.max(capacity, other.capacity))
98+
assert(newBS.numWords >= numWords)
99+
assert(newBS.numWords >= other.numWords)
100+
val smaller = math.min(numWords, other.numWords)
101+
var ind = 0
102+
while( ind < smaller ) {
103+
newBS.words(ind) = words(ind) ^ other.words(ind)
104+
ind += 1
105+
}
106+
while( ind < numWords ) {
107+
newBS.words(ind) = words(ind)
108+
ind += 1
109+
}
110+
while( ind < other.numWords ) {
111+
newBS.words(ind) = other.words(ind)
112+
ind += 1
113+
}
114+
newBS
115+
}
116+
117+
/**
118+
* Compute the difference of the two sets by performing bit-wise AND-NOT returning the
119+
* result.
120+
*/
121+
def &~(other: BitSet): BitSet = {
122+
val newBS = new BitSet(math.max(capacity, other.capacity))
123+
assert(newBS.numWords >= numWords)
124+
assert(newBS.numWords >= other.numWords)
125+
val smaller = math.min(numWords, other.numWords)
126+
var ind = 0
127+
while( ind < smaller ) {
128+
newBS.words(ind) = words(ind) & ~other.words(ind)
129+
ind += 1
130+
}
131+
while( ind < numWords ) {
132+
newBS.words(ind) = words(ind)
133+
ind += 1
134+
}
135+
newBS
136+
}
137+
91138
/**
92139
* Sets the bit at the specified index to true.
93140
* @param index the bit index

core/src/test/scala/org/apache/spark/util/collection/BitSetSuite.scala

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,45 @@ class BitSetSuite extends FunSuite {
6969
assert(bitset.nextSetBit(96) === 96)
7070
assert(bitset.nextSetBit(97) === -1)
7171
}
72+
73+
test( "xor" ) {
74+
val setBitsX = Seq( 0, 2, 3, 37, 41 )
75+
val setBitsY = Seq( 0, 1, 3, 37, 38, 41, 85)
76+
val bitsetX = new BitSet(60)
77+
setBitsX.foreach( i => bitsetX.set(i))
78+
val bitsetY = new BitSet(100)
79+
setBitsY.foreach( i => bitsetY.set(i))
80+
81+
val bitsetXor = bitsetX ^ bitsetY
82+
83+
assert(bitsetXor.nextSetBit(0) === 1)
84+
assert(bitsetXor.nextSetBit(1) === 1)
85+
assert(bitsetXor.nextSetBit(2) === 2)
86+
assert(bitsetXor.nextSetBit(3) === 38)
87+
assert(bitsetXor.nextSetBit(38) === 38)
88+
assert(bitsetXor.nextSetBit(39) === 85)
89+
assert(bitsetXor.nextSetBit(42) === 85)
90+
assert(bitsetXor.nextSetBit(85) === 85)
91+
assert(bitsetXor.nextSetBit(86) === -1)
92+
93+
}
94+
95+
test( "and-not" ) {
96+
val setBitsX = Seq( 0, 2, 3, 37, 41, 48 )
97+
val setBitsY = Seq( 0, 1, 3, 37, 38, 41, 85)
98+
val bitsetX = new BitSet(60)
99+
setBitsX.foreach( i => bitsetX.set(i))
100+
val bitsetY = new BitSet(100)
101+
setBitsY.foreach( i => bitsetY.set(i))
102+
103+
val bitsetDiff = bitsetX &~ bitsetY
104+
105+
assert(bitsetDiff.nextSetBit(0) === 2)
106+
assert(bitsetDiff.nextSetBit(1) === 2)
107+
assert(bitsetDiff.nextSetBit(2) === 2)
108+
assert(bitsetDiff.nextSetBit(3) === 48)
109+
assert(bitsetDiff.nextSetBit(48) === 48)
110+
assert(bitsetDiff.nextSetBit(49) === -1)
111+
assert(bitsetDiff.nextSetBit(65) === -1)
112+
}
72113
}

0 commit comments

Comments
 (0)