func NewLongsSketchFromSlice()

in frequencies/longs_sketch.go [101:174]


func NewLongsSketchFromSlice(slc []byte) (*LongsSketch, error) {
	pre0, err := checkPreambleSize(slc)
	if err != nil {
		return nil, err
	}
	maxPreLongs := internal.FamilyEnum.Frequency.MaxPreLongs
	preLongs := extractPreLongs(pre0)
	serVer := extractSerVer(pre0)
	familyID := extractFamilyID(pre0)
	lgMaxMapSize := extractLgMaxMapSize(pre0)
	lgCurMapSize := extractLgCurMapSize(pre0)
	empty := (extractFlags(pre0) & _EMPTY_FLAG_MASK) != 0

	// Checks
	preLongsEq1 := preLongs == 1
	preLongsEqMax := preLongs == maxPreLongs
	if !preLongsEq1 && !preLongsEqMax {
		return nil, fmt.Errorf("possible Corruption: PreLongs must be 1 or %d: %d", maxPreLongs, preLongs)
	}
	if serVer != _SER_VER {
		return nil, fmt.Errorf("possible Corruption: Ser Ver must be %d: %d", _SER_VER, serVer)
	}
	actFamID := internal.FamilyEnum.Frequency.Id
	if familyID != actFamID {
		return nil, fmt.Errorf("possible Corruption: FamilyID must be %d: %d", actFamID, familyID)
	}
	if empty && !preLongsEq1 {
		return nil, fmt.Errorf("possible Corruption: Empty Flag set incorrectly: %t", preLongsEq1)
	}
	if empty {
		return NewLongsSketch(lgMaxMapSize, _LG_MIN_MAP_SIZE)
	}
	// get full preamble
	preArr := make([]int64, preLongs)
	for i := 0; i < preLongs; i++ {
		preArr[i] = int64(binary.LittleEndian.Uint64(slc[i<<3:]))
	}
	fls, err := NewLongsSketch(lgMaxMapSize, lgCurMapSize)
	if err != nil {
		return nil, err
	}
	fls.streamWeight = 0 //update after
	fls.offset = preArr[3]

	preBytes := preLongs << 3
	activeItems := extractActiveItems(preArr[1])

	// Get countArray
	countArray := make([]int64, activeItems)
	reqBytes := preBytes + 2*activeItems*8 //count Arr + Items Arr
	if len(slc) < reqBytes {
		return nil, fmt.Errorf("possible Corruption: Insufficient bytes in array: %d, %d", len(slc), reqBytes)
	}
	for i := 0; i < activeItems; i++ {
		countArray[i] = int64(binary.LittleEndian.Uint64(slc[preBytes+(i<<3):]))
	}

	// Get itemArray
	itemsOffset := preBytes + (8 * activeItems)
	itemArray := make([]int64, activeItems)
	for i := 0; i < activeItems; i++ {
		itemArray[i] = int64(binary.LittleEndian.Uint64(slc[itemsOffset+(i<<3):]))
	}

	// UpdateMany the sketch
	for i := 0; i < activeItems && err == nil; i++ {
		err = fls.UpdateMany(itemArray[i], countArray[i])
	}
	if err != nil {
		return nil, err
	}
	fls.streamWeight = preArr[2] //override streamWeight due to updating
	return fls, nil
}