// Commented for the Learning branch package com.limegroup.bittorrent; import com.limegroup.gnutella.downloader.Interval; /** * A BTInterval clips out a range of bytes within a numbered file piece on BitTorrent. * * BitTorrent splits a file into many pieces. * The pieces are all the same size, except for the last one. * The piece size is 256 KB by default, and larger for very large files. * The first piece has piece number 0. * * A BTInterval object specifies a numbered piece, and describes a range within that piece. * BTInterval extends Interval, which describes a range. * Interval has two indices, low and high, that point to the first and last byte that make up the range. * * A range within a piece looks like this: * * piece number 57 * bbbbbbbbbbbbbbbbbbbbbbbbbbb * iiiiiii * low 6 -----> * high 12 -----------> * * The piece number is blockId, and the indices are inherited from Interval and named low and high. * * BitTorrent Request, Piece, and Cancel messages use the information a BTInterval message can hold. * The range that low and high clip out has to be within a single piece, and can't extend to more than one piece. */ public class BTInterval extends Interval { /** The piece number of the file block this interval is within. */ final Integer blockId; /** * The Java hash code we've calculated and saved for this BTInterval object. * This hash code isn't the same as the SHA1 hash of any file data. */ private int hashCode; /** * Make a new BTInterval object, which identifies a piece, and a range of bytes within it. * * @param low The distance in bytes from the start of the piece to the start of the interval * @param high The distance in bytes from the start of the piece to the end of the interval * @param id The piece number the low and high indices are in */ public BTInterval(long low, long high, int id) { // Save the range in the Interval object super(low, high); // Wrap the given piece number in an Integer object, and save it blockId = new Integer(id); } /** * Make a new BTInterval object, which identifies a piece, and a range of bytes within it. * * @param other An Interval object that clips out a range measured from the start of a piece * @param id The piece number the range is in */ public BTInterval(Interval other, int id) { // Call the previous constructor, getting the low and high indices from the given Interval object this(other.low, other.high, id); } /** * Make a new BTInterval object that identifies a single byte in a BitTorrent file. * * @param singleton The distance in bytes from the start of a piece to the byte we want to identify * @param id The piece number the byte is in */ public BTInterval(long singleton, int id) { // Call the Interval constructor, giving it the distance to the single byte super(singleton); // Sets both low and high to the distance singleton, making a range that is a single byte // Save the piece number in this new BTInterval object blockId = new Integer(id); } /** * Get the piece number this range is within. * * @return The BitTorrent file piece number */ public int getId() { // Get the number we stored in the blockId Integer object return blockId.intValue(); } /** * Determine if this BTInterval object is the same as a given one. * Compares their piece numbers, and their low and high ranges. * * @return True if they have the same information, false if they are different. */ public boolean equals(Object other) { // Make sure the given object is a BTInterval object if (!(other instanceof BTInterval)) return false; // Make sure the ranges are in the same pieces BTInterval o = (BTInterval)other; if (getId() != o.getId()) return false; // The piece numbers are different // Return true if the low and high ranges are both the same return super.equals(other); // Calls Interval.equals() } /** * Compute a hash code of this BTInternal object. * Java will use this hash code to spread out BTInterval objects in a collections class. * This isn't the same thing as the SHA1 hash of the file piece in the .torrent file. * * @return The hash code Java needs of this BTInternal object */ public int hashCode() { // If we haven't computed the hash code yet if (hashCode == 0) { // Compute it, using prime numbers like 17 and 37 hashCode = 17 * getId(); hashCode *= 37 + low; hashCode *= 37 + high; } // Return the hash code we saved return hashCode; } /** * Express this BTInternal object as a String. * If this BTInterval object represents the range 5-10 in piece number 25, composes text like "25:5-10". * * @return A String */ public String toString() { // Compose and return the text return getId() + ":" + super.toString(); } }