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

     1  // Copyright 2019 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 tool
     6  
     7  import (
     8  	"github.com/cockroachdb/pebble"
     9  	"github.com/cockroachdb/pebble/bloom"
    10  	"github.com/cockroachdb/pebble/internal/base"
    11  	"github.com/cockroachdb/pebble/objstorage/remote"
    12  	"github.com/cockroachdb/pebble/sstable"
    13  	"github.com/cockroachdb/pebble/vfs"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  // Comparer exports the base.Comparer type.
    18  type Comparer = base.Comparer
    19  
    20  // FilterPolicy exports the base.FilterPolicy type.
    21  type FilterPolicy = base.FilterPolicy
    22  
    23  // Merger exports the base.Merger type.
    24  type Merger = base.Merger
    25  
    26  // T is the container for all of the introspection tools.
    27  type T struct {
    28  	Commands        []*cobra.Command
    29  	db              *dbT
    30  	find            *findT
    31  	lsm             *lsmT
    32  	manifest        *manifestT
    33  	remotecat       *remoteCatalogT
    34  	sstable         *sstableT
    35  	wal             *walT
    36  	opts            pebble.Options
    37  	comparers       sstable.Comparers
    38  	mergers         sstable.Mergers
    39  	defaultComparer string
    40  	openErrEnhancer func(error) error
    41  }
    42  
    43  // A Option configures the Pebble introspection tool.
    44  type Option func(*T)
    45  
    46  // Comparers may be passed to New to register comparers for use by
    47  // the introspesction tools.
    48  func Comparers(cmps ...*Comparer) Option {
    49  	return func(t *T) {
    50  		for _, c := range cmps {
    51  			t.comparers[c.Name] = c
    52  		}
    53  	}
    54  }
    55  
    56  // DefaultComparer registers a comparer for use by the introspection tools and
    57  // sets it as the default.
    58  func DefaultComparer(c *Comparer) Option {
    59  	return func(t *T) {
    60  		t.comparers[c.Name] = c
    61  		t.defaultComparer = c.Name
    62  	}
    63  }
    64  
    65  // Mergers may be passed to New to register mergers for use by the
    66  // introspection tools.
    67  func Mergers(mergers ...*Merger) Option {
    68  	return func(t *T) {
    69  		for _, m := range mergers {
    70  			t.mergers[m.Name] = m
    71  		}
    72  	}
    73  }
    74  
    75  // Filters may be passed to New to register filter policies for use by the
    76  // introspection tools.
    77  func Filters(filters ...FilterPolicy) Option {
    78  	return func(t *T) {
    79  		for _, f := range filters {
    80  			t.opts.Filters[f.Name()] = f
    81  		}
    82  	}
    83  }
    84  
    85  // FS sets the filesystem implementation to use by the introspection tools.
    86  func FS(fs vfs.FS) Option {
    87  	return func(t *T) {
    88  		t.opts.FS = fs
    89  	}
    90  }
    91  
    92  // OpenErrEnhancer sets a function that enhances an error encountered when the
    93  // tool opens a database; used to provide the user additional context, for
    94  // example that a corruption error might be caused by encryption at rest not
    95  // being configured properly.
    96  func OpenErrEnhancer(fn func(error) error) Option {
    97  	return func(t *T) {
    98  		t.openErrEnhancer = fn
    99  	}
   100  }
   101  
   102  // New creates a new introspection tool.
   103  func New(opts ...Option) *T {
   104  	t := &T{
   105  		opts: pebble.Options{
   106  			Filters:  make(map[string]FilterPolicy),
   107  			FS:       vfs.Default,
   108  			ReadOnly: true,
   109  		},
   110  		comparers:       make(sstable.Comparers),
   111  		mergers:         make(sstable.Mergers),
   112  		defaultComparer: base.DefaultComparer.Name,
   113  	}
   114  
   115  	opts = append(opts,
   116  		Comparers(base.DefaultComparer),
   117  		Filters(bloom.FilterPolicy(10)),
   118  		Mergers(base.DefaultMerger))
   119  
   120  	for _, opt := range opts {
   121  		opt(t)
   122  	}
   123  
   124  	t.db = newDB(&t.opts, t.comparers, t.mergers, t.openErrEnhancer)
   125  	t.find = newFind(&t.opts, t.comparers, t.defaultComparer, t.mergers)
   126  	t.lsm = newLSM(&t.opts, t.comparers)
   127  	t.manifest = newManifest(&t.opts, t.comparers)
   128  	t.remotecat = newRemoteCatalog(&t.opts)
   129  	t.sstable = newSSTable(&t.opts, t.comparers, t.mergers)
   130  	t.wal = newWAL(&t.opts, t.comparers, t.defaultComparer)
   131  	t.Commands = []*cobra.Command{
   132  		t.db.Root,
   133  		t.find.Root,
   134  		t.lsm.Root,
   135  		t.manifest.Root,
   136  		t.remotecat.Root,
   137  		t.sstable.Root,
   138  		t.wal.Root,
   139  	}
   140  	return t
   141  }
   142  
   143  // ConfigureSharedStorage updates the shared storage options.
   144  func (t *T) ConfigureSharedStorage(
   145  	s remote.StorageFactory,
   146  	createOnShared remote.CreateOnSharedStrategy,
   147  	createOnSharedLocator remote.Locator,
   148  ) {
   149  	t.opts.Experimental.RemoteStorage = s
   150  	t.opts.Experimental.CreateOnShared = createOnShared
   151  	t.opts.Experimental.CreateOnSharedLocator = createOnSharedLocator
   152  }