summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-24 09:19:18 +0200
committerPaul Buetow <paul@buetow.org>2026-02-24 09:19:18 +0200
commit7fc16d6c98feae7aaee58666dc552384ceb4895e (patch)
tree96260c49ea86344d935dde5dac98f0880766186c
parent1cbb2430d027c9d8850bf3a2b79a05338efea3ea (diff)
refactor: remove deprecated internal stats package
-rw-r--r--internal/stats/patterns.go142
-rw-r--r--internal/stats/stats.go170
2 files changed, 0 insertions, 312 deletions
diff --git a/internal/stats/patterns.go b/internal/stats/patterns.go
deleted file mode 100644
index 06e906f..0000000
--- a/internal/stats/patterns.go
+++ /dev/null
@@ -1,142 +0,0 @@
-package stats
-
-import (
- "math"
- "time"
-)
-
-// PatternAnalysis represents the analysis of I/O patterns
-type PatternAnalysis struct {
- // Burst detection
- BurstCount int
- BurstDuration time.Duration
- BurstThreshold int64
-
- // Periodicity detection
- IsPeriodic bool
- PeriodDuration time.Duration
-
- // Trend analysis
- TrendSlope float64
- TrendDirection string // "increasing", "decreasing", "stable"
-}
-
-// AnalyzePatterns analyzes the I/O patterns from the statistics
-func (s *IOStats) AnalyzePatterns() *PatternAnalysis {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- analysis := &PatternAnalysis{
- BurstThreshold: 1000, // Configurable threshold
- }
-
- // Analyze bursts
- analysis.analyzeBursts(s.bytesHistory, s.timestamps)
-
- // Analyze periodicity
- analysis.analyzePeriodicity(s.bytesHistory, s.timestamps)
-
- // Analyze trends
- analysis.analyzeTrend(s.bytesHistory, s.timestamps)
-
- return analysis
-}
-
-func (a *PatternAnalysis) analyzeBursts(bytes []int64, timestamps []time.Time) {
- if len(bytes) < 2 {
- return
- }
-
- var currentBurstSize int64
- var burstStart time.Time
- inBurst := false
-
- for i := 0; i < len(bytes); i++ {
- if bytes[i] > a.BurstThreshold {
- if !inBurst {
- burstStart = timestamps[i]
- inBurst = true
- }
- currentBurstSize += bytes[i]
- } else if inBurst {
- a.BurstCount++
- a.BurstDuration += timestamps[i].Sub(burstStart)
- inBurst = false
- currentBurstSize = 0
- }
- }
-}
-
-func (a *PatternAnalysis) analyzePeriodicity(bytes []int64, timestamps []time.Time) {
- if len(bytes) < 4 {
- return
- }
-
- // Simple periodicity detection using autocorrelation
- mean := 0.0
- for _, b := range bytes {
- mean += float64(b)
- }
- mean /= float64(len(bytes))
-
- var maxCorrelation float64
- var bestPeriod int
-
- // Check for periods up to half the data length
- for period := 1; period < len(bytes)/2; period++ {
- correlation := 0.0
- count := 0
-
- for i := 0; i < len(bytes)-period; i++ {
- correlation += (float64(bytes[i]) - mean) * (float64(bytes[i+period]) - mean)
- count++
- }
-
- if count > 0 {
- correlation /= float64(count)
- if correlation > maxCorrelation {
- maxCorrelation = correlation
- bestPeriod = period
- }
- }
- }
-
- // If we found a strong correlation, consider it periodic
- if maxCorrelation > 0.7 { // Threshold for periodicity
- a.IsPeriodic = true
- if bestPeriod > 0 && bestPeriod < len(timestamps)-1 {
- a.PeriodDuration = timestamps[bestPeriod].Sub(timestamps[0])
- }
- }
-}
-
-func (a *PatternAnalysis) analyzeTrend(bytes []int64, timestamps []time.Time) {
- if len(bytes) < 2 {
- return
- }
-
- // Simple linear regression
- var sumX, sumY, sumXY, sumX2 float64
- n := float64(len(bytes))
-
- for i := 0; i < len(bytes); i++ {
- x := float64(timestamps[i].UnixNano())
- y := float64(bytes[i])
- sumX += x
- sumY += y
- sumXY += x * y
- sumX2 += x * x
- }
-
- // Calculate slope
- a.TrendSlope = (n*sumXY - sumX*sumY) / (n*sumX2 - sumX*sumX)
-
- // Determine trend direction
- if math.Abs(a.TrendSlope) < 0.1 {
- a.TrendDirection = "stable"
- } else if a.TrendSlope > 0 {
- a.TrendDirection = "increasing"
- } else {
- a.TrendDirection = "decreasing"
- }
-}
diff --git a/internal/stats/stats.go b/internal/stats/stats.go
deleted file mode 100644
index cd850a3..0000000
--- a/internal/stats/stats.go
+++ /dev/null
@@ -1,170 +0,0 @@
-package stats
-
-import (
- "math"
- "sort"
- "sync"
- "time"
-)
-
-// IOStats represents statistical data for I/O operations
-type IOStats struct {
- mu sync.RWMutex
-
- // Basic metrics
- Count int64
- TotalBytes int64
- TotalLatency time.Duration
-
- // Latency statistics
- MinLatency time.Duration
- MaxLatency time.Duration
- MeanLatency time.Duration
- MedianLatency time.Duration
- P95Latency time.Duration
- P99Latency time.Duration
-
- // Throughput statistics
- MinBytes int64
- MaxBytes int64
- MeanBytes float64
- MedianBytes int64
- P95Bytes int64
- P99Bytes int64
-
- // Time series data for trend analysis
- latencyHistory []time.Duration
- bytesHistory []int64
- timestamps []time.Time
-}
-
-// NewIOStats creates a new IOStats instance
-func NewIOStats() *IOStats {
- return &IOStats{
- MinLatency: time.Duration(math.MaxInt64),
- MinBytes: math.MaxInt64,
- }
-}
-
-// AddOperation adds a new I/O operation to the statistics
-func (s *IOStats) AddOperation(bytes int64, latency time.Duration) {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- now := time.Now()
- s.Count++
- s.TotalBytes += bytes
- s.TotalLatency += latency
-
- // Update latency statistics
- if latency < s.MinLatency {
- s.MinLatency = latency
- }
- if latency > s.MaxLatency {
- s.MaxLatency = latency
- }
-
- // Update bytes statistics
- if bytes < s.MinBytes {
- s.MinBytes = bytes
- }
- if bytes > s.MaxBytes {
- s.MaxBytes = bytes
- }
-
- // Store history
- s.latencyHistory = append(s.latencyHistory, latency)
- s.bytesHistory = append(s.bytesHistory, bytes)
- s.timestamps = append(s.timestamps, now)
-
- // Calculate percentiles if we have enough data
- if len(s.latencyHistory) > 0 {
- s.calculatePercentiles()
- }
-}
-
-// calculatePercentiles calculates various statistical measures
-func (s *IOStats) calculatePercentiles() {
- // Sort the data for percentile calculations
- latencies := make([]time.Duration, len(s.latencyHistory))
- copy(latencies, s.latencyHistory)
- sort.Slice(latencies, func(i, j int) bool {
- return latencies[i] < latencies[j]
- })
-
- bytes := make([]int64, len(s.bytesHistory))
- copy(bytes, s.bytesHistory)
- sort.Slice(bytes, func(i, j int) bool {
- return bytes[i] < bytes[j]
- })
-
- // Calculate mean
- var totalLatency time.Duration
- var totalBytes int64
- for i := range latencies {
- totalLatency += latencies[i]
- totalBytes += bytes[i]
- }
- s.MeanLatency = totalLatency / time.Duration(len(latencies))
- s.MeanBytes = float64(totalBytes) / float64(len(bytes))
-
- // Calculate median and percentiles
- mid := len(latencies) / 2
- s.MedianLatency = latencies[mid]
- s.MedianBytes = bytes[mid]
-
- p95Index := int(float64(len(latencies)) * 0.95)
- p99Index := int(float64(len(latencies)) * 0.99)
- if p95Index < len(latencies) {
- s.P95Latency = latencies[p95Index]
- s.P95Bytes = bytes[p95Index]
- }
- if p99Index < len(latencies) {
- s.P99Latency = latencies[p99Index]
- s.P99Bytes = bytes[p99Index]
- }
-}
-
-// GetStats returns a map of all statistics
-func (s *IOStats) GetStats() map[string]interface{} {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- return map[string]interface{}{
- "count": s.Count,
- "total_bytes": s.TotalBytes,
- "total_latency": s.TotalLatency,
- "latency": map[string]interface{}{
- "min": s.MinLatency,
- "max": s.MaxLatency,
- "mean": s.MeanLatency,
- "median": s.MedianLatency,
- "p95": s.P95Latency,
- "p99": s.P99Latency,
- },
- "bytes": map[string]interface{}{
- "min": s.MinBytes,
- "max": s.MaxBytes,
- "mean": s.MeanBytes,
- "median": s.MedianBytes,
- "p95": s.P95Bytes,
- "p99": s.P99Bytes,
- },
- }
-}
-
-// GetTimeSeriesData returns the historical data for trend analysis
-func (s *IOStats) GetTimeSeriesData() ([]time.Time, []time.Duration, []int64) {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- timestamps := make([]time.Time, len(s.timestamps))
- latencies := make([]time.Duration, len(s.latencyHistory))
- bytes := make([]int64, len(s.bytesHistory))
-
- copy(timestamps, s.timestamps)
- copy(latencies, s.latencyHistory)
- copy(bytes, s.bytesHistory)
-
- return timestamps, latencies, bytes
-}