github.com/songzhibin97/gkit@v1.2.13/delayed/delayed.go (about) 1 package delayed 2 3 type Delayed interface { 4 Do() // 执行任务 5 ExecTime() int64 // 执行时间 time.Unix() 6 Identify() string // 任务唯一标识 7 } 8 9 // copy https://github.dev/golang/go/blob/a131fd1313e0056ad094d234c67648409d081b8c/src/runtime/time.go siftupTimer and siftdownTimer 10 11 // Heap maintenance algorithms. 12 // These algorithms check for slice index errors manually. 13 // siftupDelayed puts the timer at position i in the right place 14 // in the heap by moving it up toward the top of the heap. 15 // It returns the smallest changed index. 16 func siftupDelayed(d []Delayed, i int) int { 17 if i >= len(d) { 18 return -1 19 } 20 when := d[i].ExecTime() 21 if when <= 0 { 22 return -1 23 } 24 tmp := d[i] 25 for i > 0 { 26 p := (i - 1) / 4 27 if when >= d[p].ExecTime() { 28 break 29 } 30 d[i] = d[p] 31 i = p 32 } 33 if tmp != d[i] { 34 d[i] = tmp 35 } 36 return i 37 } 38 39 // siftdownDelayed puts the Delayed at position i in the right place 40 // in the heap by moving it down toward the bottom of the heap. 41 func siftdownDelayed(d []Delayed, i int) { 42 n := len(d) 43 if i >= n { 44 return 45 } 46 when := d[i].ExecTime() 47 if when <= 0 { 48 return 49 } 50 tmp := d[i] 51 for { 52 c := i*4 + 1 // left child 53 c3 := c + 2 // mid child 54 if c >= n { 55 break 56 } 57 w := d[c].ExecTime() 58 if c+1 < n && d[c+1].ExecTime() < w { 59 w = d[c+1].ExecTime() 60 c++ 61 } 62 if c3 < n { 63 w3 := d[c3].ExecTime() 64 if c3+1 < n && d[c3+1].ExecTime() < w3 { 65 w3 = d[c3+1].ExecTime() 66 c3++ 67 } 68 if w3 < w { 69 w = w3 70 c = c3 71 } 72 } 73 if w >= when { 74 break 75 } 76 d[i] = d[c] 77 i = c 78 } 79 if tmp != d[i] { 80 d[i] = tmp 81 } 82 }