package org.openslx.bwlp.sat.fileserv; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.List; import org.apache.log4j.Logger; public class ChunkList { private static final Logger LOGGER = Logger.getLogger(ChunkList.class); /** * Chunks that are missing from the file */ private final List missingChunks = new LinkedList<>(); /** * Chunks that are currently being uploaded or hash-checked */ private final List pendingChunks = new LinkedList<>(); // Do we need to keep valid chunks, or chunks that failed too many times? public ChunkList(long fileSize, List sha1Sums) { FileChunk.createChunkList(missingChunks, fileSize, sha1Sums); } /** * Get a missing chunk, marking it pending. * * @return chunk marked as missing */ public synchronized FileChunk getMissing() { if (missingChunks.isEmpty()) return null; FileChunk c = missingChunks.remove(0); pendingChunks.add(c); return c; } /** * Mark a chunk currently transferring as successfully transfered. * * @param c The chunk in question */ public synchronized void markSuccessful(FileChunk c) { if (!pendingChunks.remove(c)) { LOGGER.warn("Inconsistent state: markTransferred called for Chunk " + c.toString() + ", but chunk is not marked as currently transferring!"); return; } } /** * Mark a chunk currently transferring or being hash checked as failed * transfer. This increases its fail count and re-adds it to the list of * missing chunks. * * @param c The chunk in question * @return Number of times transfer of this chunk failed */ public synchronized int markFailed(FileChunk c) { if (!pendingChunks.remove(c)) { LOGGER.warn("Inconsistent state: markTransferred called for Chunk " + c.toString() + ", but chunk is not marked as currently transferring!"); return -1; } // Add as first element so it will be re-transmitted immediately missingChunks.add(0, c); return c.incFailed(); } public synchronized boolean isComplete() { return missingChunks.isEmpty() && pendingChunks.isEmpty(); } }