forked from premiere/premiere-libtorrent
storage optimization to peer classes
This commit is contained in:
parent
c57d062e0d
commit
6d17f0fb66
|
@ -1,3 +1,4 @@
|
||||||
|
* storage optimization to peer classes
|
||||||
* fix torrent name in alerts of builds with deprecated functions
|
* fix torrent name in alerts of builds with deprecated functions
|
||||||
* make torrent_info::is_valid() return false if torrent failed to load
|
* make torrent_info::is_valid() return false if torrent failed to load
|
||||||
* fix per-torrent rate limits for >256 peer classes
|
* fix per-torrent rate limits for >256 peer classes
|
||||||
|
|
|
@ -39,8 +39,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/smart_ptr.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||||
|
@ -86,12 +86,13 @@ namespace libtorrent
|
||||||
int download_priority;
|
int download_priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXTRA_EXPORT peer_class : boost::enable_shared_from_this<peer_class>
|
struct TORRENT_EXTRA_EXPORT peer_class
|
||||||
{
|
{
|
||||||
friend struct peer_class_pool;
|
friend struct peer_class_pool;
|
||||||
|
|
||||||
peer_class(std::string const& l)
|
peer_class(std::string const& l)
|
||||||
: ignore_unchoke_slots(false)
|
: in_use(true)
|
||||||
|
, ignore_unchoke_slots(false)
|
||||||
, connection_limit_factor(100)
|
, connection_limit_factor(100)
|
||||||
, label(l)
|
, label(l)
|
||||||
, references(1)
|
, references(1)
|
||||||
|
@ -100,6 +101,12 @@ namespace libtorrent
|
||||||
priority[1] = 1;
|
priority[1] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
in_use = false;
|
||||||
|
label.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void set_info(peer_class_info const* pci);
|
void set_info(peer_class_info const* pci);
|
||||||
void get_info(peer_class_info* pci) const;
|
void get_info(peer_class_info* pci) const;
|
||||||
|
|
||||||
|
@ -110,6 +117,9 @@ namespace libtorrent
|
||||||
// keeps track of the current quotas
|
// keeps track of the current quotas
|
||||||
bandwidth_channel channel[2];
|
bandwidth_channel channel[2];
|
||||||
|
|
||||||
|
// this is set to false when this slot is not in use for a peer_class
|
||||||
|
bool in_use;
|
||||||
|
|
||||||
bool ignore_unchoke_slots;
|
bool ignore_unchoke_slots;
|
||||||
int connection_limit_factor;
|
int connection_limit_factor;
|
||||||
|
|
||||||
|
@ -123,7 +133,6 @@ namespace libtorrent
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int references;
|
int references;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXTRA_EXPORT peer_class_pool
|
struct TORRENT_EXTRA_EXPORT peer_class_pool
|
||||||
|
@ -138,7 +147,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// state for peer classes (a peer can belong to multiple classes)
|
// state for peer classes (a peer can belong to multiple classes)
|
||||||
// this can control
|
// this can control
|
||||||
std::vector<boost::shared_ptr<peer_class> > m_peer_classes;
|
std::deque<peer_class> m_peer_classes;
|
||||||
|
|
||||||
// indices in m_peer_classes that are no longer used
|
// indices in m_peer_classes that are no longer used
|
||||||
std::vector<peer_class_t> m_free_list;
|
std::vector<peer_class_t> m_free_list;
|
||||||
|
|
|
@ -84,16 +84,15 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
ret = m_free_list.back();
|
ret = m_free_list.back();
|
||||||
m_free_list.pop_back();
|
m_free_list.pop_back();
|
||||||
|
m_peer_classes[ret] = peer_class(label);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_peer_classes.size() < 0x100000000);
|
TORRENT_ASSERT(m_peer_classes.size() < 0x100000000);
|
||||||
ret = m_peer_classes.size();
|
ret = m_peer_classes.size();
|
||||||
m_peer_classes.push_back(boost::shared_ptr<peer_class>());
|
m_peer_classes.push_back(peer_class(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_ASSERT(m_peer_classes[ret].get() == 0);
|
|
||||||
m_peer_classes[ret] = boost::make_shared<peer_class>(label);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,11 +102,12 @@ namespace libtorrent
|
||||||
VALGRIND_CHECK_VALUE_IS_DEFINED(c);
|
VALGRIND_CHECK_VALUE_IS_DEFINED(c);
|
||||||
#endif
|
#endif
|
||||||
TORRENT_ASSERT(c < m_peer_classes.size());
|
TORRENT_ASSERT(c < m_peer_classes.size());
|
||||||
TORRENT_ASSERT(m_peer_classes[c].get());
|
TORRENT_ASSERT(m_peer_classes[c].in_use);
|
||||||
|
TORRENT_ASSERT(m_peer_classes[c].references > 0);
|
||||||
|
|
||||||
--m_peer_classes[c]->references;
|
--m_peer_classes[c].references;
|
||||||
if (m_peer_classes[c]->references) return;
|
if (m_peer_classes[c].references) return;
|
||||||
m_peer_classes[c].reset();
|
m_peer_classes[c].clear();
|
||||||
m_free_list.push_back(c);
|
m_free_list.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +117,9 @@ namespace libtorrent
|
||||||
VALGRIND_CHECK_VALUE_IS_DEFINED(c);
|
VALGRIND_CHECK_VALUE_IS_DEFINED(c);
|
||||||
#endif
|
#endif
|
||||||
TORRENT_ASSERT(c < m_peer_classes.size());
|
TORRENT_ASSERT(c < m_peer_classes.size());
|
||||||
TORRENT_ASSERT(m_peer_classes[c].get());
|
TORRENT_ASSERT(m_peer_classes[c].in_use);
|
||||||
|
|
||||||
++m_peer_classes[c]->references;
|
++m_peer_classes[c].references;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_class* peer_class_pool::at(peer_class_t c)
|
peer_class* peer_class_pool::at(peer_class_t c)
|
||||||
|
@ -127,14 +127,14 @@ namespace libtorrent
|
||||||
#ifdef TORRENT_USE_VALGRIND
|
#ifdef TORRENT_USE_VALGRIND
|
||||||
VALGRIND_CHECK_VALUE_IS_DEFINED(c);
|
VALGRIND_CHECK_VALUE_IS_DEFINED(c);
|
||||||
#endif
|
#endif
|
||||||
if (c >= m_peer_classes.size()) return 0;
|
if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return NULL;
|
||||||
return m_peer_classes[c].get();
|
return &m_peer_classes[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_class const* peer_class_pool::at(peer_class_t c) const
|
peer_class const* peer_class_pool::at(peer_class_t c) const
|
||||||
{
|
{
|
||||||
if (c >= m_peer_classes.size()) return 0;
|
if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return NULL;
|
||||||
return m_peer_classes[c].get();
|
return &m_peer_classes[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,11 +66,11 @@ TORRENT_TEST(peer_class)
|
||||||
TEST_CHECK(id3 == id2 + 1);
|
TEST_CHECK(id3 == id2 + 1);
|
||||||
|
|
||||||
// make sure refcounting works
|
// make sure refcounting works
|
||||||
TEST_CHECK(class_name(id3, pool) == "test3");
|
TEST_EQUAL(class_name(id3, pool), "test3");
|
||||||
pool.incref(id3);
|
pool.incref(id3);
|
||||||
TEST_CHECK(class_name(id3, pool) == "test3");
|
TEST_EQUAL(class_name(id3, pool), "test3");
|
||||||
pool.decref(id3);
|
pool.decref(id3);
|
||||||
TEST_CHECK(class_name(id3, pool) == "test3");
|
TEST_EQUAL(class_name(id3, pool), "test3");
|
||||||
pool.decref(id3);
|
pool.decref(id3);
|
||||||
// it should have been deleted now
|
// it should have been deleted now
|
||||||
TEST_CHECK(pool.at(id3) == NULL);
|
TEST_CHECK(pool.at(id3) == NULL);
|
||||||
|
@ -81,8 +81,8 @@ TORRENT_TEST(peer_class)
|
||||||
|
|
||||||
peer_class_info i;
|
peer_class_info i;
|
||||||
pool.at(id2)->get_info(&i);
|
pool.at(id2)->get_info(&i);
|
||||||
TEST_CHECK(i.upload_limit == 1000);
|
TEST_EQUAL(i.upload_limit, 1000);
|
||||||
TEST_CHECK(i.download_limit == 2000);
|
TEST_EQUAL(i.download_limit, 2000);
|
||||||
|
|
||||||
// test peer_class_type_filter
|
// test peer_class_type_filter
|
||||||
peer_class_type_filter filter;
|
peer_class_type_filter filter;
|
||||||
|
|
Loading…
Reference in New Issue