-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement relational NULL semantics for Nothing for in-memory Column operations #8816
Changes from all commits
32e5781
d76d2ab
8b5d2d1
f7b18e9
9b67c34
2543611
0e6422b
85ca4bf
f4e89ec
9a7b047
bba6daa
987c366
e35bfda
ad4bada
9ef1d05
1118fa2
42b7762
ef83197
0a62d1d
9046cba
49c54e6
db5634f
1c94d88
6f53139
8416e0b
10ef070
ae8c4c6
573de61
e923c7a
8425998
665a6a8
577a993
a2ef8fd
0dddfac
dcb3e0a
fd49520
4c99f18
656538c
36d9aa7
26e537e
276bf76
b33e5df
dbf0df7
8de8498
a23b341
aa193f7
af922af
1e8f1d9
a1c481a
cfce031
305c018
fd40de3
564587d
391a421
b4db21b
83645ba
b692bea
0d328cf
d5280bd
7f610d0
ac11b26
2f77775
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package org.enso.table.util; | ||
|
||
import java.util.BitSet; | ||
|
||
/** | ||
* A wrapper around BitSet that implements boolean operations conveniently. Unlike BitSet, | ||
* ImmutableBitSet takes a size parameter, which allows .not to be implemented. | ||
*/ | ||
Comment on lines
+5
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool! |
||
public class ImmutableBitSet { | ||
private BitSet bitSet; | ||
private int size; | ||
|
||
public ImmutableBitSet(BitSet bitSet, int size) { | ||
this.bitSet = bitSet; | ||
this.size = size; | ||
} | ||
|
||
public BitSet toBitSet() { | ||
return bitSet; | ||
} | ||
|
||
public ImmutableBitSet and(ImmutableBitSet other) { | ||
assert size == other.size; | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.and(other.bitSet); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public ImmutableBitSet or(ImmutableBitSet other) { | ||
assert size == other.size; | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.or(other.bitSet); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public ImmutableBitSet andNot(ImmutableBitSet other) { | ||
assert size == other.size; | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.andNot(other.bitSet); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public ImmutableBitSet not() { | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.flip(0, size); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public ImmutableBitSet notAnd(ImmutableBitSet other) { | ||
assert size == other.size; | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.flip(0, size); | ||
result.and(other.bitSet); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public ImmutableBitSet notAndNot(ImmutableBitSet other) { | ||
assert size == other.size; | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.flip(0, size); | ||
result.andNot(other.bitSet); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public ImmutableBitSet orNot(ImmutableBitSet other) { | ||
// Doing an extra operation to avoid doing an extra allocation. | ||
// a || !b => !(!a && b) | ||
assert size == other.size; | ||
BitSet result = (BitSet) bitSet.clone(); | ||
result.flip(0, size); | ||
result.and(other.bitSet); | ||
result.flip(0, size); | ||
return new ImmutableBitSet(result, size); | ||
} | ||
|
||
public static ImmutableBitSet allFalse(int size) { | ||
return new ImmutableBitSet(new BitSet(), size); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is return new ImmutableBitSet(new BitSet(size), size); going to make the allocation more efficient? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the usages, I think to the contrary. The thing is that So it creates the So actually I think that keeping not adding the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, |
||
} | ||
|
||
public static ImmutableBitSet allTrue(int size) { | ||
return new ImmutableBitSet(new BitSet(), size).not(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly return new ImmutableBitSet(new BitSet(size), size).not(); ? |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps just my lack of knowledge of the codebase, but what is the difference between Null, Nothing and Missing? This PR is about Nothing, this function takes a hadNull and generates a newMissing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think they all mean the same concept here really, so it is just a bit of chaos that got into the codebase over time.
Nothing
is the Enso-centrict name.Null
probably came from the Java internals naming convention (where theNothing
is often represented as anull
reference).Column.is_missing
instead ofColumn.is_nothing
; the external API got renamed, but the internals likely stayed. The*Missing
bitsets are used when we are storing values like integers in unboxedlong[]
arrays - such don't takenull
(likeObject[]
could), so there needs to be a separate flag of which values are missing. I guess it could be calledisNothing
though, for consistency.We could probably rename all of these to
nothing
-based names.