LCOV - code coverage report
Current view: top level - pebble/internal/keyspan - transformer.go (source / functions) Hit Total Coverage
Test: 2024-06-06 08:16Z 8fb46650 - tests + meta.lcov Lines: 59 73 80.8 %
Date: 2024-06-06 08:17:16 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 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 "github.com/cockroachdb/pebble/internal/base"
       8             : 
       9             : // Transformer defines a transformation to be applied to a Span.
      10             : type Transformer interface {
      11             :         // Transform takes a Span as input and writes the transformed Span to the
      12             :         // provided output *Span pointer. The output Span's Keys slice may be reused
      13             :         // by Transform to reduce allocations.
      14             :         Transform(cmp base.Compare, in Span, out *Span) error
      15             : }
      16             : 
      17             : // The TransformerFunc type is an adapter to allow the use of ordinary functions
      18             : // as Transformers. If f is a function with the appropriate signature,
      19             : // TransformerFunc(f) is a Transformer that calls f.
      20             : type TransformerFunc func(base.Compare, Span, *Span) error
      21             : 
      22             : // Transform calls f(cmp, in, out).
      23           2 : func (tf TransformerFunc) Transform(cmp base.Compare, in Span, out *Span) error {
      24           2 :         return tf(cmp, in, out)
      25           2 : }
      26             : 
      27             : // NoopTransform is a Transformer that performs no mutations.
      28           2 : var NoopTransform Transformer = TransformerFunc(func(_ base.Compare, s Span, dst *Span) error {
      29           2 :         dst.Start, dst.End = s.Start, s.End
      30           2 :         dst.Keys = append(dst.Keys[:0], s.Keys...)
      31           2 :         return nil
      32           2 : })
      33             : 
      34             : // VisibleTransform filters keys that are invisible at the provided snapshot
      35             : // sequence number.
      36           2 : func VisibleTransform(snapshot uint64) Transformer {
      37           2 :         return TransformerFunc(func(_ base.Compare, s Span, dst *Span) error {
      38           2 :                 dst.Start, dst.End = s.Start, s.End
      39           2 :                 dst.Keys = dst.Keys[:0]
      40           2 :                 for _, k := range s.Keys {
      41           2 :                         // NB: The InternalKeySeqNumMax value is used for the batch snapshot
      42           2 :                         // because a batch's visible span keys are filtered when they're
      43           2 :                         // fragmented. There's no requirement to enforce visibility at
      44           2 :                         // iteration time.
      45           2 :                         if base.Visible(k.SeqNum(), snapshot, base.InternalKeySeqNumMax) {
      46           2 :                                 dst.Keys = append(dst.Keys, k)
      47           2 :                         }
      48             :                 }
      49           2 :                 return nil
      50             :         })
      51             : }
      52             : 
      53             : // TransformerIter is a FragmentIterator that applies a Transformer on all
      54             : // returned keys. Used for when a caller needs to apply a transformer on an
      55             : // iterator but does not otherwise need the mergingiter's merging ability.
      56             : type TransformerIter struct {
      57             :         FragmentIterator
      58             : 
      59             :         // Transformer is applied on every Span returned by this iterator.
      60             :         Transformer Transformer
      61             :         // Comparer in use for this keyspace.
      62             :         Compare base.Compare
      63             : 
      64             :         span Span
      65             : }
      66             : 
      67           2 : func (t *TransformerIter) applyTransform(span *Span) (*Span, error) {
      68           2 :         if span == nil {
      69           2 :                 return nil, nil
      70           2 :         }
      71           2 :         t.span = Span{
      72           2 :                 Start: t.span.Start[:0],
      73           2 :                 End:   t.span.End[:0],
      74           2 :                 Keys:  t.span.Keys[:0],
      75           2 :         }
      76           2 :         if err := t.Transformer.Transform(t.Compare, *span, &t.span); err != nil {
      77           0 :                 return nil, err
      78           0 :         }
      79           2 :         return &t.span, nil
      80             : }
      81             : 
      82             : // SeekGE implements the FragmentIterator interface.
      83           2 : func (t *TransformerIter) SeekGE(key []byte) (*Span, error) {
      84           2 :         span, err := t.FragmentIterator.SeekGE(key)
      85           2 :         if err != nil {
      86           0 :                 return nil, err
      87           0 :         }
      88           2 :         return t.applyTransform(span)
      89             : }
      90             : 
      91             : // SeekLT implements the FragmentIterator interface.
      92           2 : func (t *TransformerIter) SeekLT(key []byte) (*Span, error) {
      93           2 :         span, err := t.FragmentIterator.SeekLT(key)
      94           2 :         if err != nil {
      95           0 :                 return nil, err
      96           0 :         }
      97           2 :         return t.applyTransform(span)
      98             : }
      99             : 
     100             : // First implements the FragmentIterator interface.
     101           2 : func (t *TransformerIter) First() (*Span, error) {
     102           2 :         span, err := t.FragmentIterator.First()
     103           2 :         if err != nil {
     104           0 :                 return nil, err
     105           0 :         }
     106           2 :         return t.applyTransform(span)
     107             : }
     108             : 
     109             : // Last implements the FragmentIterator interface.
     110           2 : func (t *TransformerIter) Last() (*Span, error) {
     111           2 :         span, err := t.FragmentIterator.Last()
     112           2 :         if err != nil {
     113           0 :                 return nil, err
     114           0 :         }
     115           2 :         return t.applyTransform(span)
     116             : }
     117             : 
     118             : // Next implements the FragmentIterator interface.
     119           2 : func (t *TransformerIter) Next() (*Span, error) {
     120           2 :         span, err := t.FragmentIterator.Next()
     121           2 :         if err != nil {
     122           0 :                 return nil, err
     123           0 :         }
     124           2 :         return t.applyTransform(span)
     125             : }
     126             : 
     127             : // Prev implements the FragmentIterator interface.
     128           2 : func (t *TransformerIter) Prev() (*Span, error) {
     129           2 :         span, err := t.FragmentIterator.Prev()
     130           2 :         if err != nil {
     131           0 :                 return nil, err
     132           0 :         }
     133           2 :         return t.applyTransform(span)
     134             : }
     135             : 
     136             : // Close implements the FragmentIterator interface.
     137           2 : func (t *TransformerIter) Close() error {
     138           2 :         return t.FragmentIterator.Close()
     139           2 : }

Generated by: LCOV version 1.14