in cpc/cpc_union.go [61:141]
func (u *CpcUnion) Update(source *CpcSketch) error {
if err := checkSeeds(u.seed, source.seed); err != nil {
return err
}
sourceFlavorOrd := source.getFlavor()
if sourceFlavorOrd == CpcFlavorEmpty {
return nil
}
if err := u.checkUnionState(); err != nil {
return err
}
// Downsample union if the source sketch has a smaller lgK.
if source.lgK < u.lgK {
if err := u.reduceUnionK(source.lgK); err != nil {
return err
}
}
// If the source is past SPARSE mode, ensure union is in bitMatrix mode.
if sourceFlavorOrd > CpcFlavorSparse && u.accumulator != nil {
bitMatrix, err := u.accumulator.bitMatrixOfSketch()
if err != nil {
return err
}
u.bitMatrix = bitMatrix
u.accumulator = nil
}
state := (sourceFlavorOrd - 1) << 1
if u.bitMatrix != nil {
state |= 1
}
switch state {
case 0: // Case A: source is SPARSE, union.accumulator valid, bitMatrix == nil.
if u.accumulator.lgK == 0 {
return fmt.Errorf("union accumulator cannot be nil")
}
// If the union is EMPTY and lgK matches, copy the source.
if u.accumulator.getFlavor() == CpcFlavorEmpty && u.lgK == source.lgK {
cp, err := source.Copy()
if err != nil {
return err
}
u.accumulator = cp
break
}
if err := walkTableUpdatingSketch(u.accumulator, source.pairTable); err != nil {
return err
}
// If accumulator has graduated beyond SPARSE, switch to bitMatrix.
if u.accumulator.getFlavor() > CpcFlavorSparse {
bitMatrix, err := u.accumulator.bitMatrixOfSketch()
if err != nil {
return err
}
u.bitMatrix = bitMatrix
u.accumulator = nil
}
case 1: // Case B: source is SPARSE, union already in bitMatrix mode.
u.orTableIntoMatrix(source.pairTable)
case 3, 5: // Case C: source is HYBRID or PINNED, union in bitMatrix mode.
if err := u.orWindowIntoMatrix(source.slidingWindow, 0, source.lgK); err != nil {
return err
}
u.orTableIntoMatrix(source.pairTable)
case 7: // Case D: source is SLIDING, union in bitMatrix mode.
sourceMatrix, err := source.bitMatrixOfSketch()
if err != nil {
return err
}
if err := u.orMatrixIntoMatrix(sourceMatrix, source.lgK); err != nil {
return err
}
default:
return fmt.Errorf("illegal Union state: %d", state)
}
return nil
}