00001
00002
00003
00004
00005
00006
00007 #ifdef _WIN32
00008
00009
00010 #define NOMINMAX
00011 #endif
00012
00013 #include "libtorrent/allocate_resources.hpp"
00014 #include "libtorrent/size_type.hpp"
00015 #include "libtorrent/peer_connection.hpp"
00016 #include "libtorrent/torrent.hpp"
00017 #include "libtorrent/aux_/allocate_resources_impl.hpp"
00018
00019 #include <cassert>
00020 #include <algorithm>
00021 #include <boost/limits.hpp>
00022
00023 #if defined(_MSC_VER) && _MSC_VER < 1310
00024 #define for if (false) {} else for
00025 #else
00026 #include <boost/iterator/transform_iterator.hpp>
00027 #endif
00028
00029 namespace libtorrent
00030 {
00031 int saturated_add(int a, int b)
00032 {
00033 assert(a >= 0);
00034 assert(b >= 0);
00035 assert(a <= resource_request::inf);
00036 assert(b <= resource_request::inf);
00037 assert(resource_request::inf + resource_request::inf < 0);
00038
00039 unsigned int sum = unsigned(a) + unsigned(b);
00040 if (sum > unsigned(resource_request::inf))
00041 sum = resource_request::inf;
00042
00043 assert(sum >= unsigned(a) && sum >= unsigned(b));
00044 return int(sum);
00045 }
00046
00047 #if defined(_MSC_VER) && _MSC_VER < 1310
00048
00049 namespace detail
00050 {
00051 struct iterator_wrapper
00052 {
00053 typedef std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator orig_iter;
00054
00055 orig_iter iter;
00056
00057 iterator_wrapper(orig_iter i): iter(i) {}
00058 void operator++() { ++iter; }
00059 torrent& operator*() { return *(iter->second); }
00060 bool operator==(const iterator_wrapper& i) const
00061 { return iter == i.iter; }
00062 bool operator!=(const iterator_wrapper& i) const
00063 { return iter != i.iter; }
00064 };
00065
00066 struct iterator_wrapper2
00067 {
00068 typedef std::map<tcp::endpoint, peer_connection*>::iterator orig_iter;
00069
00070 orig_iter iter;
00071
00072 iterator_wrapper2(orig_iter i): iter(i) {}
00073 void operator++() { ++iter; }
00074 peer_connection& operator*() { return *(iter->second); }
00075 bool operator==(const iterator_wrapper2& i) const
00076 { return iter == i.iter; }
00077 bool operator!=(const iterator_wrapper2& i) const
00078 { return iter != i.iter; }
00079 };
00080
00081 }
00082
00083 void allocate_resources(
00084 int resources
00085 , std::map<sha1_hash, boost::shared_ptr<torrent> >& c
00086 , resource_request torrent::* res)
00087 {
00088 aux::allocate_resources_impl(
00089 resources
00090 , detail::iterator_wrapper(c.begin())
00091 , detail::iterator_wrapper(c.end())
00092 , res);
00093 }
00094
00095 void allocate_resources(
00096 int resources
00097 , std::map<tcp::endpoint, peer_connection*>& c
00098 , resource_request peer_connection::* res)
00099 {
00100 aux::allocate_resources_impl(
00101 resources
00102 , detail::iterator_wrapper2(c.begin())
00103 , detail::iterator_wrapper2(c.end())
00104 , res);
00105 }
00106
00107 #else
00108
00109 namespace aux
00110 {
00111 peer_connection& pick_peer(
00112 std::pair<boost::shared_ptr<stream_socket>
00113 , boost::intrusive_ptr<peer_connection> > const& p)
00114 {
00115 return *p.second;
00116 }
00117
00118 peer_connection& pick_peer2(
00119 std::pair<tcp::endpoint, peer_connection*> const& p)
00120 {
00121 return *p.second;
00122 }
00123
00124 torrent& deref(std::pair<sha1_hash, boost::shared_ptr<torrent> > const& p)
00125 {
00126 return *p.second;
00127 }
00128
00129 session& deref(session* p)
00130 {
00131 return *p;
00132 }
00133 }
00134
00135 void allocate_resources(
00136 int resources
00137 , std::map<sha1_hash, boost::shared_ptr<torrent> >& c
00138 , resource_request torrent::* res)
00139 {
00140 typedef std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator orig_iter;
00141 typedef std::pair<sha1_hash, boost::shared_ptr<torrent> > in_param;
00142 typedef boost::transform_iterator<torrent& (*)(in_param const&), orig_iter> new_iter;
00143
00144 aux::allocate_resources_impl(
00145 resources
00146 , new_iter(c.begin(), &aux::deref)
00147 , new_iter(c.end(), &aux::deref)
00148 , res);
00149 }
00150
00151 void allocate_resources(
00152 int resources
00153 , std::map<tcp::endpoint, peer_connection*>& c
00154 , resource_request peer_connection::* res)
00155 {
00156 typedef std::map<tcp::endpoint, peer_connection*>::iterator orig_iter;
00157 typedef std::pair<tcp::endpoint, peer_connection*> in_param;
00158 typedef boost::transform_iterator<peer_connection& (*)(in_param const&), orig_iter> new_iter;
00159
00160 aux::allocate_resources_impl(
00161 resources
00162 , new_iter(c.begin(), &aux::pick_peer2)
00163 , new_iter(c.end(), &aux::pick_peer2)
00164 , res);
00165 }
00166
00167 void allocate_resources(
00168 int resources
00169 , std::vector<session*>& _sessions
00170 , resource_request session::* res)
00171 {
00172 typedef std::vector<session*>::iterator orig_iter;
00173 typedef session* in_param;
00174 typedef boost::transform_iterator<session& (*)(in_param), orig_iter> new_iter;
00175
00176 aux::allocate_resources_impl(
00177 resources
00178 , new_iter(_sessions.begin(), &aux::deref)
00179 , new_iter(_sessions.end(), &aux::deref)
00180 , res);
00181 }
00182
00183 #endif
00184
00185 }