Files
EdgeNode/internal/utils/counters/item.go

111 lines
2.6 KiB
Go
Raw Normal View History

// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package counters
import (
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
)
type Item struct {
lifeSeconds int64
spanSeconds int64
spans []uint64
lastUpdateTime int64
}
func NewItem(lifeSeconds int) *Item {
if lifeSeconds <= 0 {
lifeSeconds = 60
}
var spanSeconds = lifeSeconds / 10
if spanSeconds < 1 {
spanSeconds = 1
}
var countSpans = lifeSeconds/spanSeconds + 1 /** prevent index out of bounds **/
return &Item{
lifeSeconds: int64(lifeSeconds),
spanSeconds: int64(spanSeconds),
spans: make([]uint64, countSpans),
lastUpdateTime: fasttime.Now().Unix(),
}
}
func (this *Item) Increase() uint64 {
var currentTime = fasttime.Now().Unix()
var currentSpanIndex = this.calculateSpanIndex(currentTime)
// return quickly
if this.lastUpdateTime == currentTime {
this.spans[currentSpanIndex]++
return this.Sum()
}
if this.lastUpdateTime > 0 {
if currentTime-this.lastUpdateTime > this.lifeSeconds {
for index := range this.spans {
this.spans[index] = 0
}
} else {
var lastSpanIndex = this.calculateSpanIndex(this.lastUpdateTime)
var countSpans = len(this.spans)
// reset values between LAST and CURRENT
for index := lastSpanIndex + 1; ; index++ {
var realIndex = index % countSpans
if realIndex <= currentSpanIndex {
this.spans[realIndex] = 0
}
if realIndex == currentSpanIndex {
break
}
}
}
}
this.spans[currentSpanIndex]++
this.lastUpdateTime = currentTime
return this.Sum()
}
func (this *Item) Sum() (result uint64) {
if this.lastUpdateTime == 0 {
return 0
}
var currentTime = fasttime.Now().Unix()
var currentSpanIndex = this.calculateSpanIndex(currentTime)
if currentTime-this.lastUpdateTime > this.lifeSeconds {
return 0
} else {
var lastSpanIndex = this.calculateSpanIndex(this.lastUpdateTime)
var countSpans = len(this.spans)
for index := 0; index < countSpans; index++ {
if (currentSpanIndex >= lastSpanIndex && (index <= lastSpanIndex || index >= currentSpanIndex /** a >=b **/)) ||
(currentSpanIndex < lastSpanIndex && index >= currentSpanIndex && index <= lastSpanIndex /** a < b **/) {
result += this.spans[index]
}
}
}
return result
}
func (this *Item) Reset() {
for index := range this.spans {
this.spans[index] = 0
}
}
2023-07-15 11:08:25 +08:00
func (this *Item) IsExpired(currentTime int64) bool {
return this.lastUpdateTime < currentTime-this.lifeSeconds-this.spanSeconds
}
func (this *Item) calculateSpanIndex(timestamp int64) int {
return int(timestamp % this.lifeSeconds / this.spanSeconds)
}