github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/testdata/indexed_batch_mutation (about) 1 # Set a key within the indexed batch. 2 new-batch 3 set foo foo 4 ---- 5 6 # Construct an iterator over the indexed batch. 7 8 new-batch-iter i0 9 ---- 10 11 # The key we set should be visible. 12 13 iter iter=i0 14 first 15 next 16 ---- 17 foo: (foo, .) 18 . 19 20 # Set a new key, while the above iterator is still open. 21 22 mutate 23 set bar bar 24 ---- 25 26 # The new key should be invisible. 27 28 iter iter=i0 29 prev 30 next 31 ---- 32 foo: (foo, .) 33 . 34 35 # A set-options operation should refresh the Iterator's view of the batch. The 36 # bar key should now be visibile. 37 38 iter iter=i0 39 set-options 40 first 41 next 42 next 43 ---- 44 . 45 bar: (bar, .) 46 foo: (foo, .) 47 . 48 49 # Delete foo with a range deletion. 50 51 mutate 52 del-range f g 53 ---- 54 55 # Both keys should still be visible. 56 57 iter iter=i0 58 prev 59 prev 60 ---- 61 foo: (foo, .) 62 bar: (bar, .) 63 64 # After refreshing the iterator's view of the batch, foo should be deleted. 65 66 iter iter=i0 67 set-options 68 seek-ge foo 69 seek-lt foo 70 ---- 71 . 72 . 73 bar: (bar, .) 74 75 # Write a range key set and a point key. 76 77 mutate 78 range-key-set a c @1 boop 79 set b b 80 ---- 81 82 # The mutations should not be visible. 83 84 iter iter=i0 85 prev 86 next 87 ---- 88 . 89 bar: (bar, .) 90 91 # But refreshing the batch through a call to SetOptions should surface them. 92 93 iter iter=i0 94 set-options 95 first 96 next 97 next 98 ---- 99 . 100 a: (., [a-c) @1=boop UPDATED) 101 b: (b, [a-c) @1=boop) 102 bar: (bar, [a-c) @1=boop) 103 104 # Remove part of the range key to fragment it. 105 106 mutate 107 range-key-del ace arc 108 ---- 109 110 iter iter=i0 111 next 112 prev 113 prev 114 prev 115 prev 116 ---- 117 . 118 bar: (bar, [a-c) @1=boop UPDATED) 119 b: (b, [a-c) @1=boop) 120 a: (., [a-c) @1=boop) 121 . 122 123 iter iter=i0 124 set-options 125 first 126 next 127 next 128 next 129 ---- 130 . 131 a: (., [a-ace) @1=boop UPDATED) 132 arc: (., [arc-c) @1=boop UPDATED) 133 b: (b, [arc-c) @1=boop) 134 bar: (bar, [arc-c) @1=boop) 135 136 # Create a new indexed batch and a new iterator over it. 137 138 new-batch 139 set foo foo 140 ---- 141 142 new-batch-iter i1 143 ---- 144 145 iter iter=i1 146 first 147 next 148 ---- 149 foo: (foo, .) 150 . 151 152 # Test interactions with cloned iterators. 153 # First, apply mutations to the batch. They should remain invisible. 154 155 mutate 156 set bar bar 157 range-key-set a z @1 boop 158 del-range f g 159 ---- 160 161 iter iter=i1 162 first 163 next 164 ---- 165 foo: (foo, .) 166 . 167 168 # Clone i1 to create i2. 169 170 clone from=i1 to=i2 refresh-batch=false 171 ---- 172 173 # i1 unchanged. 174 175 iter iter=i1 176 first 177 next 178 ---- 179 foo: (foo, .) 180 . 181 182 # i2 sees exactly the same stale state as i1 until SetOptions is called to 183 # explicitly refresh the view of the underlying batch. 184 185 iter iter=i2 186 first 187 next 188 set-options 189 first 190 next 191 next 192 ---- 193 foo: (foo, .) 194 . 195 . 196 a: (., [a-z) @1=boop UPDATED) 197 bar: (bar, [a-z) @1=boop) 198 . 199 200 # Clone i1 to create i3, this time passing RefreshBatchView: true. This clone 201 # should view the updated view of the underlying batch. 202 clone from=i1 to=i3 refresh-batch=true 203 ---- 204 205 iter iter=i3 206 first 207 next 208 ---- 209 a: (., [a-z) @1=boop UPDATED) 210 bar: (bar, [a-z) @1=boop) 211 212 # i1 should still have the old, stale view of the batch. 213 214 iter iter=i1 215 first 216 next 217 ---- 218 foo: (foo, .) 219 . 220 221 # Mutate the underlying batch again. 222 223 mutate 224 set foo foo 225 range-key-set a z @2 bax 226 del-range b c 227 ---- 228 229 # The new mutations should be invisible until SetOptions is called. 230 231 iter iter=i1 232 first 233 next 234 set-options 235 first 236 next 237 next 238 ---- 239 foo: (foo, .) 240 . 241 . 242 a: (., [a-z) @2=bax, @1=boop UPDATED) 243 foo: (foo, [a-z) @2=bax, @1=boop) 244 . 245 246 iter iter=i2 247 first 248 next 249 next 250 set-options 251 first 252 next 253 next 254 ---- 255 a: (., [a-z) @1=boop UPDATED) 256 bar: (bar, [a-z) @1=boop) 257 . 258 . 259 a: (., [a-z) @2=bax, @1=boop UPDATED) 260 foo: (foo, [a-z) @2=bax, @1=boop) 261 . 262 263 # Commit a separate batch to the underlying engine. 264 batch 265 range-key-set a z @5 poi 266 set apple apple 267 ---- 268 269 # The writes to the underlying engine should be invisible. 270 271 iter iter=i1 272 first 273 next 274 next 275 ---- 276 a: (., [a-z) @2=bax, @1=boop UPDATED) 277 foo: (foo, [a-z) @2=bax, @1=boop) 278 . 279 280 # Clone i1 to create i4. 281 282 clone from=i1 to=i4 refresh-batch=false 283 ---- 284 285 iter iter=i4 286 first 287 next 288 next 289 ---- 290 a: (., [a-z) @2=bax, @1=boop UPDATED) 291 foo: (foo, [a-z) @2=bax, @1=boop) 292 . 293 294 # Refresh i4's view of its batch. It should still not see the newly committed 295 # writes. 296 297 iter iter=i4 298 set-options 299 first 300 next 301 next 302 ---- 303 . 304 a: (., [a-z) @2=bax, @1=boop UPDATED) 305 foo: (foo, [a-z) @2=bax, @1=boop) 306 . 307 308 # Create a new iterator i5 over the indexed batch [not a Clone]. It should see 309 # all committed writes and uncommitted writes. 310 311 new-batch-iter i5 312 ---- 313 314 iter iter=i5 315 first 316 next 317 next 318 next 319 ---- 320 a: (., [a-z) @5=poi, @2=bax, @1=boop UPDATED) 321 apple: (apple, [a-z) @5=poi, @2=bax, @1=boop) 322 foo: (foo, [a-z) @5=poi, @2=bax, @1=boop) 323 . 324 325 # Mutate all the open iterators' underlying batch. 326 327 mutate 328 range-key-set a z @6 yaya 329 set c c 330 ---- 331 332 # The iterators should still not see the committed writes, even after refreshing 333 # to observe more recent batch writes. 334 335 iter iter=i1 336 first 337 next 338 next 339 ---- 340 a: (., [a-z) @2=bax, @1=boop UPDATED) 341 foo: (foo, [a-z) @2=bax, @1=boop) 342 . 343 344 iter iter=i4 345 first 346 next 347 next 348 set-options 349 first 350 next 351 next 352 ---- 353 a: (., [a-z) @2=bax, @1=boop UPDATED) 354 foo: (foo, [a-z) @2=bax, @1=boop) 355 . 356 . 357 a: (., [a-z) @6=yaya, @2=bax, @1=boop UPDATED) 358 c: (c, [a-z) @6=yaya, @2=bax, @1=boop) 359 foo: (foo, [a-z) @6=yaya, @2=bax, @1=boop) 360 361 # Test a scenario where constructing an Iterator should NOT use the cached 362 # fragmented tombstones / range keys, because the new Iterator is a Clone which 363 # must read at an earlier batch sequence number. 364 365 # Reset and start a new batch. 366 367 reset 368 ---- 369 370 new-batch 371 set foo foo 372 ---- 373 374 new-batch-iter i1 375 ---- 376 377 iter iter=i1 378 first 379 next 380 ---- 381 foo: (foo, .) 382 . 383 384 # Apply a range deletion and a range key. 385 386 mutate 387 del-range a z 388 range-key-set a z @1 foo 389 ---- 390 391 # Create a new iterator which will see both the range deletion and the range 392 # key, and cache both on the batch so that future iterators constructed over the 393 # batch do not need to. 394 395 new-batch-iter i2 396 ---- 397 398 iter iter=i2 399 first 400 next 401 ---- 402 a: (., [a-z) @1=foo UPDATED) 403 . 404 405 # Clone the original iterator from before the delete range and the range key 406 # were created. It should not use the cached fragments of range deletions or 407 # range keys, and should not see the effects of either. 408 409 clone from=i1 to=i3 refresh-batch=false 410 ---- 411 412 iter iter=i3 413 first 414 next 415 ---- 416 foo: (foo, .) 417 . 418 419 reset 420 ---- 421 422 new-batch 423 range-key-set a c @1 poi 424 range-key-set b d @2 yaya 425 ---- 426 427 new-batch-iter i1 428 ---- 429 430 # The batch contains 2 range keys, but the skiplist of fragmented range keys 431 # contains 3 elements (a-b, b-c, c-d). 432 433 iter iter=i1 434 first 435 next 436 next 437 ---- 438 a: (., [a-b) @1=poi UPDATED) 439 b: (., [b-c) @2=yaya, @1=poi UPDATED) 440 c: (., [c-d) @2=yaya UPDATED) 441 442 # Add a new range key to the batch. The batch contains 3 internal range keys, 443 # and the skiplist of fragmented range keys contains 3 elements. 444 445 mutate 446 range-key-set e f @3 foo 447 ---- 448 449 # Refreshing the iterator's view of the batch through SetOptions should surface 450 # the new range key. An earlier bug incorrectly compared the number of 451 # fragmented range keys to the number of internal batch range keys in order to 452 # determine when to refresh the iterator. 453 454 iter iter=i1 455 first 456 next 457 next 458 set-options 459 first 460 next 461 next 462 next 463 seek-ge bat 464 ---- 465 a: (., [a-b) @1=poi UPDATED) 466 b: (., [b-c) @2=yaya, @1=poi UPDATED) 467 c: (., [c-d) @2=yaya UPDATED) 468 . 469 a: (., [a-b) @1=poi UPDATED) 470 b: (., [b-c) @2=yaya, @1=poi UPDATED) 471 c: (., [c-d) @2=yaya UPDATED) 472 e: (., [e-f) @3=foo UPDATED) 473 bat: (., [b-c) @2=yaya, @1=poi UPDATED) 474 475 # Mutate the range key under the interleaving iterator's current position in the 476 # indexed batch. 477 # 478 # The last `seek-ge` operation landed on the range key [b-c). The top-level 479 # *bitable.Iterator needs to step the iterator again to see if there's a 480 # coincident point key at (`bat`), which would've advanced the interleaving 481 # iterator to the range key with bounds [c,d), so the underlying interleaving 482 # iterator is positioned ahead at: 483 # 484 # c: (., [c-d) @2=yaya) 485 # 486 # If we call set-options to refresh the iterator's view of the indexed batch, 487 # the range-key-unset [c,d)@2 becomes visible, and the range key that the 488 # underlying interleaving iterator is positioned over should not be visible. 489 # 490 # A bug previously allowed this range key to be visible when seeking into this 491 # span's bounds (see the optimization in InterleavingIter.SeekGE). Now, the call 492 # to SetOptions clears the interleaving iterator's positional state to avoid the 493 # SeekGE optimization. 494 495 mutate 496 range-key-unset b d @2 497 ---- 498 499 iter iter=i1 500 set-options 501 seek-ge cat 502 ---- 503 . 504 e: (., [e-f) @3=foo UPDATED) 505 506 reset 507 ---- 508 509 batch 510 range-key-set a e @1 foo 511 ---- 512 513 flush 514 ---- 515 516 new-batch 517 ---- 518 519 new-batch-iter batchiter 520 ---- 521 522 new-db-iter dbiter 523 ---- 524 525 # Test RangeKeyChanged() semantics. 526 # Seeking to the same prefix returns RangeKeyChanged()=false. 527 # Seeking to a new prefix returns RangeKeyChanged()=true. 528 # Seeking to the same prefix with a SetOptions call in between returns 529 # RangeKeyChanged()=true. 530 531 iter iter=dbiter 532 seek-prefix-ge b@3 533 seek-prefix-ge b@4 534 seek-prefix-ge c@3 535 seek-prefix-ge d@3 536 set-options 537 seek-prefix-ge d@1 538 ---- 539 b@3: (., [b-"b\x00") @1=foo UPDATED) 540 b@4: (., [b-"b\x00") @1=foo) 541 c@3: (., [c-"c\x00") @1=foo UPDATED) 542 d@3: (., [d-"d\x00") @1=foo UPDATED) 543 . 544 d@1: (., [d-"d\x00") @1=foo UPDATED) 545 546 # Test the same semantics on a batch iterator. 547 548 iter iter=batchiter 549 seek-prefix-ge b@3 550 seek-prefix-ge b@4 551 seek-prefix-ge c@3 552 seek-prefix-ge d@3 553 set-options 554 seek-prefix-ge d@1 555 ---- 556 b@3: (., [b-"b\x00") @1=foo UPDATED) 557 b@4: (., [b-"b\x00") @1=foo) 558 c@3: (., [c-"c\x00") @1=foo UPDATED) 559 d@3: (., [d-"d\x00") @1=foo UPDATED) 560 . 561 d@1: (., [d-"d\x00") @1=foo UPDATED) 562 563 # Test mutating the indexed batch's range keys, overlapping the existing seek 564 # position. It should not see the new mutations, but after a call to SetOptions 565 # it should AND it should return RangeKeyChanged()=true. 566 567 mutate 568 range-key-set d e @2 foo 569 ---- 570 571 iter iter=batchiter 572 seek-prefix-ge d@2 573 set-options 574 seek-prefix-ge d@2 575 ---- 576 d@2: (., [d-"d\x00") @1=foo) 577 . 578 d@2: (., [d-"d\x00") @2=foo, @1=foo UPDATED) 579 580 # Test cloning an iterator with a range-key mask block property filter 581 # configured. If the cloned and the clonee iterators have different suffixes 582 # configured, their suffixes should be respected. Previously, the 583 # RangeKeyMasking.Filter option was a footgun, because it was a single mutable 584 # instance. Cloning the iterator without supplying new iterator options would 585 # result in two iterators using the same filter. 586 587 reset 588 ---- 589 590 batch 591 range-key-set a e @5 foo 592 set b@4 b@4 593 ---- 594 595 new-db-iter iter-a 596 ---- 597 598 iter iter=iter-a 599 set-options mask-suffix=@3 mask-filter=true 600 seek-ge a 601 next 602 next 603 ---- 604 . 605 a: (., [a-e) @5=foo UPDATED) 606 b@4: (b@4, [a-e) @5=foo) 607 . 608 609 clone from=iter-a to=iter-b refresh-batch=false 610 ---- 611 612 iter iter=iter-b 613 set-options mask-suffix=@6 614 seek-ge a 615 next 616 ---- 617 . 618 a: (., [a-e) @5=foo UPDATED) 619 . 620 621 iter iter=iter-a 622 seek-ge a 623 next 624 next 625 ---- 626 a: (., [a-e) @5=foo UPDATED) 627 b@4: (b@4, [a-e) @5=foo) 628 .