// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"runtime/trace"
	"sort"
	"testing"
	"time"
	"unsafe"
)

const (
	bufferLen   = 200_000
	warmupCount = 1_000_000
	runCount    = 5_000_000
)

type kbyte []byte
type circularBuffer [bufferLen]kbyte

type LB struct {
	// Performance measurement stuff
	delays []time.Duration // delays observed (for distribution)
	worst  time.Duration   // worst delay observed

	// For making sense of the bad outcome.
	total        time.Duration // total time spent in allocations
	allStart     time.Time     // time (very nearly) at which the trace begins
	worstIndex   int           // index of worst case allocation delay
	worstElapsed time.Duration // duration of worst case allocation delay

	sink *circularBuffer // assign a pointer here to ensure heap allocation

	// How to allocate

	// "Fluff" refers to allocating a small fraction of extra quickly-dead objects
	// to break up long runs on not-free objects that were once a cause of allocation latency.
	doFluff bool
	// "Fluff" allocations are all assigned to fluff, so that they are on-heap, but only the last one is live.
	fluff kbyte

	// The circular buffer can be on the heap, in a global, or on stack.
	// This choice affects allocation latency.
	howAllocated string
}

// globalBuffer is the globally-allocated circular buffer,
// for measuring the cost of scanning large global objects.
var globalBuffer circularBuffer

// These three methods pass a differently-allocated circularBuffer
// to the benchmarked "work" to see how that affects allocation tail latency.

//go:noinline
func (lb *LB) global(count int) {
	lb.work(&globalBuffer, count)
	for i := range globalBuffer {
		globalBuffer[i] = nil
	}
}

//go:noinline
func (lb *LB) heap(count int) {
	c := &circularBuffer{}
	lb.sink = c // force to heap
	lb.work(c, count)
	lb.sink = nil
}

//go:noinline
func (lb *LB) stack(count int) {
	var c circularBuffer
	lb.work(&c, count)
}

// newSlice allocates a 1k slice of bytes and initializes them all to byte(n)
func (lb *LB) newSlice(n int) kbyte {
	m := make(kbyte, 1024)
	if lb.doFluff && n&63 == 0 {
		lb.fluff = make(kbyte, 1024)
	}
	for i := range m {
		m[i] = byte(n)
	}
	return m
}

// storeSlice stores a newly allocated 1k slice of bytes at c[count%len(c)]
// It also checks the time needed to do this and records the worst case.
func (lb *LB) storeSlice(c *circularBuffer, count int) {
	start := time.Now()
	c[count%len(c)] = lb.newSlice(count)
	elapsed := time.Since(start)

	candElapsed := time.Since(lb.allStart) // Record location of worst in trace
	if elapsed > lb.worst {
		lb.worst = elapsed
		lb.worstIndex = count
		lb.worstElapsed = candElapsed
	}
	lb.total = time.Duration(lb.total.Nanoseconds() + elapsed.Nanoseconds())
	lb.delays = append(lb.delays, elapsed)
}

//go:noinline
func (lb *LB) work(c *circularBuffer, count int) {
	for i := 0; i < count; i++ {
		lb.storeSlice(c, i)
	}
}

func (lb *LB) doAllocations(count int) {
	switch lb.howAllocated {
	case "stack":
		lb.stack(count)
	case "heap":
		lb.heap(count)
	case "global":
		lb.global(count)
	}
}

var traceFile string

func flags() (string, bool) {
	var howAllocated = "stack"
	var doFluff bool
	flag.StringVar(&traceFile, "trace", traceFile, "name of trace file to create")
	flag.StringVar(&howAllocated, "how", howAllocated, "how the buffer is allocated = {stack,heap,global}")
	flag.BoolVar(&doFluff, "fluff", doFluff, "insert 'fluff' into allocation runs to break up sweeps")

	flag.Parse()

	switch howAllocated {
	case "stack", "heap", "global":
		break
	default:
		fmt.Fprintf(os.Stderr, "-how needs to be one of 'heap', 'stack' or 'global, saw '%s' instead\n", howAllocated)
		os.Exit(1)
	}
	return howAllocated, doFluff
}

var reportWorstFlag bool

func (lb0 *LB) bench(b *testing.B) {
	if b != nil {
		b.StopTimer()
	}

	var c *circularBuffer = &circularBuffer{}
	lb0.sink = c // force heap allocation
	lb0.delays = make([]time.Duration, 0, runCount)
	// Warm up heap, virtual memory, address space, etc.
	lb0.work(c, warmupCount)
	c, lb0.sink = nil, nil
	runtime.GC() // Start fresh, GC with all the timers turned off.

	lb := &LB{doFluff: lb0.doFluff, howAllocated: lb0.howAllocated, delays: lb0.delays[:0]}
	count := runCount

	// Confine tracing and timing defers to a small block.
	run := func() {
		if traceFile != "" {
			f, err := os.Create(traceFile)
			if err != nil {
				if b != nil {
					b.Fatalf("Could not create trace file '%s'\n", traceFile)
				} else {
					fmt.Fprintf(os.Stderr, "Could not create trace file '%s'\n", traceFile)
					os.Exit(1)
				}
			}
			defer f.Close()
			trace.Start(f)
			defer trace.Stop()
		}
		lb.allStart = time.Now() // this is for trace file navigation, not benchmark timing.

		if b != nil {
			count = b.N * count
			if b.N > 1 {
				lb.delays = make([]time.Duration, 0, count)
			}
			b.StartTimer()
			defer b.StopTimer()
		}
		lb.doAllocations(count)
	}
	run()

	sort.Slice(lb.delays, func(i, j int) bool { return lb.delays[i] < lb.delays[j] })
	delays := lb.delays
	delayLen := float64(len(delays))
	average, median := time.Duration(lb.total.Nanoseconds()/int64(count)), delays[len(delays)/2]
	p29, p39, p49, p59, p69 := lb.delays[int(0.99*delayLen)], delays[int(0.999*delayLen)], delays[int(0.9999*delayLen)], delays[int(0.99999*delayLen)], delays[int(0.999999*delayLen)]
	if b != nil {
		if testing.Short() {
			b.ReportMetric(0, "ns/op")
			b.ReportMetric(float64(p59), "p99.999-ns")
			b.ReportMetric(float64(p69), "p99.9999-ns")
		} else {
			b.ReportMetric(float64(average.Nanoseconds()), "ns/op")
			b.ReportMetric(float64(median), "p50-ns")
			b.ReportMetric(float64(p29), "p99-ns")
			b.ReportMetric(float64(p39), "p99.9-ns")
			b.ReportMetric(float64(p49), "p99.99-ns")
			b.ReportMetric(float64(p59), "p99.999-ns")
			b.ReportMetric(float64(p69), "p99.9999-ns")
		}
		if reportWorstFlag {
			b.ReportMetric(float64(lb.worst), "worst")
		}
		// Don't report worst case, it is ultra-noisy.
	} else {
		fmt.Printf("GC latency benchmark, how=%s, fluff=%v\n", lb.howAllocated, lb.doFluff)
		fmt.Println("Worst allocation latency:", lb.worst)
		fmt.Println("Worst allocation index:", lb.worstIndex)
		fmt.Println("Worst allocation occurs at run elapsed time:", lb.worstElapsed)
		fmt.Println("Average allocation latency:", average)
		fmt.Println("Median allocation latency:", median)
		fmt.Println("99% allocation latency:", p29)
		fmt.Println("99.9% allocation latency:", p39)
		fmt.Println("99.99% allocation latency:", p49)
		fmt.Println("99.999% allocation latency:", p59)
		fmt.Println("99.9999% allocation latency:", p69)
		fmt.Println("Sizeof(circularBuffer) =", unsafe.Sizeof(*c))
		fmt.Println("Approximate live memory =", unsafe.Sizeof(*c)+bufferLen*1024)
	}
}
