mirror of
https://github.com/jech/galene.git
synced 2024-11-23 00:55:58 +01:00
2454e33df3
This avoids locking in estimate.
69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
package estimator
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"sfu/rtptime"
|
|
)
|
|
|
|
type Estimator struct {
|
|
interval uint64
|
|
time uint64
|
|
bytes uint32
|
|
packets uint32
|
|
totalBytes uint32
|
|
totalPackets uint32
|
|
rate uint32
|
|
packetRate uint32
|
|
}
|
|
|
|
func New(interval time.Duration) *Estimator {
|
|
return &Estimator{
|
|
interval: rtptime.FromDuration(interval, rtptime.JiffiesPerSec),
|
|
time: rtptime.Now(rtptime.JiffiesPerSec),
|
|
}
|
|
}
|
|
|
|
func (e *Estimator) swap(now uint64) {
|
|
tm := atomic.LoadUint64(&e.time)
|
|
jiffies := now - tm
|
|
bytes := atomic.SwapUint32(&e.bytes, 0)
|
|
packets := atomic.SwapUint32(&e.packets, 0)
|
|
atomic.AddUint32(&e.totalBytes, bytes)
|
|
atomic.AddUint32(&e.totalPackets, packets)
|
|
|
|
var rate, packetRate uint32
|
|
if jiffies >= rtptime.JiffiesPerSec/1000 {
|
|
rate = uint32(uint64(bytes) * rtptime.JiffiesPerSec / jiffies)
|
|
packetRate =
|
|
uint32(uint64(packets) * rtptime.JiffiesPerSec / jiffies)
|
|
}
|
|
atomic.StoreUint32(&e.rate, rate)
|
|
atomic.StoreUint32(&e.packetRate, packetRate)
|
|
atomic.StoreUint64(&e.time, now)
|
|
}
|
|
|
|
func (e *Estimator) Accumulate(count uint32) {
|
|
atomic.AddUint32(&e.bytes, count)
|
|
atomic.AddUint32(&e.packets, 1)
|
|
}
|
|
|
|
func (e *Estimator) estimate(now uint64) (uint32, uint32) {
|
|
tm := atomic.LoadUint64(&e.time)
|
|
if now < tm || now-tm > e.interval {
|
|
e.swap(now)
|
|
}
|
|
|
|
return atomic.LoadUint32(&e.rate), atomic.LoadUint32(&e.packetRate)
|
|
}
|
|
|
|
func (e *Estimator) Estimate() (uint32, uint32) {
|
|
return e.estimate(rtptime.Now(rtptime.JiffiesPerSec))
|
|
}
|
|
|
|
func (e *Estimator) Totals() (uint32, uint32) {
|
|
b := atomic.LoadUint32(&e.totalBytes) + atomic.LoadUint32(&e.bytes)
|
|
p := atomic.LoadUint32(&e.totalPackets) + atomic.LoadUint32(&e.packets)
|
|
return p, b
|
|
}
|