@@ -15,8 +15,10 @@ import (
1515
1616 "github.com/cockroachdb/crlib/crstrings"
1717 "github.com/cockroachdb/errors"
18+ "github.com/cockroachdb/pebble/bloom"
1819 "github.com/cockroachdb/pebble/internal/base"
1920 "github.com/cockroachdb/pebble/internal/keyspan"
21+ "github.com/cockroachdb/pebble/internal/testkeys"
2022 "github.com/cockroachdb/pebble/objstorage"
2123 "github.com/cockroachdb/pebble/sstable/blob"
2224 "github.com/cockroachdb/pebble/sstable/block"
@@ -258,3 +260,91 @@ func decodeBlobInlineHandleAndAttribute(
258260 },
259261 }, base .ShortAttribute (attr [0 ]), nil
260262}
263+
264+ // ParseWriterOptions modifies WriterOptions based on the given arguments. Each
265+ // argument is a string or a fmt.Stringer (like datadriven.TestData.CmdArg) with
266+ // format either "<key>" or "<key>=<value>".
267+ func ParseWriterOptions [StringOrStringer any ](o * WriterOptions , args ... StringOrStringer ) error {
268+ for _ , arg := range args {
269+ str , ok := any (arg ).(string )
270+ if ! ok {
271+ str = any (arg ).(fmt.Stringer ).String ()
272+ }
273+ key , value , _ := strings .Cut (str , "=" )
274+ var err error
275+ switch key {
276+ case "leveldb" :
277+ o .TableFormat = TableFormatLevelDB
278+ case "format" :
279+ switch value {
280+ case "leveldb" :
281+ o .TableFormat = TableFormatLevelDB
282+ case "pebblev1" :
283+ o .TableFormat = TableFormatPebblev1
284+ case "pebblev2" :
285+ o .TableFormat = TableFormatPebblev2
286+ case "pebblev3" :
287+ o .TableFormat = TableFormatPebblev3
288+ case "pebblev4" :
289+ o .TableFormat = TableFormatPebblev4
290+ case "pebblev5" :
291+ o .TableFormat = TableFormatPebblev5
292+ case "pebblev6" :
293+ o .TableFormat = TableFormatPebblev6
294+ default :
295+ return errors .Errorf ("unknown format string %s" , value )
296+ }
297+ case "block-size" :
298+ o .BlockSize , err = strconv .Atoi (value )
299+
300+ case "index-block-size" :
301+ o .IndexBlockSize , err = strconv .Atoi (value )
302+
303+ case "filter" :
304+ o .FilterPolicy = bloom .FilterPolicy (10 )
305+
306+ case "comparer" :
307+ o .Comparer , err = comparerFromCmdArg (value )
308+
309+ case "writing-to-lowest-level" :
310+ o .WritingToLowestLevel = true
311+
312+ case "is-strict-obsolete" :
313+ o .IsStrictObsolete = true
314+
315+ default :
316+ // TODO(radu): ignoring unknown keys is error-prone; we need to find an
317+ // easy way for the upper layer to extract its own arguments.
318+ }
319+ if err != nil {
320+ return err
321+ }
322+ }
323+ return nil
324+ }
325+
326+ func comparerFromCmdArg (value string ) (* Comparer , error ) {
327+ switch value {
328+ case "split-4b-suffix" :
329+ return test4bSuffixComparer , nil
330+ case "testkeys" :
331+ return testkeys .Comparer , nil
332+ case "default" :
333+ return base .DefaultComparer , nil
334+ default :
335+ return nil , errors .Errorf ("unknown comparer: %s" , value )
336+ }
337+ }
338+
339+ var test4bSuffixComparer = func () * base.Comparer {
340+ c := new (base.Comparer )
341+ * c = * base .DefaultComparer
342+ c .Split = func (key []byte ) int {
343+ if len (key ) > 4 {
344+ return len (key ) - 4
345+ }
346+ return len (key )
347+ }
348+ c .Name = "comparer-split-4b-suffix"
349+ return c
350+ }()
0 commit comments