// Calls rand 4 times func (b *Big) MakeOne(w int, local_seed *uint32, txn *ddtxn.Query) { rnd := uint64(ddtxn.RandN(local_seed, uint32(b.ni))) txn.U1 = rnd txn.U2 = (rnd * 2) % b.ni txn.U3 = (rnd * 3) % b.ni txn.U4 = (rnd * 4) % b.ni txn.U5 = (rnd * 5) % b.ni txn.U6 = (rnd * 6) % b.ni txn.U7 = (rnd) % uint64(b.np) if *incr { txn.TXN = ddtxn.BIG_INCR } else { txn.TXN = ddtxn.BIG_RW } }
func (b *Rubis) MakeBid(w int, local_seed *uint32, txn *ddtxn.Query) { txn.TXN = ddtxn.RUBIS_BID bidder := b.users[0] var x uint32 if b.zipfd > 0 { x = uint32(b.zip[w].Uint64()) } else { x = ddtxn.RandN(local_seed, uint32(b.nproducts)) } if x >= uint32(len(b.products)) { log.Fatalf("Huh %v %v %v\n", x, len(b.products), b.nproducts) } product := b.products[x] txn.U1 = uint64(bidder) if product == 0 { log.Fatalf("store bid ID 0? %v %v", x, b.products[x]) } txn.U2 = uint64(product) txn.U3 = uint64(time.Now().UnixNano()) }
// Calls rand 4 times func (b *Buy) MakeOne(w int, local_seed *uint32, sp uint32, txn *ddtxn.Query) { var bidder int var product int if *partition { rnd := ddtxn.RandN(local_seed, sp/8) lb := int(rnd) bidder = lb + w*int(sp) } else { bidder = int(ddtxn.RandN(local_seed, uint32(b.nbidders))) } x := int(ddtxn.RandN(local_seed, 100)) if b.zipfd > 0 { product = int(b.z[w].Uint64()) } else { product = int(ddtxn.RandN(local_seed, uint32(b.nproducts))) } if x < b.read_rate { if x > b.ncontended_rate { // Contended read; use Zipfian distribution or np txn.K1 = ddtxn.UserKey(uint64(bidder)) txn.K2 = ddtxn.ProductKey(product) } else { // (Hopefully) uncontended read. Random product. product = int(ddtxn.RandN(local_seed, uint32(b.nbidders))) txn.K1 = ddtxn.UserKey(uint64(bidder)) txn.K2 = ddtxn.ProductKey(product) } txn.TXN = ddtxn.D_READ_TWO } else { amt := int32(ddtxn.RandN(local_seed, 10)) txn.K1 = ddtxn.UserKey(uint64(bidder)) txn.K2 = ddtxn.ProductKey(product) txn.A = amt txn.TXN = ddtxn.D_BUY } }
func (b *Rubis) MakeOne(w int, local_seed *uint32, txn *ddtxn.Query) { x := float64(ddtxn.RandN(local_seed, 100)) if x < b.rates[0] { txn.TXN = ddtxn.RUBIS_BID //bidder := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] bidder := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] //product := b.products[ddtxn.RandN(local_seed, uint32(b.nproducts))] var x uint32 if b.zipfd > 0 { x = uint32(b.zip[w].Uint64()) } else { x = ddtxn.RandN(local_seed, uint32(b.nproducts)) } product := b.products[x] txn.U1 = uint64(bidder) if product == 0 { log.Fatalf("store bid ID 0? %v %v", x, b.products[x]) } txn.U2 = uint64(product) //txn.U3 = uint64(ddtxn.RandN(local_seed, 10)) txn.U3 = uint64(time.Now().UnixNano()) & 0x000efff } else if x < b.rates[1] { txn.TXN = ddtxn.RUBIS_VIEWBIDHIST x := ddtxn.RandN(local_seed, uint32(b.nproducts)) product := b.products[x] if product == 0 { log.Fatalf("view bid hist ID 0? %v %v", x, b.products[x]) } txn.U1 = uint64(product) } else if x < b.rates[2] { txn.TXN = ddtxn.RUBIS_BUYNOW //bidder := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] bidder := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] x := ddtxn.RandN(local_seed, uint32(b.nproducts)) product := b.products[x] if product == 0 { log.Fatalf("buy now ID 0? %v %v", x, b.products[x]) } txn.U1 = uint64(bidder) txn.U2 = uint64(product) txn.A = int32(ddtxn.RandN(local_seed, 10)) } else if x < b.rates[3] { txn.TXN = ddtxn.RUBIS_COMMENT // u1 := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] u1 := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] // u2 := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] u2 := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] x := ddtxn.RandN(local_seed, uint32(b.nproducts)) product := b.products[x] if product == 0 { log.Fatalf("comment ID 0? %v %v", x, b.products[x]) } txn.U1 = uint64(u1) txn.U2 = uint64(u2) txn.U3 = uint64(product) txn.S1 = "xxxx" txn.U4 = 1 } else if x < b.rates[4] { txn.TXN = ddtxn.RUBIS_NEWITEM // bidder := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] bidder := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] amt := uint64(ddtxn.RandN(local_seed, 10)) txn.U1 = uint64(bidder) txn.S1 = "yyyy" txn.S2 = "zzzz" txn.U2 = amt txn.U3 = amt txn.U4 = amt txn.U5 = 1 txn.U6 = 1 txn.U7 = uint64(ddtxn.RandN(local_seed, uint32(ddtxn.NUM_CATEGORIES))) } else if x < b.rates[5] { txn.TXN = ddtxn.RUBIS_PUTBID x := ddtxn.RandN(local_seed, uint32(b.nproducts)) product := b.products[x] if product == 0 { log.Fatalf("put bid ID 0? %v %v", x, b.products[x]) } txn.U1 = uint64(product) } else if x < b.rates[6] { txn.TXN = ddtxn.RUBIS_PUTCOMMENT x := ddtxn.RandN(local_seed, uint32(b.nproducts)) product := b.products[x] if product == 0 { log.Fatalf("put comment ID 0? %v %v", x, b.products[x]) } // bidder := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] bidder := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] txn.U1 = uint64(bidder) txn.U2 = uint64(product) } else if x < b.rates[7] { txn.TXN = ddtxn.RUBIS_REGISTER txn.U1 = uint64(ddtxn.RandN(local_seed, uint32(ddtxn.NUM_REGIONS))) txn.U2 = uint64(ddtxn.RandN(local_seed, 1000000000)) } else if x < b.rates[8] { txn.TXN = ddtxn.RUBIS_SEARCHCAT txn.U1 = uint64(ddtxn.RandN(local_seed, uint32(ddtxn.NUM_CATEGORIES))) txn.U2 = 5 } else if x < b.rates[9] { txn.TXN = ddtxn.RUBIS_SEARCHREG txn.U1 = uint64(ddtxn.RandN(local_seed, uint32(ddtxn.NUM_REGIONS))) txn.U2 = uint64(ddtxn.RandN(local_seed, uint32(ddtxn.NUM_CATEGORIES))) txn.U3 = 5 } else if x < b.rates[10] { txn.TXN = ddtxn.RUBIS_VIEW x := ddtxn.RandN(local_seed, uint32(b.nproducts)) product := b.products[x] if product == 0 { log.Fatalf("view ID 0? %v %v", x, b.products[x]) } txn.U1 = uint64(product) } else if x < b.rates[11] { txn.TXN = ddtxn.RUBIS_VIEWUSER // bidder := b.users[int(ddtxn.RandN(local_seed, b.sp))+w*int(b.sp)] bidder := b.users[int(ddtxn.RandN(local_seed, uint32(b.nbidders)))] txn.U1 = uint64(bidder) } else { log.Fatalf("No such transaction\n") } }
func main() { flag.Parse() runtime.GOMAXPROCS(*nprocs) if *clientGoRoutines == 0 { *clientGoRoutines = *nprocs } if *nworkers == 0 { *nworkers = *nprocs } if *prob == -1 && *ZipfDist < 0 { log.Fatalf("Zipf distribution must be positive") } if *ZipfDist >= 0 && *prob > -1 { log.Fatalf("Set contention to -1 to use Zipf distribution of keys") } s := ddtxn.NewStore() sp := uint32(*nbidders / *nworkers) for i := 0; i < *nbidders; i++ { k := ddtxn.ProductKey(i) s.CreateKey(k, int32(0), ddtxn.SUM) } dlog.Printf("Done with Populate") coord := ddtxn.NewCoordinator(*nworkers, s) if *ddtxn.CountKeys { for i := 0; i < *nworkers; i++ { w := coord.Workers[i] w.NKeyAccesses = make([]int64, *nbidders) } } dlog.Printf("Done initializing single\n") p := prof.StartProfile() start := time.Now() var wg sync.WaitGroup pkey := int(sp - 1) dlog.Printf("Partition size: %v; Contended key %v\n", sp/2, pkey) gave_up := make([]int64, *clientGoRoutines) goZipf := make([]*ddtxn.Zipf, *clientGoRoutines) if *prob == -1 && *ZipfDist >= 0 { for i := 0; i < *clientGoRoutines; i++ { rnd := rand.New(rand.NewSource(int64(i * 12467))) goZipf[i] = ddtxn.NewZipf(rnd, *ZipfDist, 1, uint64(*nbidders)-1) if goZipf[i] == nil { panic("nil zipf") } } } for i := 0; i < *clientGoRoutines; i++ { wg.Add(1) go func(n int) { exp := ddtxn.MakeExp(50) retries := make(ddtxn.RetryHeap, 0) heap.Init(&retries) var local_seed uint32 = uint32(rand.Intn(10000000)) wi := n % (*nworkers) w := coord.Workers[wi] top := (wi + 1) * int(sp) bottom := wi * int(sp) dlog.Printf("%v: Noncontended section: %v to %v\n", n, bottom, top) end_time := time.Now().Add(time.Duration(*nsec) * time.Second) for { tm := time.Now() if !end_time.After(tm) { break } var t ddtxn.Query if len(retries) > 0 && retries[0].TS.Before(tm) { t = heap.Pop(&retries).(ddtxn.Query) } else { x := float64(ddtxn.RandN(&local_seed, 100)) if *prob == -1 { x := goZipf[n].Uint64() if x >= uint64(*nbidders) || x < 0 { log.Fatalf("x not in bounds: %v\n", x) } t.K1 = ddtxn.ProductKey(int(x)) } else if x < *prob { // contended txn t.K1 = ddtxn.ProductKey(pkey) } else { // uncontended k := pkey for k == pkey { if *partition { rnd := ddtxn.RandN(&local_seed, sp-1) lb := int(rnd) k = lb + wi*int(sp) + 1 if k < bottom || k >= top+1 { log.Fatalf("%v: outside my range %v [%v-%v]\n", n, k, bottom, top) } } else { k = int(ddtxn.RandN(&local_seed, uint32(*nbidders))) } } t.K1 = ddtxn.ProductKey(k) } t.TXN = ddtxn.D_INCR_ONE if *atomicIncr { t.TXN = ddtxn.D_ATOMIC_INCR_ONE } y := int(ddtxn.RandN(&local_seed, 100)) if y < *readrate { t.TXN = ddtxn.D_READ_ONE } } committed := false _, err := w.One(t) if err == ddtxn.EABORT { committed = false } else { committed = true } t.I++ if !committed { e := exp.Exp(t.I) if e <= 0 { e = 1 } rnd := ddtxn.RandN(&local_seed, e) if rnd <= 0 { rnd = 1 } t.TS = tm.Add(time.Duration(rnd) * time.Microsecond) if t.TS.Before(end_time) { heap.Push(&retries, t) } else { gave_up[n]++ } } } w.Finished() wg.Done() if len(retries) > 0 { dlog.Printf("[%v] Length of retry queue on exit: %v\n", n, len(retries)) } gave_up[n] = gave_up[n] + int64(len(retries)) }(i) } wg.Wait() coord.Finish() end := time.Since(start) p.Stop() stats := make([]int64, ddtxn.LAST_STAT) nitr, nwait, _, _, _, _, _ := ddtxn.CollectCounts(coord, stats) for i := 1; i < *clientGoRoutines; i++ { gave_up[0] = gave_up[0] + gave_up[i] } // nitr + NABORTS + ENOKEY is how many requests were issued. A // stashed transaction eventually executes and contributes to // nitr. out := fmt.Sprintf(" nworkers: %v, nwmoved: %v, nrmoved: %v, sys: %v, total/sec: %v, abortrate: %.2f, stashrate: %.2f, rr: %v, nkeys: %v, contention: %v, zipf: %v, done: %v, actual time: %v, nreads: %v, nincrs: %v, epoch changes: %v, throughput ns/txn: %v, naborts: %v, coord time: %v, coord stats time: %v, total worker time transitioning: %v, nstashed: %v, rlock: %v, wrratio: %v, nsamples: %v, getkeys: %v, ddwrites: %v, nolock: %v, failv: %v, nlocked: %v, stashdone: %v, nfast: %v, gaveup: %v, potential: %v ", *nworkers, ddtxn.WMoved, ddtxn.RMoved, *ddtxn.SysType, float64(nitr)/end.Seconds(), 100*float64(stats[ddtxn.NABORTS])/float64(nitr+stats[ddtxn.NABORTS]), 100*float64(stats[ddtxn.NSTASHED])/float64(nitr+stats[ddtxn.NABORTS]), *readrate, *nbidders, *prob, *ZipfDist, nitr, end, stats[ddtxn.D_READ_ONE], stats[ddtxn.D_INCR_ONE], ddtxn.NextEpoch, end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.Time_in_IE, ddtxn.Time_in_IE1, nwait, stats[ddtxn.NSTASHED], *ddtxn.UseRLocks, *ddtxn.WRRatio, stats[ddtxn.NSAMPLES], stats[ddtxn.NGETKEYCALLS], stats[ddtxn.NDDWRITES], stats[ddtxn.NO_LOCK], stats[ddtxn.NFAIL_VERIFY], stats[ddtxn.NLOCKED], stats[ddtxn.NDIDSTASHED], ddtxn.Nfast, gave_up[0], coord.PotentialPhaseChanges) fmt.Printf(out) fmt.Printf("\n") f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) if err != nil { panic(err) } defer f.Close() ddtxn.PrintStats(out, stats, f, coord, s, *nbidders) }
func main() { flag.Parse() runtime.GOMAXPROCS(*nprocs) if *clientGoRoutines == 0 { *clientGoRoutines = *nprocs } if *nworkers == 0 { *nworkers = *nprocs } if *doValidate { if !*ddtxn.Allocate { log.Fatalf("Cannot correctly validate without waiting for results; add -allocate\n") } } var nproducts int if *contention > 0 { nproducts = *nbidders / int(*contention) } else { nproducts = ddtxn.NUM_ITEMS } s := ddtxn.NewStore() coord := ddtxn.NewCoordinator(*nworkers, s) if *ddtxn.CountKeys { for i := 0; i < *nworkers; i++ { w := coord.Workers[i] w.NKeyAccesses = make([]int64, *nbidders) } } rubis := &apps.Rubis{} rubis.Init(nproducts, *nbidders, *nworkers, *clientGoRoutines, *ZipfDist, 0) rubis.PopulateBids(s, coord) // Just creates items to bid on fmt.Printf("Done populating bids\n") if !*ddtxn.Allocate { prealloc := time.Now() tmp := *ddtxn.UseRLocks *ddtxn.UseRLocks = true // Preallocate keys bids_per_worker := 200000.0 if *nworkers == 20 { bids_per_worker *= 20 } if *rounds { parallelism := 10 rounds := *nworkers / parallelism if rounds == 0 { rounds = 1 } for j := 0; j < rounds; j++ { fmt.Printf("Doing round %v\n", j) var wg sync.WaitGroup for i := j * parallelism; i < (j+1)*parallelism; i++ { if i >= *nworkers { break } wg.Add(1) go func(i int) { coord.Workers[i].PreallocateRubis(0, int(bids_per_worker), ddtxn.NUM_ITEMS) wg.Done() }(i) } wg.Wait() } } else { var wg sync.WaitGroup for i := 0; i < *nworkers; i++ { wg.Add(1) go func(i int) { coord.Workers[i].PreallocateRubis(0, int(bids_per_worker), ddtxn.NUM_ITEMS) wg.Done() }(i) } wg.Wait() } *ddtxn.UseRLocks = tmp fmt.Printf("Allocation took %v\n", time.Since(prealloc)) } fmt.Printf("Done initializing rubis\n") p := prof.StartProfile() start := time.Now() gave_up := make([]int64, *clientGoRoutines) var wg sync.WaitGroup for i := 0; i < *clientGoRoutines; i++ { exp := ddtxn.MakeExp(30) wg.Add(1) go func(n int) { retries := make(ddtxn.RetryHeap, 0) heap.Init(&retries) end_time := time.Now().Add(time.Duration(*nsec) * time.Second) var local_seed uint32 = uint32(rand.Intn(1000000)) wi := n % (*nworkers) w := coord.Workers[wi] for { tm := time.Now() if !end_time.After(tm) { break } var t ddtxn.Query if len(retries) > 0 && retries[0].TS.Before(tm) { t = heap.Pop(&retries).(ddtxn.Query) } else { rubis.MakeBid(w.ID, &local_seed, &t) if *ddtxn.Latency { t.S = time.Now() } } if *doValidate { t.W = make(chan struct { R *ddtxn.Result E error }) } committed := false _, err := w.One(t) if err == ddtxn.ESTASH { if *doValidate { x := <-t.W err = x.E } committed = true } else if err == ddtxn.EABORT { committed = false } else { committed = true } t.I++ if !committed { t.TS = tm.Add(time.Duration(ddtxn.RandN(&local_seed, exp.Exp(t.I))) * time.Microsecond) if t.TS.Before(end_time) { heap.Push(&retries, t) } else { gave_up[n]++ } } if committed && *doValidate { rubis.Add(t) } } wg.Done() if len(retries) > 0 { dlog.Printf("[%v] Length of retry queue on exit: %v\n", n, len(retries)) } gave_up[n] = gave_up[n] + int64(len(retries)) }(i) } wg.Wait() coord.Finish() end := time.Since(start) p.Stop() stats := make([]int64, ddtxn.LAST_STAT) nitr, nwait, nwait2 := ddtxn.CollectCounts(coord, stats) _ = nwait2 if *doValidate { rubis.Validate(s, int(nitr)) } for i := 1; i < *clientGoRoutines; i++ { gave_up[0] = gave_up[0] + gave_up[i] } if !*ddtxn.Allocate { keys := []rune{'b', 'c', 'd', 'i', 'k', 'u'} for i := 0; i < *nworkers; i++ { dlog.Printf("w: %v ", i) for _, k := range keys { dlog.Printf("%v %v/%v \t", strconv.QuoteRuneToASCII(k), coord.Workers[i].CurrKey[k], coord.Workers[i].LastKey[k]) } dlog.Printf("\n") } } out := fmt.Sprintf(" nworkers: %v, nwmoved: %v, nrmoved: %v, sys: %v, total/sec: %v, abortrate: %.2f, stashrate: %.2f, nbidders: %v, nitems: %v, contention: %v, done: %v, actual time: %v, throughput: ns/txn: %v, naborts: %v, coord time: %v, coord stats time: %v, total worker time transitioning: %v, nstashed: %v, rlock: %v, wrratio: %v, nsamples: %v, getkeys: %v, ddwrites: %v, nolock: %v, failv: %v, stashdone: %v, nfast: %v, gaveup: %v, epoch changes: %v, potential: %v, coordtotaltime %v, mergetime: %v, readtime: %v, gotime: %v ", *nworkers, ddtxn.WMoved, ddtxn.RMoved, *ddtxn.SysType, float64(nitr)/end.Seconds(), 100*float64(stats[ddtxn.NABORTS])/float64(nitr+stats[ddtxn.NABORTS]), 100*float64(stats[ddtxn.NSTASHED])/float64(nitr+stats[ddtxn.NABORTS]), *nbidders, nproducts, *contention, nitr, end, end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.Time_in_IE, ddtxn.Time_in_IE1, nwait, stats[ddtxn.NSTASHED], *ddtxn.UseRLocks, *ddtxn.WRRatio, stats[ddtxn.NSAMPLES], stats[ddtxn.NGETKEYCALLS], stats[ddtxn.NDDWRITES], stats[ddtxn.NO_LOCK], stats[ddtxn.NFAIL_VERIFY], stats[ddtxn.NDIDSTASHED], ddtxn.Nfast, gave_up[0], ddtxn.NextEpoch, coord.PotentialPhaseChanges, coord.TotalCoordTime, coord.MergeTime, coord.ReadTime, coord.GoTime) fmt.Printf(out) fmt.Printf("\n") fmt.Printf("DD: %v\n", coord.Workers[0].Store().DD()) f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) if err != nil { panic(err) } defer f.Close() ddtxn.PrintStats(out, stats, f, coord, s, *nbidders) x, y := coord.Latency() f.WriteString(x) f.WriteString(y) f.WriteString("\n") }
func main() { flag.Parse() runtime.GOMAXPROCS(*nprocs) if *clientGoRoutines == 0 { *clientGoRoutines = *nprocs } if *nworkers == 0 { *nworkers = *nprocs } if *doValidate { if !*ddtxn.Allocate { log.Fatalf("Cannot correctly validate without waiting for results; add -allocate\n") } } if *contention == -1.0 && *ZipfDist == -1.0 { log.Fatalf("Should use zipf or contention") } var nproducts int if *contention > 0 { nproducts = *nbidders / int(*contention) } else { nproducts = *nbidders } s := ddtxn.NewStore() buy_app := &apps.Buy{} buy_app.Init(nproducts, *nbidders, *nworkers, *readrate, *clientGoRoutines, *notcontended_readrate, *ZipfDist) dlog.Printf("Starting to initialize buy\n") buy_app.Populate(s, nil) coord := ddtxn.NewCoordinator(*nworkers, s) if *ddtxn.CountKeys { for i := 0; i < *nworkers; i++ { w := coord.Workers[i] w.NKeyAccesses = make([]int64, *nbidders) } } dlog.Printf("Done initializing buy\n") p := prof.StartProfile() start := time.Now() var wg sync.WaitGroup gave_upr := make([]int64, *clientGoRoutines) gave_upw := make([]int64, *clientGoRoutines) var ending_retries int64 for i := 0; i < *clientGoRoutines; i++ { wg.Add(1) go func(n int) { exp := ddtxn.MakeExp(50) retries := make(ddtxn.RetryHeap, 0) heap.Init(&retries) end_time := time.Now().Add(time.Duration(*nsec) * time.Second) var local_seed uint32 = uint32(rand.Intn(10000000)) var sp uint32 = uint32(*nbidders / *clientGoRoutines) w := coord.Workers[n%(*nworkers)] var tm time.Time for { tm = time.Now() if !end_time.After(tm) { break } var t ddtxn.Query if len(retries) > 0 && retries[0].TS.Before(tm) { t = heap.Pop(&retries).(ddtxn.Query) } else { buy_app.MakeOne(w.ID, &local_seed, sp, &t) if *ddtxn.Latency { t.S = time.Now() } } if *doValidate { t.W = make(chan struct { R *ddtxn.Result E error }, 1) } committed := false _, err := w.One(t) if err == ddtxn.ESTASH { if *doValidate { x := <-t.W err = x.E if err == ddtxn.EABORT { log.Fatalf("Should be run until commitment!\n") } } committed = true // The worker stash code will retry } else if err == ddtxn.EABORT { committed = false } else { committed = true } t.I++ if !committed { e := uint32(exp.Exp(t.I)) if e < 1 { e = 1 } if local_seed < 1 { local_seed = 1 } rnd := ddtxn.RandN(&local_seed, e) if rnd <= 2 { rnd = 2 } t.TS = tm.Add(time.Duration(rnd) * time.Microsecond) if t.TS.Before(end_time) { heap.Push(&retries, t) } else { if ddtxn.IsRead(t.TXN) { gave_upr[n]++ } else { gave_upw[n]++ } } } if committed && *doValidate { buy_app.Add(t) } } w.Finished() wg.Done() if len(retries) > 0 { dlog.Printf("[%v] Length of retry queue on exit: %v\n", n, len(retries)) } atomic.AddInt64(&ending_retries, int64(len(retries))) }(i) } wg.Wait() coord.Finish() end := time.Since(start) p.Stop() stats := make([]int64, ddtxn.LAST_STAT) nitr, nwait, nnoticed, nmerge, nmergewait, njoin, njoinwait := ddtxn.CollectCounts(coord, stats) if *doValidate { buy_app.Validate(s, int(nitr)) } for i := 1; i < *clientGoRoutines; i++ { gave_upr[0] = gave_upr[0] + gave_upr[i] gave_upw[0] = gave_upw[0] + gave_upw[i] } if ddtxn.NextEpoch == 0 { ddtxn.NextEpoch = 1 } // nitr + NABORTS + ENOKEY is how many requests were issued. A // stashed transaction eventually executes and contributes to // nitr. out := fmt.Sprintf(" nworkers: %v, nwmoved: %v, nrmoved: %v, sys: %v, total/sec: %v, abortrate: %.2f, stashrate: %.2f, rr: %v, nbids: %v, nproducts: %v, contention: %v, done: %v, actual time: %v, nreads: %v, nbuys: %v, epoch changes: %v, throughput ns/txn: %v, naborts: %v, coord time: %v, coord stats time: %v, nstashed: %v, rlock: %v, wrratio: %v, nsamples: %v, getkeys: %v, ddwrites: %v, nolock: %v, failv: %v, stashdone: %v, nfast: %v, gaveup_reads: %v, gaveup_writes: %v, lenretries: %v, potential: %v, coordtotaltime %v, mergetime: %v, readtime: %v, gotime: %v, workertransitiontime: %v, workernoticetime: %v, workermergetime: %v, workermergewaittime: %v, workerjointime: %v, workerjoinwaittime: %v, readaborts: %v ", *nworkers, ddtxn.WMoved, ddtxn.RMoved, *ddtxn.SysType, float64(nitr)/end.Seconds(), 100*float64(stats[ddtxn.NABORTS])/float64(nitr+stats[ddtxn.NABORTS]), 100*float64(stats[ddtxn.NSTASHED])/float64(nitr+stats[ddtxn.NABORTS]), *readrate, *nbidders, nproducts, *contention, nitr, end, stats[ddtxn.D_READ_TWO], stats[ddtxn.D_BUY], ddtxn.NextEpoch, end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.Time_in_IE, ddtxn.Time_in_IE1, stats[ddtxn.NSTASHED], *ddtxn.UseRLocks, *ddtxn.WRRatio, stats[ddtxn.NSAMPLES], stats[ddtxn.NGETKEYCALLS], stats[ddtxn.NDDWRITES], stats[ddtxn.NO_LOCK], stats[ddtxn.NFAIL_VERIFY], stats[ddtxn.NDIDSTASHED], ddtxn.Nfast, gave_upr[0], gave_upw[0], ending_retries, coord.PotentialPhaseChanges, coord.TotalCoordTime, coord.MergeTime, coord.ReadTime, coord.GoTime, nwait, nnoticed, nmerge, nmergewait, njoin, njoinwait, stats[ddtxn.NREADABORTS]) fmt.Printf(out) fmt.Printf("\n") f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) if err != nil { panic(err) } defer f.Close() fmt.Printf("DD: %v\n", coord.Workers[0].Store().DD()) ddtxn.PrintStats(out, stats, f, coord, s, *nbidders) x, y := coord.Latency() f.WriteString(x) f.WriteString(y) f.WriteString("\n") }