|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectcom.limegroup.gnutella.downloader.ManagedDownloader
A smart download. Tries to get a group of similar files by delegating to HTTPDownloader objects. Does retries and resumes automatically. Reports all changes to a DownloadManager. This class is thread safe.
Smart downloads can use many policies, and these policies are free to change as allowed by the Downloader specification. This implementation provides swarmed downloads, the ability to download copies of the same file from multiple hosts. See the accompanying white paper for details.
Subclasses may refine the requery behavior by overriding the nextRequeryTime, newRequery(n), allowAddition(..), and addDownload(..) methods. MagnetDownloader also redefines the tryAllDownloads(..) method to handle default locations, and the getFileName() method to specify the completed file name.
Subclasses that pass this RemoteFileDesc arrays of size 0 MUST override the getFileName method, otherwise an assert will fail.
This class implements the Serializable interface but defines its own writeObject and readObject methods. This is necessary because parts of the ManagedDownloader (e.g., sockets) are inherently unserializable. For this reason, serializing and deserializing a ManagedDownloader M results in a ManagedDownloader M' that is the same as M except it is unconnected. Furthermore, it is necessary to explicitly call initialize(..) after reading a ManagedDownloader from disk.
Field Summary | |
protected static java.lang.String |
UNKNOWN_FILENAME
The value of an unknown filename - potentially overridden in subclasses |
Fields inherited from interface com.limegroup.gnutella.Downloader |
ABORTED, COMPLETE, CONNECTING, CORRUPT_FILE, COULDNT_MOVE_TO_LIBRARY, DOWNLOADING, GAVE_UP, HASHING, QUEUED, REMOTE_QUEUED, SAVING, WAITING_FOR_CONNECTIONS, WAITING_FOR_RESULTS, WAITING_FOR_RETRY, WAITING_FOR_USER |
Constructor Summary | |
ManagedDownloader(RemoteFileDesc[] files,
IncompleteFileManager ifc)
Creates a new ManagedDownload to download the given files. |
Method Summary | |
boolean |
acceptDownload(java.lang.String file,
java.net.Socket socket,
int index,
byte[] clientGUID)
Accepts a push download. |
boolean |
addDownload(RemoteFileDesc rfd,
boolean cache)
Attempts to add the given location to this. |
protected boolean |
addDownloadForced(RemoteFileDesc rfd,
boolean cache)
Like addDownload, but doesn't call allowAddition(..). |
protected boolean |
allowAddition(RemoteFileDesc other)
Returns true if 'other' should be accepted as a new download location. |
boolean |
conflicts(java.io.File incFile)
Returns true if this is using (or could use) the given incomplete file. |
boolean |
conflicts(RemoteFileDesc other)
Returns true if 'other' could conflict with one of the files in this. |
void |
discardCorruptDownload(boolean delete)
either treats a corrupt file as normal file and saves it, or discards the corruptFile, depending on the value of delete. |
void |
finish()
Cleans up information before this downloader is removed from memory. |
java.lang.String |
getAddress()
Returns the last address that this tried to connect to, or null if it hasn't tried any. |
int |
getAmountRead()
Return the amount read. |
float |
getAverageBandwidth()
returns the summed average of the downloads |
RemoteFileDesc |
getBrowseEnabledHost()
Returns a browse-enabled Endpoint instance for this Downloader. |
int |
getBusyHostCount()
|
Endpoint |
getChatEnabledHost()
Returns a chat-enabled Endpoint instance for this Downloader. |
int |
getContentLength()
Returns the size of this file in bytes, i.e., the total amount to download. |
java.io.File |
getDownloadFragment()
If this download is not yet complete, returns a copy of the first contiguous fragment of the incomplete file. |
protected long[] |
getFailedState(boolean deserialized,
long timeSpentWaiting)
This method is called when 1) all downloads sources failed 2) there are no busy hosts 3) there is no room for a requery Subclasses should override this method if they want to enforce special behavior before going to the GAVE_UP state. |
java.lang.String |
getFileName()
Returns the name of the current or last file this is downloading, or null in the rare case that this has no more files to download. |
java.util.Iterator |
getHosts()
Returns the locations from which this is currently downloading, as an iterator of Endpoint. |
float |
getMeasuredBandwidth()
Returns the throughput of this in kilobytes/sec (KB/s) between the last two calls to measureBandwidth, or 0.0 if unknown. |
int |
getNumberOfAlternateLocations()
Returns the number of alternate locations that this download is using. |
int |
getNumDownloaders()
|
int |
getPossibleHostCount()
Returns the amount of other hosts this download can possibly use. |
protected int |
getQueryCount(boolean deserializedFromDisk)
We need to offer this to subclasses to override because they might have specific behavior when deserialized from disk. |
int |
getQueuedHostCount()
|
java.lang.String |
getQueuePosition()
Returns the position of the download on the uploader, relavent only if the downloader is queueud. |
int |
getRemainingStateTime()
Returns an upper bound on the amount of time this will stay in the current state, in seconds. |
int |
getRetriesWaiting()
Returns the number of retries this is waiting for. |
int |
getState()
Accessors that delegate to dloader. |
java.lang.String |
getVendor()
Returns the vendor of the last downloading host. |
boolean |
hasBrowseEnabledHost()
Returns whether or not there is a browse-enabled host available for this Downloader. |
boolean |
hasChatEnabledHost()
Returns whether or not there is a chat-enabled host available for this Downloader. |
protected boolean |
hasRFD()
Certain subclasses would like to know whether we have at least one good RFD. |
void |
initialize(DownloadManager manager,
FileManager fileManager,
ActivityCallback callback,
boolean deserialized)
Initializes a ManagedDownloader read from disk. |
protected void |
initializeIncompleteFile(java.io.File incFile)
If incompleteFile has already been set, i.e., because a download is in progress, does nothing. |
void |
measureBandwidth()
Measures the data throughput since the last call to measureBandwidth. |
protected QueryRequest |
newRequery(int numRequeries)
Returns a new QueryRequest for requery purposes. |
protected boolean |
pauseForRequery(int numRequeries,
boolean deserializedFromDisk)
This dictates whether this downloader should wait for user input before spawning a Requery. |
boolean |
resume()
Resumes this. |
protected boolean |
shouldInitAltLocs(boolean deserializedFromDisk)
Subclasses should override this method when necessary. |
void |
stop()
Stops this. |
protected void |
tryAllDownloads(boolean deserializedFromDisk)
Actually does the download, finding duplicate files, trying all locations, resuming, waiting, and retrying as necessary. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected static final java.lang.String UNKNOWN_FILENAME
Constructor Detail |
public ManagedDownloader(RemoteFileDesc[] files, IncompleteFileManager ifc)
files
- the list of files to get. This stops after ANY of the
files is downloaded.ifc
- the repository of incomplete files for resumingMethod Detail |
public void initialize(DownloadManager manager, FileManager fileManager, ActivityCallback callback, boolean deserialized)
deserialized
- True if this downloader is being initialized after
being read from disk, false otherwise.protected void initializeIncompleteFile(java.io.File incFile)
public boolean conflicts(RemoteFileDesc other)
public boolean conflicts(java.io.File incFile)
protected QueryRequest newRequery(int numRequeries) throws CantResumeException
The default implementation includes all non-trivial keywords found in all RemoteFileDesc's in this, i.e., the INTERSECTION of all file names. A keyword is "non-trivial" if it is not a number of a common English article (e.g., "the"), a number (e.g., "2"), or the file extension. The query also includes all hashes for all RemoteFileDesc's, i.e., the UNION of all hashes. Since there are no more AUTOMATIC requeries, subclasses are advised to stop using createRequery(...). All attempts to 'requery' the network is spawned by the user, so use createQuery(...) . The reason we need to use createQuery is because DownloadManager.sendQuery() has a global limit on the number of requeries sent by LW (as IDed by the guid), but it allows normal queries to always be sent.
numRequeries
- the number of requeries that have already happened
CantResumeException
- if this doesn't know what to search forprotected int getQueryCount(boolean deserializedFromDisk)
protected boolean pauseForRequery(int numRequeries, boolean deserializedFromDisk) throws java.lang.InterruptedException
numRequeries
- The number of requeries sent so far.deserializedFromDisk
- If the downloader was deserialized from a
snapshot. May be useful for subclasses.
java.lang.InterruptedException
protected boolean shouldInitAltLocs(boolean deserializedFromDisk)
protected boolean allowAddition(RemoteFileDesc other)
public boolean addDownload(RemoteFileDesc rfd, boolean cache)
This method only adds rfd if allowAddition(rfd). Subclasses may wish to override this protected method to control the behavior.
rfd
- a new download candidate. Typically rfd will be similar or
same to some entry in this, but that is not required.
protected final boolean addDownloadForced(RemoteFileDesc rfd, boolean cache)
public boolean acceptDownload(java.lang.String file, java.net.Socket socket, int index, byte[] clientGUID) throws java.io.IOException
java.io.IOException
public void stop()
Downloader
stop
in interface Downloader
public boolean resume() throws AlreadyDownloadingException
Downloader
resume
in interface Downloader
AlreadyDownloadingException
public java.io.File getDownloadFragment()
Downloader
getDownloadFragment
in interface Downloader
protected long[] getFailedState(boolean deserialized, long timeSpentWaiting)
deserialized
- true if this downloader was initialized from disk,
false if it is brand new.timeSpentWaiting
- the millisecond time that the downloader has
spent in the failed state.
public void finish()
protected void tryAllDownloads(boolean deserializedFromDisk)
public int getNumberOfAlternateLocations()
getNumberOfAlternateLocations
in interface Downloader
public int getPossibleHostCount()
getPossibleHostCount
in interface Downloader
public int getBusyHostCount()
getBusyHostCount
in interface Downloader
public int getQueuedHostCount()
getQueuedHostCount
in interface Downloader
public void discardCorruptDownload(boolean delete)
Downloader
discardCorruptDownload
in interface Downloader
public int getState()
getState
in interface Downloader
public int getRemainingStateTime()
Downloader
getRemainingStateTime
in interface Downloader
public java.lang.String getFileName()
Downloader
getFileName
in interface Downloader
protected boolean hasRFD()
public int getContentLength()
Downloader
getContentLength
in interface Downloader
public int getAmountRead()
getAmountRead
in interface Downloader
public java.lang.String getAddress()
Downloader
getAddress
in interface Downloader
public java.util.Iterator getHosts()
Downloader
getHosts
in interface Downloader
public Endpoint getChatEnabledHost()
Downloader
getChatEnabledHost
in interface Downloader
public boolean hasChatEnabledHost()
Downloader
hasChatEnabledHost
in interface Downloader
public RemoteFileDesc getBrowseEnabledHost()
Downloader
getBrowseEnabledHost
in interface Downloader
public boolean hasBrowseEnabledHost()
Downloader
hasBrowseEnabledHost
in interface Downloader
public java.lang.String getQueuePosition()
Downloader
getQueuePosition
in interface Downloader
public int getNumDownloaders()
public java.lang.String getVendor()
Downloader
getVendor
in interface Downloader
public int getRetriesWaiting()
Downloader
getRetriesWaiting
in interface Downloader
public void measureBandwidth()
BandwidthTracker
measureBandwidth
in interface BandwidthTracker
public float getMeasuredBandwidth()
BandwidthTracker
getMeasuredBandwidth
in interface BandwidthTracker
public float getAverageBandwidth()
getAverageBandwidth
in interface BandwidthTracker
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |