package org.limewire.swarm.file.selection; import java.util.NoSuchElementException; import org.limewire.collection.IntervalSet; import org.limewire.collection.Range; import org.limewire.swarm.SwarmBlockSelector; /** * This selection strategy downloads the data in order. */ public class ContiguousSelectionStrategy implements SwarmBlockSelector { public Range selectAssignment(IntervalSet candidateBytes, IntervalSet neededBytes, long blockSize) throws NoSuchElementException { // Input validation if (blockSize < 1) throw new IllegalArgumentException("Block size cannot be " + blockSize); if (candidateBytes.isEmpty()) throw new NoSuchElementException(); Range candidate = candidateBytes.getFirst(); // Calculate what the high byte offset should be. // This will be at most blockSize-1 bytes greater than the low. long alignedHigh = alignHigh(candidate.getLow(), blockSize); // alignedHigh >= candidate.low, and therefore we // only have to check if alignedHigh > candidate.high. if (alignedHigh > candidate.getHigh()) alignedHigh = candidate.getHigh(); // Our ideal interval is [candidate.low, alignedHigh] // Optimize away creation of new objects, if possible Range ret = candidate; if (ret.getHigh() != alignedHigh) ret = Range.createRange(candidate.getLow(), alignedHigh); return ret; } /** Aligns location to one byte before the next highest block boundary */ protected long alignHigh(long location, long blockSize) { location += blockSize; location -= location % blockSize; return location - 1; } }