func NewFrequencyItemsSketchFromSlice[C comparable]()

in frequencies/items_sketch.go [107:181]


func NewFrequencyItemsSketchFromSlice[C comparable](slc []byte, hasher common.ItemSketchHasher[C], serde common.ItemSketchSerde[C]) (*ItemsSketch[C], error) {
	if serde == nil {
		return nil, errors.New("no SerDe provided")
	}

	pre0, err := checkPreambleSize(slc) //make sure preamble will fit
	maxPreLongs := internal.FamilyEnum.Frequency.MaxPreLongs

	preLongs := extractPreLongs(pre0)                     //Byte 0
	serVer := extractSerVer(pre0)                         //Byte 1
	familyID := extractFamilyID(pre0)                     //Byte 2
	lgMaxMapSize := extractLgMaxMapSize(pre0)             //Byte 3
	lgCurMapSize := extractLgCurMapSize(pre0)             //Byte 4
	empty := (extractFlags(pre0) & _EMPTY_FLAG_MASK) != 0 //Byte 5

	// Checks
	preLongsEq1 := (preLongs == 1) //Byte 0
	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 { //Byte 1
		return nil, fmt.Errorf("possible corruption: ser ver must be %d: %d", _SER_VER, serVer)
	}
	actFamID := internal.FamilyEnum.Frequency.Id //Byte 2
	if familyID != actFamID {
		return nil, fmt.Errorf("possible corruption: familyID must be %d: %d", actFamID, familyID)
	}
	if empty && !preLongsEq1 { //Byte 5 and Byte 0
		return nil, fmt.Errorf("(preLongs == 1) ^ empty == true")
	}
	if empty {
		return NewFrequencyItemsSketchWithMaxMapSize[C](1<<_LG_MIN_MAP_SIZE, hasher, serde)
	}
	// Get full preamble
	preArr := make([]int64, preLongs)
	for j := 0; j < preLongs; j++ {
		preArr[j] = int64(binary.LittleEndian.Uint64(slc[j<<3:]))
	}

	fis, err := NewFrequencyItemsSketch[C](lgMaxMapSize, lgCurMapSize, hasher, serde)
	if err != nil {
		return nil, err
	}
	fis.streamWeight = 0 // update after
	fis.offset = preArr[3]

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

	// Get countArray
	countArray := make([]int64, activeItems)
	reqBytes := preBytes + activeItems*8 // count Arr only
	if len(slc) < reqBytes {
		return nil, fmt.Errorf("possible Corruption: Insufficient bytes in array: %d, %d", len(slc), reqBytes)
	}
	for j := 0; j < activeItems; j++ {
		countArray[j] = int64(binary.LittleEndian.Uint64(slc[preBytes+j<<3:]))
	}
	// Get itemArray
	itemsOffset := preBytes + (8 * activeItems)
	itemArray, err := serde.DeserializeManyFromSlice(slc[itemsOffset:], 0, activeItems)
	if err != nil {
		return nil, err
	}
	// update the sketch
	for j := 0; j < activeItems; j++ {
		err := fis.UpdateMany(itemArray[j], countArray[j])
		if err != nil {
			return nil, err
		}
	}
	fis.streamWeight = preArr[2] // override streamWeight due to updating
	return fis, nil
}