| 553 | } |
| 554 | |
| 555 | func runReadsRandomNested(cmd *cobra.Command, db *bolt.DB, options *benchOptions, nestedKeys []nestedKey, results *benchResults) error { |
| 556 | return db.View(func(tx *bolt.Tx) error { |
| 557 | t := time.Now() |
| 558 | |
| 559 | for { |
| 560 | numReads := int64(0) |
| 561 | err := func() error { |
| 562 | defer func() { results.addCompletedOps(numReads) }() |
| 563 | |
| 564 | var top = tx.Bucket(benchBucketName) |
| 565 | for _, nestedKey := range nestedKeys { |
| 566 | if b := top.Bucket(nestedKey.bucket); b != nil { |
| 567 | v := b.Get(nestedKey.key) |
| 568 | numReads++ |
| 569 | if v == nil { |
| 570 | return ErrInvalidValue |
| 571 | } |
| 572 | } |
| 573 | } |
| 574 | |
| 575 | return nil |
| 576 | }() |
| 577 | |
| 578 | if err != nil { |
| 579 | return err |
| 580 | } |
| 581 | |
| 582 | if options.writeMode == "seq-nest" && numReads != options.iterations { |
| 583 | return fmt.Errorf("read seq-nest: iter mismatch: expected %d, got %d", options.iterations, numReads) |
| 584 | } |
| 585 | |
| 586 | // Make sure we do this for at least a second. |
| 587 | if time.Since(t) >= time.Second { |
| 588 | break |
| 589 | } |
| 590 | } |
| 591 | |
| 592 | return nil |
| 593 | }) |
| 594 | } |
| 595 | |
| 596 | func checkProgress(results *benchResults, finishChan chan interface{}, stderr io.Writer) { |
| 597 | ticker := time.Tick(time.Second) |