From 9c41de54bb7c80349c45d34bd53e734ee3e88b5b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 28 Jan 2016 17:02:31 +0100 Subject: Make hashing classes more robust, report complete blocks without hash info as hashing --- .../org/openslx/filetransfer/util/ChunkList.java | 26 +++++++++++++++++----- .../org/openslx/filetransfer/util/ChunkStatus.java | 2 +- .../org/openslx/filetransfer/util/FileChunk.java | 17 +++++++++++++- .../org/openslx/filetransfer/util/HashChecker.java | 9 ++++++-- 4 files changed, 44 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/main/java/org/openslx/filetransfer/util/ChunkList.java b/src/main/java/org/openslx/filetransfer/util/ChunkList.java index c71777b..d0233ac 100644 --- a/src/main/java/org/openslx/filetransfer/util/ChunkList.java +++ b/src/main/java/org/openslx/filetransfer/util/ChunkList.java @@ -33,6 +33,11 @@ public class ChunkList // 0 = complete, 1 = missing, 2 = uploading, 3 = queued for copying, 4 = copying private final ByteBuffer statusArray; + + /** + * True if at least one block has a checksum set + */ + private boolean hasChecksum = false; // Do we need to keep valid chunks, or chunks that failed too many times? @@ -56,9 +61,12 @@ public class ChunkList for ( byte[] sum : sha1Sums ) { if ( index >= allChunks.size() ) break; - if ( sum == null ) - continue; - allChunks.get( index ).setSha1Sum( sum ); + if ( sum != null ) { + allChunks.get( index ).setSha1Sum( sum ); + if ( !hasChecksum ) { + hasChecksum = true; + } + } index++; } } @@ -91,7 +99,13 @@ public class ChunkList { byte[] array = statusArray.array(); for ( int i = 0; i < array.length; ++i ) { - array[i] = allChunks.get( i ).getStatus().val; + FileChunk chunk = allChunks.get( i ); + ChunkStatus status = chunk.getStatus(); + if ( hasChecksum && status == ChunkStatus.COMPLETE && chunk.getSha1Sum() == null ) { + array[i] = ChunkStatus.HASHING.val; + } else { + array[i] = chunk.getStatus().val; + } } return statusArray; } @@ -136,7 +150,7 @@ public class ChunkList + ", but chunk is not marked as currently transferring!" ); return; } - c.setStatus( ChunkStatus.COMPETE ); + c.setStatus( ChunkStatus.COMPLETE ); completeChunks.add( c ); this.notifyAll(); } @@ -199,7 +213,7 @@ public class ChunkList sb.append( '+' ); //// switch ( chunk.status ) { - case COMPETE: + case COMPLETE: sb.append( 'C' ); break; case COPYING: diff --git a/src/main/java/org/openslx/filetransfer/util/ChunkStatus.java b/src/main/java/org/openslx/filetransfer/util/ChunkStatus.java index fd54e34..f2a73c5 100644 --- a/src/main/java/org/openslx/filetransfer/util/ChunkStatus.java +++ b/src/main/java/org/openslx/filetransfer/util/ChunkStatus.java @@ -3,7 +3,7 @@ package org.openslx.filetransfer.util; public enum ChunkStatus { // 0 = complete, 1 = missing, 2 = uploading, 3 = queued for copying, 4 = copying, 5 = hashing - COMPETE( 0 ), + COMPLETE( 0 ), MISSING( 1 ), UPLOADING( 2 ), QUEUED_FOR_COPY( 3 ), diff --git a/src/main/java/org/openslx/filetransfer/util/FileChunk.java b/src/main/java/org/openslx/filetransfer/util/FileChunk.java index 36892fb..4b6ee74 100644 --- a/src/main/java/org/openslx/filetransfer/util/FileChunk.java +++ b/src/main/java/org/openslx/filetransfer/util/FileChunk.java @@ -16,6 +16,7 @@ public class FileChunk private int failCount = 0; protected byte[] sha1sum; protected ChunkStatus status = ChunkStatus.MISSING; + private boolean writtenToDisk = false; public FileChunk( long startOffset, long endOffset, byte[] sha1sum ) { @@ -32,7 +33,7 @@ public class FileChunk if ( this.sha1sum != null || sha1sum == null || sha1sum.length != SHA1_LENGTH ) return; this.sha1sum = sha1sum; - if ( this.status == ChunkStatus.COMPETE ) { + if ( this.status == ChunkStatus.COMPLETE ) { this.status = ChunkStatus.HASHING; } } @@ -69,9 +70,23 @@ public class FileChunk return status; } + /** + * Whether the chunk of data this chunk refers to has been written to + * disk and is assumed to be valid/up to date. + */ + public synchronized boolean isWrittenToDisk() + { + return writtenToDisk; + } + protected synchronized void setStatus( ChunkStatus status ) { if ( status != null ) { + if ( status == ChunkStatus.COMPLETE ) { + this.writtenToDisk = true; + } else if ( status == ChunkStatus.MISSING ) { + this.writtenToDisk = false; + } this.status = status; } } diff --git a/src/main/java/org/openslx/filetransfer/util/HashChecker.java b/src/main/java/org/openslx/filetransfer/util/HashChecker.java index 8bf97a4..5b647aa 100644 --- a/src/main/java/org/openslx/filetransfer/util/HashChecker.java +++ b/src/main/java/org/openslx/filetransfer/util/HashChecker.java @@ -43,6 +43,7 @@ public class HashChecker return; invalid = true; } + LOGGER.debug( "Marking all queued chunks as failed" ); for ( ;; ) { HashTask task = queue.poll(); if ( task == null ) @@ -132,7 +133,6 @@ public class HashChecker continue; } catch ( InterruptedException e ) { LOGGER.info( "Interrupted while waiting for hash task", e ); - threadFailed( this ); break; } // Calculate digest @@ -141,10 +141,15 @@ public class HashChecker HashResult result = Arrays.equals( digest, task.chunk.getSha1Sum() ) ? HashResult.VALID : HashResult.INVALID; execCallback( task, result ); if ( extraThread && queue.isEmpty() ) { - LOGGER.info( "Stopping additional hash checker" ); break; } } + if ( extraThread ) { + LOGGER.info( "Stopped additional hash checker" ); + } else { + LOGGER.info( "Stopped MAIN hash checker" ); + } + threadFailed( this ); } } -- cgit v1.2.3-55-g7522