in src/main/java/org/apache/datasketches/theta/IntersectionImpl.java [229:303]
public void intersect(final Sketch sketchIn) {
if (sketchIn == null) {
throw new SketchesArgumentException("Intersection argument must not be null.");
}
if (wmem_ != null && readOnly_) { throw new SketchesReadOnlyException(); }
if (empty_ || sketchIn.isEmpty()) { //empty rule
//Because of the def of null above and the Empty Rule (which is OR), empty_ must be true.
//Whatever the current internal state, we make our local empty.
resetToEmpty();
return;
}
ThetaUtil.checkSeedHashes(seedHash_, sketchIn.getSeedHash());
//Set minTheta
thetaLong_ = min(thetaLong_, sketchIn.getThetaLong()); //Theta rule
empty_ = false;
if (wmem_ != null) {
insertThetaLong(wmem_, thetaLong_);
clearEmpty(wmem_); //false
}
// The truth table for the following state machine. MinTheta is set above.
// Incoming sketch is not null and not empty, but could have 0 count and Theta < 1.0
// Case curCount sketchInEntries | Actions
// 1 <0 0 | First intersect, set curCount = 0; HT = null; minTh; exit
// 2 0 0 | set curCount = 0; HT = null; minTh; exit
// 3 >0 0 | set curCount = 0; HT = null; minTh; exit
// 4 | Not used
// 5 <0 >0 | First intersect, clone SketchIn; exit
// 6 0 >0 | set curCount = 0; HT = null; minTh; exit
// 7 >0 >0 | Perform full intersect
final int sketchInEntries = sketchIn.getRetainedEntries(true);
//states 1,2,3,6
if (curCount_ == 0 || sketchInEntries == 0) {
curCount_ = 0;
if (wmem_ != null) { insertCurCount(wmem_, 0); }
hashTable_ = null; //No need for a HT. Don't bother clearing mem if valid
} //end of states 1,2,3,6
// state 5
else if (curCount_ < 0 && sketchInEntries > 0) {
curCount_ = sketchIn.getRetainedEntries(true);
final int requiredLgArrLongs = minLgHashTableSize(curCount_, ThetaUtil.REBUILD_THRESHOLD);
final int priorLgArrLongs = lgArrLongs_; //prior only used in error message
lgArrLongs_ = requiredLgArrLongs;
if (wmem_ != null) { //Off heap, check if current dstMem is large enough
insertCurCount(wmem_, curCount_);
insertLgArrLongs(wmem_, lgArrLongs_);
if (requiredLgArrLongs <= maxLgArrLongs_) {
wmem_.clear(CONST_PREAMBLE_LONGS << 3, 8 << lgArrLongs_); //clear only what required
}
else { //not enough space in dstMem
final int requiredBytes = (8 << requiredLgArrLongs) + 24;
final int givenBytes = (8 << priorLgArrLongs) + 24;
throw new SketchesArgumentException(
"Insufficient internal Memory space: " + requiredBytes + " > " + givenBytes);
}
}
else { //On the heap, allocate a HT
hashTable_ = new long[1 << lgArrLongs_];
}
moveDataToTgt(sketchIn);
} //end of state 5
//state 7
else if (curCount_ > 0 && sketchInEntries > 0) {
//Sets resulting hashTable, curCount and adjusts lgArrLongs
performIntersect(sketchIn);
} //end of state 7
else {
assert false : "Should not happen";
}
}