diff --git a/community/io/src/main/java/org/neo4j/io/pagecache/PagedFile.java b/community/io/src/main/java/org/neo4j/io/pagecache/PagedFile.java index c975b221e480d..6c0c90a0e1778 100644 --- a/community/io/src/main/java/org/neo4j/io/pagecache/PagedFile.java +++ b/community/io/src/main/java/org/neo4j/io/pagecache/PagedFile.java @@ -130,6 +130,11 @@ public interface PagedFile extends AutoCloseable */ int pageSize(); + /** + * Size of file, in bytes. + */ + long fileSize() throws IOException; + /** * Flush all dirty pages into the file channel, and force the file channel to disk. */ diff --git a/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPagedFile.java b/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPagedFile.java index 8abe914cad67a..6b1656d80a47b 100644 --- a/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPagedFile.java +++ b/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPagedFile.java @@ -172,6 +172,17 @@ public int pageSize() return filePageSize; } + @Override + public long fileSize() + { + final long lastPageId = getLastPageId(); + if ( lastPageId < 0 ) + { + return 0L; + } + return (lastPageId + 1) * pageSize(); + } + File file() { return swapper.file(); diff --git a/community/io/src/test/java/org/neo4j/adversaries/pagecache/AdversarialPagedFile.java b/community/io/src/test/java/org/neo4j/adversaries/pagecache/AdversarialPagedFile.java index 762dbcf4471e9..2143ef28044ab 100644 --- a/community/io/src/test/java/org/neo4j/adversaries/pagecache/AdversarialPagedFile.java +++ b/community/io/src/test/java/org/neo4j/adversaries/pagecache/AdversarialPagedFile.java @@ -69,6 +69,13 @@ public int pageSize() return delegate.pageSize(); } + @Override + public long fileSize() throws IOException + { + adversary.injectFailure( IllegalStateException.class ); + return delegate.fileSize(); + } + @Override public void flushAndForce() throws IOException { diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/DelegatingPagedFile.java b/community/io/src/test/java/org/neo4j/io/pagecache/DelegatingPagedFile.java index 52f8c9b9e08e8..8b0cca855a24b 100644 --- a/community/io/src/test/java/org/neo4j/io/pagecache/DelegatingPagedFile.java +++ b/community/io/src/test/java/org/neo4j/io/pagecache/DelegatingPagedFile.java @@ -52,6 +52,12 @@ public int pageSize() return delegate.pageSize(); } + @Override + public long fileSize() throws IOException + { + return delegate.fileSize(); + } + public void close() throws IOException { delegate.close(); diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/StubPagedFile.java b/community/io/src/test/java/org/neo4j/io/pagecache/StubPagedFile.java index 15f91b35292c2..b5b35a66535dc 100644 --- a/community/io/src/test/java/org/neo4j/io/pagecache/StubPagedFile.java +++ b/community/io/src/test/java/org/neo4j/io/pagecache/StubPagedFile.java @@ -53,6 +53,17 @@ public int pageSize() return exposedPageSize; } + @Override + public long fileSize() throws IOException + { + final long lastPageId = getLastPageId(); + if ( lastPageId < 0 ) + { + return 0L; + } + return (lastPageId + 1) * pageSize(); + } + @Override public void flushAndForce() throws IOException { diff --git a/enterprise/com/src/main/java/org/neo4j/com/storecopy/StoreCopyServer.java b/enterprise/com/src/main/java/org/neo4j/com/storecopy/StoreCopyServer.java index 428682178f01f..58104de2cb0c2 100644 --- a/enterprise/com/src/main/java/org/neo4j/com/storecopy/StoreCopyServer.java +++ b/enterprise/com/src/main/java/org/neo4j/com/storecopy/StoreCopyServer.java @@ -165,20 +165,25 @@ public RequestContext flushStoresAndStreamStoreFiles( String triggerName, StoreW // Read from paged file if mapping exists. Otherwise read through file system. final Optional optionalPagedFile = pageCache.getExistingMapping( file ); - try ( ReadableByteChannel fileChannel = optionalPagedFile.isPresent() ? - optionalPagedFile.get().openReadableByteChannel() : - fileSystem.open( file, "r" ) ) + if ( optionalPagedFile.isPresent() ) { - monitor.startStreamingStoreFile( file ); - writer.write( relativePath( storeDirectory, file ), fileChannel, - temporaryBuffer, file.length() > 0, recordSize ); - monitor.finishStreamingStoreFile( file ); + PagedFile pagedFile = optionalPagedFile.get(); + long fileSize = pagedFile.fileSize(); + try ( ReadableByteChannel fileChannel = pagedFile.openReadableByteChannel() ) + { + doWrite( writer, temporaryBuffer, file, recordSize, fileChannel, fileSize ); + } + finally + { + pagedFile.close(); + } } - finally + else { - if ( optionalPagedFile.isPresent() ) + try ( ReadableByteChannel fileChannel = fileSystem.open( file, "r" ) ) { - optionalPagedFile.get().close(); + long fileSize = file.length(); + doWrite( writer, temporaryBuffer, file, recordSize, fileChannel, fileSize ); } } } @@ -195,4 +200,13 @@ public RequestContext flushStoresAndStreamStoreFiles( String triggerName, StoreW throw new ServerFailureException( e ); } } + + private void doWrite( StoreWriter writer, ByteBuffer temporaryBuffer, File file, int recordSize, + ReadableByteChannel fileChannel, long fileSize ) throws IOException + { + monitor.startStreamingStoreFile( file ); + writer.write( relativePath( storeDirectory, file ), fileChannel, + temporaryBuffer, fileSize > 0, recordSize ); + monitor.finishStreamingStoreFile( file ); + } } diff --git a/enterprise/com/src/main/java/org/neo4j/com/storecopy/ToNetworkStoreWriter.java b/enterprise/com/src/main/java/org/neo4j/com/storecopy/ToNetworkStoreWriter.java index 962e907d6ca25..7ee763caca482 100644 --- a/enterprise/com/src/main/java/org/neo4j/com/storecopy/ToNetworkStoreWriter.java +++ b/enterprise/com/src/main/java/org/neo4j/com/storecopy/ToNetworkStoreWriter.java @@ -60,7 +60,6 @@ public long write( String path, ReadableByteChannel data, ByteBuffer temporaryBu totalWritten += 4; totalWritten += buffer.write( data ); buffer.close(); - } return totalWritten; }