BLink implements AutoCloseable, Page.Owner { public Stream<Entry<K, V>> scan(K from, K to) { Node<K, V> n; @SuppressWarnings("unchecked") Deque<ResultCouple<K, V>> descent = DummyDeque.INSTANCE; if (from == null) { lock_anchor(READ_LOCK); n = anchor.first; unlock_anchor(READ_LOCK); lock(n, READ_LOCK); } else { try { n = locate_leaf(from, READ_LOCK, descent); } catch (IOException ex) { throw new UncheckedIOException("failed to scan from " + from + " to " + to, ex); } } return StreamSupport.stream( Spliterators.spliteratorUnknownSize( new ScanIterator(n, from, from != null, to, false), 0), false); } BLink(
            long maxSize, SizeEvaluator<K, V> evaluator,
            PageReplacementPolicy policy, BLinkIndexDataStorage<K, V> storage
    );  BLink(
            long maxSize, SizeEvaluator<K, V> evaluator,
            PageReplacementPolicy policy, BLinkIndexDataStorage<K, V> storage,
            BLinkMetadata<K> metadata
    ); @Override void close(); void truncate(); long size(); long getUsedMemory(); int nodes(); @Override void unload(long pageId); BLinkMetadata<K> checkpoint(); V search(K v); Stream<Entry<K, V>> scan(K from, K to); Stream<Entry<K, V>> scan(K from, K to, boolean toInclusive); boolean insert(K v, V e, V expected); V insert(K v, V e); V delete(K v); @Override String toString(); @SuppressWarnings("unchecked") String toStringFull();  }
@Test public void testScan() throws Exception { BLinkIndexDataStorage<Sized<Long>, Long> storage = new DummyBLinkIndexDataStorage<>(); try (BLink<Sized<Long>, Long> blink = new BLink<>(2048L, new LongSizeEvaluator(), new RandomPageReplacementPolicy(10), storage)) { final long inserts = 100; for (long l = 0; l < inserts; l++) { blink.insert(Sized.valueOf(l), l); } BLinkMetadata<Sized<Long>> metadata = blink.checkpoint(); assertNotEquals(1, metadata.nodes.size()); long offset = 10; for (long l = 0; l < inserts - offset; l++) { Stream<Entry<Sized<Long>, Long>> stream = blink.scan(Sized.valueOf(l), Sized.valueOf(l + offset)); Holder<Long> h = new Holder<>(l); Holder<Long> count = new Holder<>(0L); StringBuilder builder = new StringBuilder(); stream.forEach(entry -> { assertEquals(h.value, entry.getValue()); h.value++; count.value++; builder.append(entry.getValue()).append(", "); }); builder.setLength(builder.length() - 2); System.out.println("start " + l + " end " + (l + offset) + " -> " + builder); assertEquals(offset, (long) count.value); } } }