1 // libTorrent - BitTorrent library 2 // Copyright (C) 2005-2011, Jari Sundell 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 // In addition, as a special exception, the copyright holders give 19 // permission to link the code of portions of this program with the 20 // OpenSSL library under certain conditions as described in each 21 // individual source file, and distribute linked combinations 22 // including the two. 23 // 24 // You must obey the GNU General Public License in all respects for 25 // all of the code used other than OpenSSL. If you modify file(s) 26 // with this exception, you may extend this exception to your version 27 // of the file(s), but you are not obligated to do so. If you do not 28 // wish to do so, delete this exception statement from your version. 29 // If you delete this exception statement from all source files in the 30 // program, then also delete it here. 31 // 32 // Contact: Jari Sundell <jaris@ifi.uio.no> 33 // 34 // Skomakerveien 33 35 // 3185 Skoppum, NORWAY 36 37 #ifndef LIBTORRENT_PEER_RESOURCE_MANAGER_H 38 #define LIBTORRENT_PEER_RESOURCE_MANAGER_H 39 40 #include <string> 41 #include <vector> 42 #include <inttypes.h> 43 #include <torrent/common.h> 44 45 namespace torrent { 46 47 // This class will handle the division of various resources like 48 // uploads. For now the weight is equal to the value of the priority. 49 // 50 // Although the ConnectionManager class keeps a tally of open sockets, 51 // we still need to balance them across the different downloads so 52 // ResourceManager will also keep track of those. 53 // 54 // Add unlimited handling later. 55 56 class choke_group; 57 class DownloadMain; 58 class Rate; 59 class ResourceManager; 60 61 class LIBTORRENT_EXPORT resource_manager_entry { 62 public: 63 friend class ResourceManager; 64 65 resource_manager_entry(DownloadMain* d = NULL, uint16_t pri = 0, uint16_t grp = 0) : m_download(d)66 m_download(d), m_priority(pri), m_group(grp) {} 67 download()68 DownloadMain* download() { return m_download; } c_download()69 const DownloadMain* c_download() const { return m_download; } 70 priority()71 uint16_t priority() const { return m_priority; } group()72 uint16_t group() const { return m_group; } 73 74 const Rate* up_rate() const; 75 const Rate* down_rate() const; 76 77 protected: set_priority(uint16_t pri)78 void set_priority(uint16_t pri) { m_priority = pri; } set_group(uint16_t grp)79 void set_group(uint16_t grp) { m_group = grp; } 80 81 private: 82 DownloadMain* m_download; 83 84 uint16_t m_priority; 85 uint16_t m_group; 86 }; 87 88 89 class LIBTORRENT_EXPORT ResourceManager : 90 private std::vector<resource_manager_entry>, 91 private std::vector<choke_group*> { 92 public: 93 typedef std::vector<resource_manager_entry> base_type; 94 typedef std::vector<choke_group*> choke_base_type; 95 typedef base_type::value_type value_type; 96 typedef base_type::iterator iterator; 97 98 typedef choke_base_type::iterator group_iterator; 99 100 using base_type::begin; 101 using base_type::end; 102 using base_type::size; 103 using base_type::capacity; 104 105 ResourceManager(); 106 ~ResourceManager(); 107 insert(DownloadMain * d,uint16_t priority)108 void insert(DownloadMain* d, uint16_t priority) { insert(value_type(d, priority)); } 109 void erase(DownloadMain* d); 110 111 void push_group(const std::string& name); 112 113 iterator find(DownloadMain* d); 114 iterator find_throw(DownloadMain* d); 115 iterator find_group_end(uint16_t group); 116 group_size()117 unsigned int group_size() const { return choke_base_type::size(); } group_back()118 choke_group* group_back() { return choke_base_type::back(); } 119 120 choke_group* group_at(uint16_t grp); 121 choke_group* group_at_name(const std::string& name); 122 123 int group_index_of(const std::string& name); 124 group_begin()125 group_iterator group_begin() { return choke_base_type::begin(); } group_end()126 group_iterator group_end() { return choke_base_type::end(); } 127 entry_at(DownloadMain * d)128 resource_manager_entry& entry_at(DownloadMain* d) { return *find_throw(d); } 129 130 void set_priority(iterator itr, uint16_t pri); 131 void set_group(iterator itr, uint16_t grp); 132 133 // When setting this, make sure you choke peers, else change 134 // receive_can_unchoke. currently_upload_unchoked()135 unsigned int currently_upload_unchoked() const { return m_currentlyUploadUnchoked; } currently_download_unchoked()136 unsigned int currently_download_unchoked() const { return m_currentlyDownloadUnchoked; } 137 max_upload_unchoked()138 unsigned int max_upload_unchoked() const { return m_maxUploadUnchoked; } max_download_unchoked()139 unsigned int max_download_unchoked() const { return m_maxDownloadUnchoked; } 140 141 void set_max_upload_unchoked(unsigned int m); 142 void set_max_download_unchoked(unsigned int m); 143 144 void receive_upload_unchoke(int num); 145 void receive_download_unchoke(int num); 146 147 int retrieve_upload_can_unchoke(); 148 int retrieve_download_can_unchoke(); 149 150 void receive_tick(); 151 152 private: 153 iterator insert(const resource_manager_entry& entry); 154 155 void update_group_iterators(); 156 void validate_group_iterators(); 157 158 unsigned int total_weight() const; 159 160 int balance_unchoked(unsigned int weight, unsigned int max_unchoked, bool is_up); 161 162 unsigned int m_currentlyUploadUnchoked; 163 unsigned int m_currentlyDownloadUnchoked; 164 165 unsigned int m_maxUploadUnchoked; 166 unsigned int m_maxDownloadUnchoked; 167 }; 168 169 } 170 171 #endif 172