most of the metadata is now freed when a torrent becomes a seed. #44

This commit is contained in:
Arvid Norberg 2007-05-09 22:54:26 +00:00
parent 6e7c0ebfc9
commit a5847956e1
5 changed files with 91 additions and 26 deletions

View File

@ -373,3 +373,4 @@ namespace libtorrent
}
#endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED

View File

@ -115,7 +115,11 @@ namespace libtorrent
std::vector<file_slice> map_block(int piece, size_type offset, int size) const;
peer_request map_file(int file, size_type offset, int size) const;
std::vector<std::string> const& url_seeds() const { return m_url_seeds; }
std::vector<std::string> const& url_seeds() const
{
assert(!m_half_metadata);
return m_url_seeds;
}
typedef std::vector<file_entry>::const_iterator file_iterator;
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
@ -135,7 +139,7 @@ namespace libtorrent
size_type total_size() const { assert(m_piece_length > 0); return m_total_size; }
size_type piece_length() const { assert(m_piece_length > 0); return m_piece_length; }
int num_pieces() const { assert(m_piece_length > 0); return (int)m_piece_hash.size(); }
int num_pieces() const { assert(m_piece_length > 0); return m_num_pieces; }
const sha1_hash& info_hash() const { return m_info_hash; }
const std::string& name() const { assert(m_piece_length > 0); return m_name; }
@ -156,6 +160,7 @@ namespace libtorrent
{
assert(index >= 0);
assert(index < (int)m_piece_hash.size());
assert(!m_half_metadata);
return m_piece_hash[index];
}
@ -171,7 +176,10 @@ namespace libtorrent
typedef std::vector<std::pair<std::string, int> > nodes_t;
nodes_t const& nodes() const
{ return m_nodes; }
{
assert(!m_half_metadata);
return m_nodes;
}
void add_node(std::pair<std::string, int> const& node);
@ -180,6 +188,10 @@ namespace libtorrent
entry extra(char const* key) const
{ return m_extra_info[key]; }
// frees parts of the metadata that isn't
// used by seeds
void seed_free();
private:
void read_torrent_info(const entry& libtorrent);
@ -205,6 +217,9 @@ namespace libtorrent
// the sum of all filesizes
size_type m_total_size;
// the number of pieces in the torrent
int m_num_pieces;
// the hash that identifies this torrent
// is mutable because it's calculated
// lazily
@ -241,6 +256,11 @@ namespace libtorrent
// reproduce the info-section when sending the metadata
// to peers.
entry m_extra_info;
#ifndef NDEBUG
// this is set to true when seed_free() is called
bool m_half_metadata;
#endif
};
}

View File

@ -106,7 +106,15 @@ namespace libtorrent { namespace
{
m_requested_metadata.resize(256, 0);
}
virtual void on_files_checked()
{
// if the torrent is a seed, copy the metadata from
// the torrent before it is deallocated
if (m_torrent.is_seed())
metadata();
}
virtual boost::shared_ptr<peer_plugin> new_connection(
peer_connection* pc);
@ -211,6 +219,14 @@ namespace libtorrent { namespace
m_metadata_size = total_size;
}
void piece_pass(int)
{
// if we became a seed, copy the metadata from
// the torrent before it is deallocated
if (m_torrent.is_seed())
metadata();
}
private:
torrent& m_torrent;

View File

@ -1010,7 +1010,11 @@ namespace libtorrent
try { (*i)->on_piece_pass(index); } catch (std::exception&) {}
}
#endif
if (is_seed()) m_picker.reset();
if (is_seed())
{
m_picker.reset();
m_torrent_file.seed_free();
}
}
std::string torrent::tracker_login() const
@ -2108,9 +2112,19 @@ namespace libtorrent
if (m_sequenced_download_threshold > 0)
picker().set_sequenced_download_threshold(m_sequenced_download_threshold);
}
else
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
{
try { (*i)->on_files_checked(); } catch (std::exception&) {}
}
#endif
if (is_seed())
{
m_picker.reset();
m_torrent_file.seed_free();
}
if (!m_connections_initialized)
@ -2142,14 +2156,6 @@ namespace libtorrent
#ifndef NDEBUG
m_initial_done = boost::get<0>(bytes_done());
#endif
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
{
try { (*i)->on_files_checked(); } catch (std::exception&) {}
}
#endif
}
alert_manager& torrent::alerts() const

View File

@ -219,10 +219,14 @@ namespace libtorrent
// standard constructor that parses a torrent file
torrent_info::torrent_info(const entry& torrent_file)
: m_creation_date(pt::ptime(pt::not_a_date_time))
: m_num_pieces(0)
, m_creation_date(pt::ptime(pt::not_a_date_time))
, m_multifile(false)
, m_private(false)
, m_extra_info(entry::dictionary_t)
#ifndef NDEBUG
, m_half_metadata(false)
#endif
{
try
{
@ -241,24 +245,32 @@ namespace libtorrent
torrent_info::torrent_info(sha1_hash const& info_hash)
: m_piece_length(0)
, m_total_size(0)
, m_num_pieces(0)
, m_info_hash(info_hash)
, m_name()
, m_creation_date(pt::second_clock::universal_time())
, m_multifile(false)
, m_private(false)
, m_extra_info(entry::dictionary_t)
#ifndef NDEBUG
, m_half_metadata(false)
#endif
{
}
torrent_info::torrent_info()
: m_piece_length(0)
, m_total_size(0)
, m_num_pieces(0)
, m_info_hash(0)
, m_name()
, m_creation_date(pt::second_clock::universal_time())
, m_multifile(false)
, m_private(false)
, m_extra_info(entry::dictionary_t)
#ifndef NDEBUG
, m_half_metadata(false)
#endif
{
}
@ -278,15 +290,15 @@ namespace libtorrent
}
}
#endif
assert(!m_half_metadata);
m_piece_length = size;
int num_pieces = static_cast<int>(
m_num_pieces = static_cast<int>(
(m_total_size + m_piece_length - 1) / m_piece_length);
int old_num_pieces = static_cast<int>(m_piece_hash.size());
m_piece_hash.resize(num_pieces);
for (int i = old_num_pieces; i < num_pieces; ++i)
m_piece_hash.resize(m_num_pieces);
for (int i = old_num_pieces; i < m_num_pieces; ++i)
{
m_piece_hash[i].clear();
}
@ -344,14 +356,14 @@ namespace libtorrent
// we want this division to round upwards, that's why we have the
// extra addition
int num_pieces = static_cast<int>((m_total_size + m_piece_length - 1) / m_piece_length);
m_piece_hash.resize(num_pieces);
m_num_pieces = static_cast<int>((m_total_size + m_piece_length - 1) / m_piece_length);
m_piece_hash.resize(m_num_pieces);
const std::string& hash_string = info["pieces"].string();
if ((int)hash_string.length() != num_pieces * 20)
if ((int)hash_string.length() != m_num_pieces * 20)
throw invalid_torrent_file();
for (int i = 0; i < num_pieces; ++i)
for (int i = 0; i < m_num_pieces; ++i)
std::copy(
hash_string.begin() + i*20
, hash_string.begin() + (i+1)*20
@ -550,12 +562,12 @@ namespace libtorrent
if (m_piece_length == 0)
m_piece_length = 256 * 1024;
int num_pieces = static_cast<int>(
m_num_pieces = static_cast<int>(
(m_total_size + m_piece_length - 1) / m_piece_length);
int old_num_pieces = static_cast<int>(m_piece_hash.size());
m_piece_hash.resize(num_pieces);
if (num_pieces > old_num_pieces)
m_piece_hash.resize(m_num_pieces);
if (m_num_pieces > old_num_pieces)
std::for_each(m_piece_hash.begin() + old_num_pieces
, m_piece_hash.end(), boost::bind(&sha1_hash::clear, _1));
}
@ -736,6 +748,16 @@ namespace libtorrent
assert(false);
}
void torrent_info::seed_free()
{
std::vector<std::string>().swap(m_url_seeds);
nodes_t().swap(m_nodes);
std::vector<sha1_hash>().swap(m_piece_hash);
#ifndef NDEBUG
m_half_metadata = true;
#endif
}
// ------- start deprecation -------
void torrent_info::print(std::ostream& os) const