gotidb/pkg/engine/bolt/bolt_utils.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
}
}