func (o *Operator) GetReachTimeOf(st OpStatus) time.Time {
	return o.status.ReachTimeOf(st)
}
GetReachTimeOf returns the time when operator reaches the given status.
package operator
import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"
	"sync/atomic"
	"time"
	"github.com/pingcap/kvproto/pkg/metapb"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/tikv/pd/server/core"
)
const (
	OperatorExpireTime = 3 * time.Second
	FastOperatorWaitTime = 10 * time.Second
	SlowOperatorWaitTime = 10 * time.Minute
)
type Operator struct {
	desc             string
	brief            string
	regionID         uint64
	regionEpoch      *metapb.RegionEpoch
	kind             OpKind
	steps            []OpStep
	stepsTime        []int64  
	currentStep      int32
	status           OpStatusTracker
	level            core.PriorityLevel
	Counters         []prometheus.Counter
	FinishedCounters []prometheus.Counter
	AdditionalInfos  map[string]string
}
func NewOperator(desc, brief string, regionID uint64, regionEpoch *metapb.RegionEpoch, kind OpKind, steps ...OpStep) *Operator {
	level := core.NormalPriority
	if kind&OpAdmin != 0 {
		level = core.HighPriority
	}
	return &Operator{
		desc:            desc,
		brief:           brief,
		regionID:        regionID,
		regionEpoch:     regionEpoch,
		kind:            kind,
		steps:           steps,
		stepsTime:       make([]int64, len(steps)),
		status:          NewOpStatusTracker(),
		level:           level,
		AdditionalInfos: make(map[string]string),
	}
}
func (o *Operator) String() string {
	stepStrs := make([]string, len(o.steps))
	for i := range o.steps {
		stepStrs[i] = o.steps[i].String()
	}
	s := fmt.Sprintf("%s {%s} (kind:%s, region:%v(%v,%v), createAt:%s, startAt:%s, currentStep:%v, steps:[%s])", o.desc, o.brief, o.kind, o.regionID, o.regionEpoch.GetVersion(), o.regionEpoch.GetConfVer(), o.GetCreateTime(), o.GetStartTime(), atomic.LoadInt32(&o.currentStep), strings.Join(stepStrs, ", "))
	if o.CheckSuccess() {
		s = s + " finished"
	}
	if o.CheckTimeout() {
		s = s + " timeout"
	}
	return s
}
func (o *Operator) MarshalJSON() ([]byte, error) {
	return []byte(`"` + o.String() + `"`), nil
}
func (o *Operator) Desc() string {
	return o.desc
}
func (o *Operator) SetDesc(desc string) {
	o.desc = desc
}
func (o *Operator) AttachKind(kind OpKind) {
	o.kind |= kind
}
func (o *Operator) RegionID() uint64 {
	return o.regionID
}
func (o *Operator) RegionEpoch() *metapb.RegionEpoch {
	return o.regionEpoch
}
func (o *Operator) Kind() OpKind {
	return o.kind
}
func (o *Operator) SchedulerKind() OpKind {
	return o.kind & (-o.kind)
}
func (o *Operator) Status() OpStatus {
	return o.status.Status()
}
func (o *Operator) CheckAndGetStatus() OpStatus {
	switch {
	case o.CheckExpired():
		return EXPIRED
	case o.CheckTimeout():
		return TIMEOUT
	default:
		return o.Status()
	}
}