Files
quic-go/stream_frame_queue.go
Lucas Clemente 864105271e privatize streamFrameQueue
ref #60
2016-05-15 15:27:39 +02:00

86 lines
2.0 KiB
Go

package quic
import (
"sync"
"github.com/lucas-clemente/quic-go/frames"
"github.com/lucas-clemente/quic-go/protocol"
)
// streamFrameQueue is a Queue that handles StreamFrames
type streamFrameQueue struct {
prioFrames []*frames.StreamFrame
frames []*frames.StreamFrame
mutex sync.Mutex
}
// Push adds a new StreamFrame to the queue
func (q *streamFrameQueue) Push(frame *frames.StreamFrame, prio bool) {
q.mutex.Lock()
defer q.mutex.Unlock()
if prio {
q.prioFrames = append(q.prioFrames, frame)
} else {
q.frames = append(q.frames, frame)
}
}
// Len returns the total number of queued StreamFrames
func (q *streamFrameQueue) Len() int {
q.mutex.Lock()
defer q.mutex.Unlock()
return len(q.prioFrames) + len(q.frames)
}
// ByteLen returns the total number of bytes queued
func (q *streamFrameQueue) ByteLen() protocol.ByteCount {
q.mutex.Lock()
defer q.mutex.Unlock()
// TODO: improve performance
// This is a very unperformant implementation. However, the obvious solution of keeping track of the length on Push() and Pop() doesn't work, since the front frame can be split by the PacketPacker
var length protocol.ByteCount
for _, frame := range q.prioFrames {
length += protocol.ByteCount(len(frame.Data))
}
for _, frame := range q.frames {
length += protocol.ByteCount(len(frame.Data))
}
return length
}
// Pop returns the next element and deletes it from the queue
func (q *streamFrameQueue) Pop() *frames.StreamFrame {
q.mutex.Lock()
defer q.mutex.Unlock()
if len(q.prioFrames) > 0 {
frame := q.prioFrames[0]
q.prioFrames = q.prioFrames[1:]
return frame
}
if len(q.frames) > 0 {
frame := q.frames[0]
q.frames = q.frames[1:]
return frame
}
return nil
}
// Front returns the next element without modifying the queue
func (q *streamFrameQueue) Front() *frames.StreamFrame {
q.mutex.Lock()
defer q.mutex.Unlock()
if len(q.prioFrames) > 0 {
return q.prioFrames[0]
}
if len(q.frames) > 0 {
return q.frames[0]
}
return nil
}