mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 06:37:26 +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)
							 | 
						||
| 
								 | 
							
								.
							 |