perf(go): deduplicate unchanged mileage samples
This commit is contained in:
@@ -4,8 +4,10 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
||||
@@ -16,8 +18,10 @@ type Execer interface {
|
||||
}
|
||||
|
||||
type Writer struct {
|
||||
exec Execer
|
||||
loc *time.Location
|
||||
exec Execer
|
||||
loc *time.Location
|
||||
mu sync.Mutex
|
||||
lastTotalMileage map[string]float64
|
||||
}
|
||||
|
||||
type MetricSample struct {
|
||||
@@ -34,7 +38,7 @@ func NewWriter(exec Execer, loc *time.Location) *Writer {
|
||||
if loc == nil {
|
||||
loc = time.FixedZone("Asia/Shanghai", 8*3600)
|
||||
}
|
||||
return &Writer{exec: exec, loc: loc}
|
||||
return &Writer{exec: exec, loc: loc, lastTotalMileage: map[string]float64{}}
|
||||
}
|
||||
|
||||
func (w *Writer) EnsureSchema(ctx context.Context) error {
|
||||
@@ -50,6 +54,9 @@ func (w *Writer) Append(ctx context.Context, env envelope.FrameEnvelope) error {
|
||||
return err
|
||||
}
|
||||
for _, sample := range samples {
|
||||
if w.seenSameMileage(sample) {
|
||||
continue
|
||||
}
|
||||
if _, err := w.exec.ExecContext(ctx, upsertDailyMileageSQL,
|
||||
sample.VIN,
|
||||
sample.StatDate,
|
||||
@@ -62,6 +69,23 @@ func (w *Writer) Append(ctx context.Context, env envelope.FrameEnvelope) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Writer) seenSameMileage(sample MetricSample) bool {
|
||||
prefix := fmt.Sprintf("%s|%s|", sample.VIN, sample.Protocol)
|
||||
key := prefix + sample.StatDate
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
if last, ok := w.lastTotalMileage[key]; ok && last == sample.TotalMileageKM {
|
||||
return true
|
||||
}
|
||||
for existing := range w.lastTotalMileage {
|
||||
if strings.HasPrefix(existing, prefix) && existing != key {
|
||||
delete(w.lastTotalMileage, existing)
|
||||
}
|
||||
}
|
||||
w.lastTotalMileage[key] = sample.TotalMileageKM
|
||||
return false
|
||||
}
|
||||
|
||||
func SamplesFromEnvelope(env envelope.FrameEnvelope, loc *time.Location) ([]MetricSample, error) {
|
||||
vin := strings.TrimSpace(env.VIN)
|
||||
if vin == "" {
|
||||
|
||||
Reference in New Issue
Block a user