mirror of
https://github.com/ehang-io/nps.git
synced 2025-09-06 07:06:53 +00:00
change slide window design
This commit is contained in:
148
lib/mux/queue.go
148
lib/mux/queue.go
@@ -2,25 +2,54 @@ package mux
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"errors"
|
||||
"github.com/cnlh/nps/lib/common"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Queue struct {
|
||||
list *list.List
|
||||
type QueueOp struct {
|
||||
readOp chan struct{}
|
||||
cleanOp chan struct{}
|
||||
popWait bool
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func (Self *Queue) New() {
|
||||
Self.list = list.New()
|
||||
func (Self *QueueOp) New() {
|
||||
Self.readOp = make(chan struct{})
|
||||
Self.cleanOp = make(chan struct{}, 2)
|
||||
}
|
||||
|
||||
func (Self *Queue) Push(packager *common.MuxPackager) {
|
||||
func (Self *QueueOp) allowPop() (closed bool) {
|
||||
Self.mutex.Lock()
|
||||
Self.popWait = false
|
||||
Self.mutex.Unlock()
|
||||
select {
|
||||
case Self.readOp <- struct{}{}:
|
||||
return false
|
||||
case <-Self.cleanOp:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (Self *QueueOp) Clean() {
|
||||
Self.cleanOp <- struct{}{}
|
||||
Self.cleanOp <- struct{}{}
|
||||
close(Self.cleanOp)
|
||||
}
|
||||
|
||||
type PriorityQueue struct {
|
||||
list *list.List
|
||||
QueueOp
|
||||
}
|
||||
|
||||
func (Self *PriorityQueue) New() {
|
||||
Self.list = list.New()
|
||||
Self.QueueOp.New()
|
||||
}
|
||||
|
||||
func (Self *PriorityQueue) Push(packager *common.MuxPackager) {
|
||||
Self.mutex.Lock()
|
||||
if Self.popWait {
|
||||
defer Self.allowPop()
|
||||
@@ -35,28 +64,16 @@ func (Self *Queue) Push(packager *common.MuxPackager) {
|
||||
return
|
||||
}
|
||||
|
||||
func (Self *Queue) allowPop() (closed bool) {
|
||||
Self.mutex.Lock()
|
||||
Self.popWait = false
|
||||
Self.mutex.Unlock()
|
||||
select {
|
||||
case Self.readOp <- struct{}{}:
|
||||
return false
|
||||
case <-Self.cleanOp:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (Self *Queue) insert(packager *common.MuxPackager) {
|
||||
func (Self *PriorityQueue) insert(packager *common.MuxPackager) {
|
||||
element := Self.list.Back()
|
||||
for {
|
||||
if element == nil { // Queue dose not have any of msg package with this close package id
|
||||
if element == nil { // PriorityQueue dose not have any of msg package with this close package id
|
||||
Self.list.PushFront(packager) // insert close package to first
|
||||
break
|
||||
}
|
||||
if element.Value.(*common.MuxPackager).Flag == common.MUX_NEW_MSG &&
|
||||
element.Value.(*common.MuxPackager).Id == packager.Id {
|
||||
Self.list.InsertAfter(packager, element) // Queue has some msg package
|
||||
Self.list.InsertAfter(packager, element) // PriorityQueue has some msg package
|
||||
// with this close package id, insert close package after last msg package
|
||||
break
|
||||
}
|
||||
@@ -64,7 +81,7 @@ func (Self *Queue) insert(packager *common.MuxPackager) {
|
||||
}
|
||||
}
|
||||
|
||||
func (Self *Queue) Pop() (packager *common.MuxPackager) {
|
||||
func (Self *PriorityQueue) Pop() (packager *common.MuxPackager) {
|
||||
Self.mutex.Lock()
|
||||
element := Self.list.Front()
|
||||
if element != nil {
|
||||
@@ -73,7 +90,7 @@ func (Self *Queue) Pop() (packager *common.MuxPackager) {
|
||||
Self.mutex.Unlock()
|
||||
return
|
||||
}
|
||||
Self.popWait = true // Queue is empty, notice Push method
|
||||
Self.popWait = true // PriorityQueue is empty, notice Push method
|
||||
Self.mutex.Unlock()
|
||||
select {
|
||||
case <-Self.readOp:
|
||||
@@ -83,13 +100,90 @@ func (Self *Queue) Pop() (packager *common.MuxPackager) {
|
||||
}
|
||||
}
|
||||
|
||||
func (Self *Queue) Len() (n int) {
|
||||
func (Self *PriorityQueue) Len() (n int) {
|
||||
n = Self.list.Len()
|
||||
return
|
||||
}
|
||||
|
||||
func (Self *Queue) Clean() {
|
||||
Self.cleanOp <- struct{}{}
|
||||
Self.cleanOp <- struct{}{}
|
||||
close(Self.cleanOp)
|
||||
type ListElement struct {
|
||||
buf []byte
|
||||
l uint16
|
||||
part bool
|
||||
}
|
||||
|
||||
func (Self *ListElement) New(buf []byte, l uint16, part bool) (err error) {
|
||||
if uint16(len(buf)) != l {
|
||||
return errors.New("ListElement: buf length not match")
|
||||
}
|
||||
Self.buf = buf
|
||||
Self.l = l
|
||||
Self.part = part
|
||||
return nil
|
||||
}
|
||||
|
||||
type FIFOQueue struct {
|
||||
list []*ListElement
|
||||
length uint32
|
||||
stopOp chan struct{}
|
||||
timeout time.Time
|
||||
QueueOp
|
||||
}
|
||||
|
||||
func (Self *FIFOQueue) New() {
|
||||
Self.QueueOp.New()
|
||||
Self.stopOp = make(chan struct{}, 1)
|
||||
}
|
||||
|
||||
func (Self *FIFOQueue) Push(element *ListElement) {
|
||||
Self.mutex.Lock()
|
||||
if Self.popWait {
|
||||
defer Self.allowPop()
|
||||
}
|
||||
Self.list = append(Self.list, element)
|
||||
Self.length += uint32(element.l)
|
||||
Self.mutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (Self *FIFOQueue) Pop() (element *ListElement, err error) {
|
||||
Self.mutex.Lock()
|
||||
if len(Self.list) == 0 {
|
||||
Self.popWait = true
|
||||
Self.mutex.Unlock()
|
||||
t := Self.timeout.Sub(time.Now())
|
||||
if t <= 0 {
|
||||
t = time.Minute
|
||||
}
|
||||
timer := time.NewTimer(t)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-Self.readOp:
|
||||
Self.mutex.Lock()
|
||||
case <-Self.cleanOp:
|
||||
return
|
||||
case <-Self.stopOp:
|
||||
err = io.EOF
|
||||
return
|
||||
case <-timer.C:
|
||||
err = errors.New("mux.queue: read time out")
|
||||
return
|
||||
}
|
||||
}
|
||||
element = Self.list[0]
|
||||
Self.list = Self.list[1:]
|
||||
Self.length -= uint32(element.l)
|
||||
Self.mutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (Self *FIFOQueue) Len() (n uint32) {
|
||||
return Self.length
|
||||
}
|
||||
|
||||
func (Self *FIFOQueue) Stop() {
|
||||
Self.stopOp <- struct{}{}
|
||||
}
|
||||
|
||||
func (Self *FIFOQueue) SetTimeOut(t time.Time) {
|
||||
Self.timeout = t
|
||||
}
|
||||
|
Reference in New Issue
Block a user