mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 04:27:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			760 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			760 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
# Set a key within the indexed batch.
 | 
						|
new-batch
 | 
						|
set foo foo
 | 
						|
----
 | 
						|
 | 
						|
# Construct an iterator over the indexed batch.
 | 
						|
 | 
						|
new-batch-iter i0
 | 
						|
----
 | 
						|
 | 
						|
# The key we set should be visible.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
new-batch-only-iter i-bo0
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i-bo0
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Set a new key, while the above iterator is still open.
 | 
						|
 | 
						|
mutate
 | 
						|
set bar bar
 | 
						|
----
 | 
						|
 | 
						|
# The new key should be invisible.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
prev
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
prev
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# A set-options operation should refresh the Iterator's view of the batch. The
 | 
						|
# bar key should now be visibile.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
bar: (bar, .)
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
bar: (bar, .)
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Delete foo with a range deletion.
 | 
						|
 | 
						|
mutate
 | 
						|
del-range f g
 | 
						|
----
 | 
						|
 | 
						|
# Both keys should still be visible.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
prev
 | 
						|
prev
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
bar: (bar, .)
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
prev
 | 
						|
prev
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
bar: (bar, .)
 | 
						|
 | 
						|
# After refreshing the iterator's view of the batch, foo should be deleted.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
set-options
 | 
						|
seek-ge foo
 | 
						|
seek-lt foo
 | 
						|
----
 | 
						|
.
 | 
						|
.
 | 
						|
bar: (bar, .)
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
set-options
 | 
						|
seek-ge foo
 | 
						|
seek-lt foo
 | 
						|
----
 | 
						|
.
 | 
						|
.
 | 
						|
bar: (bar, .)
 | 
						|
 | 
						|
# Write a range key set and a point key.
 | 
						|
 | 
						|
mutate
 | 
						|
range-key-set a c @1 boop
 | 
						|
set b b
 | 
						|
----
 | 
						|
 | 
						|
# The mutations should not be visible.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
prev
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
bar: (bar, .)
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
prev
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
bar: (bar, .)
 | 
						|
 | 
						|
# But refreshing the batch through a call to SetOptions should surface them.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-c) @1=boop UPDATED)
 | 
						|
b: (b, [a-c) @1=boop)
 | 
						|
bar: (bar, [a-c) @1=boop)
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-c) @1=boop UPDATED)
 | 
						|
b: (b, [a-c) @1=boop)
 | 
						|
bar: (bar, [a-c) @1=boop)
 | 
						|
 | 
						|
# Remove part of the range key to fragment it.
 | 
						|
 | 
						|
mutate
 | 
						|
range-key-del ace arc
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
next
 | 
						|
prev
 | 
						|
prev
 | 
						|
prev
 | 
						|
prev
 | 
						|
----
 | 
						|
.
 | 
						|
bar: (bar, [a-c) @1=boop UPDATED)
 | 
						|
b: (b, [a-c) @1=boop)
 | 
						|
a: (., [a-c) @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
next
 | 
						|
prev
 | 
						|
prev
 | 
						|
prev
 | 
						|
prev
 | 
						|
----
 | 
						|
.
 | 
						|
bar: (bar, [a-c) @1=boop UPDATED)
 | 
						|
b: (b, [a-c) @1=boop)
 | 
						|
a: (., [a-c) @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
iter iter=i0
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-ace) @1=boop UPDATED)
 | 
						|
arc: (., [arc-c) @1=boop UPDATED)
 | 
						|
b: (b, [arc-c) @1=boop)
 | 
						|
bar: (bar, [arc-c) @1=boop)
 | 
						|
 | 
						|
# Same behavior with a batch-only iterator.
 | 
						|
iter iter=i-bo0
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-ace) @1=boop UPDATED)
 | 
						|
arc: (., [arc-c) @1=boop UPDATED)
 | 
						|
b: (b, [arc-c) @1=boop)
 | 
						|
bar: (bar, [arc-c) @1=boop)
 | 
						|
 | 
						|
# Create a new indexed batch and a new iterator over it.
 | 
						|
 | 
						|
new-batch
 | 
						|
set foo foo
 | 
						|
----
 | 
						|
 | 
						|
new-batch-iter i1
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Test interactions with cloned iterators.
 | 
						|
# First, apply mutations to the batch. They should remain invisible.
 | 
						|
 | 
						|
mutate
 | 
						|
set bar bar
 | 
						|
range-key-set a z @1 boop
 | 
						|
del-range f g
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Clone i1 to create i2.
 | 
						|
 | 
						|
clone from=i1 to=i2 refresh-batch=false
 | 
						|
----
 | 
						|
 | 
						|
# i1 unchanged.
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# i2 sees exactly the same stale state as i1 until SetOptions is called to
 | 
						|
# explicitly refresh the view of the underlying batch.
 | 
						|
 | 
						|
iter iter=i2
 | 
						|
first
 | 
						|
next
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
.
 | 
						|
a: (., [a-z) @1=boop UPDATED)
 | 
						|
bar: (bar, [a-z) @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Clone i1 to create i3, this time passing RefreshBatchView: true. This clone
 | 
						|
# should view the updated view of the underlying batch.
 | 
						|
clone from=i1 to=i3 refresh-batch=true
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i3
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @1=boop UPDATED)
 | 
						|
bar: (bar, [a-z) @1=boop)
 | 
						|
 | 
						|
# i1 should still have the old, stale view of the batch.
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Mutate the underlying batch again.
 | 
						|
 | 
						|
mutate
 | 
						|
set foo foo
 | 
						|
range-key-set a z @2 bax
 | 
						|
del-range b c
 | 
						|
----
 | 
						|
 | 
						|
# The new mutations should be invisible until SetOptions is called.
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
.
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
iter iter=i2
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @1=boop UPDATED)
 | 
						|
bar: (bar, [a-z) @1=boop)
 | 
						|
.
 | 
						|
.
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Commit a separate batch to the underlying engine.
 | 
						|
batch
 | 
						|
range-key-set a z @5 poi
 | 
						|
set apple apple
 | 
						|
----
 | 
						|
 | 
						|
# The writes to the underlying engine should be invisible.
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Clone i1 to create i4.
 | 
						|
 | 
						|
clone from=i1 to=i4 refresh-batch=false
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i4
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Refresh i4's view of its batch. It should still not see the newly committed
 | 
						|
# writes.
 | 
						|
 | 
						|
iter iter=i4
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Create a new iterator i5 over the indexed batch [not a Clone]. It should see
 | 
						|
# all committed writes and uncommitted writes.
 | 
						|
 | 
						|
new-batch-iter i5
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i5
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @5=poi, @2=bax, @1=boop UPDATED)
 | 
						|
apple: (apple, [a-z) @5=poi, @2=bax, @1=boop)
 | 
						|
foo: (foo, [a-z) @5=poi, @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# The batch-only iter only sees the contents of the batch.
 | 
						|
new-batch-only-iter i-bo1
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i-bo1
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Mutate all the open iterators' underlying batch.
 | 
						|
 | 
						|
mutate
 | 
						|
range-key-set a z @6 yaya
 | 
						|
set c c
 | 
						|
----
 | 
						|
 | 
						|
# The iterators should still not see the committed writes, even after refreshing
 | 
						|
# to observe more recent batch writes.
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
iter iter=i4
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
.
 | 
						|
a: (., [a-z) @6=yaya, @2=bax, @1=boop UPDATED)
 | 
						|
c: (c, [a-z) @6=yaya, @2=bax, @1=boop)
 | 
						|
foo: (foo, [a-z) @6=yaya, @2=bax, @1=boop)
 | 
						|
 | 
						|
 | 
						|
# The batch-only iter sees the more recent batch writes after refreshing.
 | 
						|
iter iter=i-bo1
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @2=bax, @1=boop UPDATED)
 | 
						|
foo: (foo, [a-z) @2=bax, @1=boop)
 | 
						|
.
 | 
						|
.
 | 
						|
a: (., [a-z) @6=yaya, @2=bax, @1=boop UPDATED)
 | 
						|
c: (c, [a-z) @6=yaya, @2=bax, @1=boop)
 | 
						|
foo: (foo, [a-z) @6=yaya, @2=bax, @1=boop)
 | 
						|
.
 | 
						|
 | 
						|
# Test a scenario where constructing an Iterator should NOT use the cached
 | 
						|
# fragmented tombstones / range keys, because the new Iterator is a Clone which
 | 
						|
# must read at an earlier batch sequence number.
 | 
						|
 | 
						|
# Reset and start a new batch.
 | 
						|
 | 
						|
reset
 | 
						|
----
 | 
						|
 | 
						|
new-batch
 | 
						|
set foo foo
 | 
						|
----
 | 
						|
 | 
						|
new-batch-iter i1
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
# Apply a range deletion and a range key.
 | 
						|
 | 
						|
mutate
 | 
						|
del-range a z
 | 
						|
range-key-set a z @1 foo
 | 
						|
----
 | 
						|
 | 
						|
# Create a new iterator which will see both the range deletion and the range
 | 
						|
# key, and cache both on the batch so that future iterators constructed over the
 | 
						|
# batch do not need to.
 | 
						|
 | 
						|
new-batch-iter i2
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i2
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-z) @1=foo UPDATED)
 | 
						|
.
 | 
						|
 | 
						|
# Clone the original iterator from before the delete range and the range key
 | 
						|
# were created. It should not use the cached fragments of range deletions or
 | 
						|
# range keys, and should not see the effects of either.
 | 
						|
 | 
						|
clone from=i1 to=i3 refresh-batch=false
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i3
 | 
						|
first
 | 
						|
next
 | 
						|
----
 | 
						|
foo: (foo, .)
 | 
						|
.
 | 
						|
 | 
						|
reset
 | 
						|
----
 | 
						|
 | 
						|
new-batch
 | 
						|
range-key-set a c @1 poi
 | 
						|
range-key-set b d @2 yaya
 | 
						|
----
 | 
						|
 | 
						|
new-batch-iter i1
 | 
						|
----
 | 
						|
 | 
						|
# The batch contains 2 range keys, but the skiplist of fragmented range keys
 | 
						|
# contains 3 elements (a-b, b-c, c-d).
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-b) @1=poi UPDATED)
 | 
						|
b: (., [b-c) @2=yaya, @1=poi UPDATED)
 | 
						|
c: (., [c-d) @2=yaya UPDATED)
 | 
						|
 | 
						|
# Add a new range key to the batch. The batch contains 3 internal range keys,
 | 
						|
# and the skiplist of fragmented range keys contains 3 elements.
 | 
						|
 | 
						|
mutate
 | 
						|
range-key-set e f @3 foo
 | 
						|
----
 | 
						|
 | 
						|
# Refreshing the iterator's view of the batch through SetOptions should surface
 | 
						|
# the new range key. An earlier bug incorrectly compared the number of
 | 
						|
# fragmented range keys to the number of internal batch range keys in order to
 | 
						|
# determine when to refresh the iterator.
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
set-options
 | 
						|
first
 | 
						|
next
 | 
						|
next
 | 
						|
next
 | 
						|
seek-ge bat
 | 
						|
----
 | 
						|
a: (., [a-b) @1=poi UPDATED)
 | 
						|
b: (., [b-c) @2=yaya, @1=poi UPDATED)
 | 
						|
c: (., [c-d) @2=yaya UPDATED)
 | 
						|
.
 | 
						|
a: (., [a-b) @1=poi UPDATED)
 | 
						|
b: (., [b-c) @2=yaya, @1=poi UPDATED)
 | 
						|
c: (., [c-d) @2=yaya UPDATED)
 | 
						|
e: (., [e-f) @3=foo UPDATED)
 | 
						|
bat: (., [b-c) @2=yaya, @1=poi UPDATED)
 | 
						|
 | 
						|
# Mutate the range key under the interleaving iterator's current position in the
 | 
						|
# indexed batch.
 | 
						|
#
 | 
						|
# The last `seek-ge` operation landed on the range key [b-c). The top-level
 | 
						|
# *pebble.Iterator needs to step the iterator again to see if there's a
 | 
						|
# coincident point key at (`bat`), which would've advanced the interleaving
 | 
						|
# iterator to the range key with bounds [c,d), so the underlying interleaving
 | 
						|
# iterator is positioned ahead at:
 | 
						|
#
 | 
						|
#     c: (., [c-d) @2=yaya)
 | 
						|
#
 | 
						|
# If we call set-options to refresh the iterator's view of the indexed batch,
 | 
						|
# the range-key-unset [c,d)@2 becomes visible, and the range key that the
 | 
						|
# underlying interleaving iterator is positioned over should not be visible.
 | 
						|
#
 | 
						|
# A bug previously allowed this range key to be visible when seeking into this
 | 
						|
# span's bounds (see the optimization in InterleavingIter.SeekGE). Now, the call
 | 
						|
# to SetOptions clears the interleaving iterator's positional state to avoid the
 | 
						|
# SeekGE optimization.
 | 
						|
 | 
						|
mutate
 | 
						|
range-key-unset b d @2
 | 
						|
----
 | 
						|
 | 
						|
iter iter=i1
 | 
						|
set-options
 | 
						|
seek-ge cat
 | 
						|
----
 | 
						|
.
 | 
						|
e: (., [e-f) @3=foo UPDATED)
 | 
						|
 | 
						|
reset
 | 
						|
----
 | 
						|
 | 
						|
batch
 | 
						|
range-key-set a e @1 foo
 | 
						|
----
 | 
						|
 | 
						|
flush
 | 
						|
----
 | 
						|
 | 
						|
new-batch
 | 
						|
----
 | 
						|
 | 
						|
new-batch-iter batchiter
 | 
						|
----
 | 
						|
 | 
						|
new-db-iter dbiter
 | 
						|
----
 | 
						|
 | 
						|
# Test RangeKeyChanged() semantics.
 | 
						|
# Seeking to the same prefix returns RangeKeyChanged()=false.
 | 
						|
# Seeking to a new prefix returns RangeKeyChanged()=true.
 | 
						|
# Seeking to the same prefix with a SetOptions call in between returns
 | 
						|
# RangeKeyChanged()=true.
 | 
						|
 | 
						|
iter iter=dbiter
 | 
						|
seek-prefix-ge b@3
 | 
						|
seek-prefix-ge b@4
 | 
						|
seek-prefix-ge c@3
 | 
						|
seek-prefix-ge d@3
 | 
						|
set-options
 | 
						|
seek-prefix-ge d@1
 | 
						|
----
 | 
						|
b@3: (., [b-"b\x00") @1=foo UPDATED)
 | 
						|
b@4: (., [b-"b\x00") @1=foo)
 | 
						|
c@3: (., [c-"c\x00") @1=foo UPDATED)
 | 
						|
d@3: (., [d-"d\x00") @1=foo UPDATED)
 | 
						|
.
 | 
						|
d@1: (., [d-"d\x00") @1=foo UPDATED)
 | 
						|
 | 
						|
# Test the same semantics on a batch iterator.
 | 
						|
 | 
						|
iter iter=batchiter
 | 
						|
seek-prefix-ge b@3
 | 
						|
seek-prefix-ge b@4
 | 
						|
seek-prefix-ge c@3
 | 
						|
seek-prefix-ge d@3
 | 
						|
set-options
 | 
						|
seek-prefix-ge d@1
 | 
						|
----
 | 
						|
b@3: (., [b-"b\x00") @1=foo UPDATED)
 | 
						|
b@4: (., [b-"b\x00") @1=foo)
 | 
						|
c@3: (., [c-"c\x00") @1=foo UPDATED)
 | 
						|
d@3: (., [d-"d\x00") @1=foo UPDATED)
 | 
						|
.
 | 
						|
d@1: (., [d-"d\x00") @1=foo UPDATED)
 | 
						|
 | 
						|
# Test mutating the indexed batch's range keys, overlapping the existing seek
 | 
						|
# position. It should not see the new mutations, but after a call to SetOptions
 | 
						|
# it should AND it should return RangeKeyChanged()=true.
 | 
						|
 | 
						|
mutate
 | 
						|
range-key-set d e @2 foo
 | 
						|
----
 | 
						|
 | 
						|
iter iter=batchiter
 | 
						|
seek-prefix-ge d@2
 | 
						|
set-options
 | 
						|
seek-prefix-ge d@2
 | 
						|
----
 | 
						|
d@2: (., [d-"d\x00") @1=foo)
 | 
						|
.
 | 
						|
d@2: (., [d-"d\x00") @2=foo, @1=foo UPDATED)
 | 
						|
 | 
						|
# Test cloning an iterator with a range-key mask block property filter
 | 
						|
# configured. If the cloned and the clonee iterators have different suffixes
 | 
						|
# configured, their suffixes should be respected. Previously, the
 | 
						|
# RangeKeyMasking.Filter option was a footgun, because it was a single mutable
 | 
						|
# instance. Cloning the iterator without supplying new iterator options would
 | 
						|
# result in two iterators using the same filter.
 | 
						|
 | 
						|
reset
 | 
						|
----
 | 
						|
 | 
						|
batch
 | 
						|
range-key-set a e @5 foo
 | 
						|
set b@4 b@4
 | 
						|
----
 | 
						|
 | 
						|
new-db-iter iter-a
 | 
						|
----
 | 
						|
 | 
						|
iter iter=iter-a
 | 
						|
set-options mask-suffix=@3 mask-filter=true
 | 
						|
seek-ge a
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-e) @5=foo UPDATED)
 | 
						|
b@4: (b@4, [a-e) @5=foo)
 | 
						|
.
 | 
						|
 | 
						|
clone from=iter-a to=iter-b refresh-batch=false
 | 
						|
----
 | 
						|
 | 
						|
iter iter=iter-b
 | 
						|
set-options mask-suffix=@6
 | 
						|
seek-ge a
 | 
						|
next
 | 
						|
----
 | 
						|
.
 | 
						|
a: (., [a-e) @5=foo UPDATED)
 | 
						|
.
 | 
						|
 | 
						|
iter iter=iter-a
 | 
						|
seek-ge a
 | 
						|
next
 | 
						|
next
 | 
						|
----
 | 
						|
a: (., [a-e) @5=foo UPDATED)
 | 
						|
b@4: (b@4, [a-e) @5=foo)
 | 
						|
.
 |