1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package server
- import (
- "sync"
- "time"
- )
- const (
- queueCapacity = 200
- )
- type statsQueue struct {
- items [queueCapacity]*packageStats
- size int
- front int
- back int
- totalPkgSize int
- rwl sync.RWMutex
- }
- func (q *statsQueue) Len() int {
- return q.size
- }
- func (q *statsQueue) PkgSize() int {
- return q.totalPkgSize
- }
- // FrontAndBack gets the front and back elements in the queue
- // We must grab front and back together with the protection of the lock
- func (q *statsQueue) frontAndBack() (*packageStats, *packageStats) {
- q.rwl.RLock()
- defer q.rwl.RUnlock()
- if q.size != 0 {
- return q.items[q.front], q.items[q.back]
- }
- return nil, nil
- }
- // Insert function insert a packageStats into the queue and update the records
- func (q *statsQueue) Insert(p *packageStats) {
- q.rwl.Lock()
- defer q.rwl.Unlock()
- q.back = (q.back + 1) % queueCapacity
- if q.size == queueCapacity { //dequeue
- q.totalPkgSize -= q.items[q.front].size
- q.front = (q.back + 1) % queueCapacity
- } else {
- q.size++
- }
- q.items[q.back] = p
- q.totalPkgSize += q.items[q.back].size
- }
- // Rate function returns the package rate and byte rate
- func (q *statsQueue) Rate() (float64, float64) {
- front, back := q.frontAndBack()
- if front == nil || back == nil {
- return 0, 0
- }
- if time.Now().Sub(back.Time()) > time.Second {
- q.Clear()
- return 0, 0
- }
- sampleDuration := back.Time().Sub(front.Time())
- pr := float64(q.Len()) / float64(sampleDuration) * float64(time.Second)
- br := float64(q.PkgSize()) / float64(sampleDuration) * float64(time.Second)
- return pr, br
- }
- // Clear function clear up the statsQueue
- func (q *statsQueue) Clear() {
- q.rwl.Lock()
- defer q.rwl.Unlock()
- q.back = -1
- q.front = 0
- q.size = 0
- q.totalPkgSize = 0
- }
|