github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/timer/x_sched.go (about)

     1  package timer
     2  
     3  import "time"
     4  
     5  type xScheduler struct {
     6  	intervals    []time.Duration
     7  	currentIndex int
     8  	isFinite     bool
     9  }
    10  
    11  var (
    12  	_ Scheduler = (*xScheduler)(nil)
    13  )
    14  
    15  func NewFiniteScheduler(intervals ...time.Duration) Scheduler {
    16  	if len(intervals) == 0 {
    17  		return nil
    18  	}
    19  	for _, interval := range intervals {
    20  		if interval.Milliseconds() <= 0 {
    21  			return nil
    22  		}
    23  	}
    24  	return &xScheduler{
    25  		isFinite:     true,
    26  		intervals:    intervals,
    27  		currentIndex: 0,
    28  	}
    29  }
    30  
    31  func NewInfiniteScheduler(intervals ...time.Duration) Scheduler {
    32  	if len(intervals) == 0 {
    33  		return nil
    34  	}
    35  	for _, interval := range intervals {
    36  		if interval.Milliseconds() <= 0 {
    37  			return nil
    38  		}
    39  	}
    40  	return &xScheduler{
    41  		intervals:    intervals,
    42  		currentIndex: 0,
    43  	}
    44  }
    45  
    46  func (x *xScheduler) next(beginMs int64) (nextExpiredMs int64) {
    47  	beginTime := MillisToUTCTime(beginMs)
    48  	if beginTime.IsZero() || len(x.intervals) == 0 {
    49  		return -1
    50  	}
    51  
    52  	if x.currentIndex >= len(x.intervals) {
    53  		if x.isFinite {
    54  			return -1
    55  		}
    56  		x.currentIndex = 0
    57  	}
    58  	if x.intervals[x.currentIndex].Milliseconds() <= 0 {
    59  		return -1
    60  	}
    61  	next := beginTime.Add(x.intervals[x.currentIndex])
    62  	x.currentIndex++
    63  	return next.UnixMilli()
    64  }
    65  
    66  func (x *xScheduler) GetRestLoopCount() int64 {
    67  	if x.isFinite {
    68  		return int64(len(x.intervals) - x.currentIndex)
    69  	}
    70  	return -1
    71  }
    72  
    73  func MillisToUTCTime(millis int64) time.Time {
    74  	return time.Unix(0, millis*int64(time.Millisecond)).UTC()
    75  }