LCOV - code coverage report
Current view: top level - pebble/internal/keyspan - get.go (source / functions) Hit Total Coverage
Test: 2023-12-14 08:16Z 288bf0fb - tests + meta.lcov Lines: 35 35 100.0 %
Date: 2023-12-14 08:17:14 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2018 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             : // Get returns the newest span that contains the target key. If no span
      10             : // contains the target key, an empty span is returned. The snapshot
      11             : // parameter controls the visibility of spans (only spans older than the
      12             : // snapshot sequence number are visible). The iterator must contain
      13             : // fragmented spans: no span may overlap another.
      14           2 : func Get(cmp base.Compare, iter FragmentIterator, key []byte) *Span {
      15           2 :         // NB: We use SeekLT in order to land on the proper span for a search
      16           2 :         // key that resides in the middle of a span. Consider the scenario:
      17           2 :         //
      18           2 :         //     a---e
      19           2 :         //         e---i
      20           2 :         //
      21           2 :         // The spans are indexed by their start keys `a` and `e`. If the
      22           2 :         // search key is `c` we want to land on the span [a,e). If we were
      23           2 :         // to use SeekGE then the search key `c` would land on the span
      24           2 :         // [e,i) and we'd have to backtrack. The one complexity here is what
      25           2 :         // happens for the search key `e`. In that case SeekLT will land us
      26           2 :         // on the span [a,e) and we'll have to move forward.
      27           2 :         iterSpan := iter.SeekLT(key)
      28           2 :         if iterSpan == nil {
      29           2 :                 iterSpan = iter.Next()
      30           2 :                 if iterSpan == nil {
      31           2 :                         // The iterator is empty.
      32           2 :                         return nil
      33           2 :                 }
      34           2 :                 if cmp(key, iterSpan.Start) < 0 {
      35           2 :                         // The search key lies before the first span.
      36           2 :                         return nil
      37           2 :                 }
      38             :         }
      39             : 
      40             :         // Invariant: key > iterSpan.Start
      41           2 :         if cmp(key, iterSpan.End) >= 0 {
      42           2 :                 // The current span lies before the search key. Advance the iterator
      43           2 :                 // once to potentially land on a key with a start key exactly equal to
      44           2 :                 // key. (See the comment at the beginning of this function.)
      45           2 :                 iterSpan = iter.Next()
      46           2 :                 if iterSpan == nil || cmp(key, iterSpan.Start) < 0 {
      47           2 :                         // We've run out of spans or we've moved on to a span which
      48           2 :                         // starts after our search key.
      49           2 :                         return nil
      50           2 :                 }
      51             :         }
      52           2 :         return iterSpan
      53             : }

Generated by: LCOV version 1.14