时间轮数据结构由环形链表改为数组存储,提高访问效率

pull/21/merge
ouqiang 2017-05-15 22:52:47 +08:00
parent c9eb4e31af
commit a7fd364b7d
2 changed files with 18 additions and 14 deletions

View File

@ -97,7 +97,7 @@ func Register(m *macaron.Macaron) {
m.Group("/api/v1", func() { m.Group("/api/v1", func() {
m.Route("/tasklog/update-status", "GET,POST", tasklog.UpdateStatus) m.Route("/tasklog/update-status", "GET,POST", tasklog.UpdateStatus)
m.Post("/tasklog/remove/:id", tasklog.Remove) m.Post("/tasklog/remove/:id", tasklog.Remove)
m.Post("/delaytask/create", delaytask.Create) m.Post("/delaytask/push", delaytask.Create)
m.Post("/delaytask/remove/:id", delaytask.Remove) m.Post("/delaytask/remove/:id", delaytask.Remove)
}); });

View File

@ -2,7 +2,6 @@ package timewheel
import ( import (
"time" "time"
"container/ring"
"container/list" "container/list"
) )
@ -11,7 +10,8 @@ import (
type TimeWheel struct { type TimeWheel struct {
interval time.Duration interval time.Duration
ticker *time.Ticker ticker *time.Ticker
slots *ring.Ring slots []*list.List
currentPos int
slotNum int slotNum int
taskChannel chan Task taskChannel chan Task
stopChannel chan bool stopChannel chan bool
@ -32,7 +32,8 @@ func New(interval time.Duration, slotNum int) *TimeWheel {
} }
tw := &TimeWheel{ tw := &TimeWheel{
interval: interval, interval: interval,
slots: ring.New(slotNum), slots: make([]*list.List, slotNum),
currentPos: 0,
slotNum: slotNum, slotNum: slotNum,
taskChannel: make(chan Task), taskChannel: make(chan Task),
stopChannel: make(chan bool), stopChannel: make(chan bool),
@ -44,9 +45,8 @@ func New(interval time.Duration, slotNum int) *TimeWheel {
} }
func (tw *TimeWheel) initSlots() { func (tw *TimeWheel) initSlots() {
for i := 0; i < tw.slots.Len(); i++ { for i := 0; i < tw.slotNum; i++ {
tw.slots.Value = list.New() tw.slots[i] = list.New()
tw.slots = tw.slots.Next()
} }
} }
@ -81,9 +81,13 @@ func (tw *TimeWheel) start() {
} }
func (tw *TimeWheel) tickHandler() { func (tw *TimeWheel) tickHandler() {
l := tw.slots.Value.(*list.List) l := tw.slots[tw.currentPos]
tw.scanAndRunTask(l) tw.scanAndRunTask(l)
tw.slots = tw.slots.Next() if tw.currentPos == tw.slotNum - 1 {
tw.currentPos = 0
} else {
tw.currentPos++
}
} }
func (tw *TimeWheel) scanAndRunTask(l *list.List) { func (tw *TimeWheel) scanAndRunTask(l *list.List) {
@ -103,18 +107,18 @@ func (tw *TimeWheel) scanAndRunTask(l *list.List) {
} }
func (tw *TimeWheel) addTask(task *Task) { func (tw *TimeWheel) addTask(task *Task) {
step, circle := tw.getStepAndCircle(task.delay) pos, circle := tw.getPositionAndCircle(task.delay)
task.circle = circle task.circle = circle
l := tw.slots.Move(step).Value.(*list.List) tw.slots[pos].PushBack(task)
l.PushBack(task)
} }
func (tw *TimeWheel) getStepAndCircle(d time.Duration) (step int, circle int) { func (tw *TimeWheel) getPositionAndCircle(d time.Duration) (pos int, circle int) {
delaySeconds := int(d.Seconds()) delaySeconds := int(d.Seconds())
intervalSeconds := int(tw.interval.Seconds()) intervalSeconds := int(tw.interval.Seconds())
circle = int(delaySeconds / intervalSeconds / tw.slotNum) circle = int(delaySeconds / intervalSeconds / tw.slotNum)
step = int(delaySeconds / intervalSeconds) % tw.slotNum pos = int(tw.currentPos + delaySeconds / intervalSeconds) % tw.slotNum
return return
} }