# Test a single level. define a-c:{(#10,RANGEKEYSET,@5,apples) (#10,RANGEKEYDEL) (#8,RANGEKEYUNSET,@1) (#4,RANGEKEYSET,@3,bananas)} c-d:{(#4,RANGEKEYSET,@3,coconut)} e-f:{(#20,RANGEKEYSET,@5,pineapple) (#20,RANGEKEYSET,@3,guava)} h-j:{(#22,RANGEKEYDEL) (#21,RANGEKEYSET,@5,peaches) (#21,RANGEKEYSET,@3,starfruit)} l-m:{(#2,RANGEKEYUNSET,@9) (#2,RANGEKEYUNSET,@5)} q-z:{(#14,RANGEKEYSET,@9,mangos)} ---- 1 levels iter first next next next next next next ---- a-c:{(#10,RANGEKEYSET,@5,apples) (#10,RANGEKEYDEL) (#8,RANGEKEYUNSET,@1) (#4,RANGEKEYSET,@3,bananas)} c-d:{(#4,RANGEKEYSET,@3,coconut)} e-f:{(#20,RANGEKEYSET,@5,pineapple) (#20,RANGEKEYSET,@3,guava)} h-j:{(#22,RANGEKEYDEL) (#21,RANGEKEYSET,@5,peaches) (#21,RANGEKEYSET,@3,starfruit)} l-m:{(#2,RANGEKEYUNSET,@9) (#2,RANGEKEYUNSET,@5)} q-z:{(#14,RANGEKEYSET,@9,mangos)} # Test snapshot filtering. iter snapshot=12 first next next next next next next ---- a-c:{(#10,RANGEKEYSET,@5,apples) (#10,RANGEKEYDEL) (#8,RANGEKEYUNSET,@1) (#4,RANGEKEYSET,@3,bananas)} c-d:{(#4,RANGEKEYSET,@3,coconut)} e-f:{} h-j:{} l-m:{(#2,RANGEKEYUNSET,@9) (#2,RANGEKEYUNSET,@5)} q-z:{} # Test error handling on seeks. iter probes=(0,ErrInjected,(Log "# inner.")) first last seek-ge boo seek-lt lemon ---- # inner.First() = nil err= # inner.Last() = nil err= # inner.SeekLT("boo") = nil err= # inner.SeekGE("lemon") = nil err= # Test error handling on steps. iter probes=(0,(If (Or OpNext OpPrev) ErrInjected noop),(Log "# inner.")) first next last prev ---- # inner.First() = a-c:{(#10,RANGEKEYSET,@5,apples) (#10,RANGEKEYDEL) (#8,RANGEKEYUNSET,@1) (#4,RANGEKEYSET,@3,bananas)} a-c:{(#10,RANGEKEYSET,@5,apples) (#10,RANGEKEYDEL) (#8,RANGEKEYUNSET,@1) (#4,RANGEKEYSET,@3,bananas)} # inner.Next() = nil err= # inner.Last() = q-z:{(#14,RANGEKEYSET,@9,mangos)} q-z:{(#14,RANGEKEYSET,@9,mangos)} # inner.Prev() = nil err= define b-d:{#10,RANGEKEYSET,@1,apples} e-h:{#8,RANGEKEYDEL} -- a-c:{#3,RANGEKEYUNSET,@1} h-k:{#5,RANGEKEYDEL} ---- 2 levels iter first next next next next next ---- a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} iter last prev prev prev prev prev ---- h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} # Test changing directions at each iterator position, reverse to forward. iter last next last prev next ---- h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} iter last prev prev next ---- h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} iter last prev prev prev next ---- h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} iter last prev prev prev prev next ---- h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} iter last prev prev prev prev prev next ---- h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} # Test changing directions at each iterator position, forward to reverse. iter first prev first next prev ---- a-b:{(#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} iter first next next prev ---- a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} iter first next next next prev ---- a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} iter first next next next next next prev ---- a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} iter first next next next next prev ---- a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} # Test SeekGE. Note that MergingIter's SeekGE implements the FragmentIterator's # SeekGE semantics. It returns the first fragment that covers a key ≥ the search # key. iter seek-ge cc ---- c-d:{(#10,RANGEKEYSET,@1,apples)} iter seek-ge 1 seek-ge a seek-ge b seek-ge bb ---- a-b:{(#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} iter seek-ge c seek-ge cc seek-ge e seek-ge f ---- c-d:{(#10,RANGEKEYSET,@1,apples)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} iter seek-ge h seek-ge i seek-ge k seek-ge l ---- h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} # Test SeekLT. Note that MergingIter's SeekLT implements the FragmentIterator's # SeekLT semantics. It returns the first fragment with a Start key < the search # key, NOT the first fragment that covers a key < the search key. # # NB: seek-lt bb finds b-c#3.RANGEKEYUNSET (the last fragment with the bounds # [b,c), unlike the above seek-ge b which finds the first). iter seek-lt b ---- a-b:{(#3,RANGEKEYUNSET,@1)} iter seek-lt 1 seek-lt a seek-lt aa seek-lt b seek-lt bb seek-lt c ---- a-b:{(#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} iter seek-lt cc seek-lt d seek-lt dd seek-lt e seek-lt ee seek-lt h seek-lt hh seek-lt k seek-lt z ---- c-d:{(#10,RANGEKEYSET,@1,apples)} c-d:{(#10,RANGEKEYSET,@1,apples)} c-d:{(#10,RANGEKEYSET,@1,apples)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-h:{(#8,RANGEKEYDEL)} e-h:{(#8,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} # Test error handling with multiple levels. Inject errors in all operations on # the first iterator, and none of the second iterator. iter probes=(0,ErrInjected,(Log "# a.")) probes=(1,(Log "# b.")) seek-ge a seek-ge b seek-ge c seek-ge d seek-ge e seek-ge f seek-ge g seek-ge h seek-ge i seek-ge j seek-ge k seek-ge z ---- # a.SeekLT("a") = nil # b.SeekLT("a") = nil err= # a.SeekLT("b") = nil # b.SeekLT("b") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("c") = nil # b.SeekLT("c") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("d") = nil # b.SeekLT("d") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("e") = nil # b.SeekLT("e") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("f") = nil # b.SeekLT("f") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("g") = nil # b.SeekLT("g") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("h") = nil # b.SeekLT("h") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekLT("i") = nil # b.SeekLT("i") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekLT("j") = nil # b.SeekLT("j") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekLT("k") = nil # b.SeekLT("k") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekLT("z") = nil # b.SeekLT("z") = h-k:{(#5,RANGEKEYDEL)} err= # Test the same as above, but with errors injected on the second iterator. iter probes=(0,(Log "# a.")) probes=(1,ErrInjected,(Log "# b.")) seek-ge a seek-ge b seek-ge c seek-ge d seek-ge e seek-ge f seek-ge g seek-ge h seek-ge i seek-ge j seek-ge k seek-ge z ---- # a.SeekLT("a") = nil # b.SeekLT("a") = nil err= # a.SeekLT("b") = nil # b.SeekLT("b") = nil err= # a.SeekLT("c") = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.SeekLT("c") = nil err= # a.SeekLT("d") = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.SeekLT("d") = nil err= # a.SeekLT("e") = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.SeekLT("e") = nil err= # a.SeekLT("f") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("f") = nil err= # a.SeekLT("g") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("g") = nil err= # a.SeekLT("h") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("h") = nil err= # a.SeekLT("i") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("i") = nil err= # a.SeekLT("j") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("j") = nil err= # a.SeekLT("k") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("k") = nil err= # a.SeekLT("z") = e-h:{(#8,RANGEKEYDEL)} # b.SeekLT("z") = nil err= # Test SeekLTs with errors injected on the first iterator. iter probes=(0,ErrInjected,(Log "# a.")) probes=(1,(Log "# b.")) seek-lt a seek-lt b seek-lt c seek-lt d seek-lt e seek-lt f seek-lt g seek-lt h seek-lt i seek-lt j seek-lt k seek-lt z ---- # a.SeekGE("a") = nil # b.SeekGE("a") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekGE("b") = nil # b.SeekGE("b") = a-c:{(#3,RANGEKEYUNSET,@1)} err= # a.SeekGE("c") = nil # b.SeekGE("c") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("d") = nil # b.SeekGE("d") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("e") = nil # b.SeekGE("e") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("f") = nil # b.SeekGE("f") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("g") = nil # b.SeekGE("g") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("h") = nil # b.SeekGE("h") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("i") = nil # b.SeekGE("i") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("j") = nil # b.SeekGE("j") = h-k:{(#5,RANGEKEYDEL)} err= # a.SeekGE("k") = nil # b.SeekGE("k") = nil err= # a.SeekGE("z") = nil # b.SeekGE("z") = nil err= # Test SeekLTs with errors injected on the second iterator. iter probes=(0,(Log "# a.")) probes=(1,ErrInjected,(Log "# b.")) seek-lt a seek-lt b seek-lt c seek-lt d seek-lt e seek-lt f seek-lt g seek-lt h seek-lt i seek-lt j seek-lt k seek-lt z ---- # a.SeekGE("a") = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.SeekGE("a") = nil err= # a.SeekGE("b") = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.SeekGE("b") = nil err= # a.SeekGE("c") = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.SeekGE("c") = nil err= # a.SeekGE("d") = e-h:{(#8,RANGEKEYDEL)} # b.SeekGE("d") = nil err= # a.SeekGE("e") = e-h:{(#8,RANGEKEYDEL)} # b.SeekGE("e") = nil err= # a.SeekGE("f") = e-h:{(#8,RANGEKEYDEL)} # b.SeekGE("f") = nil err= # a.SeekGE("g") = e-h:{(#8,RANGEKEYDEL)} # b.SeekGE("g") = nil err= # a.SeekGE("h") = nil # b.SeekGE("h") = nil err= # a.SeekGE("i") = nil # b.SeekGE("i") = nil err= # a.SeekGE("j") = nil # b.SeekGE("j") = nil err= # a.SeekGE("k") = nil # b.SeekGE("k") = nil err= # a.SeekGE("z") = nil # b.SeekGE("z") = nil err= # Test error handling during Next. iter probes=(0,(If OpNext ErrInjected noop),(Log "# a.")) probes=(1,(Log "# b.")) first next next next ---- # a.First() = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.First() = a-c:{(#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} # b.Next() = h-k:{(#5,RANGEKEYDEL)} c-d:{(#10,RANGEKEYSET,@1,apples)} # a.Next() = nil err= iter probes=(0,(Log "# a.")) probes=(1,(If OpNext ErrInjected noop),(Log "# b.")) first next next ---- # a.First() = b-d:{(#10,RANGEKEYSET,@1,apples)} # b.First() = a-c:{(#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} # b.Next() = nil err= # Test error handling during Prev. iter probes=(0,(If OpPrev ErrInjected noop),(Log "# a.")) probes=(1,(Log "# b.")) last prev prev ---- # a.Last() = e-h:{(#8,RANGEKEYDEL)} # b.Last() = h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} # b.Prev() = a-c:{(#3,RANGEKEYUNSET,@1)} e-h:{(#8,RANGEKEYDEL)} # a.Prev() = nil err= iter probes=(0,(Log "# a.")) probes=(1,(If OpPrev ErrInjected noop),(Log "# b.")) last prev ---- # a.Last() = e-h:{(#8,RANGEKEYDEL)} # b.Last() = h-k:{(#5,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} # b.Prev() = nil err= define a-f:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} k-s:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} ---- 1 levels iter first prev next ---- a-f:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} a-f:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} iter last next prev ---- k-s:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} k-s:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} define w-x:{(#5,RANGEKEYDEL) (#3,RANGEKEYDEL)} x-z:{(#5,RANGEKEYDEL)} -- w-y:{(#4,RANGEKEYDEL) (#1,RANGEKEYDEL)} ---- 2 levels iter last next prev first prev next ---- y-z:{(#5,RANGEKEYDEL)} y-z:{(#5,RANGEKEYDEL)} w-x:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL) (#3,RANGEKEYDEL) (#1,RANGEKEYDEL)} w-x:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL) (#3,RANGEKEYDEL) (#1,RANGEKEYDEL)} iter seek-ge x prev seek-ge xray prev ---- x-y:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL) (#1,RANGEKEYDEL)} w-x:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL) (#3,RANGEKEYDEL) (#1,RANGEKEYDEL)} x-y:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL) (#1,RANGEKEYDEL)} w-x:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL) (#3,RANGEKEYDEL) (#1,RANGEKEYDEL)} define il-qb:{(#10,RANGEKEYDEL)} sn-wn:{(#10,RANGEKEYDEL)} -- qt-kh:{(#9,RANGEKEYDEL) (#8,RANGEKEYDEL) (#7,RANGEKEYDEL)} ky-sv:{(#8,RANGEKEYDEL) (#7,RANGEKEYDEL)} -- as-fz:{(#5,RANGEKEYDEL) (#4,RANGEKEYDEL)} hh-ir:{(#4,RANGEKEYDEL)} rf-yx:{(#4,RANGEKEYDEL)} ---- 3 levels iter seek-ge qp next next next next next seek-ge yz prev ---- qb-rf:{(#8,RANGEKEYDEL) (#7,RANGEKEYDEL)} rf-sn:{(#8,RANGEKEYDEL) (#7,RANGEKEYDEL) (#4,RANGEKEYDEL)} sn-sv:{(#10,RANGEKEYDEL) (#8,RANGEKEYDEL) (#7,RANGEKEYDEL) (#4,RANGEKEYDEL)} sv-wn:{(#10,RANGEKEYDEL) (#4,RANGEKEYDEL)} wn-yx:{(#4,RANGEKEYDEL)} wn-yx:{(#4,RANGEKEYDEL)} # Test that empty spans from child iterators are preserved define b-d:{#10,RANGEKEYSET,@1,apples} e-f:{} g-h:{#8,RANGEKEYDEL} -- a-c:{#3,RANGEKEYUNSET,@1} h-k:{#5,RANGEKEYDEL} k-m:{} ---- 2 levels iter first next next next next next next next ---- a-b:{(#3,RANGEKEYUNSET,@1)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} c-d:{(#10,RANGEKEYSET,@1,apples)} e-f:{} g-h:{(#8,RANGEKEYDEL)} h-k:{(#5,RANGEKEYDEL)} k-m:{} iter last prev prev prev prev prev prev prev ---- k-m:{} h-k:{(#5,RANGEKEYDEL)} g-h:{(#8,RANGEKEYDEL)} e-f:{} c-d:{(#10,RANGEKEYSET,@1,apples)} b-c:{(#10,RANGEKEYSET,@1,apples) (#3,RANGEKEYUNSET,@1)} a-b:{(#3,RANGEKEYUNSET,@1)}