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 }