Line data Source code
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 1 : func Comparers(cmps ...*Comparer) Option {
49 1 : return func(t *T) {
50 1 : for _, c := range cmps {
51 1 : t.comparers[c.Name] = c
52 1 : }
53 : }
54 : }
55 :
56 : // DefaultComparer registers a comparer for use by the introspection tools and
57 : // sets it as the default.
58 1 : func DefaultComparer(c *Comparer) Option {
59 1 : return func(t *T) {
60 1 : t.comparers[c.Name] = c
61 1 : t.defaultComparer = c.Name
62 1 : }
63 : }
64 :
65 : // Mergers may be passed to New to register mergers for use by the
66 : // introspection tools.
67 1 : func Mergers(mergers ...*Merger) Option {
68 1 : return func(t *T) {
69 1 : for _, m := range mergers {
70 1 : t.mergers[m.Name] = m
71 1 : }
72 : }
73 : }
74 :
75 : // Filters may be passed to New to register filter policies for use by the
76 : // introspection tools.
77 1 : func Filters(filters ...FilterPolicy) Option {
78 1 : return func(t *T) {
79 1 : for _, f := range filters {
80 1 : t.opts.Filters[f.Name()] = f
81 1 : }
82 : }
83 : }
84 :
85 : // FS sets the filesystem implementation to use by the introspection tools.
86 1 : func FS(fs vfs.FS) Option {
87 1 : return func(t *T) {
88 1 : t.opts.FS = fs
89 1 : }
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 1 : func OpenErrEnhancer(fn func(error) error) Option {
97 1 : return func(t *T) {
98 1 : t.openErrEnhancer = fn
99 1 : }
100 : }
101 :
102 : // New creates a new introspection tool.
103 1 : func New(opts ...Option) *T {
104 1 : t := &T{
105 1 : opts: pebble.Options{
106 1 : Filters: make(map[string]FilterPolicy),
107 1 : FS: vfs.Default,
108 1 : ReadOnly: true,
109 1 : },
110 1 : comparers: make(sstable.Comparers),
111 1 : mergers: make(sstable.Mergers),
112 1 : defaultComparer: base.DefaultComparer.Name,
113 1 : }
114 1 :
115 1 : opts = append(opts,
116 1 : Comparers(base.DefaultComparer),
117 1 : Filters(bloom.FilterPolicy(10)),
118 1 : Mergers(base.DefaultMerger))
119 1 :
120 1 : for _, opt := range opts {
121 1 : opt(t)
122 1 : }
123 :
124 1 : t.db = newDB(&t.opts, t.comparers, t.mergers, t.openErrEnhancer)
125 1 : t.find = newFind(&t.opts, t.comparers, t.defaultComparer, t.mergers)
126 1 : t.lsm = newLSM(&t.opts, t.comparers)
127 1 : t.manifest = newManifest(&t.opts, t.comparers)
128 1 : t.remotecat = newRemoteCatalog(&t.opts)
129 1 : t.sstable = newSSTable(&t.opts, t.comparers, t.mergers)
130 1 : t.wal = newWAL(&t.opts, t.comparers, t.defaultComparer)
131 1 : t.Commands = []*cobra.Command{
132 1 : t.db.Root,
133 1 : t.find.Root,
134 1 : t.lsm.Root,
135 1 : t.manifest.Root,
136 1 : t.remotecat.Root,
137 1 : t.sstable.Root,
138 1 : t.wal.Root,
139 1 : }
140 1 : return t
141 : }
142 :
143 : // ConfigureSharedStorage updates the shared storage options.
144 : func (t *T) ConfigureSharedStorage(
145 : s remote.StorageFactory, createOnShared bool, createOnSharedLocator remote.Locator,
146 0 : ) {
147 0 : t.opts.Experimental.RemoteStorage = s
148 0 : t.opts.Experimental.CreateOnShared = createOnShared
149 0 : t.opts.Experimental.CreateOnSharedLocator = createOnSharedLocator
150 0 : }
|