github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/testdata/level_iter_seek (about) 1 # Note that this test file uses a levelIterTestIter which combines a 2 # point iterator and a range-del iterator, returning both results in a 3 # single key: 4 # 5 # <point-key>/<tombstone>#<point-seqnum,point-kind> 6 7 # Verify that SeekGE, SeekLT, Next, and Prev all pause at table 8 # boundaries in the presence of lower/upper bounds and range 9 # tombstones. Verify that SeekPrefixGE pauses at a table boundary in 10 # the presence of range tombstones. 11 12 build 13 a.SET.9:a 14 b.SET.8:b 15 ---- 16 0: a#9,1-b#8,1 17 18 build 19 c.SET.7:c 20 d.RANGEDEL.6:e 21 f.SET.5:f 22 ---- 23 0: a#9,1-b#8,1 24 1: c#7,1-f#5,1 25 26 build 27 g.SET.4:g 28 h.SET.3:h 29 ---- 30 0: a#9,1-b#8,1 31 1: c#7,1-f#5,1 32 2: g#4,1-h#3,1 33 34 iter 35 seek-ge d 36 ---- 37 f/d-e:{(#6,RANGEDEL)}#5,1:f 38 39 iter 40 set-bounds upper=d 41 seek-ge d 42 ---- 43 d/d-e:{(#6,RANGEDEL)}#72057594037927935,15: 44 45 iter 46 set-bounds upper=d 47 seek-ge c 48 next 49 prev 50 next 51 next 52 ---- 53 c/d-e:{(#6,RANGEDEL)}#7,1:c 54 d#72057594037927935,15: 55 c#7,1:c 56 d#72057594037927935,15: 57 . 58 59 # There is no point key with d, but since there is a rangedel, levelIter returns 60 # the boundary key using the largest key, f, in the file. 61 iter 62 seek-prefix-ge d 63 ---- 64 f/d-e:{(#6,RANGEDEL)}#5,1: 65 66 # Tests a sequence of SeekPrefixGE with monotonically increasing keys, some of 67 # which are present and some not (so fail the bloom filter match). The seek to 68 # cc returns a boundary key. 69 iter 70 seek-prefix-ge aa 71 seek-prefix-ge c 72 seek-prefix-ge cc 73 seek-prefix-ge f 74 seek-prefix-ge g 75 seek-prefix-ge gg 76 seek-prefix-ge h 77 ---- 78 ./<invalid>#0,0: 79 c/d-e:{(#6,RANGEDEL)}#7,1:c 80 f/d-e:{(#6,RANGEDEL)}#5,1: 81 f/<invalid>#5,1:f 82 g/<invalid>#4,1:g 83 ./<invalid>#0,0: 84 h/<invalid>#3,1:h 85 86 # Test that when sequentially iterate through all 3 files, the stats 87 # accumulate as we close a file and switch to the next one. Also, while in the 88 # middle of the first file, a reset-stats propagates to the underlying 89 # iterators, and when done iterating, a reset-stats does reset the local 90 # state. 91 iter 92 seek-ge a 93 stats 94 reset-stats 95 stats 96 next 97 stats 98 next 99 stats 100 next 101 stats 102 next 103 stats 104 next 105 stats 106 next 107 stats 108 reset-stats 109 stats 110 ---- 111 a/<invalid>#9,1:a 112 {BlockBytes:56 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 113 {BlockBytes:0 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 114 b#8,1:b 115 {BlockBytes:0 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 116 c#7,1:c 117 {BlockBytes:56 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 118 f#5,1:f 119 {BlockBytes:56 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 120 g#4,1:g 121 {BlockBytes:112 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 122 h#3,1:h 123 {BlockBytes:112 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 124 . 125 {BlockBytes:112 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 126 {BlockBytes:0 BlockBytesInCache:0 BlockReadDuration:0s KeyBytes:0 ValueBytes:0 PointCount:0 PointsCoveredByRangeTombstones:0 SeparatedPointValue:{Count:0 ValueBytes:0 ValueBytesFetched:0}} 127 128 iter 129 set-bounds lower=d 130 seek-lt d 131 ---- 132 d/d-e:{(#6,RANGEDEL)}#72057594037927935,15: 133 134 iter 135 set-bounds lower=d 136 seek-lt g 137 prev 138 next 139 prev 140 prev 141 ---- 142 f/d-e:{(#6,RANGEDEL)}#5,1:f 143 d#72057594037927935,15: 144 f#5,1:f 145 d#72057594037927935,15: 146 . 147 148 # Verify that First() in the presence of an upper-bound pauses at the 149 # table containing the upper-bound. 150 151 clear 152 ---- 153 154 build 155 d.RANGEDEL.6:e 156 f.SET.5:f 157 ---- 158 0: d#6,15-f#5,1 159 160 iter 161 set-bounds upper=f 162 first 163 ---- 164 f#72057594037927935,15: 165 166 # Verify that Last() in the presence of a lower-bound pauses at the 167 # table containing the lower-bound. 168 169 clear 170 ---- 171 172 build 173 c.SET.7:c 174 d.RANGEDEL.6:e 175 ---- 176 0: c#7,1-e#72057594037927935,15 177 178 iter 179 set-bounds lower=c 180 last 181 ---- 182 c#7,1:c 183 184 # Verify that a seek to a file with range tombstones as boundaries pauses on 185 # those boundaries. 186 187 clear 188 ---- 189 190 build 191 a.RANGEDEL.5:b 192 c.SET.7:c 193 d.RANGEDEL.6:e 194 ---- 195 0: a#5,15-e#72057594037927935,15 196 197 build 198 f.SET.8:f 199 g.SET.9:g 200 ---- 201 0: a#5,15-e#72057594037927935,15 202 1: f#8,1-g#9,1 203 204 iter 205 seek-ge d 206 prev 207 next 208 next 209 ---- 210 e/d-e:{(#6,RANGEDEL)}#72057594037927935,15: 211 c#7,1:c 212 e#72057594037927935,15: 213 f#8,1:f 214 215 iter 216 seek-lt b 217 next 218 prev 219 prev 220 ---- 221 a/a-b:{(#5,RANGEDEL)}#5,15: 222 c#7,1:c 223 a#5,15: 224 . 225 226 # Verify that prev when positioned at the largest boundary returns the 227 # last key. 228 229 clear 230 ---- 231 232 build 233 a.SET.1:a 234 b.SET.1:b 235 d.RANGEDEL.2:e 236 ---- 237 0: a#1,1-e#72057594037927935,15 238 239 iter 240 seek-lt c 241 seek-ge d 242 prev 243 ---- 244 b/<invalid>#1,1:b 245 e/d-e:{(#2,RANGEDEL)}#72057594037927935,15: 246 b#1,1:b 247 248 # Verify that next when positioned at the smallest boundary returns 249 # the first key. 250 251 clear 252 ---- 253 254 build 255 a.RANGEDEL.1:b 256 d.SET.2:d 257 e.SET.2:e 258 ---- 259 0: a#1,15-e#2,1 260 261 iter 262 seek-ge d 263 seek-lt d 264 next 265 ---- 266 d/<invalid>#2,1:d 267 a/a-b:{(#1,RANGEDEL)}#1,15: 268 d#2,1:d 269 270 # Verify SeekPrefixGE correctness with trySeekUsingNext=true 271 clear 272 ---- 273 274 build 275 a.SET.1:a 276 b.SET.2:b 277 c.RANGEDEL.4:e 278 ---- 279 0: a#1,1-e#72057594037927935,15 280 281 build 282 e.SET.4:e 283 f.SINGLEDEL.5: 284 f.SET.4:f 285 g.SET.6:g 286 h.SINGLEDEL.7: 287 ---- 288 0: a#1,1-e#72057594037927935,15 289 1: e#4,1-h#7,7 290 291 build 292 h.SET.6:h 293 i.SET.6:i 294 ---- 295 0: a#1,1-e#72057594037927935,15 296 1: e#4,1-h#7,7 297 2: h#6,1-i#6,1 298 299 build 300 j.SET.7:j 301 ---- 302 0: a#1,1-e#72057594037927935,15 303 1: e#4,1-h#7,7 304 2: h#6,1-i#6,1 305 3: j#7,1-j#7,1 306 307 # Seeks to immediately following keys. 308 iter 309 seek-prefix-ge a false 310 seek-prefix-ge a true 311 seek-prefix-ge b true 312 next 313 seek-prefix-ge c false 314 seek-prefix-ge d true 315 seek-prefix-ge f true 316 seek-prefix-ge g true 317 seek-prefix-ge h true 318 seek-prefix-ge i true 319 seek-prefix-ge j true 320 ---- 321 a/c-e:{(#4,RANGEDEL)}#1,1:a 322 a/c-e:{(#4,RANGEDEL)}#1,1:a 323 b/c-e:{(#4,RANGEDEL)}#2,1:b 324 e#72057594037927935,15: 325 e/c-e:{(#4,RANGEDEL)}#72057594037927935,15: 326 e/c-e:{(#4,RANGEDEL)}#72057594037927935,15: 327 f/<invalid>#5,7: 328 g/<invalid>#6,1:g 329 h/<invalid>#7,7: 330 i/<invalid>#6,1:i 331 j/<invalid>#7,1:j 332 333 # Seeks to keys that are in the next file, so cannot use Next. 334 iter 335 seek-prefix-ge a false 336 seek-prefix-ge e true 337 seek-prefix-ge i true 338 seek-prefix-ge j true 339 ---- 340 a/c-e:{(#4,RANGEDEL)}#1,1:a 341 e/<invalid>#4,1:e 342 i/<invalid>#6,1:i 343 j/<invalid>#7,1:j 344 345 # Verify that we do not open files that do not have point keys. 346 347 clear 348 ---- 349 350 build 351 a.SET.9:a 352 b.SET.8:b 353 ---- 354 0: a#9,1-b#8,1 355 356 build 357 c.SET.7:c 358 d.RANGEDEL.6:e 359 f.SET.5:f 360 ---- 361 0: a#9,1-b#8,1 362 1: c#7,1-f#5,1 363 364 build format=pebblev2 365 g.RANGEKEYDEL.6:h 366 ---- 367 0: a#9,1-b#8,1 368 1: c#7,1-f#5,1 369 2: g#6,19-h#72057594037927935,19 370 371 build 372 i.SET.4:i 373 j.SET.3:j 374 ---- 375 0: a#9,1-b#8,1 376 1: c#7,1-f#5,1 377 2: g#6,19-h#72057594037927935,19 378 3: i#4,1-j#3,1 379 380 iter 381 seek-ge f 382 next 383 ---- 384 f/<invalid>#5,1:f 385 i#4,1:i 386 387 # The below count should be 2, as we skip over the rangekey-only file. 388 389 iters-created 390 ---- 391 2