github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/internal/keyspan/testdata/defragmenting_iter (about)

     1  # Test a scenario that should NOT result in defragmentation.
     2  
     3  define
     4  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
     5  c-d:{(#4,RANGEKEYSET,@3,bananas)}
     6  d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
     7  ----
     8  
     9  iter
    10  first
    11  next
    12  next
    13  last
    14  prev
    15  prev
    16  ----
    17  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    18  c-d:{(#4,RANGEKEYSET,@3,bananas)}
    19  d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
    20  d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
    21  c-d:{(#4,RANGEKEYSET,@3,bananas)}
    22  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    23  
    24  iter
    25  first
    26  next
    27  next
    28  next
    29  last
    30  prev
    31  prev
    32  prev
    33  ----
    34  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    35  c-d:{(#4,RANGEKEYSET,@3,bananas)}
    36  d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
    37  <nil>
    38  d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
    39  c-d:{(#4,RANGEKEYSET,@3,bananas)}
    40  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    41  <nil>
    42  
    43  # Test a scenario that SHOULD result in internal defragmentation ([a,c) and
    44  # [c,d) should be merged.
    45  
    46  define
    47  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    48  c-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    49  d-e:{(#1,RANGEKEYSET,@3,bananas)}
    50  ----
    51  
    52  iter
    53  first
    54  next
    55  next
    56  ----
    57  a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    58  d-e:{(#1,RANGEKEYSET,@3,bananas)}
    59  <nil>
    60  
    61  # Test defragmenting in both directions at seek keys.
    62  
    63  define
    64  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    65  f-h:{(#3,RANGEKEYSET,@3,bananas)}
    66  h-p:{(#3,RANGEKEYSET,@3,bananas)}
    67  p-t:{(#3,RANGEKEYSET,@3,bananas)}
    68  ----
    69  
    70  iter
    71  seekge b
    72  prev
    73  seekge b
    74  next
    75  seeklt d
    76  next
    77  seeklt d
    78  prev
    79  ----
    80  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    81  <nil>
    82  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    83  f-t:{(#3,RANGEKEYSET,@3,bananas)}
    84  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    85  f-t:{(#3,RANGEKEYSET,@3,bananas)}
    86  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    87  <nil>
    88  
    89  iter
    90  seeklt d
    91  next
    92  prev
    93  ----
    94  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    95  f-t:{(#3,RANGEKEYSET,@3,bananas)}
    96  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
    97  
    98  # Test next-ing and prev-ing around seek keys.
    99  
   100  define
   101  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   102  f-h:{(#3,RANGEKEYSET,@3,bananas)}
   103  h-p:{(#3,RANGEKEYSET,@3,bananas)}
   104  p-t:{(#3,RANGEKEYSET,@3,bananas)}
   105  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   106  ----
   107  
   108  iter
   109  seekge r
   110  prev
   111  next
   112  next
   113  ----
   114  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   115  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   116  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   117  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   118  
   119  iter
   120  seekge f
   121  seekge h
   122  seekge p
   123  seekge t
   124  seekge u
   125  seekge v
   126  seekge z
   127  ----
   128  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   129  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   130  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   131  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   132  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   133  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   134  <nil>
   135  
   136  iter
   137  seeklt f
   138  seeklt h
   139  seeklt p
   140  seeklt t
   141  seeklt u
   142  seeklt z
   143  ----
   144  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   145  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   146  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   147  f-t:{(#3,RANGEKEYSET,@3,bananas)}
   148  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   149  t-z:{(#4,RANGEKEYSET,@2,oranges)}
   150  
   151  # Test iteration with a reducer that collects keys across all spans that
   152  # constitute a defragmented span. Abutting spans are always combined.
   153  
   154  define
   155  a-b:{(#3,RANGEDEL) (#2,RANGEDEL)}
   156  b-c:{(#4,RANGEDEL) (#1,RANGEDEL)}
   157  c-d:{(#5,RANGEDEL)}
   158  e-f:{(#1,RANGEDEL)}
   159  f-g:{(#2,RANGEDEL)}
   160  ----
   161  
   162  iter equal=always reducer=collect
   163  first
   164  next
   165  next
   166  last
   167  prev
   168  prev
   169  ----
   170  a-d:{(#5,RANGEDEL) (#4,RANGEDEL) (#3,RANGEDEL) (#2,RANGEDEL) (#1,RANGEDEL)}
   171  e-g:{(#2,RANGEDEL) (#1,RANGEDEL)}
   172  <nil>
   173  e-g:{(#2,RANGEDEL) (#1,RANGEDEL)}
   174  a-d:{(#5,RANGEDEL) (#4,RANGEDEL) (#3,RANGEDEL) (#2,RANGEDEL) (#1,RANGEDEL)}
   175  <nil>
   176  
   177  # Test defragmentation of non-empty (i.e. more than one value) fragments, while
   178  # empty fragments are left untouched.
   179  
   180  define
   181  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   182  c-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   183  d-e:{}
   184  e-f:{}
   185  g-h:{(#1,RANGEKEYSET,@3,bananas)}
   186  ----
   187  
   188  iter
   189  first
   190  next
   191  next
   192  next
   193  next
   194  ----
   195  a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   196  d-e:{}
   197  e-f:{}
   198  g-h:{(#1,RANGEKEYSET,@3,bananas)}
   199  <nil>
   200  
   201  iter
   202  last
   203  prev
   204  prev
   205  prev
   206  prev
   207  ----
   208  g-h:{(#1,RANGEKEYSET,@3,bananas)}
   209  e-f:{}
   210  d-e:{}
   211  a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   212  <nil>
   213  
   214  iter
   215  seekge d
   216  next
   217  prev
   218  seekge e
   219  next
   220  prev
   221  prev
   222  prev
   223  ----
   224  d-e:{}
   225  e-f:{}
   226  d-e:{}
   227  e-f:{}
   228  g-h:{(#1,RANGEKEYSET,@3,bananas)}
   229  e-f:{}
   230  d-e:{}
   231  a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   232  
   233  iter
   234  seeklt e
   235  next
   236  prev
   237  seeklt f
   238  next
   239  prev
   240  prev
   241  prev
   242  ----
   243  d-e:{}
   244  e-f:{}
   245  d-e:{}
   246  e-f:{}
   247  g-h:{(#1,RANGEKEYSET,@3,bananas)}
   248  e-f:{}
   249  d-e:{}
   250  a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   251  
   252  # Test that the defragmenting iterator does yield errors in cases that do not
   253  # need to defragment.
   254  
   255  define
   256  a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   257  c-d:{(#4,RANGEKEYSET,@3,bananas)}
   258  d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   259  ----
   260  
   261  iter probes=(ErrInjected)
   262  seek-ge b
   263  seek-lt d
   264  first
   265  last
   266  ----
   267  <nil> err=<injected error>
   268  <nil> err=<injected error>
   269  <nil> err=<injected error>
   270  <nil> err=<injected error>
   271  
   272  # Next and Prev may only be called on positioned iterators, so to test
   273  # propagation of errors on Next or Prev, we must use a probe that injects errors
   274  # on Next or Prev but leaves seeks untouched.
   275  #
   276  # The situation is complicated by the fact that a seek on the defragmenting
   277  # iterator will result in Next/Prevs on the embedded iterator (in order to peek
   278  # ahead to see if anything needs to be defragmented).
   279  #
   280  # First we test the seeks too result in injected errors when they Next/Prev
   281  # ahead to determine if there's anything to defragment.
   282  
   283  iter probes=((If (Or OpNext OpPrev) ErrInjected noop), (Log "#  inner."))
   284  seek-ge b
   285  next
   286  seek-lt cat
   287  prev
   288  ----
   289  #  inner.SeekGE("b") = a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   290  #  inner.Prev() = nil <err="injected error">
   291  <nil> err=<injected error>
   292  #  inner.Next() = nil <err="injected error">
   293  <nil> err=<injected error>
   294  #  inner.SeekLT("cat") = c-d:{(#4,RANGEKEYSET,@3,bananas)}
   295  #  inner.Next() = nil <err="injected error">
   296  <nil> err=<injected error>
   297  #  inner.Prev() = nil <err="injected error">
   298  <nil> err=<injected error>
   299  
   300  # Use a probe that injects errors whenever we otherwise would've returned the
   301  # c-d span. First and Last calls should both return errors because during
   302  # defragmenting they'll step the internal iterator on to the error position.
   303  
   304  iter probes=((If (Equal StartKey (Bytes "c")) ErrInjected noop), (Log "#  inner."))
   305  first
   306  last
   307  ----
   308  #  inner.First() = a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
   309  #  inner.Next() = nil <err="injected error">
   310  <nil> err=<injected error>
   311  #  inner.Last() = d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   312  #  inner.Prev() = nil <err="injected error">
   313  <nil> err=<injected error>
   314  
   315  # In order to test that errors are injected when Next-ing the top-level
   316  # iterator, define test data that includes 5 spans.
   317  
   318  define
   319  a-b:{(#3,RANGEKEYUNSET,@5)}
   320  b-c:{(#4,RANGEKEYSET,@5,apples)}
   321  c-d:{(#5,RANGEKEYSET,@3,bananas)}
   322  d-e:{(#6,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   323  e-f:{(#4,RANGEKEYSET,@1,pineapple)}
   324  ----
   325  
   326  # Use a probe that injects errors whenever we would've otherwise returned the
   327  # c-d span. Our initial First/Last seeks should not step on to the error
   328  # position and should not error. The subsequent Next/Prev however should.
   329  
   330  iter probes=((If (Equal StartKey (Bytes "c")) ErrInjected noop), (Log "#  inner."))
   331  first
   332  next
   333  last
   334  prev
   335  ----
   336  #  inner.First() = a-b:{(#3,RANGEKEYUNSET,@5)}
   337  #  inner.Next() = b-c:{(#4,RANGEKEYSET,@5,apples)}
   338  a-b:{(#3,RANGEKEYUNSET,@5)}
   339  #  inner.Next() = nil <err="injected error">
   340  <nil> err=<injected error>
   341  #  inner.Last() = e-f:{(#4,RANGEKEYSET,@1,pineapple)}
   342  #  inner.Prev() = d-e:{(#6,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   343  e-f:{(#4,RANGEKEYSET,@1,pineapple)}
   344  #  inner.Prev() = nil <err="injected error">
   345  <nil> err=<injected error>
   346  
   347  # When seeking, the defragmenting iterator needs to defragment in both
   348  # directions. A forward seek first defragments in the reverse direction, and
   349  # then in the forward direction. A backward seek does the inverse. If an error
   350  # is encountered while performing the first defragment scan, it must be
   351  # surfaced.
   352  #
   353  # To test this scenario we again inject errors instead of the c-d span.
   354  #   - The SeekGE('d') should land on d-e, try to defragment backward first and
   355  #     encounter the error.
   356  #   - The SeekLT('c') should land on b-c, try to defragment forward first and
   357  #     encounter the error.
   358  iter probes=((If (Equal StartKey (Bytes "c")) ErrInjected noop), (Log "#  inner."))
   359  seek-ge d
   360  seek-lt c
   361  ----
   362  #  inner.SeekGE("d") = d-e:{(#6,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   363  #  inner.Prev() = nil <err="injected error">
   364  <nil> err=<injected error>
   365  #  inner.SeekLT("c") = b-c:{(#4,RANGEKEYSET,@5,apples)}
   366  #  inner.Next() = nil <err="injected error">
   367  <nil> err=<injected error>
   368  
   369  # When changing directions in some circumstances we step an iterator and then
   370  # defragment twice; once to skip over the current span and once to construct the
   371  # next defragmented span in the new iteration direction. If the first step of
   372  # the iterator surfaces an error, ensure that it's still propagated.
   373  iter probes=((If (And OpPrev (Equal StartKey (Bytes "c"))) ErrInjected noop), (Log "#  inner."))
   374  seek-ge c
   375  prev
   376  ----
   377  #  inner.SeekGE("c") = c-d:{(#5,RANGEKEYSET,@3,bananas)}
   378  #  inner.Prev() = b-c:{(#4,RANGEKEYSET,@5,apples)}
   379  #  inner.Next() = c-d:{(#5,RANGEKEYSET,@3,bananas)}
   380  #  inner.Next() = d-e:{(#6,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   381  c-d:{(#5,RANGEKEYSET,@3,bananas)}
   382  #  inner.Prev() = nil <err="injected error">
   383  <nil> err=<injected error>
   384  
   385  iter probes=((If (And OpNext (Equal StartKey (Bytes "c"))) ErrInjected noop), (Log "#  inner."))
   386  seek-lt d
   387  next
   388  ----
   389  #  inner.SeekLT("d") = c-d:{(#5,RANGEKEYSET,@3,bananas)}
   390  #  inner.Next() = d-e:{(#6,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
   391  #  inner.Prev() = c-d:{(#5,RANGEKEYSET,@3,bananas)}
   392  #  inner.Prev() = b-c:{(#4,RANGEKEYSET,@5,apples)}
   393  c-d:{(#5,RANGEKEYSET,@3,bananas)}
   394  #  inner.Next() = nil <err="injected error">
   395  <nil> err=<injected error>