132 lines
2.6 KiB
Go
132 lines
2.6 KiB
Go
package bolt
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.pyer.club/kingecg/gotidb/pkg/engine"
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
// loadStats 从数据库加载统计信息
|
|
func (b *BoltEngine) loadStats() error {
|
|
return b.db.View(func(tx *bolt.Tx) error {
|
|
bucket := tx.Bucket([]byte(metaBucketName))
|
|
if bucket == nil {
|
|
return fmt.Errorf("meta bucket not found")
|
|
}
|
|
|
|
statsData := bucket.Get([]byte(statsKey))
|
|
if statsData == nil {
|
|
// 没有保存的统计信息,使用默认值
|
|
return nil
|
|
}
|
|
|
|
if err := json.Unmarshal(statsData, &b.stats); err != nil {
|
|
return fmt.Errorf("failed to unmarshal stats: %v", err)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// saveStats 将统计信息保存到数据库
|
|
func (b *BoltEngine) saveStats() error {
|
|
return b.db.Update(func(tx *bolt.Tx) error {
|
|
bucket := tx.Bucket([]byte(metaBucketName))
|
|
if bucket == nil {
|
|
return fmt.Errorf("meta bucket not found")
|
|
}
|
|
|
|
statsData, err := json.Marshal(b.stats)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal stats: %v", err)
|
|
}
|
|
|
|
if err := bucket.Put([]byte(statsKey), statsData); err != nil {
|
|
return fmt.Errorf("failed to save stats: %v", err)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// updateSeriesCount 更新序列数统计信息
|
|
func (b *BoltEngine) updateSeriesCount() error {
|
|
var count int64
|
|
|
|
err := b.db.View(func(tx *bolt.Tx) error {
|
|
indexBucket := tx.Bucket([]byte(indexBucketName))
|
|
if indexBucket == nil {
|
|
return fmt.Errorf("index bucket not found")
|
|
}
|
|
|
|
count = int64(indexBucket.Stats().KeyN)
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
b.stats.SeriesCount = count
|
|
return nil
|
|
}
|
|
|
|
// matchTags 检查数据点的标签是否匹配查询标签
|
|
func matchTags(pointTags, queryTags map[string]string) bool {
|
|
for k, v := range queryTags {
|
|
if pointTags[k] != v {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// calculateAggregate 计算聚合值
|
|
func calculateAggregate(points []engine.DataPoint, aggregateType engine.AggregateType) float64 {
|
|
if len(points) == 0 {
|
|
return 0
|
|
}
|
|
|
|
switch aggregateType {
|
|
case engine.AggregateTypeAvg:
|
|
sum := 0.0
|
|
for _, p := range points {
|
|
sum += p.Value
|
|
}
|
|
return sum / float64(len(points))
|
|
|
|
case engine.AggregateTypeSum:
|
|
sum := 0.0
|
|
for _, p := range points {
|
|
sum += p.Value
|
|
}
|
|
return sum
|
|
|
|
case engine.AggregateTypeMin:
|
|
min := points[0].Value
|
|
for _, p := range points {
|
|
if p.Value < min {
|
|
min = p.Value
|
|
}
|
|
}
|
|
return min
|
|
|
|
case engine.AggregateTypeMax:
|
|
max := points[0].Value
|
|
for _, p := range points {
|
|
if p.Value > max {
|
|
max = p.Value
|
|
}
|
|
}
|
|
return max
|
|
|
|
case engine.AggregateTypeCount:
|
|
return float64(len(points))
|
|
|
|
default:
|
|
return 0
|
|
}
|
|
}
|