use unlimit list instead slice of array

This commit is contained in:
Yecheng Fu 2015-07-21 19:54:41 +08:00
parent b151716326
commit 4aa4ec30fc
1 changed files with 28 additions and 38 deletions

View File

@ -1,6 +1,7 @@
package time2 package time2
import ( import (
"container/list"
"sync" "sync"
"time" "time"
) )
@ -8,15 +9,11 @@ import (
const ( const (
tvn_bits uint64 = 6 tvn_bits uint64 = 6
tvr_bits uint64 = 8 tvr_bits uint64 = 8
tvn_size uint64 = 64 //1 << tvn_bits tvn_size uint64 = 64 // 1 << tvn_bits
tvr_size uint64 = 256 //1 << tvr_bits tvr_size uint64 = 256 // 1 << tvr_bits
tvn_mask uint64 = 63 //tvn_size - 1 tvn_mask uint64 = 63 // tvn_size - 1
tvr_mask uint64 = 255 //tvr_size -1 tvr_mask uint64 = 255 // tvr_size -1
)
const (
defaultTimerSize = 128
) )
type timer struct { type timer struct {
@ -28,8 +25,8 @@ type timer struct {
w *Wheel w *Wheel
vec []*timer vec *list.List
index int e *list.Element
} }
type Wheel struct { type Wheel struct {
@ -37,11 +34,11 @@ type Wheel struct {
jiffies uint64 jiffies uint64
tv1 [][]*timer tv1 []*list.List
tv2 [][]*timer tv2 []*list.List
tv3 [][]*timer tv3 []*list.List
tv4 [][]*timer tv4 []*list.List
tv5 [][]*timer tv5 []*list.List
tick time.Duration tick time.Duration
@ -54,10 +51,10 @@ func NewWheel(tick time.Duration) *Wheel {
w.quit = make(chan struct{}) w.quit = make(chan struct{})
f := func(size int) [][]*timer { f := func(size int) []*list.List {
tv := make([][]*timer, size) tv := make([]*list.List, size)
for i := range tv { for i := range tv {
tv[i] = make([]*timer, 0, defaultTimerSize) tv[i] = list.New()
} }
return tv return tv
@ -80,7 +77,7 @@ func (w *Wheel) addTimerInternal(t *timer) {
expires := t.expires expires := t.expires
idx := t.expires - w.jiffies idx := t.expires - w.jiffies
var tv [][]*timer var tv []*list.List
var i uint64 var i uint64
if idx < tvr_size { if idx < tvr_size {
@ -109,18 +106,16 @@ func (w *Wheel) addTimerInternal(t *timer) {
tv = w.tv5 tv = w.tv5
} }
tv[i] = append(tv[i], t) t.e = tv[i].PushBack(t)
t.vec = tv[i] t.vec = tv[i]
t.index = len(tv[i]) - 1
} }
func (w *Wheel) cascade(tv [][]*timer, index int) int { func (w *Wheel) cascade(tv []*list.List, index int) int {
vec := tv[index] vec := tv[index]
tv[index] = vec[0:0:defaultTimerSize] tv[index] = list.New()
for _, t := range vec { for e := vec.Front(); e != nil; e = e.Next() {
w.addTimerInternal(t) w.addTimerInternal(e.Value.(*timer))
} }
return index return index
@ -145,17 +140,14 @@ func (w *Wheel) onTick() {
w.jiffies++ w.jiffies++
vec := w.tv1[index] vec := w.tv1[index]
w.tv1[index] = vec[0:0:defaultTimerSize] w.tv1[index] = list.New()
w.Unlock() w.Unlock()
f := func(vec []*timer) { f := func(vec *list.List) {
now := time.Now() now := time.Now()
for _, t := range vec { for e := vec.Front(); e != nil; e = e.Next() {
if t == nil { t := e.Value.(*timer)
continue
}
t.f(now, t.arg) t.f(now, t.arg)
if t.period > 0 { if t.period > 0 {
@ -165,7 +157,7 @@ func (w *Wheel) onTick() {
} }
} }
if len(vec) > 0 { if vec.Len() > 0 {
go f(vec) go f(vec)
} }
} }
@ -178,11 +170,9 @@ func (w *Wheel) addTimer(t *timer) {
func (w *Wheel) delTimer(t *timer) { func (w *Wheel) delTimer(t *timer) {
w.Lock() w.Lock()
vec := t.vec
index := t.index
if len(vec) > index && vec[index] == t { if t.vec.Remove(t.e) != t {
vec[index] = nil panic("internal error")
} }
w.Unlock() w.Unlock()