storage optimization to peer classes

This commit is contained in:
arvidn 2017-01-20 23:30:05 -05:00 committed by Arvid Norberg
parent c57d062e0d
commit 6d17f0fb66
4 changed files with 33 additions and 23 deletions

View File

@ -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

View File

@ -39,8 +39,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <vector>
#include <deque>
#include <string>
#include <boost/smart_ptr.hpp>
#include <boost/cstdint.hpp>
#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<peer_class>
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<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
std::vector<peer_class_t> m_free_list;

View File

@ -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<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;
}
@ -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];
}
}

View File

@ -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;