diff --git a/ChangeLog b/ChangeLog index 12fc85240..dea188316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * storage optimization to peer classes * fix torrent name in alerts of builds with deprecated functions * make torrent_info::is_valid() return false if torrent failed to load * fix per-torrent rate limits for >256 peer classes diff --git a/include/libtorrent/peer_class.hpp b/include/libtorrent/peer_class.hpp index f11f412b0..3c278ccb1 100644 --- a/include/libtorrent/peer_class.hpp +++ b/include/libtorrent/peer_class.hpp @@ -39,8 +39,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/disable_warnings_push.hpp" #include +#include #include -#include #include #include "libtorrent/aux_/disable_warnings_pop.hpp" @@ -86,12 +86,13 @@ namespace libtorrent int download_priority; }; - struct TORRENT_EXTRA_EXPORT peer_class : boost::enable_shared_from_this + struct TORRENT_EXTRA_EXPORT peer_class { friend struct peer_class_pool; peer_class(std::string const& l) - : ignore_unchoke_slots(false) + : in_use(true) + , ignore_unchoke_slots(false) , connection_limit_factor(100) , label(l) , references(1) @@ -100,6 +101,12 @@ namespace libtorrent priority[1] = 1; } + void clear() + { + in_use = false; + label.clear(); + } + void set_info(peer_class_info const* pci); void get_info(peer_class_info* pci) const; @@ -110,6 +117,9 @@ namespace libtorrent // keeps track of the current quotas 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; int connection_limit_factor; @@ -123,7 +133,6 @@ namespace libtorrent private: int references; - }; struct TORRENT_EXTRA_EXPORT peer_class_pool @@ -138,7 +147,7 @@ namespace libtorrent // state for peer classes (a peer can belong to multiple classes) // this can control - std::vector > m_peer_classes; + std::deque m_peer_classes; // indices in m_peer_classes that are no longer used std::vector m_free_list; diff --git a/src/peer_class.cpp b/src/peer_class.cpp index 945ab641a..ea1979920 100644 --- a/src/peer_class.cpp +++ b/src/peer_class.cpp @@ -84,16 +84,15 @@ namespace libtorrent { ret = m_free_list.back(); m_free_list.pop_back(); + m_peer_classes[ret] = peer_class(label); } else { TORRENT_ASSERT(m_peer_classes.size() < 0x100000000); ret = m_peer_classes.size(); - m_peer_classes.push_back(boost::shared_ptr()); + m_peer_classes.push_back(peer_class(label)); } - TORRENT_ASSERT(m_peer_classes[ret].get() == 0); - m_peer_classes[ret] = boost::make_shared(label); return ret; } @@ -103,11 +102,12 @@ namespace libtorrent VALGRIND_CHECK_VALUE_IS_DEFINED(c); #endif 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; - if (m_peer_classes[c]->references) return; - m_peer_classes[c].reset(); + --m_peer_classes[c].references; + if (m_peer_classes[c].references) return; + m_peer_classes[c].clear(); m_free_list.push_back(c); } @@ -117,9 +117,9 @@ namespace libtorrent VALGRIND_CHECK_VALUE_IS_DEFINED(c); #endif 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) @@ -127,14 +127,14 @@ namespace libtorrent #ifdef TORRENT_USE_VALGRIND VALGRIND_CHECK_VALUE_IS_DEFINED(c); #endif - if (c >= m_peer_classes.size()) return 0; - return m_peer_classes[c].get(); + if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return NULL; + return &m_peer_classes[c]; } peer_class const* peer_class_pool::at(peer_class_t c) const { - if (c >= m_peer_classes.size()) return 0; - return m_peer_classes[c].get(); + if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return NULL; + return &m_peer_classes[c]; } } diff --git a/test/test_peer_classes.cpp b/test/test_peer_classes.cpp index d81d3ec84..541af1766 100644 --- a/test/test_peer_classes.cpp +++ b/test/test_peer_classes.cpp @@ -66,11 +66,11 @@ TORRENT_TEST(peer_class) TEST_CHECK(id3 == id2 + 1); // make sure refcounting works - TEST_CHECK(class_name(id3, pool) == "test3"); + TEST_EQUAL(class_name(id3, pool), "test3"); pool.incref(id3); - TEST_CHECK(class_name(id3, pool) == "test3"); + TEST_EQUAL(class_name(id3, pool), "test3"); pool.decref(id3); - TEST_CHECK(class_name(id3, pool) == "test3"); + TEST_EQUAL(class_name(id3, pool), "test3"); pool.decref(id3); // it should have been deleted now TEST_CHECK(pool.at(id3) == NULL); @@ -81,8 +81,8 @@ TORRENT_TEST(peer_class) peer_class_info i; pool.at(id2)->get_info(&i); - TEST_CHECK(i.upload_limit == 1000); - TEST_CHECK(i.download_limit == 2000); + TEST_EQUAL(i.upload_limit, 1000); + TEST_EQUAL(i.download_limit, 2000); // test peer_class_type_filter peer_class_type_filter filter;