Fields Summary |
---|
private static final byte | PIECE_STATUS_NEEDED |
private static final byte | PIECE_STATUS_WRITTEN |
private static final byte | PIECE_STATUS_CHECKING |
private static final byte | PIECE_STATUS_MASK_DOWNLOADABLE |
private static final byte | PIECE_STATUS_MASK_NEEDS_CHECK |
private final DiskManagerHelper | diskManager |
private final int | pieceNumber |
private final short | nbBlocksthe number of blocks in this piece: can be short as this gives up to .5GB piece sizes with 16K blocks |
protected volatile boolean[] | written |
private byte | statusFlags |
private short | read_countit's *very* important to accurately maintain the "done" state of a piece. Currently the statusFlags
are updated in a non-thread-safe manner so a 'done' field is maintained seperatly. Synchronizing
access to statusFlags or done would cause a tremendous performance hit. |
private boolean | done |
Methods Summary |
---|
public boolean | calcDone()
return done;
|
public boolean | calcNeeded()
boolean filesNeeded =false;
final DMPieceList pieceList =diskManager.getPieceList(pieceNumber);
for (int i =0; i <pieceList.size(); i++)
{
final DiskManagerFileInfoImpl file =pieceList.get(i).getFile();
final long fileLength =file.getLength();
filesNeeded |=fileLength >0 &&file.getDownloaded() <fileLength &&!file.isSkipped();
}
if (filesNeeded)
{
statusFlags |=PIECE_STATUS_NEEDED;
return true;
}
statusFlags &=~PIECE_STATUS_NEEDED;
return false;
|
public void | clearNeeded()
statusFlags &=~PIECE_STATUS_NEEDED;
|
public int | getBlockSize(int blockNumber)
if ( blockNumber == nbBlocks -1 ){
int len = getLength() % DiskManager.BLOCK_SIZE;
if ( len != 0 ){
return( len );
}
}
return DiskManager.BLOCK_SIZE;
|
public int | getLength()
return( diskManager.getPieceLength( pieceNumber ));
|
public DiskManager | getManager()
return diskManager;
|
public int | getNbBlocks()
return nbBlocks;
|
public int | getNbWritten()
if (done)
return nbBlocks;
final boolean[] writtenRef =written;
if (writtenRef ==null)
return 0;
int res =0;
for (int i =0; i <nbBlocks; i++ )
{
if (writtenRef[i])
res++;
}
return res;
|
public int | getPieceNumber()
return pieceNumber;
|
public short | getReadCount()
return( read_count );
|
public java.lang.String | getString()
String text = "";
text += ( isNeeded()?"needed,":"" );
text += ( isDone()?"done,":"" );
if ( !isDone()){
text += ( isDownloadable()?"downable,":"" );
text += ( isWritten()?"written":("written " + getNbWritten())) + ",";
text += ( isChecking()?"checking":"" );
}
if ( text.endsWith(",")){
text = text.substring(0,text.length()-1);
}
return( text );
|
public boolean[] | getWritten()written[] can be null, in which case if the piece is Done,
all blocks are complete otherwise no blocks are complete
return written;
|
public boolean | isChecking()
return (statusFlags &PIECE_STATUS_CHECKING) !=0;
|
public boolean | isDone()
return done;
|
public boolean | isDownloadable()
return !done &&(statusFlags &PIECE_STATUS_MASK_DOWNLOADABLE) == PIECE_STATUS_NEEDED;
|
public boolean | isInteresting()
return !done &&(statusFlags &PIECE_STATUS_NEEDED) != 0;
|
public boolean | isNeeded()
return (statusFlags &PIECE_STATUS_NEEDED) !=0;
|
public boolean | isNeedsCheck()
return !done &&(statusFlags &PIECE_STATUS_MASK_NEEDS_CHECK) ==PIECE_STATUS_WRITTEN;
|
public boolean | isSkipped()
final DMPieceList pieceList =diskManager.getPieceList(pieceNumber);
for (int i =0; i <pieceList.size(); i++){
if ( !pieceList.get(i).getFile().isSkipped()){
return( false );
}
}
return( true );
|
public boolean | isWritten()
return (statusFlags &PIECE_STATUS_WRITTEN) !=0;
|
public boolean | isWritten(int blockNumber)
if (done)
return true;
final boolean[] writtenRef =written;
if (writtenRef ==null)
return false;
return writtenRef[blockNumber];
|
public void | reDownloadBlock(int blockNumber)
final boolean[] written_ref = written;
if (written_ref !=null)
{
written_ref[blockNumber] =false;
setDownloadable();
}
|
public void | reset()
setDownloadable();
written =null;
|
public void | setChecking()
statusFlags |=PIECE_STATUS_CHECKING;
|
public void | setDone(boolean b)
// we delegate this operation to the disk manager so it can synchronise the activity
if (b !=done)
{
diskManager.setPieceDone(this, b);
}
|
public void | setDoneSupport(boolean b)this is ONLY used by the disk manager to update the done state while synchronized
i.e. don't use it else where!
done =b;
if (done)
written =null;
|
public void | setDownloadable()
setDone(false);
statusFlags &=~(PIECE_STATUS_MASK_DOWNLOADABLE);
calcNeeded(); // Needed wouldn't have been calced before if couldn't download more
|
public void | setNeeded()
statusFlags |=PIECE_STATUS_NEEDED;
|
public void | setNeeded(boolean b)
if (b)
statusFlags |=PIECE_STATUS_NEEDED;
else
statusFlags &=~PIECE_STATUS_NEEDED;
|
public void | setReadCount(short c)
read_count = c;
|
public void | setWritten(int blockNumber)
if (written ==null)
written =new boolean[nbBlocks];
final boolean[] written_ref =written;
written_ref[blockNumber] =true;
for (int i =0; i <nbBlocks; i++)
{
if (!written_ref[i])
return;
}
statusFlags |=PIECE_STATUS_WRITTEN;
|