package com.limegroup.gnutella.downloader; import org.limewire.collection.IntervalSet; import org.limewire.collection.Range; import org.limewire.core.api.download.DownloadPiecesInfo; class GnutellaPieceInfo implements DownloadPiecesInfo { private final IntervalSet written; private final IntervalSet active; private final IntervalSet available; private final long pieceSize; private final int pieceCount; private final int piecesCompletedCount; private final long length; public GnutellaPieceInfo(IntervalSet written, IntervalSet active, IntervalSet available, long pieceSize, long length) { this.written = written; this.active = active; this.available = available; this.pieceSize = pieceSize; this.length = length; this.piecesCompletedCount = aproximatePiecesCompleted(); if(length <= 0) { this.pieceCount = 0; } else { this.pieceCount = (int)Math.min(Integer.MAX_VALUE, Math.ceil((double)length / pieceSize)); } } @Override public int getNumPieces() { return pieceCount; } @Override public PieceState getPieceState(int piece) { long pieceStart = piece * pieceSize; long pieceEnd = Math.max(0, Math.min(pieceStart + pieceSize, length)-1); Range range = Range.createRange(pieceStart, pieceEnd); PieceState state; if(written.contains(range)) { state = PieceState.DOWNLOADED; } else if(active.containsAny(range)) { state = PieceState.ACTIVE; } else if(available.contains(range)) { if(written.containsAny(range)) { state = PieceState.PARTIAL; } else { state = PieceState.AVAILABLE; } } else { state = PieceState.UNAVAILABLE; } return state; } @Override public long getPieceSize() { return pieceSize; } @Override public int getNumPiecesCompleted() { return piecesCompletedCount; } /** * @return an approximation of the pieces currently completed. Calculated * by the number of bytes completed over the number of bytes in a piece. */ private int aproximatePiecesCompleted() { return (int)Math.floor((double)written.getSize() / pieceSize); } }