func trials(tables, buckets, slots, trials int, eseed int64, lf float64, ibase int, verbose, ranr, ranb bool) (d *dstest.DSTest, cs *cuckoo.Counters, avg float64, used int, rmax int, fails int) {
	var key cuckoo.Key
	var acs cuckoo.Counters
	var labels = []string{"init", "fill", "verify", "delete", "verify"}
	var durations = make([]time.Duration, 5)
	var msb, msa runtime.MemStats
	var print = func(i, used int) {
		if verbose {
			tmp := labels[i]
			f2 := hrff.Float64{float64(used) * (float64(time.Second) / float64(durations[i])), "ops/sec"}
			fmt.Printf("    %s: %v %h\n", tmp, durations[i], f2)
		}
	}
	cs = &acs
	cs.InitCounters()
	tot := float64(0)
	fails = 0
	if ranr {
		bseed = time.Now().UTC().UnixNano()
		b := make([]byte, 8)
		_, err := cr.Read(b)
		if err != nil {
			fmt.Println("error:", err)
			return
		}
		bseed = int64(uint64(b[0])<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 |
			uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7])<<0)
	} else {
		bseed = int64(*seedb)
	}
	td := dstest.NewTester(nil, *startLevel, 0)  
	for t := 0; t < trials; t++ {
		start := time.Now()
		c := cuckoo.New(tables, buckets, slots, int64(*seede), lf, *hash)
		if c == nil {
			panic("New failed")
		}
		if *trace {
			c.Trace = true
		}
		d = dstest.NewTester(c, *startLevel, bseed)  
		siz := int(unsafe.Sizeof(key))
		switch siz {
		case 4, 8:
			c.SetNumericKeySize(siz)
		}
		c.SetGrow(!*dg)
		c.StartLevel = *startLevel
		c.LowestLevel = *lowLevel
		stop := time.Now()
		if t == 0 {
			sz := hrff.Int64{int64(c.Size * c.BucketSize), "bytes"}
			fmt.Printf("trials: bseed=%#x, seede=%#x, cucko hash table size=%H, trials=%d\n", uint64(bseed), *seede, sz, trials)
		}
		durations[0] = tdiff(start, stop)
		print(0, tables*buckets*slots)
		runtime.ReadMemStats(&msb)
		start = time.Now()
		fs := d.Fill(tables, buckets, slots, ibase, *flf, verbose, *pl, *pr, ranb)
		used = fs.Used
		stop = time.Now()
		runtime.ReadMemStats(&msa)
		bpi := float64(c.Bumps) / float64(c.Inserts)
		ppi := float64(c.Probes) / float64(c.Inserts)
		ipi := float64(c.Iterations) / float64(c.Inserts)
		rmax = fs.Thresh
		durations[1] = tdiff(start, stop)
		print(1, fs.Used)
		tot += fs.Load
		if fs.Failed {
			fails++
		}
		if d.Limited {
			td.Limited = true
		}
		if *fo {
			continue
		}
		start = time.Now()
		d.Verify(fs.Base, c.Elements, *pr)
		stop = time.Now()
		durations[2] = tdiff(start, stop)
		print(2, fs.Used)
		savElements := c.Elements
		start = time.Now()
		ok := d.Delete(fs.Base, c.Elements, verbose, *pr)
		if !ok || c.Elements != 0 {
			s := fmt.Sprintf("Delete failed ok=%v, c.Elements=%d\n", ok, c.Elements)
			fmt.Printf(s)
		}
		stop = time.Now()
		durations[3] = tdiff(start, stop)
		print(3, fs.Used)
		c.Elements = savElements
		cs.CountersAdd(&c.Counters)
		if d.Ll < td.Ll {
			td.Ll = d.Ll
		}
		if d.Mr > td.Mr {
			td.Mr = d.Mr
		}
		if false {
			for k, v := range labels {
				f2 := hrff.Float64{float64(fs.Used) * (float64(time.Second) / float64(durations[k])), "ops/sec"}
				fmt.Printf("    %s: %v %h\n", v, durations[k], f2)
			}
			fmt.Printf("\n")
		}
		if verbose {
			fmt.Printf("trials: cf=%#v\n", c.Config)
			fmt.Printf("trials: cs=%#v\n", c.Counters)
			fmt.Printf("trials: fs=%#v\n", fs)
		}
		if *pt || printStatusOneShot || (*pf && fs.Failed) {
			fmt.Printf("trials: trial=%d, TraceCnt=%d, fails=%d, L=%v, F=%v, Remaining=%d, Aborts=%d, LowestLevel=%d, MaxProbes=%d, MaxIterations=%d, bpi=%0.2f, ppi=%0.2f, ipi=%0.4f, lf=%0.2f (%d/%d)\n",
				t, c.TraceCnt, fails, fs.Limited, fs.Failed, fs.Remaining, c.Aborts, fs.LowestLevel, c.MaxProbes, c.MaxIterations, bpi, ppi, ipi, float64(c.Elements)/float64(c.Size), c.Elements, c.Size)
			fmt.Printf("trials: fs=%#v\n", fs)
			printStatusOneShot = false
		}
		bseed++
		if verbose {
			fmt.Printf("\n")
		}
	}
	avg = tot / float64(trials)
	return  
}
func trials(tables, buckets, slots, trials int, lf float64, ibase int, verbose, r bool) (cs *cuckoo.Counters, avg float64, rmax int, fails int) {
package main
import (
	cr "crypto/rand"
	"flag"
	"fmt"
	"log"
	_ "math"
	_ "math/rand"
	"os"
	"runtime"
	"runtime/pprof"
	"time"
	"unsafe"
	"leb.io/cuckoo"
	"leb.io/cuckoo/internal/dstest"
	"leb.io/cuckoo/internal/siginfo"
	"leb.io/cuckoo/primes"
	"leb.io/hrff"
)
func tdiff(begin, end time.Time) time.Duration {
	d := end.Sub(begin)
	return d
}
var ranb = flag.Bool("rb", false, "ignore base, use random base value")
var ranr = flag.Bool("rr", false, "random run, seed for base values is random")
var rane = flag.Bool("re", false, "use a random seed for evictions source")
var ranh = flag.Bool("rh", false, "use a random seed for table hash functions")
var seedb = flag.Int("sb", 0, "seed for base values")
var seede = flag.Int("se", 0, "seed for eviction values")
var auto = flag.Bool("a", false, "automatic")
var fo = flag.Bool("fo", false, "fill only")
var dg = flag.Bool("dg", false, "dont't add hash tables automatically")
var hash = flag.String("h", "aes", "name of hash function {aes, j264, j364}")
var ntables = flag.Int("t", 4, "tables")
var nbuckets = flag.Int("b", 31, "buckets")
var nslots = flag.Int("s", 8, "slots")
var _ntrials = hrff.Int{V: 5, U: "trials"}
var ntrials *int = &_ntrials.V
var ibase = flag.Int("base", 1, "base of fill series, -1 for random")
var startLevel = flag.Int("sl", 2000, "starting level")
var lowLevel = flag.Int("ll", -8000, "lowest level")
var lf = flag.Float64("lf", 0.96, "maximum load factor")
var flf = flag.Float64("flf", 1.0, "fill load factor")
var pl = flag.Bool("pl", false, "print level of each insert")
var pt = flag.Bool("pt", false, "print summary for each trail")
var ps = flag.Bool("ps", false, "print stats at the end of all trails")
var pr = flag.Bool("pr", false, "print progress")
var pf = flag.Bool("pf", false, "print info on failure")
var trace = flag.Bool("trace", false, "produce trace on stdout")
var verbose = flag.Bool("v", false, "verbose")
var cp = flag.String("cp", "", "write cpu profile to file")
var mp = flag.String("mp", "", "write memory profile to this file")
var printStatusOneShot bool
var bseed = int64(0)  
var cseed = int64(0)  
func hu(v uint64, u string) hrff.Int64 {
	return hrff.Int64{V: int64(v), U: u}
}
func hi(v int64, u string) hrff.Int64 {
	return hrff.Int64{V: int64(v), U: u}
}
func dump_mstats(m *runtime.MemStats, mstats, cstats, gc bool) {
	if mstats {
		fmt.Printf("Alloc=%h, TotalAlloc=%h, Sys=%h, Lookups=%h, Mallocs=%h, Frees=%h\n",
			hu(m.Alloc, "B"), hu(m.TotalAlloc, "B"), hu(m.Sys, "B"), hu(m.Lookups, ""), hu(m.Mallocs, ""), hu(m.Frees, ""))
		fmt.Printf("HeapAlloc=%h, HeapSys=%h, HeapIdle=%h, HeapInuse=%h, HeapReleased=%h, HeapObjects=%h\n",
			hu(m.HeapAlloc, "B"), hu(m.HeapSys, "B"), hu(m.HeapIdle, "B"), hu(m.HeapInuse, "B"), hu(m.HeapReleased, "B"), hu(m.HeapObjects, ""))
		fmt.Printf("StackInuse=%d, StackSys=%d, MSpanInuse=%d, MSpanSys=%d, MCacheSys=%d, BuckHashSys=%d\n", m.StackInuse, m.StackSys, m.MSpanInuse, m.MSpanSys, m.MCacheSys, m.BuckHashSys)
		fmt.Printf("NextGC=%d, LastGC=%d, PauseTotalNs=%d, NumGC=%d, EnableGC=%v, DebugGC=%v\n", m.NextGC, m.LastGC, m.PauseTotalNs, m.NumGC, m.EnableGC, m.DebugGC)
	}
	if cstats {
		for i, b := range m.BySize {
			if b.Mallocs == 0 {
				continue
			}
			fmt.Printf("BySize[%d]: Size=%d, Malloc=%d, Frees=%d\n", i, b.Size, b.Mallocs, b.Frees)
		}
	}
	if gc {
		for i := range m.PauseNs {
			fmt.Printf("PauseNs: ")
			fmt.Printf("%d, ", m.PauseNs[(int(m.NumGC)+255+i)%256])
			fmt.Printf("\n")
		}
	}
}