- All Implemented Interfaces:
Comparable<PartialPiece>
Handles out-of-order chunk reception and manages a BitField tracking received chunks. Implements Comparable for prioritization by piece number and completeness.
Usage Notes: - Not thread-safe except for synchronized public methods. - Objects for the same piece should not be shared between peers. - Used extensively by PeerCoordinator and PeerState for request management.
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final ByteCacheCache supplying the chunk buffers.private final MetaInfoBEP 47: to recognize padding-only chunks and skip requesting them; may be null.private BitFieldBEP 47: per-piece padding sub-block mask, lazily computed; null until first use.private final BitFieldWhich chunks have arrived so far.private final byte[]In-memory storage if the piece is small.private static final intSize of a chunk part.private static final intLargest piece kept in memory by default.private static intThreshold below which pieces are kept in memory rather than a temp file, can be reduced dynamically.private intOffset of the next expected chunk start.private final intLength of the piece in bytes.private final PieceThe piece being filled in.private RandomAccessFileFile the piece data is written through.private static final intBEP 47: sub-block granularity for requests that straddle padding files.private final FileDirectory for the temp file of a large piece.private FileThe temp file holding the piece data.Constructor Summary
ConstructorsConstructorDescriptionPartialPiece(Piece piece, int len, File tempDir) A PartialPiece for the given piece with the specified length.PartialPiece(Piece piece, int len, File tempDir, MetaInfo meta) A PartialPiece for the given piece with the specified length.Method Summary
Modifier and TypeMethodDescriptionintcompareTo(PartialPiece other) Compares this piece with another by piece number, highest priority first, then by highest downloaded first.private voidCreates the temporary file and opens a RandomAccessFile.static voidLogs a debug message for this class.booleanEquality based on piece ID only.intReturns the total number of bytes downloaded in this piece, accurately accounting for holes.byte[]getHash()Computes and returns the SHA1 hash of the complete piece data.intReturns the length of the piece in bytes.intgetPiece()Returns the piece number.Creates a Request object for the next missing chunk in this piece.getRequest(int minOffset) Creates a Request object for the next missing chunk at or after the given offset.private voidhandleChunkReception(int subBlock, int offset, int len) Handles updating the bitfield and offset when a chunk is received.booleanhasData()Checks if any chunks of this piece have been downloaded.inthashCode()booleanhasSubBlock(int subBlock) Checks if the given sub-block index has been downloaded.static voidLogs an info message for this class.booleanChecks if the entire piece has been downloaded.(package private) booleanisPaddingSubBlock(int subBlock) True if the sub-block lies entirely within BEP 47 padding files.voidmarkSubBlock(int subBlock) Marks a sub-block as received without any data, for BEP 47 padding-only sub-blocks whose bytes are all zeros.voidread(DataInputStream din, int offset, int len, BandwidthListener bwl) Reads data from the input stream into this piece starting at offset.voidrelease()Releases temporary file and resources associated with this piece.toString()static voidLogs a warning message for this class.voidwrite(DataOutput out, int offset, int len) Writes piece data from the given offset and length to the output.
Field Details
piece
The piece being filled in.bs
private final byte[] bsIn-memory storage if the piece is small.pclen
private final int pclenLength of the piece in bytes.tempDir
Directory for the temp file of a large piece._meta
BEP 47: to recognize padding-only chunks and skip requesting them; may be null._paddingMask
BEP 47: per-piece padding sub-block mask, lazily computed; null until first use.tempfile
The temp file holding the piece data.raf
File the piece data is written through.bitfield
Which chunks have arrived so far.off
private int offOffset of the next expected chunk start.BUFSIZE
private static final int BUFSIZESize of a chunk part._cache
Cache supplying the chunk buffers.SUB_PARTSIZE
private static final int SUB_PARTSIZEBEP 47: sub-block granularity for requests that straddle padding files. A request is a run of consecutive real sub-blocks capped at PARTSIZE, so at most SUB_PARTSIZE bytes of padding are ever requested per boundary. A power of two, so it is the same class of block size as the short tail block every client accepts.Next logical step: request the exact real sub-range of a straddling sub-block instead of the whole sub-block, eliminating the remaining pad waste entirely. Risk: arbitrary (non power-of-two) block sizes are rejected by a few strict peers; reward: up to ~2K average pad bytes per boundary, tens of MB on pad-heavy torrents. Would require a per-peer fallback to sub-block requests.
MAX_IN_MEM
private static final int MAX_IN_MEMLargest piece kept in memory by default.- See Also:
maxInMem
private static int maxInMemThreshold below which pieces are kept in memory rather than a temp file, can be reduced dynamically.
Constructor Details
PartialPiece
A PartialPiece for the given piece with the specified length. If piece length exceeds threshold or memory is constrained, stores on disk.- Parameters:
piece- The Piece identifier objectlen- Length of this piece in bytes (must match piece length)tempDir- Directory for temporary file storage if needed
PartialPiece
A PartialPiece for the given piece with the specified length. If piece length exceeds threshold or memory is constrained, stores on disk.- Parameters:
piece- The Piece identifier objectlen- Length of this piece in bytes (must match piece length)tempDir- Directory for temporary file storage if neededmeta- the torrent meta info, for skipping BEP 47 padding-only chunks, or null
Method Details
createTemp
Creates the temporary file and opens a RandomAccessFile. Synchronized for safe concurrent use.- Throws:
IOException- if file creation or opening fails
getRequest
Creates a Request object for the next missing chunk in this piece. Returns null if the entire piece is complete. Chunks lying entirely within BEP 47 padding files are marked as received (their data is all zeros) and never requested.- Returns:
- the next Request for downloading or null if complete
getRequest
Creates a Request object for the next missing chunk at or after the given offset. Chunks lying entirely within BEP 47 padding files are marked as received (their data is all zeros) and never requested. A request is a run of consecutive real sub-blocks capped at PARTSIZE, so a chunk straddling a padding file is fetched at sub-block granularity, wasting at most SUB_PARTSIZE bytes of padding.- Parameters:
minOffset- byte offset to start scanning at, rounded up to a sub-block boundary; the caller advances it past the last request (callers pass 0 or off + len, both already sub-block aligned) so in-flight chunks are not re-requested- Returns:
- the next Request for downloading or null if complete
markSubBlock
public void markSubBlock(int subBlock) Marks a sub-block as received without any data, for BEP 47 padding-only sub-blocks whose bytes are all zeros. The in-memory buffer stays zero-filled, so the piece hashes correctly once the remaining sub-blocks arrive. Does not advance the sequential offset; the caller's scan does that.- Parameters:
subBlock- zero-based sub-block index
isPaddingSubBlock
boolean isPaddingSubBlock(int subBlock) True if the sub-block lies entirely within BEP 47 padding files. The padding layout of a piece never changes, so the sub-block mask is computed once on first use.- Parameters:
subBlock- zero-based sub-block index- Returns:
- true if the whole sub-block falls inside the padded range of the file, false if it carries real data
getPiece
public int getPiece()Returns the piece number.- Returns:
- piece number identifier
getLength
public int getLength()Returns the length of the piece in bytes.- Returns:
- the piece length; the last piece of a torrent may be shorter
isComplete
public boolean isComplete()Checks if the entire piece has been downloaded.- Returns:
- true if complete, else false
hasData
public boolean hasData()Checks if any chunks of this piece have been downloaded.- Returns:
- true if any data present, false if none
hasSubBlock
public boolean hasSubBlock(int subBlock) Checks if the given sub-block index has been downloaded.- Parameters:
subBlock- zero-based sub-block index- Returns:
- true if sub-block downloaded, false otherwise
getDownloaded
public int getDownloaded()Returns the total number of bytes downloaded in this piece, accurately accounting for holes.- Returns:
- number of bytes downloaded
getHash
Computes and returns the SHA1 hash of the complete piece data. Caller must ensure piece completeness and synchronize before calling.- Returns:
- the 20 byte SHA1 of the piece data
- Throws:
IOException- if data is incomplete or read fails
read
public void read(DataInputStream din, int offset, int len, BandwidthListener bwl) throws IOException Reads data from the input stream into this piece starting at offset. Marks chunks as downloaded in the bitfield. Handles out-of-order chunks by logging warnings.- Parameters:
din- input stream to read fromoffset- offset to read into the piece (must be multiple of chunk size)len- length of data to readbwl- bandwidth listener to report downloaded bytes- Throws:
IOException- on I/O errors or incorrect offset
handleChunkReception
private void handleChunkReception(int subBlock, int offset, int len) Handles updating the bitfield and offset when a chunk is received. Logs warnings if out-of-order chunks or holes are detected. Caller must synchronize before calling.- Parameters:
subBlock- first sub-block index received (may span several)offset- byte offset in the piece corresponding to the sub-blocklen- length of data in bytes
write
Writes piece data from the given offset and length to the output. Caller must synchronize on the output stream and piece for thread safety.- Parameters:
out- destination output to write data tooffset- offset in this piece to start writing fromlen- length of data to write- Throws:
IOException- on I/O failure
release
public void release()Releases temporary file and resources associated with this piece. Safe to call multiple times.compareTo
Compares this piece with another by piece number, highest priority first, then by highest downloaded first.- Specified by:
compareToin interfaceComparable<PartialPiece>- Parameters:
other- the other PartialPiece to compare to- Returns:
- negative if this piece has higher priority, positive if lower, zero if equal
hashCode
equals
toString
warn
Logs a warning message for this class.- Parameters:
s- warning message string
debug
Logs a debug message for this class.- Parameters:
s- debug message string
info
Logs an info message for this class.- Parameters:
s- info message string