github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/keyspan/bounded_test.go (about)

     1  // Copyright 2022 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/stretchr/testify/require"
    14  	"github.com/zuoyebang/bitalostable/internal/datadriven"
    15  	"github.com/zuoyebang/bitalostable/internal/testkeys"
    16  )
    17  
    18  func TestBoundedIter(t *testing.T) {
    19  	getBounds := func(td *datadriven.TestData) (lower, upper []byte) {
    20  		for _, cmdArg := range td.CmdArgs {
    21  			switch cmdArg.Key {
    22  			case "lower":
    23  				if len(cmdArg.Vals[0]) > 0 {
    24  					lower = []byte(cmdArg.Vals[0])
    25  				}
    26  			case "upper":
    27  				if len(cmdArg.Vals[0]) > 0 {
    28  					upper = []byte(cmdArg.Vals[0])
    29  				}
    30  			}
    31  		}
    32  		return lower, upper
    33  	}
    34  
    35  	cmp := testkeys.Comparer.Compare
    36  	split := testkeys.Comparer.Split
    37  	var buf bytes.Buffer
    38  	var iter BoundedIter
    39  	var hasPrefix bool
    40  	var prefix []byte
    41  	datadriven.RunTest(t, "testdata/bounded_iter", func(td *datadriven.TestData) string {
    42  		switch td.Cmd {
    43  		case "define":
    44  			var spans []Span
    45  			lines := strings.Split(strings.TrimSpace(td.Input), "\n")
    46  			for _, line := range lines {
    47  				spans = append(spans, ParseSpan(line))
    48  			}
    49  			inner := &invalidatingIter{iter: NewIter(cmp, spans)}
    50  			lower, upper := getBounds(td)
    51  			iter.Init(cmp, split, inner, lower, upper, &hasPrefix, &prefix)
    52  			return ""
    53  		case "set-prefix":
    54  			hasPrefix = len(td.CmdArgs) > 0
    55  			if hasPrefix {
    56  				prefix = []byte(td.CmdArgs[0].String())
    57  				return fmt.Sprintf("set prefix to %q\n", prefix)
    58  			}
    59  			return "cleared prefix"
    60  		case "iter":
    61  			buf.Reset()
    62  			lower, upper := getBounds(td)
    63  			iter.SetBounds(lower, upper)
    64  
    65  			lines := strings.Split(strings.TrimSpace(td.Input), "\n")
    66  			for _, line := range lines {
    67  				line = strings.TrimSpace(line)
    68  				i := strings.IndexByte(line, ' ')
    69  				iterCmd := line
    70  				if i > 0 {
    71  					iterCmd = string(line[:i])
    72  				}
    73  				switch iterCmd {
    74  				case "first":
    75  					fmt.Fprintln(&buf, iter.First())
    76  				case "last":
    77  					fmt.Fprintln(&buf, iter.Last())
    78  				case "next":
    79  					fmt.Fprintln(&buf, iter.Next())
    80  				case "prev":
    81  					fmt.Fprintln(&buf, iter.Prev())
    82  				case "seek-ge":
    83  					fmt.Fprintln(&buf, iter.SeekGE([]byte(strings.TrimSpace(line[i:]))))
    84  				case "seek-lt":
    85  					fmt.Fprintln(&buf, iter.SeekLT([]byte(strings.TrimSpace(line[i:]))))
    86  				default:
    87  					return fmt.Sprintf("unrecognized iter command %q", iterCmd)
    88  				}
    89  				require.NoError(t, iter.Error())
    90  			}
    91  			return strings.TrimSpace(buf.String())
    92  		default:
    93  			return fmt.Sprintf("unrecognized command %q", td.Cmd)
    94  		}
    95  	})
    96  }