in hll/union.go [200:308]
func (u *unionImpl) unionImpl(source HllSketch) (hllSketchStateI, error) {
if u.gadget.GetTgtHllType() != TgtHllTypeHll8 {
return nil, fmt.Errorf("gadget must be HLL_8")
}
if source == nil || source.IsEmpty() {
return u.gadget.(*hllSketchState).sketch, nil
}
gadgetC := u.gadget.(*hllSketchState)
sourceC := source.(*hllSketchState)
srcMode := sourceC.sketch.GetCurMode()
if srcMode == curModeList {
err := sourceC.mergeTo(u.gadget)
return u.gadget.(*hllSketchState).sketch, err
}
srcLgK := source.GetLgConfigK()
gdgtLgK := u.gadget.GetLgConfigK()
gdgtEmpty := u.gadget.IsEmpty()
if srcMode == curModeSet {
if gdgtEmpty && srcLgK == gdgtLgK {
un, err := sourceC.CopyAs(TgtHllTypeHll8)
gadgetC.sketch = un.(*hllSketchState).sketch
return gadgetC.sketch, err
}
err := sourceC.mergeTo(u.gadget)
return gadgetC.sketch, err
}
// Hereafter, the source is in HLL mode.
var (
bits12 int
bit3 int
bit4 int
)
if !gdgtEmpty {
bits12 = int(gadgetC.GetCurMode()) << 1
} else {
bits12 = 3 << 1
}
if srcLgK < gdgtLgK {
bit3 = 0
}
if srcLgK > u.lgMaxK {
bit4 = 16
}
sw := bit4 | bit3 | bits12
switch sw {
case 0, 8, 2, 10:
// case 0: src <= max, src >= gdt, gdtLIST, gdtHeap
// case 8: src <= max, src < gdt, gdtLIST, gdtHeap
// case 2: src <= max, src >= gdt, gdtSET, gdtHeap
// case 10: src <= max, src < gdt, gdtSET, gdtHeap
{
// Action: copy src, reverse merge w/autofold, ooof=src
srcHll8, err := sourceC.CopyAs(TgtHllTypeHll8)
if err != nil {
return nil, err
}
err = gadgetC.mergeTo(srcHll8.(*hllSketchState))
return srcHll8.(*hllSketchState).sketch, err
}
case 16, 18:
// case 16: src > max, src >= gdt, gdtList, gdtHeap
// case 18: src > max, src >= gdt, gdtSet, gdtHeap
{ //Action: downsample src to MaxLgK, reverse merge w/autofold, ooof=src
return nil, fmt.Errorf("not implemented cas 16,18")
}
case 4, 20:
// case 4: src <= max, src >= gdt, gdtHLL, gdtHeap
// case 20: src > max, src >= gdt, gdtHLL, gdtHeap
{ //Action: forward HLL merge w/autofold, ooof=True
//merge src(Hll4,6,8,heap/mem,Mode=HLL) -> gdt(Hll8,heap,Mode=HLL)
err := mergeHlltoHLLmode(source, u.gadget, srcLgK, gdgtLgK)
if err != nil {
return nil, err
}
u.gadget.(*hllSketchState).sketch.putOutOfOrder(true)
return u.gadget.(*hllSketchState).sketch, nil
}
case 12: //src <= max, src < gdt, gdtHLL, gdtHeap
{ //Action: downsample gdt to srcLgK, forward HLL merge w/autofold, ooof=True
return nil, fmt.Errorf("not implemented case 12")
}
case 6, 14:
// case 6: src <= max, src >= gdt, gdtEmpty, gdtHeap
// case 14: src <= max, src < gdt, gdtEmpty, gdtHeap
{ //Action: copy src, replace gdt, ooof=src
srcHll8, err := sourceC.CopyAs(TgtHllTypeHll8)
if err != nil {
return nil, err
}
return srcHll8.(*hllSketchState).sketch, nil
}
case 22: //src > max, src >= gdt, gdtEmpty, gdtHeap
{ //Action: downsample src to lgMaxK, replace gdt, ooof=src
return nil, fmt.Errorf("not implemented")
}
default:
return nil, fmt.Errorf("impossible")
}
}