github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/internal/keyspan/truncate_test.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 keyspan
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/cockroachdb/datadriven"
    14  	"github.com/cockroachdb/pebble/internal/base"
    15  )
    16  
    17  func TestTruncate(t *testing.T) {
    18  	cmp := base.DefaultComparer.Compare
    19  	fmtKey := base.DefaultComparer.FormatKey
    20  	var iter FragmentIterator
    21  	var savedIter FragmentIterator
    22  	defer func() {
    23  		if savedIter != nil {
    24  			savedIter.Close()
    25  			savedIter = nil
    26  		}
    27  	}()
    28  
    29  	datadriven.RunTest(t, "testdata/truncate", func(t *testing.T, d *datadriven.TestData) string {
    30  		doTruncate := func() FragmentIterator {
    31  			if len(d.Input) > 0 {
    32  				t.Fatalf("unexpected input: %s", d.Input)
    33  			}
    34  			if len(d.CmdArgs) < 1 || len(d.CmdArgs) > 3 {
    35  				t.Fatalf("expected 1-3 arguments: %s", d.CmdArgs)
    36  			}
    37  			parts := strings.Split(d.CmdArgs[0].String(), "-")
    38  			var startKey, endKey *base.InternalKey
    39  			if len(d.CmdArgs) > 1 {
    40  				for _, arg := range d.CmdArgs[1:] {
    41  					switch arg.Key {
    42  					case "startKey":
    43  						startKey = &base.InternalKey{}
    44  						*startKey = base.ParseInternalKey(arg.Vals[0])
    45  					case "endKey":
    46  						endKey = &base.InternalKey{}
    47  						*endKey = base.ParseInternalKey(arg.Vals[0])
    48  					}
    49  				}
    50  			}
    51  			if len(parts) != 2 {
    52  				t.Fatalf("malformed arg: %s", d.CmdArgs[0])
    53  			}
    54  			lower := []byte(parts[0])
    55  			upper := []byte(parts[1])
    56  
    57  			tIter := Truncate(
    58  				cmp, iter, lower, upper, startKey, endKey, false,
    59  			)
    60  			return tIter
    61  		}
    62  
    63  		switch d.Cmd {
    64  		case "build":
    65  			tombstones := buildSpans(t, cmp, fmtKey, d.Input, base.InternalKeyKindRangeDelete)
    66  			iter = NewIter(cmp, tombstones)
    67  			return formatAlphabeticSpans(tombstones)
    68  
    69  		case "truncate":
    70  			tIter := doTruncate()
    71  			defer tIter.Close()
    72  			var truncated []Span
    73  			for s := tIter.First(); s != nil; s = tIter.Next() {
    74  				truncated = append(truncated, s.ShallowClone())
    75  			}
    76  			return formatAlphabeticSpans(truncated)
    77  
    78  		case "truncate-and-save-iter":
    79  			if savedIter != nil {
    80  				savedIter.Close()
    81  			}
    82  			savedIter = doTruncate()
    83  			return "ok"
    84  
    85  		case "saved-iter":
    86  			var buf bytes.Buffer
    87  			runIterCmd(t, d, savedIter, &buf)
    88  			return buf.String()
    89  
    90  		default:
    91  			return fmt.Sprintf("unknown command: %s", d.Cmd)
    92  		}
    93  	})
    94  }