func (ctx *LockCtx) IterateValuesNotLocked(f func([]byte, []byte)) {
	ctx.ValuesLock.Lock()
	defer ctx.ValuesLock.Unlock()
	for key, val := range ctx.Values {
		if !val.AlreadyLocked {
			f([]byte(key), val.Value)
		}
	}
}
IterateValuesNotLocked applies f to all key-values that are not already
locked.
package kv
import (
	"math"
	"sync"
	"time"
	tikverr "github.com/tikv/client-go/v2/error"
	"github.com/tikv/client-go/v2/util"
)
type ReturnedValue struct {
	Value         []byte
	AlreadyLocked bool
}
const (
	LockAlwaysWait = int64(math.MaxInt64)
	LockNoWait     = int64(0)
)
type lockWaitTimeInMs struct {
	value int64
}
func defaultLockWaitTime() *lockWaitTimeInMs {
	return &lockWaitTimeInMs{value: LockAlwaysWait}
}
type LockCtx struct {
	Killed                *uint32
	ForUpdateTS           uint64
	lockWaitTime          *lockWaitTimeInMs
	WaitStartTime         time.Time
	PessimisticLockWaited *int32
	LockKeysDuration      *int64
	LockKeysCount         *int32
	ReturnValues          bool
	Values                map[string]ReturnedValue
	ValuesLock            sync.Mutex
	LockExpired           *uint32
	Stats                 *util.LockKeysDetails
	ResourceGroupTag      []byte
	OnDeadlock            func(*tikverr.ErrDeadlock)
}
func (ctx *LockCtx) LockWaitTime() int64 {
	if ctx.lockWaitTime == nil {
		ctx.lockWaitTime = defaultLockWaitTime()
	}
	return ctx.lockWaitTime.value
}
func NewLockCtx(forUpdateTS uint64, lockWaitTime int64, waitStartTime time.Time) *LockCtx {
	return &LockCtx{
		ForUpdateTS:   forUpdateTS,
		lockWaitTime:  &lockWaitTimeInMs{value: lockWaitTime},
		WaitStartTime: waitStartTime,
	}
}
func (ctx *LockCtx) InitReturnValues(valueLen int) {
	ctx.ReturnValues = true
	ctx.Values = make(map[string]ReturnedValue, valueLen)
}
func (ctx *LockCtx) GetValueNotLocked(key []byte) ([]byte, bool) {
	rv := ctx.Values[string(key)]
	if !rv.AlreadyLocked {
		return rv.Value, true
	}
	return nil, false
}