com.limegroup.gnutella
Class DownloadManager

java.lang.Object
  extended bycom.limegroup.gnutella.DownloadManager
All Implemented Interfaces:
BandwidthTracker

public class DownloadManager
extends java.lang.Object
implements BandwidthTracker

The list of all downloads in progress. DownloadManager has a fixed number of download slots given by the MAX_SIM_DOWNLOADS property. It is responsible for starting downloads and scheduling and queing them as needed. This class is thread safe.

As with other classes in this package, a DownloadManager instance may not be used until initialize(..) is called. The arguments to this are not passed in to the constructor in case there are circular dependencies.

DownloadManager provides ways to serialize download state to disk. Reads are initiated by RouterService, since we have to wait until the GUI is initiated. Writes are initiated by this, since we need to be notified of completed downloads. Downloads in the COULDNT_DOWNLOAD state are not serialized.


Field Summary
static long TIME_BETWEEN_REQUERIES
          The global minimum time between any two requeries, in milliseconds.
 
Constructor Summary
DownloadManager()
           
 
Method Summary
 void acceptDownload(java.net.Socket socket)
          Accepts the given socket for a push download to this host.
 java.lang.String conflicts(RemoteFileDesc[] files, ManagedDownloader dloader)
          Returns the name of any of the files in 'files' conflict with any of the downloads in this except for dloader, which may be null.
 Downloader download(java.io.File incompleteFile)
          Starts a resume download for the given incomplete file.
 Downloader download(RemoteFileDesc[] files, java.util.List alts, boolean overwrite)
          Tries to "smart download" any of the given files.
 Downloader download(java.lang.String query, java.lang.String richQuery, byte[] guid, MediaType type)
          Starts a "requery download", aka, a "wishlist download".
 Downloader download(URN urn, java.lang.String textQuery, java.lang.String filename, java.lang.String[] defaultURL)
          Creates a new MAGNET downloader.
 int downloadsInProgress()
           
 float getAverageBandwidth()
          returns the summed average of the downloads
 IncompleteFileManager getIncompleteFileManager()
          Returns the IncompleteFileManager used by this DownloadManager and all ManagedDownloaders.
 float getMeasuredBandwidth()
          Returns the total upload throughput, i.e., the sum over all uploads.
 int getNumActiveDownloads()
           
 int getNumIndividualDownloaders()
           
 int getNumWaitingDownloads()
           
 void handleQueryReply(QueryReply qr)
          Adds all responses (and alternates) in qr to any downloaders, if appropriate.
 void initialize()
          Initializes this manager.
 void measureBandwidth()
          Calls measureBandwidth on each uploader.
 void postGuiInit()
          Performs the slow, low-priority initialization tasks: reading in snapshots and scheduling snapshot checkpointing.
 boolean readSnapshot(java.io.File file)
          Reads the downloaders serialized in DOWNLOAD_SNAPSHOT_FILE and adds them to this, queued.
 void remove(ManagedDownloader downloader, boolean success)
          Removes downloader entirely from the list of current downloads.
 boolean sendPush(RemoteFileDesc file)
          Sends a push request for the given file.
 boolean sendQuery(ManagedDownloader requerier, QueryRequest query)
          Attempts to send the given requery to provide the given downloader with more sources to download.
 void waitForSlot(ManagedDownloader downloader)
          Blocks until a download slot has been assigned to downloader.
 void yieldSlot(ManagedDownloader downloader)
          Relinquishes downloader's slot.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

TIME_BETWEEN_REQUERIES

public static long TIME_BETWEEN_REQUERIES
The global minimum time between any two requeries, in milliseconds.

See Also:
com.limegroup.gnutella.downloader.ManagedDownloader#TIME_BETWEEN_REQUERIES
Constructor Detail

DownloadManager

public DownloadManager()
Method Detail

initialize

public void initialize()
Initializes this manager. This method must be called before any other methods are used.


postGuiInit

public void postGuiInit()
Performs the slow, low-priority initialization tasks: reading in snapshots and scheduling snapshot checkpointing.


getIncompleteFileManager

public IncompleteFileManager getIncompleteFileManager()
Returns the IncompleteFileManager used by this DownloadManager and all ManagedDownloaders.


downloadsInProgress

public int downloadsInProgress()

getNumIndividualDownloaders

public int getNumIndividualDownloaders()

getNumActiveDownloads

public int getNumActiveDownloads()

getNumWaitingDownloads

public int getNumWaitingDownloads()

readSnapshot

public boolean readSnapshot(java.io.File file)
Reads the downloaders serialized in DOWNLOAD_SNAPSHOT_FILE and adds them to this, queued. The queued downloads will restart immediately if slots are available. Returns false iff the file could not be read for any reason. THIS METHOD SHOULD BE CALLED BEFORE ANY GUI ACTION. It is public for testing purposes only!

Parameters:
file - the downloads.dat snapshot file

download

public Downloader download(RemoteFileDesc[] files,
                           java.util.List alts,
                           boolean overwrite)
                    throws FileExistsException,
                           AlreadyDownloadingException,
                           java.io.FileNotFoundException
Tries to "smart download" any of the given files.

If any of the files already being downloaded (or queued for downloaded) has the same temporary name as any of the files in 'files', throws AlreadyDownloadingException. Note, however, that this doesn't guarantee that a successfully downloaded file can be moved to the library.

If overwrite==false, then if any of the files already exists in the download directory, FileExistsException is thrown and no files are modified. If overwrite==true, the files may be overwritten.

Otherwise returns a Downloader that allows you to stop and resume this download. The ActivityCallback will also be notified of this download, so the return value can usually be ignored. The download begins immediately, unless it is queued. It stops after any of the files succeeds.

Throws:
FileExistsException
AlreadyDownloadingException
java.io.FileNotFoundException

download

public Downloader download(URN urn,
                           java.lang.String textQuery,
                           java.lang.String filename,
                           java.lang.String[] defaultURL)
                    throws java.lang.IllegalArgumentException,
                           AlreadyDownloadingException
Creates a new MAGNET downloader. Immediately tries to download from defaultURL, if specified. If that fails, or if defaultURL does not provide alternate locations, issues a requery with textQuery and urn, as provided. (At least one must be non-null.) If filename is specified, it will be used as the name of the complete file; otherwise it will be taken from any search results or guessed from defaultURLs.

Parameters:
urn - the hash of the file (exact topic), or null if unknown
textQuery - requery keywords (keyword topic), or null if unknown
filename - the final file name, or null if unknown
Throws:
AlreadyDownloadingException - couldn't download because the another downloader is getting the file
java.lang.IllegalArgumentException - both urn and textQuery are null

download

public Downloader download(java.io.File incompleteFile)
                    throws AlreadyDownloadingException,
                           CantResumeException
Starts a resume download for the given incomplete file.

Throws:
AlreadyDownloadingException - couldn't download because the another downloader is getting the file
CantResumeException - incompleteFile is not a valid incomplete file

download

public Downloader download(java.lang.String query,
                           java.lang.String richQuery,
                           byte[] guid,
                           MediaType type)
                    throws AlreadyDownloadingException
Starts a "requery download", aka, a "wishlist download". A "requery download" should be started when the user has not received any results for her query, and wants LimeWire to spawn a specialized Downloader that requeries the network until a 'appropriate' file is found.

Parameters:
query - The original query string.
richQuery - The original richQuery string.
guid - The guid associated with this query request.
type - The mediatype associated with this search.
Throws:
AlreadyDownloadingException

conflicts

public java.lang.String conflicts(RemoteFileDesc[] files,
                                  ManagedDownloader dloader)
Returns the name of any of the files in 'files' conflict with any of the downloads in this except for dloader, which may be null. Returns null if there are no conflicts. This is used before starting and resuming downloads.


handleQueryReply

public void handleQueryReply(QueryReply qr)
Adds all responses (and alternates) in qr to any downloaders, if appropriate.


acceptDownload

public void acceptDownload(java.net.Socket socket)
Accepts the given socket for a push download to this host. If the GIV is for a file that was never requested or has already been downloaded, this will deal with it appropriately. In any case this eventually closes the socket. Non-blocking.


waitForSlot

public void waitForSlot(ManagedDownloader downloader)
                 throws java.lang.InterruptedException
Blocks until a download slot has been assigned to downloader. Throws InterruptedException if the current thread is interrupted while waiting. If InterruptedException is thrown, this is not modified.

Throws:
java.lang.InterruptedException

yieldSlot

public void yieldSlot(ManagedDownloader downloader)
Relinquishes downloader's slot. This is idempotent and non-blocking.


remove

public void remove(ManagedDownloader downloader,
                   boolean success)
Removes downloader entirely from the list of current downloads. Notifies callback of the change in status.


sendQuery

public boolean sendQuery(ManagedDownloader requerier,
                         QueryRequest query)
Attempts to send the given requery to provide the given downloader with more sources to download. May not actually send the requery if it doing so would exceed the maximum requery rate.

Parameters:
query - the requery to send, which should have a marked GUID. Queries are subjected to global rate limiting iff they have marked requery GUIDs.
requerier - the downloader requesting more sources. Needed to ensure fair requery scheduling. This MUST be in the waiting list, i.e., it MUST NOT have a download slot.
Returns:
true iff the query was actually sent. If false is returned, the downloader should attempt to send the query later.

sendPush

public boolean sendPush(RemoteFileDesc file)
Sends a push request for the given file. Returns false iff no push could be sent, i.e., because no routing entry exists. That generally means you shouldn't send any more pushes for this file.

Parameters:
file - the RemoteFileDesc constructed from the query hit, containing data about the host we're pushing to
Returns:
true if the push was successfully sent, otherwise false

measureBandwidth

public void measureBandwidth()
Calls measureBandwidth on each uploader.

Specified by:
measureBandwidth in interface BandwidthTracker

getMeasuredBandwidth

public float getMeasuredBandwidth()
Returns the total upload throughput, i.e., the sum over all uploads.

Specified by:
getMeasuredBandwidth in interface BandwidthTracker

getAverageBandwidth

public float getAverageBandwidth()
returns the summed average of the downloads

Specified by:
getAverageBandwidth in interface BandwidthTracker