Files
qb/proto/proto.go

449 lines
9.3 KiB
Go
Raw Normal View History

2026-02-10 14:02:11 +00:00
package proto
import (
"fmt"
"time"
2026-06-10 06:18:45 +03:00
bin "gordenko.dev/dima/bin/little"
"gordenko.dev/dima/qb"
2026-02-10 14:02:11 +00:00
"gordenko.dev/dima/qb/bufreader"
)
const (
TypeDeleteMeasures byte = 1
TypeListCurrentValues byte = 2
TypeListInstantMeasures byte = 3
TypeListCumulativeMeasures byte = 33
TypeListInstantPeriods byte = 4
TypeListCumulativePeriods byte = 44
TypeGetMetric byte = 5
TypeAddMetric byte = 6
TypeListAllInstantMeasures byte = 8
TypeListAllCumulativeMeasures byte = 88
TypeAppendMeasure byte = 10
TypeAppendMeasures byte = 11
TypeDeleteMetric byte = 12
RespPartOfValue byte = 255
RespEndOfValue byte = 254
RespError byte = 253
RespSuccess byte = 252
RespValue byte = 251
ErrNoMetric = 1
ErrDuplicate = 2
ErrWrongMetricType = 3
ErrWrongFracDigits = 4
ErrExpiredMeasure = 5
ErrNonMonotonicValue = 6
ErrEmptyMetricID = 7
ErrInvalidRange = 8
ErrUnexpected = 9
)
func ErrorCodeToText(code uint16) string {
switch code {
case ErrNoMetric:
return "NoMetric"
case ErrDuplicate:
return "Duplicate"
case ErrWrongMetricType:
return "WrongMetricType"
case ErrWrongFracDigits:
return "WrongFracDigits"
case ErrExpiredMeasure:
return "ExpiredMeasure"
case ErrNonMonotonicValue:
return "NonMonotonicValue"
case ErrEmptyMetricID:
return "EmptyMetricID"
case ErrInvalidRange:
return "InvalidRange"
case ErrUnexpected:
return "Unexpected"
default:
return ""
}
}
// common
type Metric struct {
MetricID uint32
2026-06-10 06:18:45 +03:00
MetricType qb.MetricType
2026-02-10 14:02:11 +00:00
FracDigits int
}
type AppendError struct {
MetricID uint32
ErrorCode uint16
}
type TimeBound struct {
Year int
Month time.Month
Day int
}
type CumulativeMeasure struct {
Timestamp uint32
Value float64
Total float64
}
type CumulativePeriod struct {
Period uint32
Since uint32
Until uint32
EndValue float64
Total float64
}
type InstantMeasure struct {
Timestamp uint32
Value float64
}
type InstantPeriod struct {
Period uint32
Since uint32
Until uint32
Min float64
Max float64
Avg float64
}
type CurrentValue struct {
MetricID uint32
Timestamp uint32
Value float64
}
// API reqs
type GetMetricReq struct {
MetricID uint32
}
func ReadGetMetricReq(r *bufreader.BufferedReader) (m GetMetricReq, err error) {
m.MetricID, err = bin.ReadUint32(r)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return
}
type ListCurrentValuesReq struct {
MetricIDs []uint32
}
func ReadListCurrentValuesReq(r *bufreader.BufferedReader) (m ListCurrentValuesReq, err error) {
qty, err := bin.ReadUint16(r)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
for i := range int(qty) {
var metricID uint32
metricID, err = bin.ReadUint32(r)
if err != nil {
err = fmt.Errorf("read metricID (#%d): %s", i, err)
return
}
m.MetricIDs = append(m.MetricIDs, metricID)
}
return
}
type AddMetricReq struct {
MetricID uint32
2026-06-10 06:18:45 +03:00
MetricType qb.MetricType
2026-06-12 06:11:57 +00:00
FracDigits byte
2026-02-10 14:02:11 +00:00
}
func ReadAddMetricReq(r *bufreader.BufferedReader) (m AddMetricReq, err error) {
arr, err := r.ReadN(6)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackAddMetricReq(arr), nil
}
func UnpackAddMetricReq(arr []byte) (m AddMetricReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr)
m.MetricType = qb.MetricType(arr[4])
2026-06-12 06:11:57 +00:00
m.FracDigits = arr[5]
2026-02-10 14:02:11 +00:00
return
}
type DeleteMetricReq struct {
MetricID uint32
}
func ReadDeleteMetricReq(r *bufreader.BufferedReader) (m DeleteMetricReq, err error) {
m.MetricID, err = bin.ReadUint32(r)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return
}
type DeleteMeasuresReq struct {
MetricID uint32
Since uint32 // timestamp (optional)
}
func ReadDeleteMeasuresReq(r *bufreader.BufferedReader) (m DeleteMeasuresReq, err error) {
arr, err := r.ReadN(8)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackDeleteMeasuresReq(arr), nil
}
func UnpackDeleteMeasuresReq(arr []byte) (m DeleteMeasuresReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr)
m.Since, _ = bin.GetUint32(arr[4:])
2026-02-10 14:02:11 +00:00
return
}
type AppendMeasureReq struct {
MetricID uint32
Timestamp uint32
Value float64
}
func ReadAppendMeasureReq(r *bufreader.BufferedReader) (m AppendMeasureReq, err error) {
arr, err := r.ReadN(16)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackAppendMeasureReq(arr), nil
}
func UnpackAppendMeasureReq(arr []byte) (m AppendMeasureReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr)
m.Timestamp, _ = bin.GetUint32(arr[4:])
m.Value, _ = bin.GetFloat64(arr[8:])
2026-02-10 14:02:11 +00:00
return
}
type AppendMeasuresReq struct {
MetricID uint32
Measures []Measure
}
type Measure struct {
Timestamp uint32
Value float64
}
func ReadAppendMeasuresReq(r *bufreader.BufferedReader) (m AppendMeasuresReq, err error) {
prefix, err := bin.ReadN(r, 6) // metricID + measures qty
if err != nil {
err = fmt.Errorf("read prefix: %s", err)
return
}
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(prefix[0:])
qty, _ := bin.GetUint16(prefix[4:])
2026-02-10 14:02:11 +00:00
for i := range int(qty) {
var measure Measure
measure.Timestamp, err = bin.ReadUint32(r)
if err != nil {
err = fmt.Errorf("read timestamp (#%d): %s", i, err)
return
}
measure.Value, err = bin.ReadFloat64(r)
if err != nil {
err = fmt.Errorf("read value (#%d): %s", i, err)
return
}
m.Measures = append(m.Measures, measure)
}
return
}
type MetricMeasure struct {
MetricID uint32
Timestamp uint32
Value float64
}
func ReadAppendMeasurePerMetricReq(r *bufreader.BufferedReader) (measures []MetricMeasure, err error) {
2026-06-10 06:18:45 +03:00
count, err := bin.ReadUint16(r)
2026-02-10 14:02:11 +00:00
if err != nil {
return
}
2026-06-10 06:18:45 +03:00
for range count {
var m MetricMeasure
m.MetricID, err = bin.ReadUint32(r)
if err != nil {
return
}
m.Timestamp, err = bin.ReadUint32(r)
if err != nil {
return
}
m.Value, err = bin.ReadFloat64(r)
2026-02-10 14:02:11 +00:00
if err != nil {
return
}
2026-06-10 06:18:45 +03:00
measures = append(measures, m)
2026-02-10 14:02:11 +00:00
}
return
}
type ListAllInstantMetricMeasuresReq struct {
MetricID uint32
}
func ReadListAllInstantMeasuresReq(r *bufreader.BufferedReader) (m ListAllInstantMetricMeasuresReq, err error) {
m.MetricID, err = bin.ReadUint32(r)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return
}
type ListAllCumulativeMeasuresReq struct {
MetricID uint32
}
func ReadListAllCumulativeMeasuresReq(r *bufreader.BufferedReader) (m ListAllCumulativeMeasuresReq, err error) {
m.MetricID, err = bin.ReadUint32(r)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return
}
type ListInstantMeasuresReq struct {
MetricID uint32
Since uint32
Until uint32
}
func ReadListInstantMeasuresReq(r *bufreader.BufferedReader) (m ListInstantMeasuresReq, err error) {
arr, err := r.ReadN(12)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackListInstantMeasuresReq(arr), nil
}
func UnpackListInstantMeasuresReq(arr []byte) (m ListInstantMeasuresReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr[0:])
m.Since, _ = bin.GetUint32(arr[4:])
m.Until, _ = bin.GetUint32(arr[8:])
2026-02-10 14:02:11 +00:00
return
}
type ListCumulativeMeasuresReq struct {
MetricID uint32
Since uint32
Until uint32
}
func ReadListCumulativeMeasuresReq(r *bufreader.BufferedReader) (m ListCumulativeMeasuresReq, err error) {
arr, err := r.ReadN(12)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackListCumulativeMeasuresReq(arr), nil
}
func UnpackListCumulativeMeasuresReq(arr []byte) (m ListCumulativeMeasuresReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr)
m.Since, _ = bin.GetUint32(arr[4:])
m.Until, _ = bin.GetUint32(arr[8:])
2026-02-10 14:02:11 +00:00
return
}
type ListInstantPeriodsReq struct {
MetricID uint32
Since TimeBound
Until TimeBound
2026-06-10 06:18:45 +03:00
GroupBy qb.GroupBy
2026-02-10 14:02:11 +00:00
AggregateFuncs byte
FirstHourOfDay int
}
func ReadListInstantPeriodsReq(r *bufreader.BufferedReader) (m ListInstantPeriodsReq, err error) {
arr, err := r.ReadN(15)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackListInstantPeriodsReq(arr), nil
}
func UnpackListInstantPeriodsReq(arr []byte) (m ListInstantPeriodsReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr)
sinceYear, _ := bin.GetUint16(arr[4:])
untilYear, _ := bin.GetUint16(arr[8:])
2026-02-10 14:02:11 +00:00
m.Since = TimeBound{
2026-06-10 06:18:45 +03:00
Year: int(sinceYear),
2026-02-10 14:02:11 +00:00
Month: time.Month(arr[6]),
Day: int(arr[7]),
}
m.Until = TimeBound{
2026-06-10 06:18:45 +03:00
Year: int(untilYear),
2026-02-10 14:02:11 +00:00
Month: time.Month(arr[10]),
Day: int(arr[11]),
}
2026-06-10 06:18:45 +03:00
m.GroupBy = qb.GroupBy(arr[12])
2026-02-10 14:02:11 +00:00
m.AggregateFuncs = arr[13]
m.FirstHourOfDay = int(arr[14])
return
}
type ListCumulativePeriodsReq struct {
MetricID uint32
Since TimeBound
Until TimeBound
2026-06-10 06:18:45 +03:00
GroupBy qb.GroupBy
2026-02-10 14:02:11 +00:00
FirstHourOfDay int
}
func ReadListCumulativePeriodsReq(r *bufreader.BufferedReader) (m ListCumulativePeriodsReq, err error) {
arr, err := r.ReadN(14)
if err != nil {
err = fmt.Errorf("read req: %s", err)
return
}
return UnpackListCumulativePeriodsReq(arr), nil
}
func UnpackListCumulativePeriodsReq(arr []byte) (m ListCumulativePeriodsReq) {
2026-06-10 06:18:45 +03:00
m.MetricID, _ = bin.GetUint32(arr[0:])
sinceYear, _ := bin.GetUint16(arr[4:])
untilYear, _ := bin.GetUint16(arr[8:])
2026-02-10 14:02:11 +00:00
m.Since = TimeBound{
2026-06-10 06:18:45 +03:00
Year: int(sinceYear),
2026-02-10 14:02:11 +00:00
Month: time.Month(arr[6]),
Day: int(arr[7]),
}
m.Until = TimeBound{
2026-06-10 06:18:45 +03:00
Year: int(untilYear),
2026-02-10 14:02:11 +00:00
Month: time.Month(arr[10]),
Day: int(arr[11]),
}
2026-06-10 06:18:45 +03:00
m.GroupBy = qb.GroupBy(arr[12])
2026-02-10 14:02:11 +00:00
m.FirstHourOfDay = int(arr[13])
return
}