gotidb/pkg/engine/engine.go

210 lines
4.7 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 engine
import (
"context"
"sort"
"strings"
"time"
)
// Engine 定义存储引擎的通用接口
type Engine interface {
// 生命周期管理
Open() error
Close() error
// 数据操作
Write(ctx context.Context, points []DataPoint) error
Query(ctx context.Context, query Query) (QueryResult, error)
// 管理功能
Compact() error
Cleanup() error
// 监控和统计
Stats() EngineStats
}
// DataPoint 表示一个时序数据点
type DataPoint struct {
Timestamp int64
Value float64
Labels map[string]string
Metadata map[string]interface{} // 可选的元数据
}
// GetSeriesID 从标签生成序列ID
func (p DataPoint) GetSeriesID() string {
// 如果没有标签返回默认ID
if len(p.Labels) == 0 {
return "default_series"
}
// 获取所有标签的键,并排序
keys := make([]string, 0, len(p.Labels))
for k := range p.Labels {
keys = append(keys, k)
}
// 按字典序排序键
sort.Strings(keys)
// 构建序列ID
var sb strings.Builder
for i, k := range keys {
if i > 0 {
sb.WriteString(",")
}
sb.WriteString(k)
sb.WriteString("=")
sb.WriteString(p.Labels[k])
}
return sb.String()
}
// QueryType 定义查询类型
type QueryType string
const (
QueryTypeRaw QueryType = "raw" // 原始数据查询
QueryTypeLatest QueryType = "latest" // 最新值查询
QueryTypeAggregate QueryType = "aggregate" // 聚合查询
QueryTypeValueDuration QueryType = "value_duration" // 值持续时间查询
)
// AggregateType 定义聚合类型
type AggregateType string
const (
AggregateTypeAvg AggregateType = "avg"
AggregateTypeSum AggregateType = "sum"
AggregateTypeMin AggregateType = "min"
AggregateTypeMax AggregateType = "max"
AggregateTypeCount AggregateType = "count"
)
// Query 表示查询请求
type Query struct {
Type QueryType
StartTime int64
EndTime int64
Tags map[string]string
Limit int
AggregateType AggregateType // 用于聚合查询
}
// QueryResult 表示查询结果
type QueryResult []SeriesResult
// SeriesResult 表示单个序列的查询结果
type SeriesResult struct {
SeriesID string
Points []DataPoint
}
// EngineStats 存储引擎统计信息
type EngineStats struct {
// 基本统计
PointsCount int64 // 数据点总数
SeriesCount int64 // 序列总数
LastWriteTime time.Time // 最后写入时间
// 性能指标
WriteLatency time.Duration // 平均写入延迟
QueryLatency time.Duration // 平均查询延迟
// 资源使用
MemoryUsage int64 // 内存使用量(字节)
DiskUsage int64 // 磁盘使用量(字节)
// 引擎特定指标
CompactionCount int64 // 压缩次数
LastCompaction time.Time // 最后压缩时间
WriteErrors int64 // 写入错误次数
QueryErrors int64 // 查询错误次数
}
// WriteBufferHandler 定义写入缓冲区处理器接口
type WriteBufferHandler interface {
WriteToBuffer(point DataPoint) error
FlushBuffer() error
ValidatePoint(point DataPoint) error // 新增方法,只检查不写入
}
// WriteBuffer 实现写入缓冲区
type WriteBuffer struct {
handler WriteBufferHandler
buffer []DataPoint
size int
}
// NewWriteBuffer 创建新的写入缓冲区
func NewWriteBuffer(handler WriteBufferHandler, size int) *WriteBuffer {
bufferCap := size
if bufferCap < 0 {
bufferCap = 0
}
return &WriteBuffer{
handler: handler,
buffer: make([]DataPoint, 0, bufferCap),
size: size,
}
}
// Write 写入数据点到缓冲区
func (b *WriteBuffer) Write(point DataPoint) error {
// 如果缓冲区大小为0直接写入并返回
if b.size <= 0 {
if err := b.handler.WriteToBuffer(point); err != nil {
return err
}
return b.handler.FlushBuffer()
}
// 先验证数据点是否可写入(不实际写入)
if err := b.handler.ValidatePoint(point); err != nil {
return err
}
// 如果缓冲区已满,先刷新
if len(b.buffer) >= b.size {
if err := b.Flush(); err != nil {
return err
}
}
// 添加到缓冲区
b.buffer = append(b.buffer, point)
// 如果缓冲区已满,立即刷新
if len(b.buffer) >= b.size {
return b.Flush()
}
return nil
}
// Flush 刷新缓冲区
func (b *WriteBuffer) Flush() error {
if len(b.buffer) == 0 {
return nil
}
// 批量写入
for _, point := range b.buffer {
if err := b.handler.WriteToBuffer(point); err != nil {
// 即使出错也清空缓冲区,避免重复处理错误数据
b.buffer = b.buffer[:0]
// 尝试调用刷新方法,但优先返回写入错误
_ = b.handler.FlushBuffer()
return err
}
}
// 清空缓冲区
b.buffer = b.buffer[:0]
// 调用处理器的刷新方法
return b.handler.FlushBuffer()
}