mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-06 09:17:10 +08:00
remove task O(1), and none block tickerHandler() (#72)
* remove task O(1), and none block tickerHandler() * remove task O(1), and none block tickerHandler()
This commit is contained in:
@@ -6,13 +6,18 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type location struct {
|
||||||
|
slot int
|
||||||
|
etask *list.Element
|
||||||
|
}
|
||||||
|
|
||||||
// TimeWheel can execute job after waiting given duration
|
// TimeWheel can execute job after waiting given duration
|
||||||
type TimeWheel struct {
|
type TimeWheel struct {
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
ticker *time.Ticker
|
ticker *time.Ticker
|
||||||
slots []*list.List
|
slots []*list.List
|
||||||
|
|
||||||
timer map[string]int
|
timer map[string]*location
|
||||||
currentPos int
|
currentPos int
|
||||||
slotNum int
|
slotNum int
|
||||||
addTaskChannel chan task
|
addTaskChannel chan task
|
||||||
@@ -35,7 +40,7 @@ func New(interval time.Duration, slotNum int) *TimeWheel {
|
|||||||
tw := &TimeWheel{
|
tw := &TimeWheel{
|
||||||
interval: interval,
|
interval: interval,
|
||||||
slots: make([]*list.List, slotNum),
|
slots: make([]*list.List, slotNum),
|
||||||
timer: make(map[string]int),
|
timer: make(map[string]*location),
|
||||||
currentPos: 0,
|
currentPos: 0,
|
||||||
slotNum: slotNum,
|
slotNum: slotNum,
|
||||||
addTaskChannel: make(chan task),
|
addTaskChannel: make(chan task),
|
||||||
@@ -99,12 +104,12 @@ func (tw *TimeWheel) start() {
|
|||||||
|
|
||||||
func (tw *TimeWheel) tickHandler() {
|
func (tw *TimeWheel) tickHandler() {
|
||||||
l := tw.slots[tw.currentPos]
|
l := tw.slots[tw.currentPos]
|
||||||
tw.scanAndRunTask(l)
|
|
||||||
if tw.currentPos == tw.slotNum-1 {
|
if tw.currentPos == tw.slotNum-1 {
|
||||||
tw.currentPos = 0
|
tw.currentPos = 0
|
||||||
} else {
|
} else {
|
||||||
tw.currentPos++
|
tw.currentPos++
|
||||||
}
|
}
|
||||||
|
go tw.scanAndRunTask(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tw *TimeWheel) scanAndRunTask(l *list.List) {
|
func (tw *TimeWheel) scanAndRunTask(l *list.List) {
|
||||||
@@ -138,11 +143,18 @@ func (tw *TimeWheel) addTask(task *task) {
|
|||||||
pos, circle := tw.getPositionAndCircle(task.delay)
|
pos, circle := tw.getPositionAndCircle(task.delay)
|
||||||
task.circle = circle
|
task.circle = circle
|
||||||
|
|
||||||
tw.slots[pos].PushBack(task)
|
e := tw.slots[pos].PushBack(task)
|
||||||
|
loc := &location{
|
||||||
if task.key != "" {
|
slot: pos,
|
||||||
tw.timer[task.key] = pos
|
etask: e,
|
||||||
}
|
}
|
||||||
|
if task.key != "" {
|
||||||
|
_, ok := tw.timer[task.key]
|
||||||
|
if ok {
|
||||||
|
tw.removeTask(task.key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tw.timer[task.key] = loc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tw *TimeWheel) getPositionAndCircle(d time.Duration) (pos int, circle int) {
|
func (tw *TimeWheel) getPositionAndCircle(d time.Duration) (pos int, circle int) {
|
||||||
@@ -155,18 +167,11 @@ func (tw *TimeWheel) getPositionAndCircle(d time.Duration) (pos int, circle int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tw *TimeWheel) removeTask(key string) {
|
func (tw *TimeWheel) removeTask(key string) {
|
||||||
position, ok := tw.timer[key]
|
pos, ok := tw.timer[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l := tw.slots[position]
|
l := tw.slots[pos.slot]
|
||||||
for e := l.Front(); e != nil; {
|
l.Remove(pos.etask)
|
||||||
task := e.Value.(*task)
|
delete(tw.timer, key)
|
||||||
if task.key == key {
|
|
||||||
delete(tw.timer, task.key)
|
|
||||||
l.Remove(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
e = e.Next()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user