mirror of https://github.com/ginuerzh/gost
5 changed files with 147 additions and 7 deletions
@ -0,0 +1,108 @@ |
|||||
|
// pool for buffer
|
||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"container/list" |
||||
|
//"log"
|
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
type poolItem struct { |
||||
|
when time.Time |
||||
|
item interface{} |
||||
|
} |
||||
|
|
||||
|
type pool struct { |
||||
|
quque *list.List |
||||
|
takeChan, putChan chan interface{} |
||||
|
age time.Duration |
||||
|
max int |
||||
|
} |
||||
|
|
||||
|
func (p *pool) run() { |
||||
|
for { |
||||
|
if p.size() == 0 { |
||||
|
select { |
||||
|
case b := <-p.putChan: |
||||
|
p.put(b) |
||||
|
} |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
i := p.quque.Front() |
||||
|
timeout := time.NewTimer(p.age) |
||||
|
|
||||
|
select { |
||||
|
case b := <-p.putChan: |
||||
|
timeout.Stop() |
||||
|
p.put(b) |
||||
|
case p.takeChan <- i.Value.(*poolItem).item: |
||||
|
timeout.Stop() |
||||
|
p.quque.Remove(i) |
||||
|
case <-timeout.C: |
||||
|
i = p.quque.Back() |
||||
|
for i != nil { |
||||
|
if time.Since(i.Value.(*poolItem).when) < p.age { |
||||
|
break |
||||
|
} |
||||
|
e := i.Prev() |
||||
|
p.quque.Remove(i) |
||||
|
i = e |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (p *pool) size() int { |
||||
|
return p.quque.Len() |
||||
|
} |
||||
|
|
||||
|
func (p *pool) put(v interface{}) { |
||||
|
if p.size() < p.max { |
||||
|
p.quque.PushFront(&poolItem{when: time.Now(), item: v}) |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
type MemPool struct { |
||||
|
pool |
||||
|
bs int |
||||
|
} |
||||
|
|
||||
|
func NewMemPool(bs int, age time.Duration, max int) *MemPool { |
||||
|
if bs <= 0 { |
||||
|
bs = 8192 |
||||
|
} |
||||
|
|
||||
|
if age == 0 { |
||||
|
age = 1 * time.Minute |
||||
|
} |
||||
|
|
||||
|
p := &MemPool{ |
||||
|
pool: pool{ |
||||
|
quque: list.New(), |
||||
|
takeChan: make(chan interface{}), |
||||
|
putChan: make(chan interface{}), |
||||
|
age: age, |
||||
|
max: max, |
||||
|
}, |
||||
|
bs: bs, |
||||
|
} |
||||
|
|
||||
|
go p.run() |
||||
|
|
||||
|
return p |
||||
|
} |
||||
|
|
||||
|
func (p *MemPool) Take() []byte { |
||||
|
select { |
||||
|
case v := <-p.takeChan: |
||||
|
return v.([]byte) |
||||
|
default: |
||||
|
return make([]byte, p.bs) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (p *MemPool) Put(b []byte) { |
||||
|
p.putChan <- b |
||||
|
} |
||||
Loading…
Reference in new issue