github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/cmd/pebble/queue.go (about)

     1  // Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"sync"
    11  	"sync/atomic"
    12  	"time"
    13  
    14  	"github.com/cockroachdb/pebble"
    15  	"github.com/cockroachdb/pebble/internal/randvar"
    16  	"github.com/spf13/cobra"
    17  	"golang.org/x/exp/rand"
    18  )
    19  
    20  var queueConfig struct {
    21  	size   int
    22  	values *randvar.BytesFlag
    23  }
    24  
    25  func initQueue(cmd *cobra.Command) {
    26  	cmd.Flags().IntVar(
    27  		&queueConfig.size, "queue-size", 256,
    28  		"size of the queue to maintain")
    29  	queueConfig.values = randvar.NewBytesFlag("16384")
    30  	cmd.Flags().Var(
    31  		queueConfig.values, "queue-values",
    32  		"queue value size distribution [{zipf,uniform}:]min[-max][/<target-compression>]")
    33  }
    34  
    35  func queueTest() (test, *atomic.Int64) {
    36  	ops := new(atomic.Int64) // atomic
    37  	var (
    38  		lastOps     int64
    39  		lastElapsed time.Duration
    40  	)
    41  	return test{
    42  		init: func(d DB, wg *sync.WaitGroup) {
    43  			var (
    44  				value []byte
    45  				rng   = rand.New(rand.NewSource(1449168817))
    46  				queue = make([][]byte, queueConfig.size)
    47  			)
    48  			for i := 0; i < queueConfig.size; i++ {
    49  				b := d.NewBatch()
    50  				queue[i] = mvccEncode(nil, encodeUint32Ascending([]byte("queue-"), uint32(i)), uint64(i+1), 0)
    51  				value = queueConfig.values.Bytes(rng, value)
    52  				b.Set(queue[i], value, pebble.NoSync)
    53  				if err := b.Commit(pebble.NoSync); err != nil {
    54  					log.Fatal(err)
    55  				}
    56  			}
    57  			if err := d.Flush(); err != nil {
    58  				log.Fatal(err)
    59  			}
    60  
    61  			limiter := maxOpsPerSec.newRateLimiter()
    62  			wg.Add(1)
    63  			go func() {
    64  				defer wg.Done()
    65  
    66  				for i := queueConfig.size; ; i++ {
    67  					idx := i % queueConfig.size
    68  
    69  					// Delete the head.
    70  					b := d.NewBatch()
    71  					if err := b.Delete(queue[idx], pebble.Sync); err != nil {
    72  						log.Fatal(err)
    73  					}
    74  					if err := b.Commit(pebble.Sync); err != nil {
    75  						log.Fatal(err)
    76  					}
    77  					_ = b.Close()
    78  					wait(limiter)
    79  
    80  					// Append to the tail.
    81  					b = d.NewBatch()
    82  					queue[idx] = mvccEncode(queue[idx][:0], encodeUint32Ascending([]byte("queue-"), uint32(i)), uint64(i+1), 0)
    83  					value = queueConfig.values.Bytes(rng, value)
    84  					b.Set(queue[idx], value, nil)
    85  					if err := b.Commit(pebble.Sync); err != nil {
    86  						log.Fatal(err)
    87  					}
    88  					_ = b.Close()
    89  					wait(limiter)
    90  					ops.Add(1)
    91  				}
    92  			}()
    93  		},
    94  		tick: func(elapsed time.Duration, i int) {
    95  			if i%20 == 0 {
    96  				fmt.Println("Queue___elapsed_______ops/sec")
    97  			}
    98  
    99  			curOps := ops.Load()
   100  			dur := elapsed - lastElapsed
   101  			fmt.Printf("%15s %13.1f\n",
   102  				time.Duration(elapsed.Seconds()+0.5)*time.Second,
   103  				float64(curOps-lastOps)/dur.Seconds(),
   104  			)
   105  			lastOps = curOps
   106  			lastElapsed = elapsed
   107  		},
   108  		done: func(elapsed time.Duration) {
   109  			curOps := ops.Load()
   110  			fmt.Println("\nQueue___elapsed___ops/sec(cum)")
   111  			fmt.Printf("%13.1fs %14.1f\n\n",
   112  				elapsed.Seconds(),
   113  				float64(curOps)/elapsed.Seconds())
   114  		},
   115  	}, ops
   116  }