public void test_indexStuff(){
  final byte[] k3=i2k(3);
  final byte[] k5=i2k(5);
  final byte[] k7=i2k(7);
  final byte[] k9=i2k(9);
  final byte[] v3a=new byte[]{3};
  final byte[] v5a=new byte[]{5};
  final byte[] v7a=new byte[]{7};
  final byte[] v9a=new byte[]{9};
  final byte[] v3b=new byte[]{3,1};
  final byte[] v5b=new byte[]{5,1};
  final byte[] v7b=new byte[]{7,1};
  final byte[] v9b=new byte[]{9,1};
  final IRawStore store=new SimpleMemoryRawStore();
  final BTree btree1, btree2;
{
    final IndexMetadata md=new IndexMetadata(UUID.randomUUID());
    md.setBranchingFactor(3);
    md.setDeleteMarkers(true);
    md.setTupleSerializer(NOPTupleSerializer.INSTANCE);
    btree1=BTree.create(store,md);
    btree2=BTree.create(store,md.clone());
  }
  final FusedView view=new FusedView(new AbstractBTree[]{btree1,btree2});
  btree2.insert(k3,v3a);
  btree2.insert(k7,v7a);
  assertEquals(0,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(2,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3a,v7a},view.rangeIterator(null,null));
  assertTrue(view.contains(k3));
  assertFalse(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(v3a,view.putIfAbsent(k3,v3b));
  assertEquals(v3a,view.lookup(k3));
  assertEquals(null,view.insert(k5,v5a));
  assertEquals(1,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(3,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v5a},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3a,v5a,v7a},view.rangeIterator(null,null));
  assertTrue(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(v5a,view.putIfAbsent(k5,v5b));
  assertEquals(v5a,view.lookup(k5));
  assertEquals(v7a,view.insert(k7,v7b));
  assertEquals(2,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(4,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v5a,v7b},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3a,v5a,v7b},view.rangeIterator(null,null));
  assertTrue(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(v3a,view.remove(k3));
  assertEquals(3,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(5,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v5a,v7b},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{null,v5a,v7b},btree1.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v5a,v7b},view.rangeIterator(null,null));
  assertSameIterator(new byte[][]{null,v5a,v7b},view.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertFalse(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(v5a,view.insert(k5,v5b));
  assertEquals(3,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(5,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v5b,v7b},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{null,v5b,v7b},btree1.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v5b,v7b},view.rangeIterator(null,null));
  assertSameIterator(new byte[][]{null,v5b,v7b},view.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertFalse(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(null,view.insert(k3,v3b));
  assertEquals(3,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(5,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},btree1.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},view.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},view.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertTrue(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(v3b,view.putIfAbsent(k3,v3a));
  assertEquals(v3b,view.lookup(k3));
  assertEquals(v7b,view.putIfAbsent(k7,v7a));
  assertEquals(v7b,view.lookup(k7));
  assertEquals(v3b,view.remove(k3));
  assertEquals(3,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(5,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v5b,v7b},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{null,v5b,v7b},btree1.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v5b,v7b},view.rangeIterator(null,null));
  assertSameIterator(new byte[][]{null,v5b,v7b},view.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertFalse(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(null,view.putIfAbsent(k3,v3b));
  assertEquals(3,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(5,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},btree1.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},view.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b},view.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertTrue(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertEquals(null,view.putIfAbsent(k9,v9a));
  assertEquals(4,btree1.rangeCount(null,null));
  assertEquals(2,btree2.rangeCount(null,null));
  assertEquals(6,view.rangeCount(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b,v9a},btree1.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b,v9a},btree1.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertSameIterator(new byte[][]{v3a,v7a},btree2.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b,v9a},view.rangeIterator(null,null));
  assertSameIterator(new byte[][]{v3b,v5b,v7b,v9a},view.rangeIterator(null,null,0,IRangeQuery.DEFAULT | IRangeQuery.DELETED,null));
  assertTrue(view.contains(k3));
  assertTrue(view.contains(k5));
  assertTrue(view.contains(k7));
  assertTrue(view.contains(k9));
  assertEquals(v9a,view.putIfAbsent(k9,v9b));
  assertEquals(v9a,view.lookup(k9));
}

public void test_indexStuff ( ) { final byte [ ] k3 = i2k ( 3 ) ; final byte [ ] k5 = i2k ( 5 ) ; final byte [ ] k7 = i2k ( 7 ) ; final byte [ ] k9 = i2k ( 9 ) ; final byte [ ] v3a = new byte [ ] { 3 } ; final byte [ ] v5a = new byte [ ] { 5 } ; final byte [ ] v7a = new byte [ ] { 7 } ; final byte [ ] v9a = new byte [ ] { 9 } ; final byte [ ] v3b = new byte [ ] { 3 , 1 } ; final byte [ ] v5b = new byte [ ] { 5 , 1 } ; final byte [ ] v7b = new byte [ ] { 7 , 1 } ; final byte [ ] v9b = new byte [ ] { 9 , 1 } ; final IRawStore store = new SimpleMemoryRawStore ( ) ; final BTree btree1 , btree2 ; { final IndexMetadata md = new IndexMetadata ( UUID . randomUUID ( ) ) ; md . setBranchingFactor ( 3 ) ; md . setDeleteMarkers ( true ) ; md . setTupleSerializer ( NOPTupleSerializer . INSTANCE ) ; btree1 = BTree . create ( store , md ) ; btree2 = BTree . create ( store , md . clone ( ) ) ; } final FusedView view = new FusedView ( new AbstractBTree [ ] { btree1 , btree2 } ) ; btree2 . insert ( k3 , v3a ) ; btree2 . insert ( k7 , v7a ) ; assertEquals ( 0 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 2 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , view . rangeIterator ( null , null ) ) ; assertTrue ( view . contains ( k3 ) ) ; assertFalse ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( v3a , view . putIfAbsent ( k3 , v3b ) ) ; assertEquals ( v3a , view . lookup ( k3 ) ) ; assertEquals ( null , view . insert ( k5 , v5a ) ) ; assertEquals ( 1 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 3 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5a } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v5a , v7a } , view . rangeIterator ( null , null ) ) ; assertTrue ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( v5a , view . putIfAbsent ( k5 , v5b ) ) ; assertEquals ( v5a , view . lookup ( k5 ) ) ; assertEquals ( v7a , view . insert ( k7 , v7b ) ) ; assertEquals ( 2 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 4 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5a , v7b } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v5a , v7b } , view . rangeIterator ( null , null ) ) ; assertTrue ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( v3a , view . remove ( k3 ) ) ; assertEquals ( 3 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 5 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5a , v7b } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { null , v5a , v7b } , btree1 . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5a , v7b } , view . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { null , v5a , v7b } , view . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertFalse ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( v5a , view . insert ( k5 , v5b ) ) ; assertEquals ( 3 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 5 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5b , v7b } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { null , v5b , v7b } , btree1 . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5b , v7b } , view . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { null , v5b , v7b } , view . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertFalse ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( null , view . insert ( k3 , v3b ) ) ; assertEquals ( 3 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 5 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , btree1 . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , view . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , view . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertTrue ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( v3b , view . putIfAbsent ( k3 , v3a ) ) ; assertEquals ( v3b , view . lookup ( k3 ) ) ; assertEquals ( v7b , view . putIfAbsent ( k7 , v7a ) ) ; assertEquals ( v7b , view . lookup ( k7 ) ) ; assertEquals ( v3b , view . remove ( k3 ) ) ; assertEquals ( 3 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 5 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5b , v7b } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { null , v5b , v7b } , btree1 . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v5b , v7b } , view . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { null , v5b , v7b } , view . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertFalse ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( null , view . putIfAbsent ( k3 , v3b ) ) ; assertEquals ( 3 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 5 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , btree1 . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , view . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b } , view . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertTrue ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertEquals ( null , view . putIfAbsent ( k9 , v9a ) ) ; assertEquals ( 4 , btree1 . rangeCount ( null , null ) ) ; assertEquals ( 2 , btree2 . rangeCount ( null , null ) ) ; assertEquals ( 6 , view . rangeCount ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b , v9a } , btree1 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b , v9a } , btree1 . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3a , v7a } , btree2 . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b , v9a } , view . rangeIterator ( null , null ) ) ; assertSameIterator ( new byte [ ] [ ] { v3b , v5b , v7b , v9a } , view . rangeIterator ( null , null , 0 , IRangeQuery . DEFAULT | IRangeQuery . DELETED , null ) ) ; assertTrue ( view . contains ( k3 ) ) ; assertTrue ( view . contains ( k5 ) ) ; assertTrue ( view . contains ( k7 ) ) ; assertTrue ( view . contains ( k9 ) ) ; assertEquals ( v9a , view . putIfAbsent ( k9 , v9b ) ) ; assertEquals ( v9a , view . lookup ( k9 ) ) ; }
test verifies some of the basic principles of the fused view , including that a deleted entry in the first source will mask an undeleted entry in a secondary source . it also verifies that insert ( ) and remove ( ) return the current value under the key from the view ( not just from the btree to which the write operations are directed ) .
