LCOV - code coverage report
Current view: top level - pebble/internal/base - test_utils.go (source / functions) Hit Total Coverage
Test: 2024-11-16 08:16Z 9ed54bc4 - tests only.lcov Lines: 133 160 83.1 %
Date: 2024-11-16 08:17:17 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2024 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 base
       6             : 
       7             : import (
       8             :         "context"
       9             :         "fmt"
      10             :         "io"
      11             :         "strconv"
      12             :         "strings"
      13             : 
      14             :         "github.com/cockroachdb/pebble/internal/treeprinter"
      15             : )
      16             : 
      17             : // NewDeletableSumValueMerger return a ValueMerger which computes the sum of its
      18             : // arguments, but transforms a zero sum into a non-existent entry.
      19           1 : func NewDeletableSumValueMerger(key, value []byte) (ValueMerger, error) {
      20           1 :         m := &deletableSumValueMerger{}
      21           1 :         return m, m.MergeNewer(value)
      22           1 : }
      23             : 
      24             : type deletableSumValueMerger struct {
      25             :         sum int64
      26             : }
      27             : 
      28           1 : func (m *deletableSumValueMerger) parseAndCalculate(value []byte) error {
      29           1 :         v, err := strconv.ParseInt(string(value), 10, 64)
      30           1 :         if err == nil {
      31           1 :                 m.sum += v
      32           1 :         }
      33           1 :         return err
      34             : }
      35             : 
      36           1 : func (m *deletableSumValueMerger) MergeNewer(value []byte) error {
      37           1 :         return m.parseAndCalculate(value)
      38           1 : }
      39             : 
      40           1 : func (m *deletableSumValueMerger) MergeOlder(value []byte) error {
      41           1 :         return m.parseAndCalculate(value)
      42           1 : }
      43             : 
      44           1 : func (m *deletableSumValueMerger) Finish(includesBase bool) ([]byte, io.Closer, error) {
      45           1 :         if m.sum == 0 {
      46           1 :                 return nil, nil, nil
      47           1 :         }
      48           1 :         return []byte(strconv.FormatInt(m.sum, 10)), nil, nil
      49             : }
      50             : 
      51             : func (m *deletableSumValueMerger) DeletableFinish(
      52             :         includesBase bool,
      53           1 : ) ([]byte, bool, io.Closer, error) {
      54           1 :         value, closer, err := m.Finish(includesBase)
      55           1 :         return value, len(value) == 0, closer, err
      56           1 : }
      57             : 
      58             : // FakeKVs constructs InternalKVs from the given key strings, in the format
      59             : // "key:seq-num". The values are empty.
      60           1 : func FakeKVs(keys ...string) []InternalKV {
      61           1 :         kvs := make([]InternalKV, len(keys))
      62           1 :         for i, k := range keys {
      63           1 :                 kvs[i] = InternalKV{K: fakeIkey(k)}
      64           1 :         }
      65           1 :         return kvs
      66             : }
      67             : 
      68           1 : func fakeIkey(s string) InternalKey {
      69           1 :         j := strings.Index(s, ":")
      70           1 :         seqNum, err := strconv.Atoi(s[j+1:])
      71           1 :         if err != nil {
      72           0 :                 panic(err)
      73             :         }
      74           1 :         return MakeInternalKey([]byte(s[:j]), SeqNum(seqNum), InternalKeyKindSet)
      75             : }
      76             : 
      77             : // NewFakeIter returns an iterator over the given KVs.
      78           1 : func NewFakeIter(kvs []InternalKV) *FakeIter {
      79           1 :         return &FakeIter{
      80           1 :                 kvs:   kvs,
      81           1 :                 index: 0,
      82           1 :                 valid: len(kvs) > 0,
      83           1 :         }
      84           1 : }
      85             : 
      86             : // FakeIter is an iterator over a fixed set of KVs.
      87             : type FakeIter struct {
      88             :         lower    []byte
      89             :         upper    []byte
      90             :         kvs      []InternalKV
      91             :         index    int
      92             :         valid    bool
      93             :         closeErr error
      94             : }
      95             : 
      96             : // FakeIter implements the InternalIterator interface.
      97             : var _ InternalIterator = (*FakeIter)(nil)
      98             : 
      99             : // SetCloseErr causes future calls to Error() and Close() to return this error.
     100           1 : func (f *FakeIter) SetCloseErr(closeErr error) {
     101           1 :         f.closeErr = closeErr
     102           1 : }
     103             : 
     104           0 : func (f *FakeIter) String() string {
     105           0 :         return "fake"
     106           0 : }
     107             : 
     108             : // SeekGE is part of the InternalIterator interface.
     109           1 : func (f *FakeIter) SeekGE(key []byte, flags SeekGEFlags) *InternalKV {
     110           1 :         f.valid = false
     111           1 :         for f.index = 0; f.index < len(f.kvs); f.index++ {
     112           1 :                 if DefaultComparer.Compare(key, f.key().UserKey) <= 0 {
     113           1 :                         if f.upper != nil && DefaultComparer.Compare(f.upper, f.key().UserKey) <= 0 {
     114           1 :                                 return nil
     115           1 :                         }
     116           1 :                         f.valid = true
     117           1 :                         return f.KV()
     118             :                 }
     119             :         }
     120           1 :         return nil
     121             : }
     122             : 
     123             : // SeekPrefixGE is part of the InternalIterator interface.
     124           1 : func (f *FakeIter) SeekPrefixGE(prefix, key []byte, flags SeekGEFlags) *InternalKV {
     125           1 :         return f.SeekGE(key, flags)
     126           1 : }
     127             : 
     128             : // SeekLT is part of the InternalIterator interface.
     129           1 : func (f *FakeIter) SeekLT(key []byte, flags SeekLTFlags) *InternalKV {
     130           1 :         f.valid = false
     131           1 :         for f.index = len(f.kvs) - 1; f.index >= 0; f.index-- {
     132           1 :                 if DefaultComparer.Compare(key, f.key().UserKey) > 0 {
     133           1 :                         if f.lower != nil && DefaultComparer.Compare(f.lower, f.key().UserKey) > 0 {
     134           1 :                                 return nil
     135           1 :                         }
     136           1 :                         f.valid = true
     137           1 :                         return f.KV()
     138             :                 }
     139             :         }
     140           1 :         return nil
     141             : }
     142             : 
     143             : // First is part of the InternalIterator interface.
     144           1 : func (f *FakeIter) First() *InternalKV {
     145           1 :         f.valid = false
     146           1 :         f.index = -1
     147           1 :         if kv := f.Next(); kv == nil {
     148           1 :                 return nil
     149           1 :         }
     150           1 :         if f.upper != nil && DefaultComparer.Compare(f.upper, f.key().UserKey) <= 0 {
     151           0 :                 return nil
     152           0 :         }
     153           1 :         f.valid = true
     154           1 :         return f.KV()
     155             : }
     156             : 
     157             : // Last is part of the InternalIterator interface.
     158           1 : func (f *FakeIter) Last() *InternalKV {
     159           1 :         f.valid = false
     160           1 :         f.index = len(f.kvs)
     161           1 :         if kv := f.Prev(); kv == nil {
     162           0 :                 return nil
     163           0 :         }
     164           1 :         if f.lower != nil && DefaultComparer.Compare(f.lower, f.key().UserKey) > 0 {
     165           0 :                 return nil
     166           0 :         }
     167           1 :         f.valid = true
     168           1 :         return f.KV()
     169             : }
     170             : 
     171             : // Next is part of the InternalIterator interface.
     172           1 : func (f *FakeIter) Next() *InternalKV {
     173           1 :         f.valid = false
     174           1 :         if f.index == len(f.kvs) {
     175           1 :                 return nil
     176           1 :         }
     177           1 :         f.index++
     178           1 :         if f.index == len(f.kvs) {
     179           1 :                 return nil
     180           1 :         }
     181           1 :         if f.upper != nil && DefaultComparer.Compare(f.upper, f.key().UserKey) <= 0 {
     182           1 :                 return nil
     183           1 :         }
     184           1 :         f.valid = true
     185           1 :         return f.KV()
     186             : }
     187             : 
     188             : // Prev is part of the InternalIterator interface.
     189           1 : func (f *FakeIter) Prev() *InternalKV {
     190           1 :         f.valid = false
     191           1 :         if f.index < 0 {
     192           0 :                 return nil
     193           0 :         }
     194           1 :         f.index--
     195           1 :         if f.index < 0 {
     196           1 :                 return nil
     197           1 :         }
     198           1 :         if f.lower != nil && DefaultComparer.Compare(f.lower, f.key().UserKey) > 0 {
     199           1 :                 return nil
     200           1 :         }
     201           1 :         f.valid = true
     202           1 :         return f.KV()
     203             : }
     204             : 
     205             : // NextPrefix is part of the InternalIterator interface.
     206           0 : func (f *FakeIter) NextPrefix(succKey []byte) *InternalKV {
     207           0 :         return f.SeekGE(succKey, SeekGEFlagsNone)
     208           0 : }
     209             : 
     210             : // key returns the current Key the iterator is positioned at regardless of the
     211             : // value of f.valid.
     212           1 : func (f *FakeIter) key() *InternalKey {
     213           1 :         return &f.kvs[f.index].K
     214           1 : }
     215             : 
     216             : // KV is part of the InternalIterator interface.
     217           1 : func (f *FakeIter) KV() *InternalKV {
     218           1 :         if f.valid {
     219           1 :                 return &f.kvs[f.index]
     220           1 :         }
     221             :         // It is invalid to call Key() when Valid() returns false. Rather than
     222             :         // returning nil here which would technically be more correct, return a
     223             :         // non-nil key which is the behavior of some InternalIterator
     224             :         // implementations. This provides better testing of users of
     225             :         // InternalIterators.
     226           0 :         if f.index < 0 {
     227           0 :                 return &f.kvs[0]
     228           0 :         }
     229           0 :         return &f.kvs[len(f.kvs)-1]
     230             : }
     231             : 
     232             : // Valid is part of the InternalIterator interface.
     233           0 : func (f *FakeIter) Valid() bool {
     234           0 :         return f.index >= 0 && f.index < len(f.kvs) && f.valid
     235           0 : }
     236             : 
     237             : // Error is part of the InternalIterator interface.
     238           1 : func (f *FakeIter) Error() error {
     239           1 :         return f.closeErr
     240           1 : }
     241             : 
     242             : // Close is part of the InternalIterator interface.
     243           1 : func (f *FakeIter) Close() error {
     244           1 :         return f.closeErr
     245           1 : }
     246             : 
     247             : // SetBounds is part of the InternalIterator interface.
     248           1 : func (f *FakeIter) SetBounds(lower, upper []byte) {
     249           1 :         f.lower = lower
     250           1 :         f.upper = upper
     251           1 : }
     252             : 
     253             : // SetContext is part of the InternalIterator interface.
     254           0 : func (f *FakeIter) SetContext(_ context.Context) {}
     255             : 
     256             : // DebugTree is part of the InternalIterator interface.
     257           0 : func (f *FakeIter) DebugTree(tp treeprinter.Node) {
     258           0 :         tp.Childf("%T(%p)", f, f)
     259           0 : }
     260             : 
     261             : // ParseUserKeyBounds parses UserKeyBounds from a string representation of the
     262             : // form "[foo, bar]" or "[foo, bar)".
     263           1 : func ParseUserKeyBounds(s string) UserKeyBounds {
     264           1 :         first, last, s := s[0], s[len(s)-1], s[1:len(s)-1]
     265           1 :         start, end, ok := strings.Cut(s, ", ")
     266           1 :         if !ok || first != '[' || (last != ']' && last != ')') {
     267           0 :                 panic(fmt.Sprintf("invalid bounds %q", s))
     268             :         }
     269           1 :         return UserKeyBoundsEndExclusiveIf([]byte(start), []byte(end), last == ')')
     270             : }

Generated by: LCOV version 1.14