*** empty log message ***
This commit is contained in:
parent
a25addd496
commit
71e1fd4407
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2003, Magnus Jonsson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_ALLOCATE_RESOURCES_HPP_INCLUDED
|
||||
#define TORRENT_ALLOCATE_RESOURCES_HPP_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <boost/any.hpp>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
struct resource_consumer;
|
||||
|
||||
|
||||
// Function to allocate a limited resource fairly among many consumers.
|
||||
// It takes into account the current use, and the consumer's desired use.
|
||||
// Should be invoked periodically to allow it adjust to the situation.
|
||||
|
||||
void allocate_resources(int resources,
|
||||
std::vector<resource_consumer> & consumers);
|
||||
|
||||
// information needed by allocate_resources about each client.
|
||||
struct resource_consumer
|
||||
{
|
||||
resource_consumer(
|
||||
boost::any who, // who is this info about?
|
||||
int desired_use, // the max that the consumer is willing/able to use
|
||||
int current_use // how many resources does it use right now?
|
||||
);
|
||||
|
||||
// who/what is this info about?
|
||||
boost::any const &who() const { return m_who; }
|
||||
|
||||
// after the allocation process, this is the resulting
|
||||
// number of resources that this consumer is allowed to
|
||||
// use up. If it's currently using up more resources it
|
||||
// must free up resources accordingly.
|
||||
int allowed_use() const { return m_allowed_use; };
|
||||
|
||||
// how many resources does it use right now?
|
||||
int current_use() const { return m_current_use; }
|
||||
|
||||
// how many resources does it desire to use?
|
||||
// - the max that the consumer is willing/able to use
|
||||
int desired_use() const { return m_desired_use; }
|
||||
|
||||
// give allowance to use num_resources more resources
|
||||
// than currently allowed. returns how many the consumer
|
||||
// accepts. used internally by allocate_resources.
|
||||
int give(int num_resources);
|
||||
|
||||
private:
|
||||
boost::any m_who;
|
||||
int m_current_use;
|
||||
int m_desired_use;
|
||||
int m_allowed_use;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -103,6 +103,7 @@ namespace libtorrent
|
|||
void not_interested(peer_connection& c);
|
||||
|
||||
void set_max_uploads(int num_unchoked);
|
||||
int get_max_uploads() const { return m_max_uploads; }
|
||||
|
||||
/*
|
||||
A limit on the number of sockets opened, for use on systems where a
|
||||
|
@ -110,6 +111,7 @@ namespace libtorrent
|
|||
which has a buggy tcp-stack.
|
||||
*/
|
||||
void set_max_connections(int num_connected);
|
||||
int get_max_connections() const { return m_max_connections; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool has_connection(const peer_connection* p);
|
||||
|
|
|
@ -155,6 +155,7 @@ namespace libtorrent
|
|||
{
|
||||
friend class invariant_access;
|
||||
typedef std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > connection_map;
|
||||
typedef std::map<sha1_hash, boost::shared_ptr<torrent> > torrent_map;
|
||||
|
||||
session_impl(
|
||||
std::pair<int, int> listen_port_range
|
||||
|
@ -169,7 +170,7 @@ namespace libtorrent
|
|||
const peer_id& get_peer_id() const { return m_peer_id; }
|
||||
|
||||
tracker_manager m_tracker_manager;
|
||||
std::map<sha1_hash, boost::shared_ptr<torrent> > m_torrents;
|
||||
torrent_map m_torrents;
|
||||
|
||||
// this maps sockets to their peer_connection
|
||||
// object. It is the complete list of all connected
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2003, Magnus Jonsson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "libtorrent/allocate_resources.hpp"
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
resource_consumer::resource_consumer(boost::any who, int desired_use, int current_use)
|
||||
: m_who(who)
|
||||
, m_desired_use(desired_use)
|
||||
, m_current_use(current_use)
|
||||
, m_allowed_use(0)
|
||||
{
|
||||
assert(desired_use>=0);
|
||||
assert(current_use>=0);
|
||||
}
|
||||
|
||||
int resource_consumer::give(int num_resources)
|
||||
{
|
||||
assert(num_resources>0);
|
||||
|
||||
int accepted_resources=std::min(num_resources, m_desired_use-m_allowed_use);
|
||||
assert(accepted_resources>=0);
|
||||
|
||||
m_allowed_use+=accepted_resources;
|
||||
assert(m_allowed_use<=m_desired_use);
|
||||
|
||||
return accepted_resources;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool by_desired_use(
|
||||
const resource_consumer &a,
|
||||
const resource_consumer &b)
|
||||
{
|
||||
return a.desired_use() < b.desired_use();
|
||||
}
|
||||
|
||||
int saturated_add(int a, int b)
|
||||
{
|
||||
assert(a>=0);
|
||||
assert(b>=0);
|
||||
|
||||
int sum=a+b;
|
||||
if(sum<0)
|
||||
sum=std::numeric_limits<int>::max();
|
||||
|
||||
assert(sum>=a && sum>=b);
|
||||
return sum;
|
||||
}
|
||||
|
||||
int round_up_division(int numer, int denom)
|
||||
{
|
||||
assert(numer>0);
|
||||
assert(denom>0);
|
||||
int result=(numer+denom-1)/denom;
|
||||
assert(result>0);
|
||||
assert(result<=numer);
|
||||
return result;
|
||||
}
|
||||
|
||||
int total_demand(std::vector<resource_consumer> & consumers)
|
||||
{
|
||||
int total_demand=0;
|
||||
|
||||
for(int i=0;i<(int)consumers.size();i++)
|
||||
{
|
||||
total_demand=saturated_add(total_demand, consumers[i].desired_use());
|
||||
if(total_demand == std::numeric_limits<int>::max())
|
||||
break;
|
||||
}
|
||||
|
||||
assert(total_demand>=0);
|
||||
return total_demand;
|
||||
}
|
||||
}
|
||||
|
||||
void allocate_resources(int resources,
|
||||
std::vector<resource_consumer> & consumers)
|
||||
{
|
||||
assert(resources>=0);
|
||||
|
||||
// no competition for resources?
|
||||
if(resources==std::numeric_limits<int>::max())
|
||||
{
|
||||
for(int i=0;i<(int)consumers.size();i++)
|
||||
consumers[i].give(std::numeric_limits<int>::max());
|
||||
}
|
||||
else
|
||||
{
|
||||
int resources_to_distribute =
|
||||
std::min(
|
||||
resources,
|
||||
total_demand(consumers));
|
||||
|
||||
if (resources_to_distribute != 0)
|
||||
{
|
||||
assert(resources_to_distribute>0);
|
||||
|
||||
std::random_shuffle(consumers.begin(),consumers.end());
|
||||
std::sort(consumers.begin(),consumers.end(),by_desired_use);
|
||||
|
||||
while(resources_to_distribute > 0)
|
||||
for(int i = 0; i < (int)consumers.size() && resources_to_distribute>0; i++)
|
||||
resources_to_distribute -=
|
||||
consumers[i].give(
|
||||
std::min(
|
||||
round_up_division(
|
||||
(int)resources_to_distribute,
|
||||
(int)consumers.size()),
|
||||
std::min(
|
||||
consumers[i].current_use()*2+1, // allow for fast growth
|
||||
consumers[i].desired_use())));
|
||||
}
|
||||
assert(resources_to_distribute == 0);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
int sum_given = 0;
|
||||
int sum_desired = 0;
|
||||
for (std::vector<resource_consumer>::iterator i = consumers.begin();
|
||||
i != consumers.end();
|
||||
++i)
|
||||
{
|
||||
assert(i->allowed_use() <= i->desired_use());
|
||||
|
||||
sum_given = saturated_add(sum_given, i->allowed_use());
|
||||
sum_desired = saturated_add(sum_desired, i->desired_use());
|
||||
}
|
||||
assert(sum_given == std::min(resources,sum_desired));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
|
@ -92,13 +92,13 @@ namespace
|
|||
}
|
||||
|
||||
void control_upload_rates(
|
||||
int upload_limit
|
||||
, libtorrent::detail::session_impl::connection_map connections)
|
||||
int upload_limit,
|
||||
libtorrent::detail::session_impl::connection_map connections)
|
||||
{
|
||||
assert(upload_limit >= 0);
|
||||
|
||||
using namespace libtorrent;
|
||||
std::vector<resource_consumer> peers;
|
||||
|
||||
assert(upload_limit >= 0);
|
||||
|
||||
for (detail::session_impl::connection_map::iterator c = connections.begin();
|
||||
c != connections.end(); ++c)
|
||||
|
@ -148,6 +148,39 @@ namespace
|
|||
}
|
||||
#endif
|
||||
}
|
||||
void control_number_of_connections(
|
||||
int connections_limit,
|
||||
libtorrent::detail::session_impl::torrent_map hash_list)
|
||||
{
|
||||
assert(connections_limit >= 0);
|
||||
|
||||
using namespace libtorrent;
|
||||
std::vector<resource_consumer> torrents;
|
||||
|
||||
for (detail::session_impl::torrent_map::iterator c = hash_list.begin();
|
||||
c != hash_list.end(); ++c)
|
||||
{
|
||||
boost::shared_ptr<torrent> t = c->second;
|
||||
|
||||
int estimated_capacity=t->num_peers()+1;
|
||||
int limit =t->get_policy().get_max_connections();
|
||||
if(limit==-1)
|
||||
limit=std::numeric_limits<int>::max();
|
||||
|
||||
torrents.push_back(resource_consumer(t,limit,estimated_capacity));
|
||||
}
|
||||
|
||||
allocate_resources(connections_limit, torrents);
|
||||
|
||||
for (std::vector<resource_consumer>::iterator r=torrents.begin();
|
||||
r!=torrents.end(); ++r)
|
||||
{
|
||||
// TODO: inform torrent of how many connections it's allowed.
|
||||
// boost::any_cast<boost::shared_ptr<torrent> >
|
||||
// (r->who())->set_send_quota(r->allowed_use());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// This struct is used by control_upload_rates() below. It keeps
|
||||
// track how much bandwidth has been allocated to each connection
|
||||
|
|
Loading…
Reference in New Issue