diff options
Diffstat (limited to 'internal/statsengine')
| -rw-r--r-- | internal/statsengine/bench_test.go | 4 | ||||
| -rw-r--r-- | internal/statsengine/filerank.go | 11 | ||||
| -rw-r--r-- | internal/statsengine/process.go | 25 | ||||
| -rw-r--r-- | internal/statsengine/syscall.go | 25 | ||||
| -rw-r--r-- | internal/statsengine/syscall_test.go | 12 |
5 files changed, 44 insertions, 33 deletions
diff --git a/internal/statsengine/bench_test.go b/internal/statsengine/bench_test.go index 646bdda..99d5c87 100644 --- a/internal/statsengine/bench_test.go +++ b/internal/statsengine/bench_test.go @@ -1,7 +1,7 @@ package statsengine import ( - "math/rand" + "math/rand/v2" "testing" "time" @@ -9,7 +9,7 @@ import ( ) func BenchmarkSyscallAccumulatorSnapshot(b *testing.B) { - acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewSource(123))) + acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewPCG(123, 0))) traceIDs := []types.TraceId{ types.SYS_ENTER_READ, types.SYS_ENTER_WRITE, diff --git a/internal/statsengine/filerank.go b/internal/statsengine/filerank.go index dd83e8d..d24ab93 100644 --- a/internal/statsengine/filerank.go +++ b/internal/statsengine/filerank.go @@ -1,8 +1,9 @@ package statsengine import ( + "cmp" "container/heap" - "sort" + "slices" "ior/internal/event" "ior/internal/types" @@ -123,11 +124,11 @@ func buildFileSnapshots(inputs []fileSnapshotInput) []FileSnapshot { for _, in := range inputs { out = append(out, in.toSnapshot()) } - sort.Slice(out, func(i, j int) bool { - if out[i].Accesses != out[j].Accesses { - return out[i].Accesses > out[j].Accesses + slices.SortFunc(out, func(a, b FileSnapshot) int { + if a.Accesses != b.Accesses { + return cmp.Compare(b.Accesses, a.Accesses) } - return out[i].Path < out[j].Path + return cmp.Compare(a.Path, b.Path) }) return out } diff --git a/internal/statsengine/process.go b/internal/statsengine/process.go index b00a4bb..3bfd019 100644 --- a/internal/statsengine/process.go +++ b/internal/statsengine/process.go @@ -1,7 +1,8 @@ package statsengine import ( - "sort" + "cmp" + "slices" "time" "ior/internal/event" @@ -115,14 +116,14 @@ func buildProcessSnapshots(inputs []processSnapshotInput, elapsed time.Duration) for _, in := range inputs { result = append(result, in.toSnapshot(rateDiv)) } - sort.Slice(result, func(i, j int) bool { - if result[i].Syscalls != result[j].Syscalls { - return result[i].Syscalls > result[j].Syscalls + slices.SortFunc(result, func(a, b ProcessSnapshot) int { + if a.Syscalls != b.Syscalls { + return cmp.Compare(b.Syscalls, a.Syscalls) } - if result[i].Bytes != result[j].Bytes { - return result[i].Bytes > result[j].Bytes + if a.Bytes != b.Bytes { + return cmp.Compare(b.Bytes, a.Bytes) } - return result[i].PID < result[j].PID + return cmp.Compare(a.PID, b.PID) }) return result } @@ -136,8 +137,14 @@ func (a *processAccumulator) compactIfNeeded() { for _, stats := range a.byPID { ordered = append(ordered, stats) } - sort.Slice(ordered, func(i, j int) bool { - return betterProcessRank(ordered[i], ordered[j]) + slices.SortFunc(ordered, func(a, b *processStats) int { + if betterProcessRank(a, b) { + return -1 + } + if betterProcessRank(b, a) { + return 1 + } + return 0 }) if len(ordered) > a.topN { ordered = ordered[:a.topN] diff --git a/internal/statsengine/syscall.go b/internal/statsengine/syscall.go index 4feeab2..93931d1 100644 --- a/internal/statsengine/syscall.go +++ b/internal/statsengine/syscall.go @@ -1,9 +1,10 @@ package statsengine import ( + "cmp" "math" - "math/rand" - "sort" + "math/rand/v2" + "slices" "time" "ior/internal/event" @@ -55,15 +56,17 @@ type syscallSnapshotInput struct { } func newSyscallAccumulator() *syscallAccumulator { - return newSyscallAccumulatorWithConfig(syscallReservoirSampleCapDefault, rand.New(rand.NewSource(time.Now().UnixNano()))) + return newSyscallAccumulatorWithConfig(syscallReservoirSampleCapDefault, nil) } +// newSyscallAccumulatorWithConfig creates a syscall accumulator with the given +// sample capacity and optional RNG. A nil rng uses the auto-seeded default. func newSyscallAccumulatorWithConfig(sampleCap int, rng *rand.Rand) *syscallAccumulator { if sampleCap <= 0 { sampleCap = syscallReservoirSampleCapDefault } if rng == nil { - rng = rand.New(rand.NewSource(time.Now().UnixNano())) + rng = rand.New(rand.NewPCG(rand.Uint64(), rand.Uint64())) } return &syscallAccumulator{ @@ -135,11 +138,11 @@ func buildSyscallSnapshots(inputs []syscallSnapshotInput, elapsed time.Duration) for _, in := range inputs { result = append(result, in.toSnapshot(rateDiv)) } - sort.Slice(result, func(i, j int) bool { - if result[i].Count != result[j].Count { - return result[i].Count > result[j].Count + slices.SortFunc(result, func(a, b SyscallSnapshot) int { + if a.Count != b.Count { + return cmp.Compare(b.Count, a.Count) } - return result[i].Name < result[j].Name + return cmp.Compare(a.Name, b.Name) }) return result } @@ -161,8 +164,8 @@ func (s *syscallStats) addSample(duration uint64, cap int, rng *rand.Rand) { return } - idx := rng.Int63n(int64(s.seenLatencies)) - if idx >= int64(cap) { + idx := rng.IntN(int(s.seenLatencies)) + if idx >= cap { return } s.samples[idx] = duration @@ -183,7 +186,7 @@ func (s *syscallStats) ensurePercentiles() { } sorted := append([]uint64(nil), s.samples...) - sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) + slices.Sort(sorted) s.cachedP50 = samplePercentile(sorted, 0.50) s.cachedP95 = samplePercentile(sorted, 0.95) s.cachedP99 = samplePercentile(sorted, 0.99) diff --git a/internal/statsengine/syscall_test.go b/internal/statsengine/syscall_test.go index b315bd8..b00582d 100644 --- a/internal/statsengine/syscall_test.go +++ b/internal/statsengine/syscall_test.go @@ -2,7 +2,7 @@ package statsengine import ( "math" - "math/rand" + "math/rand/v2" "testing" "time" @@ -11,7 +11,7 @@ import ( ) func TestSyscallAccumulatorBasicStats(t *testing.T) { - acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewSource(1))) + acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewPCG(1, 0))) traceID := types.SYS_ENTER_READ acc.Add(newPair(traceID, 10, 100, 0)) @@ -54,7 +54,7 @@ func TestSyscallAccumulatorBasicStats(t *testing.T) { } func TestSyscallAccumulatorSortsByCountThenName(t *testing.T) { - acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewSource(2))) + acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewPCG(2, 0))) idA := types.SYS_ENTER_OPENAT idB := types.SYS_ENTER_READ @@ -76,7 +76,7 @@ func TestSyscallAccumulatorSortsByCountThenName(t *testing.T) { } func TestSyscallAccumulatorReservoirPercentilesAccuracy(t *testing.T) { - acc := newSyscallAccumulatorWithConfig(100, rand.New(rand.NewSource(7))) + acc := newSyscallAccumulatorWithConfig(100, rand.New(rand.NewPCG(7, 0))) traceID := types.SYS_ENTER_WRITE for d := uint64(1); d <= 10_000; d++ { @@ -95,7 +95,7 @@ func TestSyscallAccumulatorReservoirPercentilesAccuracy(t *testing.T) { } func TestSyscallAccumulatorZeroElapsedRate(t *testing.T) { - acc := newSyscallAccumulatorWithConfig(32, rand.New(rand.NewSource(9))) + acc := newSyscallAccumulatorWithConfig(32, rand.New(rand.NewPCG(9, 0))) acc.Add(newPair(types.SYS_ENTER_READ, 9, 0, 0)) snap := acc.Snapshot(0) @@ -108,7 +108,7 @@ func TestSyscallAccumulatorZeroElapsedRate(t *testing.T) { } func TestSyscallAccumulatorPercentilesRecomputeAfterThreshold(t *testing.T) { - acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewSource(11))) + acc := newSyscallAccumulatorWithConfig(10_000, rand.New(rand.NewPCG(11, 0))) traceID := types.SYS_ENTER_READ for i := 1; i <= 1000; i++ { |
