Skip to content

Commit 54bb06f

Browse files
committed
tool: separate blob mode flags
This allows us to specify a relative path for our scan tool instead of enforcing some rule about the order of arguments to scan.
1 parent 586965a commit 54bb06f

File tree

7 files changed

+60
-106
lines changed

7 files changed

+60
-106
lines changed

sstable/values.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,16 @@ var DebugHandlesBlobContext = TableBlobContext{
3535
InlineHandlePreface: preface,
3636
HandleSuffix: handleSuffix,
3737
}
38-
return base.MakeInPlaceValue([]byte(ih.String()))
38+
// Prepend "blob-value:" to the handle to help identify blob values
39+
// from inline values later on (we want to be able to format the former
40+
// differently during value formatting).
41+
//
42+
// TODO(annie): Revisit this once we support determining the type
43+
// of value we are dealing with in our sstable internal iterator.
44+
// We can use some information about the ValuePrefix to separate
45+
// how we want to format in-place values and blob value handles
46+
// (via a new formatter) instead of prepending "blob-value:".
47+
return base.MakeInPlaceValue([]byte("blob-value:" + ih.String()))
3948
},
4049
}
4150

tool/find.go

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ type findT struct {
5656
fmtKey keyFormatter
5757
fmtValue valueFormatter
5858
verbose bool
59-
blobMode string
59+
blobModeLoad bool
6060

6161
// Map from file num to version edit index which references the file num.
6262
editRefs map[base.DiskFileNum][]int
@@ -121,8 +121,8 @@ provenance of the sstables (flushed, ingested, compacted).
121121
&f.fmtKey, "key", "key formatter")
122122
f.Root.Flags().Var(
123123
&f.fmtValue, "value", "value formatter")
124-
f.Root.Flags().StringVar(
125-
&f.blobMode, "blob-mode", "none", "blob value formatter")
124+
f.Root.Flags().BoolVar(
125+
&f.blobModeLoad, "load-blobs", false, "load values from blob file when encountered")
126126
return f
127127
}
128128

@@ -483,16 +483,9 @@ func (f *findT) searchTables(stdout io.Writer, searchKey []byte, refs []findRef)
483483
fragTransforms = m.FragmentIterTransforms()
484484
}
485485

486-
var blobContext sstable.TableBlobContext
487-
switch ConvertToBlobRefMode(f.blobMode) {
488-
case BlobRefModePrint:
489-
f.fmtValue.mustSet("[%s]")
490-
blobContext = sstable.DebugHandlesBlobContext
491-
case BlobRefModeLoad:
492-
f.fmtValue.mustSet("[%s]")
486+
blobContext := sstable.DebugHandlesBlobContext
487+
if f.blobModeLoad {
493488
blobContext = f.blobMappings.LoadValueBlobContext(base.PhysicalTableFileNum(fl.DiskFileNum))
494-
default:
495-
blobContext = sstable.AssertNoBlobHandles
496489
}
497490
iter, err := r.NewIter(transforms, nil, nil, blobContext)
498491
if err != nil {

tool/sstable.go

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ type sstableT struct {
4444
mergers sstable.Mergers
4545

4646
// Flags.
47-
fmtKey keyFormatter
48-
fmtValue valueFormatter
49-
start key
50-
end key
51-
filter key
52-
count int64
53-
verbose bool
54-
blobMode string
47+
fmtKey keyFormatter
48+
fmtValue valueFormatter
49+
start key
50+
end key
51+
filter key
52+
count int64
53+
verbose bool
54+
blobModeLoad string
5555
}
5656

5757
func newSSTable(
@@ -103,9 +103,6 @@ properties are pretty-printed or displayed in a verbose/raw format.
103103
Print the records in the sstables. The sstables are scanned in command line
104104
order which means the records will be printed in that order. Raw range
105105
tombstones are displayed interleaved with point records.
106-
107-
When --blob-mode=load is specified, the path to a directory containing a
108-
manifest and blob file must be provided as the last argument.
109106
`,
110107
Args: cobra.MinimumNArgs(1),
111108
Run: s.runScan,
@@ -145,7 +142,8 @@ inclusive-inclusive range specified by --start and --end.
145142
s.Scan.Flags().Int64Var(
146143
&s.count, "count", 0, "key count for scan (0 is unlimited)")
147144
s.Scan.Flags().StringVar(
148-
&s.blobMode, "blob-mode", "none", "blob value formatter")
145+
&s.blobModeLoad, "load-blobs-from", "", "relative path to a directory containing a manifest and "+
146+
"blob file to load values from")
149147

150148
return s
151149
}
@@ -339,25 +337,14 @@ func (s *sstableT) runProperties(cmd *cobra.Command, args []string) {
339337

340338
func (s *sstableT) runScan(cmd *cobra.Command, args []string) {
341339
stdout, stderr := cmd.OutOrStdout(), cmd.OutOrStderr()
342-
// If in blob load mode, the last argument is the path to our directory
343-
// containing the manifest(s) and blob file(s).
344-
blobMode := ConvertToBlobRefMode(s.blobMode)
345-
var blobDir string
346340
var blobMappings *blobFileMappings
347-
if blobMode == BlobRefModeLoad {
348-
if len(args) < 2 {
349-
fmt.Fprintf(stderr, "when --blob-mode=load is specified, the path to a "+
350-
"directory containing a manifest and blob file must be provided as the last argument")
351-
return
352-
}
353-
blobDir = args[len(args)-1]
354-
args = args[:len(args)-1]
355-
manifests, err := findManifests(stderr, s.opts.FS, blobDir)
341+
if s.blobModeLoad != "" {
342+
manifests, err := findManifests(stderr, s.opts.FS, s.blobModeLoad)
356343
if err != nil {
357344
fmt.Fprintf(stderr, "%s\n", err)
358345
return
359346
}
360-
blobMappings, err = newBlobFileMappings(stderr, s.opts.FS, blobDir, manifests)
347+
blobMappings, err = newBlobFileMappings(stderr, s.opts.FS, s.blobModeLoad, manifests)
361348
if err != nil {
362349
fmt.Fprintf(stderr, "%s\n", err)
363350
return
@@ -379,22 +366,15 @@ func (s *sstableT) runScan(cmd *cobra.Command, args []string) {
379366
prefix = fmt.Sprintf("%s: ", path)
380367
}
381368

382-
var blobContext sstable.TableBlobContext
383-
switch blobMode {
384-
case BlobRefModePrint:
385-
s.fmtValue.mustSet("[%s]")
386-
blobContext = sstable.DebugHandlesBlobContext
387-
case BlobRefModeLoad:
369+
blobContext := sstable.DebugHandlesBlobContext
370+
if s.blobModeLoad != "" {
388371
// If the file number is unset, we are likely trying to read a
389372
// non numerically named file.
390373
if r.BlockReader().FileNum() == 0 {
391374
fmt.Fprintf(stderr, "unset file in path %s\n", path)
392375
return
393376
}
394-
s.fmtValue.mustSet("[%s]")
395377
blobContext = blobMappings.LoadValueBlobContext(base.PhysicalTableFileNum(r.BlockReader().FileNum()))
396-
default:
397-
blobContext = sstable.AssertNoBlobHandles
398378
}
399379
iter, err := r.NewIter(sstable.NoTransforms, nil, s.end, blobContext)
400380
if err != nil {

tool/testdata/find

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,13 @@ Unable to decode sstable find-mixed/000001.sst, pebble/table: invalid table 0000
142142
find
143143
testdata/find-db
144144
eee
145-
--blob-mode=print
146145
----
147146
000004.log
148147
bbb-eee#19,RANGEDEL
149148

150149
find
151150
testdata/find-val-sep-db
152151
crdb:aaa
153-
--blob-mode=print
154152
----
155153
000005.sst [aaa\x00#10,SET-ddd\x00#13,SET]
156154
(flushed to L0)
@@ -159,48 +157,46 @@ crdb:aaa
159157
find
160158
testdata/find-val-sep-db
161159
crdb:eee
162-
--blob-mode=print
163160
----
164161
000004.log
165-
eee\x00#14,SET [pigeon]
162+
eee\x00#14,SET [706967656f6e]
166163
000008.sst [eee\x00#14,SET-fff\x00#15,SET]
167164
(flushed to L0)
168165
eee\x00#14,SET [(f0,blk0,id0,len6)]
169166

170167
find
171168
testdata/find-val-sep-db
172169
crdb:ddd
173-
--blob-mode=print
174170
----
175171
000005.sst [aaa\x00#10,SET-ddd\x00#13,SET]
176172
(flushed to L0)
177-
ddd\x00#13,SET [6]
173+
ddd\x00#13,SET [36]
178174

179175
find
180176
testdata/find-val-sep-db
181177
crdb:aaa
182-
--blob-mode=load
178+
--load-blobs
183179
----
184180
000005.sst [aaa\x00#10,SET-ddd\x00#13,SET]
185181
(flushed to L0)
186-
aaa\x00#10,SET [yuumi]
182+
aaa\x00#10,SET [7975756d69]
187183

188184
find
189185
testdata/find-val-sep-db
190186
crdb:ddd
191-
--blob-mode=load
187+
--load-blobs
192188
----
193189
000005.sst [aaa\x00#10,SET-ddd\x00#13,SET]
194190
(flushed to L0)
195-
ddd\x00#13,SET [6]
191+
ddd\x00#13,SET [36]
196192

197193
find
198194
testdata/find-val-sep-db
199195
crdb:eee
200-
--blob-mode=load
196+
--load-blobs
201197
----
202198
000004.log
203-
eee\x00#14,SET [pigeon]
199+
eee\x00#14,SET [706967656f6e]
204200
000008.sst [eee\x00#14,SET-fff\x00#15,SET]
205201
(flushed to L0)
206-
eee\x00#14,SET [pigeon]
202+
eee\x00#14,SET [706967656f6e]

tool/testdata/sstable_scan

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -415,46 +415,36 @@ tcrsfsqc@1366.233420574,0#0,SET [1b22f2128e75f0433e8eda52c41872e6]
415415

416416
sstable scan
417417
./testdata/find-val-sep-db
418-
--blob-mode=print
419418
----
420419
find-val-sep-db/000005.sst
421420
aaa\x00#10,SET [(f0,blk0,id0,len5)]
422421
bbb\x00#11,SET [(f0,blk0,id1,len3)]
423422
ccc\x00#12,SET [(f0,blk0,id2,len10)]
424-
ddd\x00#13,SET [6]
423+
ddd\x00#13,SET [36]
425424
find-val-sep-db/000008.sst
426425
eee\x00#14,SET [(f0,blk0,id0,len6)]
427426
fff\x00#15,SET [(f0,blk0,id1,len7)]
428427

429-
sstable scan
430-
--filter=armed
431-
--blob-mode=print
432-
../sstable/testdata/hamlet-sst/000002.sst
433-
----
434-
000002.sst: armed#0,SET [2]
435-
436428
sstable scan
437429
./testdata/find-val-sep-db/000005.sst
438-
--blob-mode=load
430+
--load-blobs-from
439431
----
440-
when --blob-mode=load is specified, the path to a directory containing a manifest and blob file must be provided as the last argument
432+
flag needs an argument: --load-blobs-from
441433

442434
sstable scan
443435
./testdata/find-val-sep-db/000005.sst
444-
./testdata/find-val-sep-db
445-
--blob-mode=load
436+
--load-blobs-from=find-val-sep-db
446437
----
447438
000005.sst
448-
aaa\x00#10,SET [yuumi]
449-
bbb\x00#11,SET [mai]
450-
ccc\x00#12,SET [poiandyaya]
451-
ddd\x00#13,SET [6]
439+
aaa\x00#10,SET [7975756d69]
440+
bbb\x00#11,SET [6d6169]
441+
ccc\x00#12,SET [706f69616e6479617961]
442+
ddd\x00#13,SET [36]
452443

453444
sstable scan
454445
./testdata/find-val-sep-db/000008.sst
455-
./testdata/find-val-sep-db
456-
--blob-mode=load
446+
--load-blobs-from=find-val-sep-db
457447
----
458448
000008.sst
459-
eee\x00#14,SET [pigeon]
460-
fff\x00#15,SET [chicken]
449+
eee\x00#14,SET [706967656f6e]
450+
fff\x00#15,SET [636869636b656e]

tool/tool.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -200,30 +200,6 @@ func (t *T) ConfigureSharedStorage(
200200
t.opts.Experimental.CreateOnSharedLocator = createOnSharedLocator
201201
}
202202

203-
// BlobRefMode specifies how blob references should be handled.
204-
type BlobRefMode int
205-
206-
const (
207-
// BlobRefModeNone specifies the AssertNoBlobHandles TableBlobContext.
208-
BlobRefModeNone BlobRefMode = iota
209-
// BlobRefModePrint specifies the DebugHandlesBlobContext TableBlobContext.
210-
BlobRefModePrint
211-
// BlobRefModeLoad specifies the LoadValBlobContext
212-
// TableBlobContext.
213-
BlobRefModeLoad
214-
)
215-
216-
func ConvertToBlobRefMode(s string) BlobRefMode {
217-
switch s {
218-
case "print":
219-
return BlobRefModePrint
220-
case "load":
221-
return BlobRefModeLoad
222-
default:
223-
return BlobRefModeNone
224-
}
225-
}
226-
227203
// debugReaderProvider is a cache-less ReaderProvider meant for debugging blob
228204
// files.
229205
type debugReaderProvider struct {

tool/util.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package tool
66

77
import (
8+
"bytes"
89
"encoding/hex"
910
"fmt"
1011
"io"
@@ -176,6 +177,15 @@ func (f *valueFormatter) Set(spec string) error {
176177
return fmtFormatter{f.spec, v}
177178
}
178179
}
180+
fn := f.fn
181+
// Format blob values differently from inline values.
182+
f.fn = func(k, v []byte) fmt.Formatter {
183+
valuePrefix := []byte("blob-value:")
184+
if bytes.HasPrefix(v, valuePrefix) {
185+
return fmtFormatter{"[%s]", v[len(valuePrefix):]}
186+
}
187+
return fn(k, v)
188+
}
179189
return nil
180190
}
181191

0 commit comments

Comments
 (0)