root/hydranode/hncore/ed2k/downloadlist.h

Revision 2760, 6.8 kB (checked in by madcat, 3 years ago)

TCP server source requests are now split to 15-file-blocks, and sent at 4-minute intervals (max 75 files per 20 minutes). Rarest files are asked first.
UDP server source requests are now based on the rarity of the file, so that the rarest 25 or 31 files are always asked for. This should balance the average source count of large downloadlist, and ensure that all files have at least some sources.

Line 
1 /*
2  *  Copyright (C) 2004-2006 Alo Sarv <madcat_@users.sourceforge.net>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 /**
20  * \file downloadlist.h Interface for Download and DownloadList classes
21  */
22
23 #ifndef __ED2K_DOWNLOADLIST_H__
24 #define __ED2K_DOWNLOADLIST_H__
25
26 #include <hncore/ed2k/fwd.h>
27 #include <hnbase/hash.h>
28 #include <hnbase/event.h>
29 #include <hncore/fwd.h>
30 #include <boost/tuple/tuple.hpp>
31 #include <boost/signals.hpp>
32
33 namespace Donkey {
34
35 class DownloadList;
36 namespace Detail {
37         struct MIDownloadList;
38         struct DownloadIter;
39 }
40
41 /**
42  * Constants related to source-exchange times
43  */
44 enum {
45         SRCEXCH_CTIME = 40*60*1000, //!< one query per client per 40 minutes
46         SRCEXCH_FTIME = 5*60*1000   //!< one query per file per 5 minutes
47 };
48
49 /**
50  * Download is a wrapper class around ed2k-compatible PartData objects. It keeps
51  * track of which clients are offering this file, providing means of getting an
52  * overview of sources-per-file and cross-reference. Download objects are
53  * owned and managed by DownloadList class.
54  */
55 class Download : public Trackable {
56         //! identical to AnswerSources::Source
57         typedef boost::tuple<uint32_t, uint16_t, uint32_t, uint16_t> Source;
58         typedef std::set<Client*>::const_iterator CIter;
59 public:
60         uint32_t getSourceCount() const { return m_sources.size(); }
61         uint64_t getLastSrcExch() const { return m_lastSrcExch; }
62         PartData* getPartData() const { return m_partData; }
63         uint32_t getSourceLimit() const { return m_sourceLimit; }
64         Hash<ED2KHash> getHash() const { return m_hash; }
65         uint32_t getSize() const;
66
67         void addSource(Client *c) { m_sources.insert(c); }
68         void delSource(Client *c) { m_sources.erase(c); }
69         void setSourceLimit(uint32_t l) { m_sourceLimit = l; }
70         void setLastSrcExch(uint64_t t) { m_lastSrcExch = t; }
71
72         /**
73          * Generate a vector of sources, for sending with AnswerSources packet
74          * for example. Up to 500 sources may be returned.
75          */
76         std::vector<Source> getSources() const;
77
78         /**
79          * Check if a client is allowed to request sources for this file at
80          * this time.
81          *
82          * @param c      Client wishing to perform SourceExchange request
83          * @return       True if request is allowed, false otherwise
84          */
85         bool isSourceReqAllowed(Client *c) const;
86
87 private:
88         friend class DownloadList;
89         friend bool operator<(const Download &x, const Download &y) {
90                 return x.m_hash < y.m_hash;
91         }
92
93         /**
94          * Construct new Download; this is allowed only by DownloadList
95          *
96          * @param pd      PartData object to wrap around
97          * @param hash    Hash of the PartData object
98          */
99         Download(PartData *pd, const Hash<ED2KHash> &hash);
100
101         //! Destructor only allowed by DownloadList
102         ~Download();
103
104         //! Copy-construction is forbidden and not implemented
105         Download(const Download&);
106         //! Assignment operator is forbidden and not implemented
107         Download& operator=(const Download&);
108
109         /**
110          * Called prior to this object's destruction, signals all sources that
111          * download is being destroyed.
112          */
113         void destroy();
114
115         /**
116          * Signal handler for PartData::getLinks signal.
117          */
118         void getLink(PartData *file, std::vector<std::string>& links);
119
120         PartData*         m_partData;      //!< Implementation object
121         Hash<ED2KHash>    m_hash;          //!< hash of this file
122         std::set<Client*> m_sources;       //!< list of sources of this file
123         uint64_t          m_lastSrcExch;   //!< time of last source-exchange req
124         uint32_t          m_sourceLimit;   //!< limit sources
125 };
126
127 namespace Detail {
128         struct MIDownloadList;
129         struct MIDownloadListIterator;
130 }
131
132 /**
133  * DownloadList is a container for Download objects, wrapping around PartData
134  * objects. The purpose is to provide a simpler and faster interface than
135  * FilesList, and to provide some ed2k-specific features that FilesList cannot
136  * offer.
137  *
138  * Two public signals declared in this class indicate when new downloads are
139  * added or removed. Iterating on the list can be done using nested type Iter,
140  * and begin() / end() functions.
141  */
142 class DownloadList {
143 public:
144         /**
145          * Iterator for the underlying implementation.
146          */
147         class Iter {
148                 typedef boost::shared_ptr<Detail::MIDownloadListIterator> Impl;
149         public:
150                 Download& operator*();
151                 Download& operator->();
152                 void operator++();
153                 void operator--();
154                 bool operator==(const Iter&) const;
155                 bool operator!=(const Iter&) const;
156         private:
157                 friend class DownloadList;
158                 Iter(Impl impl);  //!< Only allowed by DownloadList
159                 Impl m_impl;      //!< Implementation object
160         };
161
162         /**
163          * \returns Iterator to the beginning of the list
164          */
165         Iter begin();
166
167         /**
168          * \return Returns iterator to one-past-end of the list
169          */
170         Iter end();
171
172         /**
173          * \returns Reference to the only instance of this Singleton class
174          */
175         static DownloadList& instance();
176
177         /**
178          * Find a specific download, searching with hash
179          *
180          * \param hash       Hash to be searched for
181          * \returns          Pointer to the file, or 0 if not found
182          */
183         Download* find(const Hash<ED2KHash> &hash) const;
184
185         /**
186          * Check the validity of a Download pointer
187          *
188          * @param ptr      Pointer to check validity
189          * @return         True if the pointer is valid; false otherwise
190          */
191         bool valid(Download *ptr) const;
192
193         //! Emitted when a download is removed
194         boost::signal<void (Download&)> onRemoved;
195         //! Emitted when a download is added
196         boost::signal<void (Download&)> onAdded;
197 private:
198         DownloadList();
199         DownloadList(const DownloadList&);
200         ~DownloadList();
201         DownloadList& operator=(const DownloadList&);
202
203         friend class ED2K;
204         void init();    //!< Initialize this class
205         void exit();    //!< Exit this class
206
207         void onPDEvent(PartData *pd, int evt);
208         void onSFEvent(SharedFile *sf, int evt);
209
210         /**
211          * Imports ed2k-compatible downloads from location
212          *
213          * @param p   Path to import from
214          */
215         void import(boost::filesystem::path p);
216
217         /**
218          * Attempts to import a single file
219          *
220          * @param p   File to be imported
221          */
222         void doImport(const boost::filesystem::path &p);
223
224         /**
225          * Try to add a download to the list. The file needs to have ed2k-
226          * compatible hashes and must be <4gb in size. If addition succeeds,
227          * onAdded() signal is emitted (but only if the download is in `running'
228          * state.
229          *
230          * \param file   File to be added
231          */
232         void tryAddFile(PartData *pd);
233
234         //! List implementation
235         boost::scoped_ptr<Detail::MIDownloadList> m_list;
236 };
237
238 } // end namespace Donkey
239
240 #endif
Note: See TracBrowser for help on using the browser.