github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/sstable/testdata/block_properties (about)

     1  # The following collectors are available:
     2  # - value-first - uses the first character of the value to construct an interval
     3  # - value-last - uses the last character of the value to construct an interval
     4  # - suffix - constructs an interval from the '@timestamp' suffix of each key
     5  # - suffix-point-keys-only - same as "suffix", but only applies to point keys
     6  # - suffix-range-keys-only - same as "suffix", but only applies to range keys
     7  # - nil-points-and-ranges - a trivial collector with neither a point nor range collector
     8  
     9  # Single collector.
    10  
    11  build collectors=(value-first)
    12  a.SET.1:10
    13  b.SET.2:20
    14  c.SET.3:30
    15  ----
    16  point:    [a#1,1,c#3,1]
    17  rangedel: [#0,0,#0,0]
    18  rangekey: [#0,0,#0,0]
    19  seqnums:  [1,3]
    20  
    21  # collectors returns the collectors used when writing the table, keyed by the
    22  # shortID of the collector.
    23  collectors
    24  ----
    25  0: value-first
    26  
    27  # table-props returns the table-level properties, keyed by the shortID.
    28  table-props
    29  ----
    30  0: [1, 4)
    31  
    32  # block-props returns the block-level properties. For each block, the separator
    33  # is printed, along with the properties for the block, keyed by the shortID.
    34  block-props
    35  ----
    36  d#72057594037927935,17:
    37    0: [1, 4)
    38  
    39  # Multiple collectors.
    40  
    41  build collectors=(value-first,value-last)
    42  a.SET.1:17
    43  b.SET.2:29
    44  c.SET.3:38
    45  ----
    46  point:    [a#1,1,c#3,1]
    47  rangedel: [#0,0,#0,0]
    48  rangekey: [#0,0,#0,0]
    49  seqnums:  [1,3]
    50  
    51  collectors
    52  ----
    53  0: value-first
    54  1: value-last
    55  
    56  table-props
    57  ----
    58  0: [1, 4)
    59  1: [7, 10)
    60  
    61  block-props
    62  ----
    63  d#72057594037927935,17:
    64    0: [1, 4)
    65    1: [7, 10)
    66  
    67  # Reduce the block size to a value such that each block has at most two KV
    68  # pairs.
    69  
    70  build block-size=25 collectors=(value-first,value-last)
    71  a.SET.1:15
    72  b.SET.2:86
    73  c.SET.3:72
    74  d.SET.4:21
    75  e.SET.5:47
    76  f.SET.6:54
    77  g.SET.7:63
    78  h.SET.8:38
    79  ----
    80  point:    [a#1,1,h#8,1]
    81  rangedel: [#0,0,#0,0]
    82  rangekey: [#0,0,#0,0]
    83  seqnums:  [1,8]
    84  
    85  collectors
    86  ----
    87  0: value-first
    88  1: value-last
    89  
    90  table-props
    91  ----
    92  0: [1, 9)
    93  1: [1, 9)
    94  
    95  block-props
    96  ----
    97  b#2,1:
    98    0: [1, 9)
    99    1: [5, 7)
   100  d#4,1:
   101    0: [2, 8)
   102    1: [1, 3)
   103  f#6,1:
   104    0: [4, 6)
   105    1: [4, 8)
   106  i#72057594037927935,17:
   107    0: [3, 7)
   108    1: [3, 9)
   109  
   110  # Range keys contribute to the table-level property but do not affect point key
   111  # data blocks.
   112  
   113  build collectors=(suffix)
   114  a@5.SET.1:foo
   115  b@10.SET.2:bar
   116  c@15.SET.3:baz
   117  rangekey: d@10-e@15:{(#4,RANGEKEYSET,@20,foo)}
   118  rangekey: e@15-f@20:{(#5,RANGEKEYUNSET,@25)}
   119  rangekey: f@20-z@25:{(#6,RANGEKEYDEL)}
   120  ----
   121  point:    [a@5#1,1,c@15#3,1]
   122  rangedel: [#0,0,#0,0]
   123  rangekey: [d@10#4,21,z@25#72057594037927935,19]
   124  seqnums:  [1,6]
   125  
   126  collectors
   127  ----
   128  0: suffix
   129  
   130  block-props
   131  ----
   132  d#72057594037927935,17:
   133    0: [5, 16)
   134  
   135  table-props
   136  ----
   137  0: [5, 26)
   138  
   139  # Same as the above, but only collect point key properties.
   140  
   141  build collectors=(suffix-point-keys-only)
   142  a@5.SET.1:foo
   143  b@10.SET.2:bar
   144  c@15.SET.3:baz
   145  rangekey: d@10-e@15:{(#4,RANGEKEYSET,@20,foo)}
   146  rangekey: e@15-f@20:{(#5,RANGEKEYUNSET,@25)}
   147  rangekey: f@20-z@25:{(#6,RANGEKEYDEL)}
   148  ----
   149  point:    [a@5#1,1,c@15#3,1]
   150  rangedel: [#0,0,#0,0]
   151  rangekey: [d@10#4,21,z@25#72057594037927935,19]
   152  seqnums:  [1,6]
   153  
   154  collectors
   155  ----
   156  0: suffix-point-keys-only
   157  
   158  block-props
   159  ----
   160  d#72057594037927935,17:
   161    0: [5, 16)
   162  
   163  table-props
   164  ----
   165  0: [5, 16)
   166  
   167  # Same as the above, but only collect range key properties.
   168  
   169  build collectors=(suffix-range-keys-only)
   170  a@5.SET.1:foo
   171  b@10.SET.2:bar
   172  c@15.SET.3:baz
   173  rangekey: d@10-e@15:{(#4,RANGEKEYSET,@20,foo)}
   174  rangekey: e@15-f@20:{(#5,RANGEKEYUNSET,@25)}
   175  rangekey: f@20-z@25:{(#6,RANGEKEYDEL)}
   176  ----
   177  point:    [a@5#1,1,c@15#3,1]
   178  rangedel: [#0,0,#0,0]
   179  rangekey: [d@10#4,21,z@25#72057594037927935,19]
   180  seqnums:  [1,6]
   181  
   182  collectors
   183  ----
   184  0: suffix-range-keys-only
   185  
   186  block-props
   187  ----
   188  d#72057594037927935,17:
   189  
   190  table-props
   191  ----
   192  0: [20, 26)
   193  
   194  # Create a table with multiple data blocks and a range key block. Two block
   195  # property collectors are used, one for range keys and one for point keys, each
   196  # acting independently.
   197  
   198  build block-size=1 collectors=(suffix-point-keys-only,suffix-range-keys-only)
   199  a@5.SET.1:foo
   200  b@10.SET.2:bar
   201  c@15.SET.3:baz
   202  rangekey: d@10-e@15:{(#4,RANGEKEYSET,@20,foo)}
   203  rangekey: e@15-f@20:{(#5,RANGEKEYUNSET,@25)}
   204  rangekey: f@20-z@25:{(#6,RANGEKEYDEL)}
   205  ----
   206  point:    [a@5#1,1,c@15#3,1]
   207  rangedel: [#0,0,#0,0]
   208  rangekey: [d@10#4,21,z@25#72057594037927935,19]
   209  seqnums:  [1,6]
   210  
   211  collectors
   212  ----
   213  0: suffix-point-keys-only
   214  1: suffix-range-keys-only
   215  
   216  block-props
   217  ----
   218  b#72057594037927935,17:
   219    0: [5, 6)
   220  c#72057594037927935,17:
   221    0: [10, 11)
   222  d#72057594037927935,17:
   223    0: [15, 16)
   224  
   225  table-props
   226  ----
   227  0: [5, 16)
   228  1: [20, 26)
   229  
   230  # Partially matching point key filter.
   231  
   232  filter point-filter=(suffix-point-keys-only,10,20)
   233  ----
   234  points: true, blocks=[1,2]
   235  ranges: true (no filters provided)
   236  
   237  # Non-matching point key filter.
   238  
   239  filter point-filter=(suffix-point-keys-only,100,200)
   240  ----
   241  points: false
   242  ranges: true (no filters provided)
   243  
   244  # Partially matching range key filter.
   245  
   246  filter range-filter=(suffix-range-keys-only,10,25)
   247  ----
   248  points: true (no filters provided)
   249  ranges: true
   250  
   251  # Non-matching range key filter.
   252  
   253  filter range-filter=(suffix-range-keys-only,100,200)
   254  ----
   255  points: true (no filters provided)
   256  ranges: false
   257  
   258  # Matching point and range key filter.
   259  
   260  filter point-filter=(suffix-point-keys-only,10,20) range-filter=(suffix-range-keys-only,10,25)
   261  ----
   262  points: true, blocks=[1,2]
   263  ranges: true
   264  
   265  # Matching point key filter and non-matching range key filter.
   266  
   267  filter point-filter=(suffix-point-keys-only,10,20) range-filter=(suffix-range-keys-only,100,200)
   268  ----
   269  points: true, blocks=[1,2]
   270  ranges: false
   271  
   272  # Non-matching point key filter and matching range key filter.
   273  
   274  filter point-filter=(suffix-point-keys-only,100,200) range-filter=(suffix-range-keys-only,10,25)
   275  ----
   276  points: false
   277  ranges: true
   278  
   279  # Non-matching point and range key filter.
   280  
   281  filter point-filter=(suffix-point-keys-only,100,200) range-filter=(suffix-range-keys-only,100,100)
   282  ----
   283  points: false
   284  ranges: false
   285  
   286  # Providing a nil collector for both points and ranges is a user-error.
   287  
   288  build collectors=(nil-points-and-ranges)
   289  ----
   290  sstable: at least one interval collector must be provided
   291  
   292  # Test a small index-block-size and block-size, so every data block has one KV
   293  # and every index block points to one data block.
   294  
   295  build collectors=(suffix-point-keys-only) index-block-size=1 block-size=1
   296  a@1.SET.1:foo
   297  b@10.SET.2:bar
   298  c@15.SET.3:baz
   299  d@25.SET.4:bax
   300  e@3.SET.5:box
   301  f@5.SET.3:mop
   302  ----
   303  point:    [a@1#1,1,f@5#3,1]
   304  rangedel: [#0,0,#0,0]
   305  rangekey: [#0,0,#0,0]
   306  seqnums:  [1,5]
   307  
   308  collectors
   309  ----
   310  0: suffix-point-keys-only
   311  
   312  table-props
   313  ----
   314  0: [1, 26)
   315  
   316  # Because of the tiny index block size, every index block should have the same
   317  # properties as the single data block contained in the table. Indentation shows
   318  # the hierarchy.
   319  
   320  block-props
   321  ----
   322  b#72057594037927935,17:
   323    0: [1, 2)
   324    b#72057594037927935,17:
   325      0: [1, 2)
   326  c#72057594037927935,17:
   327    0: [10, 11)
   328    c#72057594037927935,17:
   329      0: [10, 11)
   330  d#72057594037927935,17:
   331    0: [15, 16)
   332    d#72057594037927935,17:
   333      0: [15, 16)
   334  e#72057594037927935,17:
   335    0: [25, 26)
   336    e#72057594037927935,17:
   337      0: [25, 26)
   338  f#72057594037927935,17:
   339    0: [3, 4)
   340    f#72057594037927935,17:
   341      0: [3, 4)
   342  g#72057594037927935,17:
   343    0: [5, 6)
   344    g#72057594037927935,17:
   345      0: [5, 6)
   346  
   347  # Test the same sstable, but with a larger index block size that fits multiple
   348  # (3) KV pairs. Each entry in the top-level index should hold the unioned ranges
   349  # of all the data blocks' properties.
   350  
   351  build collectors=(suffix-point-keys-only) index-block-size=64 block-size=1
   352  a@1.SET.1:foo
   353  b@10.SET.2:bar
   354  c@15.SET.3:baz
   355  d@25.SET.4:bax
   356  e@3.SET.5:box
   357  f@5.SET.3:mop
   358  ----
   359  point:    [a@1#1,1,f@5#3,1]
   360  rangedel: [#0,0,#0,0]
   361  rangekey: [#0,0,#0,0]
   362  seqnums:  [1,5]
   363  
   364  collectors
   365  ----
   366  0: suffix-point-keys-only
   367  
   368  block-props
   369  ----
   370  d#72057594037927935,17:
   371    0: [1, 16)
   372    b#72057594037927935,17:
   373      0: [1, 2)
   374    c#72057594037927935,17:
   375      0: [10, 11)
   376    d#72057594037927935,17:
   377      0: [15, 16)
   378  g#72057594037927935,17:
   379    0: [3, 26)
   380    e#72057594037927935,17:
   381      0: [25, 26)
   382    f#72057594037927935,17:
   383      0: [3, 4)
   384    g#72057594037927935,17:
   385      0: [5, 6)
   386  
   387  # Regression test for a bug in boundary checking when skipping over irrelevant
   388  # index blocks in a two-level indexed sstable.
   389  
   390  iter lower=a point-key-filter=(suffix-point-keys-only,1,2)
   391  seek-lt h
   392  last
   393  ----
   394  <a@1:1> MaybeFilteredKeys()=true
   395  <a@1:1> MaybeFilteredKeys()=true
   396  
   397  # Same as above, but each index block holds 2 keys. This exercises a variant of
   398  # the above bug. Specifically, the bounds check performed /within/ skipBackward,
   399  # instead of within SeekLT and Last.
   400  
   401  build collectors=(suffix-point-keys-only) index-block-size=48 block-size=1
   402  a@1.SET.1:foo
   403  b@10.SET.2:bar
   404  c@15.SET.3:baz
   405  d@25.SET.4:bax
   406  e@3.SET.5:box
   407  f@5.SET.3:mop
   408  ----
   409  point:    [a@1#1,1,f@5#3,1]
   410  rangedel: [#0,0,#0,0]
   411  rangekey: [#0,0,#0,0]
   412  seqnums:  [1,5]
   413  
   414  block-props
   415  ----
   416  c#72057594037927935,17:
   417    0: [1, 11)
   418    b#72057594037927935,17:
   419      0: [1, 2)
   420    c#72057594037927935,17:
   421      0: [10, 11)
   422  e#72057594037927935,17:
   423    0: [15, 26)
   424    d#72057594037927935,17:
   425      0: [15, 16)
   426    e#72057594037927935,17:
   427      0: [25, 26)
   428  g#72057594037927935,17:
   429    0: [3, 6)
   430    f#72057594037927935,17:
   431      0: [3, 4)
   432    g#72057594037927935,17:
   433      0: [5, 6)
   434  
   435  # Regression test for a bug in boundary checking when skipping over irrelevant
   436  # index blocks in a two-level indexed sstable.
   437  
   438  iter lower=a upper=z point-key-filter=(suffix-point-keys-only,1,2)
   439  seek-lt h
   440  ----
   441  <a@1:1> MaybeFilteredKeys()=true
   442  
   443  # Test MaybeFilteredKeys().
   444  
   445  # Use timestamp range [1,9), which matches a@1, e@3 and f@5 and filters
   446  # a continuous section of three keys b@10, c@15 and d@25.
   447  
   448  iter point-key-filter=(suffix-point-keys-only,1,9)
   449  first
   450  next
   451  next
   452  next
   453  seek-ge b
   454  seek-ge e@3
   455  ----
   456  <a@1:1> MaybeFilteredKeys()=false
   457  <e@3:5> MaybeFilteredKeys()=true
   458  <f@5:3> MaybeFilteredKeys()=false
   459  . MaybeFilteredKeys()=false
   460  <e@3:5> MaybeFilteredKeys()=true
   461  <e@3:5> MaybeFilteredKeys()=false
   462  
   463  
   464  # NB: `seek-ge e` and `seek-ge dog` return MaybeFilteredKeys()=true, despite no
   465  # filtered keys existing within the range [e,e@3) or [dog,e@3). This is a
   466  # consequence of the index separator `e`. After seeking the index block, the
   467  # iterator only knows that the first block MAY contain keys ≤ e. However, it can
   468  # be skipped regardless, because block properties filters exclude it. In this
   469  # case, the iterator still returns MaybeFilteredKeys()=true, since keys MAY have
   470  # been excluded by the filter.
   471  
   472  iter point-key-filter=(suffix-point-keys-only,1,9)
   473  seek-ge e
   474  seek-ge dog
   475  ----
   476  <e@3:5> MaybeFilteredKeys()=true
   477  <e@3:5> MaybeFilteredKeys()=true
   478  
   479  iter point-key-filter=(suffix-point-keys-only,1,100)
   480  first
   481  next
   482  next
   483  next
   484  next
   485  next
   486  next
   487  seek-lt d
   488  seek-ge d
   489  ----
   490  <a@1:1> MaybeFilteredKeys()=false
   491  <b@10:2> MaybeFilteredKeys()=false
   492  <c@15:3> MaybeFilteredKeys()=false
   493  <d@25:4> MaybeFilteredKeys()=false
   494  <e@3:5> MaybeFilteredKeys()=false
   495  <f@5:3> MaybeFilteredKeys()=false
   496  . MaybeFilteredKeys()=false
   497  <c@15:3> MaybeFilteredKeys()=false
   498  <d@25:4> MaybeFilteredKeys()=false
   499  
   500  # [10,16) intersects {b@10, c@15}.
   501  
   502  iter point-key-filter=(suffix-point-keys-only,10,16)
   503  last
   504  prev
   505  prev
   506  seek-lt a
   507  seek-lt c
   508  seek-lt ca
   509  seek-lt f
   510  seek-lt e
   511  seek-lt d
   512  ----
   513  <c@15:3> MaybeFilteredKeys()=true
   514  <b@10:2> MaybeFilteredKeys()=false
   515  . MaybeFilteredKeys()=true
   516  . MaybeFilteredKeys()=true
   517  <b@10:2> MaybeFilteredKeys()=false
   518  <c@15:3> MaybeFilteredKeys()=false
   519  <c@15:3> MaybeFilteredKeys()=true
   520  <c@15:3> MaybeFilteredKeys()=true
   521  <c@15:3> MaybeFilteredKeys()=false
   522  
   523  # Test monotonically increasing bounds optimization, with the first seek
   524  # filtering keys. The subsequent seek must not reuse the current iterator
   525  # position and improperly returning MaybeFilteredKeys=false when keys were
   526  # filtered.
   527  
   528  iter point-key-filter=(suffix-point-keys-only,10,16)
   529  set-bounds lower=b upper=ee
   530  seek-ge d
   531  set-bounds lower=ee upper=g
   532  seek-ge ee
   533  ----
   534  . MaybeFilteredKeys()=false
   535  . MaybeFilteredKeys()=true
   536  . MaybeFilteredKeys()=true
   537  . MaybeFilteredKeys()=true
   538  
   539  iter point-key-filter=(suffix-point-keys-only,10,16)
   540  set-bounds lower=a upper=b
   541  seek-ge a
   542  set-bounds lower=b upper=e
   543  seek-ge b
   544  seek-ge bb
   545  ----
   546  . MaybeFilteredKeys()=false
   547  . MaybeFilteredKeys()=true
   548  . MaybeFilteredKeys()=true
   549  <b@10:2> MaybeFilteredKeys()=true
   550  <c@15:3> MaybeFilteredKeys()=false
   551  
   552  # Test monotonically decreasing bounds optimization, with the first seek
   553  # filtering keys. The subsequent seek must not reuse the current iterator
   554  # position and improperly returning MaybeFilteredKeys=false when keys were
   555  # filtered.
   556  
   557  iter point-key-filter=(suffix-point-keys-only,10,16)
   558  set-bounds lower=e upper=f
   559  seek-lt f
   560  set-bounds lower=c upper=e
   561  seek-lt e
   562  set-bounds lower=a upper=c
   563  seek-lt c
   564  seek-lt b
   565  ----
   566  . MaybeFilteredKeys()=false
   567  . MaybeFilteredKeys()=true
   568  . MaybeFilteredKeys()=true
   569  <c@15:3> MaybeFilteredKeys()=true
   570  . MaybeFilteredKeys()=true
   571  <b@10:2> MaybeFilteredKeys()=false
   572  . MaybeFilteredKeys()=true
   573  
   574  # The below case tests try-seek-using-next.
   575  #
   576  # The `seek-ge aa` does not reposition the iterator. This case should preserve
   577  # the existing MaybeFilteredKeys()=true value.
   578  #
   579  # The `seek-ge c@16` and seek-ge c@19` must also return MaybeFilteredKeys()=true.
   580  
   581  iter point-key-filter=(suffix-point-keys-only,10,16)
   582  seek-ge a
   583  seek-ge aa true
   584  seek-ge bb true
   585  seek-ge c@16 true
   586  seek-ge c@19 true
   587  ----
   588  <b@10:2> MaybeFilteredKeys()=true
   589  <b@10:2> MaybeFilteredKeys()=true
   590  <c@15:3> MaybeFilteredKeys()=false
   591  . MaybeFilteredKeys()=true
   592  . MaybeFilteredKeys()=true
   593  
   594  # Test another case of monotonically increasing bounds optimization, with a
   595  # different index block structure. The first seek down below should filter keys,
   596  # and leave the top-level index positioned at the last index block. The
   597  # subsequent seek must return MaybeFilteredKeys=true when keys were filtered.
   598  
   599  build collectors=(suffix-point-keys-only) index-block-size=1 block-size=64
   600  a@1.SET.1:foo
   601  b@10.SET.2:bar
   602  c@15.SET.3:baz
   603  d@25.SET.4:bax
   604  e@3.SET.5:box
   605  f@5.SET.3:mop
   606  ----
   607  point:    [a@1#1,1,f@5#3,1]
   608  rangedel: [#0,0,#0,0]
   609  rangekey: [#0,0,#0,0]
   610  seqnums:  [1,5]
   611  
   612  block-props
   613  ----
   614  d#72057594037927935,17:
   615    0: [1, 16)
   616    d#72057594037927935,17:
   617      0: [1, 16)
   618  g#72057594037927935,17:
   619    0: [3, 26)
   620    g#72057594037927935,17:
   621      0: [3, 26)
   622  
   623  iter point-key-filter=(suffix-point-keys-only,1,2)
   624  set-bounds lower=b upper=e
   625  seek-ge d
   626  set-bounds lower=e upper=g
   627  seek-ge ee
   628  ----
   629  . MaybeFilteredKeys()=false
   630  . MaybeFilteredKeys()=true
   631  . MaybeFilteredKeys()=true
   632  . MaybeFilteredKeys()=true
   633  
   634  # Test another case of monotonically increasing bounds optimization, with a new
   635  # index block structure: This one has only one level. The first seek down below
   636  # should filter keys, and leave the index positioned at the last index block.
   637  # The subsequent seek must return MaybeFilteredKeys=true when keys were
   638  # filtered.
   639  
   640  build collectors=(suffix-point-keys-only) block-size=32
   641  a@1.SET.1:foo
   642  b@10.SET.2:bar
   643  c@15.SET.3:baz
   644  d@25.SET.4:bax
   645  e@3.SET.5:box
   646  f@5.SET.3:mop
   647  ----
   648  point:    [a@1#1,1,f@5#3,1]
   649  rangedel: [#0,0,#0,0]
   650  rangekey: [#0,0,#0,0]
   651  seqnums:  [1,5]
   652  
   653  block-props
   654  ----
   655  c#72057594037927935,17:
   656    0: [1, 11)
   657  e#72057594037927935,17:
   658    0: [15, 26)
   659  g#72057594037927935,17:
   660    0: [3, 6)
   661  
   662  iter point-key-filter=(suffix-point-keys-only,1,2)
   663  set-bounds lower=b upper=ee
   664  seek-ge d
   665  set-bounds lower=ee upper=g
   666  seek-ge ee
   667  ----
   668  . MaybeFilteredKeys()=false
   669  . MaybeFilteredKeys()=true
   670  . MaybeFilteredKeys()=true
   671  . MaybeFilteredKeys()=true