# Test a scenario that should NOT result in defragmentation.

define
a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
c-d:{(#4,RANGEKEYSET,@3,bananas)}
d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
----

iter
first
next
next
last
prev
prev
----
first     a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      c-d:{(#4,RANGEKEYSET,@3,bananas)}
next      d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
last      d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
prev      c-d:{(#4,RANGEKEYSET,@3,bananas)}
prev      a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}

iter
first
next
next
next
last
prev
prev
prev
----
first     a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      c-d:{(#4,RANGEKEYSET,@3,bananas)}
next      d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
next      .
last      d-e:{(#4,RANGEKEYSET,@3,bananas) (#4,RANGEKEYSET,@1,pineapple)}
prev      c-d:{(#4,RANGEKEYSET,@3,bananas)}
prev      a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
prev      .

# Test a scenario that SHOULD result in internal defragmentation ([a,c) and
# [c,d) should be merged.

define
a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
c-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
d-e:{(#1,RANGEKEYSET,@3,bananas)}
----

iter
first
next
next
----
first     a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      d-e:{(#1,RANGEKEYSET,@3,bananas)}
next      .

# Test defragmenting in both directions at seek keys.

define
a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
f-h:{(#3,RANGEKEYSET,@3,bananas)}
h-p:{(#3,RANGEKEYSET,@3,bananas)}
p-t:{(#3,RANGEKEYSET,@3,bananas)}
----

iter
seekge b
prev
seekge b
next
seeklt d
next
seeklt d
prev
----
seekge b  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
prev      .
seekge b  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      f-t:{(#3,RANGEKEYSET,@3,bananas)}
seeklt d  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      f-t:{(#3,RANGEKEYSET,@3,bananas)}
seeklt d  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
prev      .

iter
seeklt d
next
prev
----
seeklt d  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      f-t:{(#3,RANGEKEYSET,@3,bananas)}
prev      a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}

# Test next-ing and prev-ing around seek keys.

define
a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
f-h:{(#3,RANGEKEYSET,@3,bananas)}
h-p:{(#3,RANGEKEYSET,@3,bananas)}
p-t:{(#3,RANGEKEYSET,@3,bananas)}
t-z:{(#4,RANGEKEYSET,@2,oranges)}
----

iter
seekge r
prev
next
next
----
seekge r  f-t:{(#3,RANGEKEYSET,@3,bananas)}
prev      a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      f-t:{(#3,RANGEKEYSET,@3,bananas)}
next      t-z:{(#4,RANGEKEYSET,@2,oranges)}

iter
seekge f
seekge h
seekge p
seekge t
seekge u
seekge v
seekge z
----
seekge f  f-t:{(#3,RANGEKEYSET,@3,bananas)}
seekge h  f-t:{(#3,RANGEKEYSET,@3,bananas)}
seekge p  f-t:{(#3,RANGEKEYSET,@3,bananas)}
seekge t  t-z:{(#4,RANGEKEYSET,@2,oranges)}
seekge u  t-z:{(#4,RANGEKEYSET,@2,oranges)}
seekge v  t-z:{(#4,RANGEKEYSET,@2,oranges)}
seekge z  .

iter
seeklt f
seeklt h
seeklt p
seeklt t
seeklt u
seeklt z
----
seeklt f  a-f:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
seeklt h  f-t:{(#3,RANGEKEYSET,@3,bananas)}
seeklt p  f-t:{(#3,RANGEKEYSET,@3,bananas)}
seeklt t  f-t:{(#3,RANGEKEYSET,@3,bananas)}
seeklt u  t-z:{(#4,RANGEKEYSET,@2,oranges)}
seeklt z  t-z:{(#4,RANGEKEYSET,@2,oranges)}

# Test iteration with a reducer that collects keys across all spans that
# constitute a defragmented span. Abutting spans are always combined.

define
a-b:{(#3,RANGEDEL) (#2,RANGEDEL)}
b-c:{(#4,RANGEDEL) (#1,RANGEDEL)}
c-d:{(#5,RANGEDEL)}
e-f:{(#1,RANGEDEL)}
f-g:{(#2,RANGEDEL)}
----

iter equal=always reducer=collect
first
next
next
last
prev
prev
----
first     a-d:{(#5,RANGEDEL) (#4,RANGEDEL) (#3,RANGEDEL) (#2,RANGEDEL) (#1,RANGEDEL)}
next      e-g:{(#2,RANGEDEL) (#1,RANGEDEL)}
next      .
last      e-g:{(#2,RANGEDEL) (#1,RANGEDEL)}
prev      a-d:{(#5,RANGEDEL) (#4,RANGEDEL) (#3,RANGEDEL) (#2,RANGEDEL) (#1,RANGEDEL)}
prev      .

# Test defragmentation of non-empty (i.e. more than one value) fragments, while
# empty fragments are left untouched.

define
a-c:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
c-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
d-e:{}
e-f:{}
g-h:{(#1,RANGEKEYSET,@3,bananas)}
----

iter
first
next
next
next
next
----
first     a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
next      d-e:{}
next      e-f:{}
next      g-h:{(#1,RANGEKEYSET,@3,bananas)}
next      .

iter
last
prev
prev
prev
prev
----
last      g-h:{(#1,RANGEKEYSET,@3,bananas)}
prev      e-f:{}
prev      d-e:{}
prev      a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
prev      .

iter
seekge d
next
prev
seekge e
next
prev
prev
prev
----
seekge d  d-e:{}
next      e-f:{}
prev      d-e:{}
seekge e  e-f:{}
next      g-h:{(#1,RANGEKEYSET,@3,bananas)}
prev      e-f:{}
prev      d-e:{}
prev      a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}

iter
seeklt e
next
prev
seeklt f
next
prev
prev
prev
----
seeklt e  d-e:{}
next      e-f:{}
prev      d-e:{}
seeklt f  e-f:{}
next      g-h:{(#1,RANGEKEYSET,@3,bananas)}
prev      e-f:{}
prev      d-e:{}
prev      a-d:{(#3,RANGEKEYUNSET,@5) (#2,RANGEKEYSET,@5,apples) (#1,RANGEKEYSET,@3,bananas)}
