func (p *partitionImpl) KeyRows(kfn sif.KeyingOperation) (sif.OperablePartition, error) {
	var multierr *multierror.Error
	inPlace := true  
	result := p
	keys := make([]uint64, p.internalData.Capacity)
	tempRow := &rowImpl{}
	for i := 0; i < p.GetNumRows(); i++ {
		row := p.getRow(tempRow, i)
		hasher := xxhash.New()
		keyBuf, err := kfn(row)
		if err != nil {
			multierr = multierror.Append(multierr, err)
			if inPlace {
				inPlace = false
				result := createPartitionImpl(int(p.internalData.MaxRows), int(p.internalData.NumRows), p.schema)
				for j := 0; j < i; j++ {
					err := result.AppendRowData(p.getRow(tempRow, j))
					if err != nil {
						return nil, err
					}
				}
			}
		} else if inPlace {
			hasher.Write(keyBuf)
			keys[i] = hasher.Sum64()
		} else if !inPlace {
			hasher.Write(keyBuf)
			err := result.AppendRowData(p.getRow(tempRow, i))
			keys[i] = hasher.Sum64()
			if err != nil {
				return nil, err
			}
		}
	}
	result.internalData.Keys = keys
	return p, multierr.ErrorOrNil()
}
KeyRows generates hash keys for a row from a key column. Attempts to manipulate partition in-place, falling back to creating a fresh partition if there are row errors
package partition
import (
	"fmt"
	xxhash "github.com/cespare/xxhash/v2"
	"github.com/go-sif/sif"
	"github.com/hashicorp/go-multierror"
)
func createKeyablePartition(maxRows int, schema sif.Schema) sif.KeyablePartition {
	return createPartitionImpl(maxRows, defaultCapacity, schema)
}