func (s *StoreInfo) IsSlow() bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.rawStats.GetSlowScore() >= slowStoreThreshold
}
IsSlow checks if the slow score reaches the threshold.
package core
import (
	"math"
	"strings"
	"time"
	"github.com/gogo/protobuf/proto"
	"github.com/pingcap/kvproto/pkg/metapb"
	"github.com/pingcap/log"
	"github.com/tikv/pd/pkg/errs"
	"github.com/tikv/pd/server/core/storelimit"
	"go.uber.org/zap"
)
const (
	storePersistInterval   = 5 * time.Minute
	mb                     = 1 << 20  
	gb                     = 1 << 30  
	initialMaxRegionCounts = 30       
	initialMinSpace        = 1 << 33  
	slowStoreThreshold     = 80
	EngineKey = "engine"
	EngineTiFlash = "tiflash"
	EngineTiKV = "tikv"
)
type StoreInfo struct {
	meta *metapb.Store
	*storeStats
	pauseLeaderTransfer bool  
	slowStoreEvicted    bool  
	leaderCount         int
	regionCount         int
	leaderSize          int64
	regionSize          int64
	pendingPeerCount    int
	lastPersistTime     time.Time
	leaderWeight        float64
	regionWeight        float64
	limiter             map[storelimit.Type]*storelimit.StoreLimit
}
func NewStoreInfo(store *metapb.Store, opts ...StoreCreateOption) *StoreInfo {
	storeInfo := &StoreInfo{
		meta:         store,
		storeStats:   newStoreStats(),
		leaderWeight: 1.0,
		regionWeight: 1.0,
		limiter:      make(map[storelimit.Type]*storelimit.StoreLimit),
	}
	for _, opt := range opts {
		opt(storeInfo)
	}
	return storeInfo
}
func (s *StoreInfo) Clone(opts ...StoreCreateOption) *StoreInfo {
	meta := proto.Clone(s.meta).(*metapb.Store)
	store := &StoreInfo{
		meta:                meta,
		storeStats:          s.storeStats,
		pauseLeaderTransfer: s.pauseLeaderTransfer,
		slowStoreEvicted:    s.slowStoreEvicted,
		leaderCount:         s.leaderCount,
		regionCount:         s.regionCount,
		leaderSize:          s.leaderSize,
		regionSize:          s.regionSize,
		pendingPeerCount:    s.pendingPeerCount,
		lastPersistTime:     s.lastPersistTime,
		leaderWeight:        s.leaderWeight,
		regionWeight:        s.regionWeight,
		limiter:             s.limiter,
	}
	for _, opt := range opts {
		opt(store)
	}
	return store
}
func (s *StoreInfo) ShallowClone(opts ...StoreCreateOption) *StoreInfo {
	store := &StoreInfo{
		meta:                s.meta,
		storeStats:          s.storeStats,
		pauseLeaderTransfer: s.pauseLeaderTransfer,
		slowStoreEvicted:    s.slowStoreEvicted,
		leaderCount:         s.leaderCount,
		regionCount:         s.regionCount,
		leaderSize:          s.leaderSize,
		regionSize:          s.regionSize,
		pendingPeerCount:    s.pendingPeerCount,
		lastPersistTime:     s.lastPersistTime,
		leaderWeight:        s.leaderWeight,
		regionWeight:        s.regionWeight,
		limiter:             s.limiter,
	}
	for _, opt := range opts {
		opt(store)
	}
	return store
}
func (s *StoreInfo) AllowLeaderTransfer() bool {
	return !s.pauseLeaderTransfer
}
func (s *StoreInfo) EvictedAsSlowStore() bool {
	return s.slowStoreEvicted
}
func (s *StoreInfo) IsAvailable(limitType storelimit.Type) bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	if s.limiter != nil && s.limiter[limitType] != nil {
		return s.limiter[limitType].Available() >= storelimit.RegionInfluence[limitType]
	}
	return true
}
func (s *StoreInfo) IsUp() bool {
	return s.GetState() == metapb.StoreState_Up
}
func (s *StoreInfo) IsOffline() bool {
	return s.GetState() == metapb.StoreState_Offline
}
func (s *StoreInfo) IsTombstone() bool {
	return s.GetState() == metapb.StoreState_Tombstone
}
func (s *StoreInfo) GetSlowScore() uint64 {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.rawStats.GetSlowScore()
}