blockchain/internal/lib/strategy/ring_queue.go

56 lines
1.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package strategy
import (
"container/list"
"github.com/shopspring/decimal"
)
/************** 基礎的固定長度隊列,用來計算移動平均 **************/
// 請注意: 目前為非併發版本,使用場警還不需要
type ringQD struct {
N uint // 窗口大小(需要保留的資料數量)需要保留的數量沒有負數
l *list.List // 用於儲存資料的雙向鏈表
sum decimal.Decimal // 當前窗口的總和,方便快速計算平均值
}
// 建立一個固定長度的隊列
func newRingQD(n uint) *ringQD {
return &ringQD{N: n, l: list.New(), sum: decimal.Zero}
}
// push將新的數值放入隊列並維護總和
func (q *ringQD) push(x decimal.Decimal) {
q.l.PushBack(x)
q.sum = q.sum.Add(x)
// 如果超出最大長度,移除最舊的數值
if uint(q.l.Len()) > q.N {
f := q.l.Front()
q.sum = q.sum.Sub(f.Value.(decimal.Decimal))
q.l.Remove(f)
}
}
// ready判斷隊列是否已經填滿
func (q *ringQD) ready() bool { return q.N > 0 && uint(q.l.Len()) == q.N }
// mean計算平均值
func (q *ringQD) mean() decimal.Decimal {
if q.l.Len() == 0 {
return decimal.Zero
}
return q.sum.Div(decimal.NewFromInt(int64(q.l.Len())))
}
// values返回隊列中所有的值複製一份不影響原資料
func (q *ringQD) values() []decimal.Decimal {
out := make([]decimal.Decimal, 0, q.l.Len())
for e := q.l.Front(); e != nil; e = e.Next() {
out = append(out, e.Value.(decimal.Decimal))
}
return out
}