BlockFileLoader: make stream of ByteBuffer available

* Inner class `BlockFileIterator` now iterates `ByteBuffer`
* `stream()` method calls `MessageSerializer.makeBlock()`
* `streamBuffers()` method makes raw `ByteBuffer` blocks available
* Add integration test `streamEntireBitcoindBlockChainAsBuffers()`
This commit is contained in:
Sean Gilligan 2023-08-15 09:54:24 -07:00 committed by Andreas Schildbach
parent 62e2e013c4
commit 59ab13680d
2 changed files with 24 additions and 8 deletions

View file

@ -119,10 +119,10 @@ public class BlockFileLoader implements Iterable<Block> {
/** /**
* Iterates all the blocks in a single block file. * Iterates all the blocks in a single block file.
*/ */
public class BlockFileIterator implements Iterator<Block> { public class BlockFileIterator implements Iterator<ByteBuffer> {
private final File file; private final File file;
private final BufferedInputStream currentFileStream; private final BufferedInputStream currentFileStream;
private org.bitcoinj.core.Block nextBlock = null; private ByteBuffer nextBlock = null;
public BlockFileIterator(File blockFile) throws FileNotFoundException { public BlockFileIterator(File blockFile) throws FileNotFoundException {
this.file = blockFile; this.file = blockFile;
@ -137,10 +137,10 @@ public class BlockFileLoader implements Iterable<Block> {
} }
@Override @Override
public Block next() throws NoSuchElementException { public ByteBuffer next() throws NoSuchElementException {
if (!hasNext()) if (!hasNext())
throw new NoSuchElementException(); throw new NoSuchElementException();
Block next = nextBlock; ByteBuffer next = nextBlock;
nextBlock = null; nextBlock = null;
return next; return next;
} }
@ -181,7 +181,7 @@ public class BlockFileLoader implements Iterable<Block> {
return; return;
} }
try { try {
nextBlock = serializer.makeBlock(ByteBuffer.wrap(dataBytes)); nextBlock = ByteBuffer.wrap(dataBytes);
} catch (ProtocolException e) { } catch (ProtocolException e) {
nextBlock = null; nextBlock = null;
} catch (Exception e) { } catch (Exception e) {
@ -204,17 +204,23 @@ public class BlockFileLoader implements Iterable<Block> {
} }
public Stream<Block> stream() { public Stream<Block> stream() {
return files.stream()
.flatMap(this::fileBlockStream)
.map(serializer::makeBlock);
}
public Stream<ByteBuffer> streamBuffers() {
return files.stream() return files.stream()
.flatMap(this::fileBlockStream); .flatMap(this::fileBlockStream);
} }
protected Stream<Block> fileBlockStream(File file) { protected Stream<ByteBuffer> fileBlockStream(File file) {
return StreamSupport.stream(fileBlockSpliterator(file), false); return StreamSupport.stream(fileBlockSpliterator(file), false);
} }
protected Spliterator<Block> fileBlockSpliterator(File file) { protected Spliterator<ByteBuffer> fileBlockSpliterator(File file) {
try { try {
Iterator<Block> iterator = new BlockFileIterator(file); Iterator<ByteBuffer> iterator = new BlockFileIterator(file);
int characteristics = Spliterator.DISTINCT | Spliterator.ORDERED; int characteristics = Spliterator.DISTINCT | Spliterator.ORDERED;
return Spliterators.spliteratorUnknownSize(iterator, characteristics); return Spliterators.spliteratorUnknownSize(iterator, characteristics);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {

View file

@ -84,4 +84,14 @@ public class BlockFileLoaderBitcoindTest {
System.out.println("Final block height: " + (blockCount - 1)); System.out.println("Final block height: " + (blockCount - 1));
assertTrue(blockCount > 1); assertTrue(blockCount > 1);
} }
@Test
public void streamEntireBitcoindBlockchainAsBuffers() {
BlockFileLoader loader = new BlockFileLoader(BitcoinNetwork.MAINNET, BlockFileLoader.getReferenceClientBlockFileList());
long blockCount = loader.streamBuffers().count();
System.out.println("Final block height: " + (blockCount - 1));
assertTrue(blockCount > 1);
}
} }