LCOV - code coverage report
Current view: top level - pebble/internal/keyspan - transformer.go (source / functions) Hit Total Coverage
Test: 2024-06-16 08:16Z 0e4fb77b - meta test only.lcov Lines: 59 73 80.8 %
Date: 2024-06-16 08:16:53 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           1 : func (tf TransformerFunc) Transform(cmp base.Compare, in Span, out *Span) error {
      24           1 :         return tf(cmp, in, out)
      25           1 : }
      26             : 
      27             : // NoopTransform is a Transformer that performs no mutations.
      28           1 : var NoopTransform Transformer = TransformerFunc(func(_ base.Compare, s Span, dst *Span) error {
      29           1 :         dst.Start, dst.End = s.Start, s.End
      30           1 :         dst.Keys = append(dst.Keys[:0], s.Keys...)
      31           1 :         return nil
      32           1 : })
      33             : 
      34             : // VisibleTransform filters keys that are invisible at the provided snapshot
      35             : // sequence number.
      36           1 : func VisibleTransform(snapshot uint64) Transformer {
      37           1 :         return TransformerFunc(func(_ base.Compare, s Span, dst *Span) error {
      38           1 :                 dst.Start, dst.End = s.Start, s.End
      39           1 :                 dst.Keys = dst.Keys[:0]
      40           1 :                 for _, k := range s.Keys {
      41           1 :                         // NB: The InternalKeySeqNumMax value is used for the batch snapshot
      42           1 :                         // because a batch's visible span keys are filtered when they're
      43           1 :                         // fragmented. There's no requirement to enforce visibility at
      44           1 :                         // iteration time.
      45           1 :                         if base.Visible(k.SeqNum(), snapshot, base.InternalKeySeqNumMax) {
      46           1 :                                 dst.Keys = append(dst.Keys, k)
      47           1 :                         }
      48             :                 }
      49           1 :                 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           1 : func (t *TransformerIter) applyTransform(span *Span) (*Span, error) {
      68           1 :         if span == nil {
      69           1 :                 return nil, nil
      70           1 :         }
      71           1 :         t.span = Span{
      72           1 :                 Start: t.span.Start[:0],
      73           1 :                 End:   t.span.End[:0],
      74           1 :                 Keys:  t.span.Keys[:0],
      75           1 :         }
      76           1 :         if err := t.Transformer.Transform(t.Compare, *span, &t.span); err != nil {
      77           0 :                 return nil, err
      78           0 :         }
      79           1 :         return &t.span, nil
      80             : }
      81             : 
      82             : // SeekGE implements the FragmentIterator interface.
      83           1 : func (t *TransformerIter) SeekGE(key []byte) (*Span, error) {
      84           1 :         span, err := t.FragmentIterator.SeekGE(key)
      85           1 :         if err != nil {
      86           0 :                 return nil, err
      87           0 :         }
      88           1 :         return t.applyTransform(span)
      89             : }
      90             : 
      91             : // SeekLT implements the FragmentIterator interface.
      92           1 : func (t *TransformerIter) SeekLT(key []byte) (*Span, error) {
      93           1 :         span, err := t.FragmentIterator.SeekLT(key)
      94           1 :         if err != nil {
      95           0 :                 return nil, err
      96           0 :         }
      97           1 :         return t.applyTransform(span)
      98             : }
      99             : 
     100             : // First implements the FragmentIterator interface.
     101           1 : func (t *TransformerIter) First() (*Span, error) {
     102           1 :         span, err := t.FragmentIterator.First()
     103           1 :         if err != nil {
     104           0 :                 return nil, err
     105           0 :         }
     106           1 :         return t.applyTransform(span)
     107             : }
     108             : 
     109             : // Last implements the FragmentIterator interface.
     110           1 : func (t *TransformerIter) Last() (*Span, error) {
     111           1 :         span, err := t.FragmentIterator.Last()
     112           1 :         if err != nil {
     113           0 :                 return nil, err
     114           0 :         }
     115           1 :         return t.applyTransform(span)
     116             : }
     117             : 
     118             : // Next implements the FragmentIterator interface.
     119           1 : func (t *TransformerIter) Next() (*Span, error) {
     120           1 :         span, err := t.FragmentIterator.Next()
     121           1 :         if err != nil {
     122           0 :                 return nil, err
     123           0 :         }
     124           1 :         return t.applyTransform(span)
     125             : }
     126             : 
     127             : // Prev implements the FragmentIterator interface.
     128           1 : func (t *TransformerIter) Prev() (*Span, error) {
     129           1 :         span, err := t.FragmentIterator.Prev()
     130           1 :         if err != nil {
     131           0 :                 return nil, err
     132           0 :         }
     133           1 :         return t.applyTransform(span)
     134             : }
     135             : 
     136             : // Close implements the FragmentIterator interface.
     137           1 : func (t *TransformerIter) Close() error {
     138           1 :         return t.FragmentIterator.Close()
     139           1 : }

Generated by: LCOV version 1.14