// 時間視窗 var fiveMinAccMap = NewAccumulatorsMap(5 * time.Minute) var tenMinAccMap = NewAccumulatorsMap(10 * time.Minute) var fifteenMinAccMap = NewAccumulatorsMap(15 * time.Minute) var thirtyMinAccMap = NewAccumulatorsMap(30 * time.Minute) var oneHourAccMap = NewAccumulatorsMap(time.Hour) // Accumulator 結構用於儲存單個鍵的相關資訊 type Accumulator struct { sync.Mutex // 用於同步訪問累加器 window *list.List // 雙向連結串列,用於儲存時間視窗內的值 total float64 // 視窗內的總增加量 max float64 // 視窗內的最大值 min float64 // 視窗內的最小值 windowSize time.Duration // 視窗大小 } // NewAccumulator 建立一個新的增加量累加器例項 func NewAccumulator(windowSize time.Duration) *Accumulator { return &Accumulator{ window: list.New(), windowSize: windowSize, max: math.Inf(-1), min: math.Inf(1), } } // AddAcc 增加一個新的值到累加器 func (acc *Accumulator) AddAcc(value float64, timestamp time.Time) { acc.Lock() defer acc.Unlock() // 建立一個新的節點儲存增加值和時間戳 _ = acc.window.PushFront(struct { Value float64 Timestamp time.Time }{Value: value, Timestamp: timestamp}) acc.total += value // 移除過期項(超過時間視窗的項) now := time.Now() for e := acc.window.Back(); e != nil; { entry := e.Value.(struct { Value float64 Timestamp time.Time }) if now.Sub(entry.Timestamp) > acc.windowSize { acc.total -= entry.Value next := e.Prev() acc.window.Remove(e) e = next } else { break } } } // MaxAcc 增加一個新的值到累加器 func (acc *Accumulator) MaxAcc(value float64, timestamp time.Time) { acc.Lock() defer acc.Unlock() // 建立一個新的節點儲存增加值和時間戳 _ = acc.window.PushFront(struct { Value float64 Timestamp time.Time }{Value: value, Timestamp: timestamp}) if value > acc.max { acc.max = value } // 移除過期項(超過時間視窗的項) now := time.Now() for e := acc.window.Back(); e != nil; { oldEntry := e.Value.(struct { Value float64 Timestamp time.Time }) if now.Sub(oldEntry.Timestamp) > acc.windowSize { acc.total -= oldEntry.Value // 檢查移除的項是否是當前最大值,如果是則需要重新計算最大值 if oldEntry.Value == acc.max { acc.recalculateMaxValue() } next := e.Prev() acc.window.Remove(e) e = next } else { break } } } // recalculateMaxValue 重新計算當前時間視窗內的最大值 func (acc *Accumulator) recalculateMaxValue() { // 負無窮大 var maxValue = math.Inf(-1) for e := acc.window.Front(); e != nil; e = e.Next() { entry := e.Value.(struct { Value float64 Timestamp time.Time }) if entry.Value > maxValue { maxValue = entry.Value } } acc.max = maxValue // 更新累加器中的最大值 } // MinAcc 增加一個新的值到累加器 func (acc *Accumulator) MinAcc(value float64, timestamp time.Time) { acc.Lock() defer acc.Unlock() // 建立一個新的節點儲存增加值和時間戳 _ = acc.window.PushFront(struct { Value float64 Timestamp time.Time }{Value: value, Timestamp: timestamp}) if value < acc.min { acc.min = value } // 移除過期項(超過時間視窗的項) now := time.Now() for e := acc.window.Back(); e != nil; { oldEntry := e.Value.(struct { Value float64 Timestamp time.Time }) if now.Sub(oldEntry.Timestamp) > acc.windowSize { acc.total -= oldEntry.Value // 檢查移除的項是否是當前最大值,如果是則需要重新計算最小值 if oldEntry.Value == acc.min { acc.recalculateMinValue() } next := e.Prev() acc.window.Remove(e) e = next } else { break } } } // recalculateMaxValue 重新計算當前時間視窗內的最小值 func (acc *Accumulator) recalculateMinValue() { // 正無窮大 var minValue = math.Inf(1) for e := acc.window.Front(); e != nil; e = e.Next() { entry := e.Value.(struct { Value float64 Timestamp time.Time }) if entry.Value < minValue { minValue = entry.Value } } acc.min = minValue // 更新累加器中的最小值 } // GetMaxValue 獲取當前時間視窗內的最大值 func (acc *Accumulator) GetMaxValue() float64 { acc.Lock() defer acc.Unlock() return acc.max } // GetMinValue 獲取當前時間視窗內的最小值 func (acc *Accumulator) GetMinValue() float64 { acc.Lock() defer acc.Unlock() return acc.min } // GetTotalIncrease 獲取當前時間視窗內的總增加量 func (acc *Accumulator) GetTotalIncrease() float64 { acc.Lock() defer acc.Unlock() return acc.total } // AccumulatorsMap 儲存不同鍵的累加器Map type AccumulatorsMap struct { sync.RWMutex accumulators map[string]*Accumulator windowSize time.Duration } // NewAccumulatorsMap 建立一個新的時間視窗例項 func NewAccumulatorsMap(windowSize time.Duration) *AccumulatorsMap { return &AccumulatorsMap{ accumulators: make(map[string]*Accumulator), windowSize: windowSize, } } // AddAccMap 增加一個新的值到累加器 func (am *AccumulatorsMap) AddAccMap(key string, value float64) { am.Lock() acc, exists := am.accumulators[key] if !exists { acc = NewAccumulator(am.windowSize) am.accumulators[key] = acc } am.Unlock() acc.AddAcc(value, time.Now()) } // MaxAccMap 增加一個新的值到累加器 func (am *AccumulatorsMap) MaxAccMap(key string, value float64) { am.Lock() acc, exists := am.accumulators[key] if !exists { acc = NewAccumulator(am.windowSize) am.accumulators[key] = acc } am.Unlock() acc.MaxAcc(value, time.Now()) } // MinAccMap 增加一個新的值到累加器 func (am *AccumulatorsMap) MinAccMap(key string, value float64) { am.Lock() acc, exists := am.accumulators[key] if !exists { acc = NewAccumulator(am.windowSize) am.accumulators[key] = acc } am.Unlock() acc.MinAcc(value, time.Now()) } // GetTotalIncrease 獲取key的當前時間視窗內的總增加量 func (am *AccumulatorsMap) GetTotalIncrease(key string) float64 { am.RLock() acc, exists := am.accumulators[key] am.RUnlock() if exists { return acc.GetTotalIncrease() } return 0 } // GetMax 獲取key的當前時間視窗內的最大值 func (am *AccumulatorsMap) GetMax(key string) float64 { am.RLock() acc, exists := am.accumulators[key] am.RUnlock() if exists { return acc.GetMaxValue() } return 0 } // GetMin 獲取key的當前時間視窗內的最小值 func (am *AccumulatorsMap) GetMin(key string) float64 { am.RLock() acc, exists := am.accumulators[key] am.RUnlock() if exists { return acc.GetMinValue() } return 0 }