added seed mode support (lazy hash checking)

This commit is contained in:
Arvid Norberg
2009-02-03 07:46:24 +00:00
parent a0333f82db
commit 1ac8f806fa
19 changed files with 481 additions and 230 deletions

View File

@@ -244,12 +244,14 @@ namespace libtorrent
if (m_size && (bits & 7)) m_bytes[(m_size + 7) / 8 - 1] &= 0xff << (7 - (bits & 7));
}
void free() { dealloc(); m_size = 0; }
private:
void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; }
unsigned char* m_bytes;
int m_size; // in bits
bool m_own;
int m_size:31; // in bits
bool m_own:1;
};
}

View File

@@ -425,6 +425,7 @@ private:
// the number of bytes in the send buffer
// that have been encrypted (only used for
// encrypted connections)
public:
int m_encrypted_bytes;
#endif

View File

@@ -91,6 +91,7 @@ namespace libtorrent
, clear_read_cache
, abort_torrent
, update_settings
, read_and_hash
};
action_t action;
@@ -260,6 +261,8 @@ namespace libtorrent
cache_t::iterator find_cached_piece(
cache_t& cache, disk_io_job const& j
, mutex_t::scoped_lock& l);
int copy_from_piece(cache_t::iterator p, bool& hit
, disk_io_job const& j, mutex_t::scoped_lock& l);
// write cache operations
void flush_oldest_piece(mutex_t::scoped_lock& l);
@@ -271,13 +274,16 @@ namespace libtorrent
// read cache operations
bool clear_oldest_read_piece(cache_t::iterator ignore
, mutex_t::scoped_lock& l);
int read_into_piece(cached_piece_entry& p, int start_block, mutex_t::scoped_lock& l);
int read_into_piece(cached_piece_entry& p, int start_block
, int options, mutex_t::scoped_lock& l);
int cache_read_block(disk_io_job const& j, mutex_t::scoped_lock& l);
int cache_read_piece(disk_io_job const& j, mutex_t::scoped_lock& l);
void free_piece(cached_piece_entry& p, mutex_t::scoped_lock& l);
bool make_room(int num_blocks
, cache_t::iterator ignore
, mutex_t::scoped_lock& l);
int try_read_from_cache(disk_io_job const& j);
int read_piece_from_cache_and_hash(disk_io_job const& j, sha1_hash& h);
// this mutex only protects m_jobs, m_queue_buffer_size
// and m_abort

View File

@@ -49,7 +49,8 @@ namespace libtorrent
enum error_code_enum
{
no_error = 0,
file_collision
file_collision,
failed_hash_check
};
}

View File

@@ -173,6 +173,7 @@ namespace libtorrent
, duplicate_is_error(false)
, storage(sc)
, userdata(0)
, seed_mode(false)
{}
boost::intrusive_ptr<torrent_info> ti;
@@ -187,6 +188,7 @@ namespace libtorrent
bool duplicate_is_error;
storage_constructor_type storage;
void* userdata;
bool seed_mode;
};
class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_initializer

View File

@@ -191,7 +191,7 @@ namespace libtorrent
session_settings* m_settings;
};
typedef storage_interface* (&storage_constructor_type)(
typedef storage_interface* (*storage_constructor_type)(
file_storage const&, fs::path const&, file_pool&);
TORRENT_EXPORT storage_interface* default_storage_constructor(
@@ -234,6 +234,11 @@ namespace libtorrent
, boost::function<void(int, disk_io_job const&)> const& handler
, int priority = 0);
void async_read_and_hash(
peer_request const& r
, boost::function<void(int, disk_io_job const&)> const& handler
, int priority = 0);
void async_write(
peer_request const& r
, disk_buffer_holder& buffer

View File

@@ -83,6 +83,7 @@ namespace libtorrent
struct bitfield;
struct announce_entry;
struct tracker_request;
struct add_torrent_params;
namespace aux
{
@@ -118,36 +119,8 @@ namespace libtorrent
{
public:
torrent(
aux::session_impl& ses
, boost::intrusive_ptr<torrent_info> tf
, fs::path const& save_path
, tcp::endpoint const& net_interface
, storage_mode_t m_storage_mode
, int block_size
, storage_constructor_type sc
, bool paused
, std::vector<char>* resume_data
, int seq
, bool auto_managed);
// used with metadata-less torrents
// (the metadata is downloaded from the peers)
torrent(
aux::session_impl& ses
, char const* tracker_url
, sha1_hash const& info_hash
, char const* name
, fs::path const& save_path
, tcp::endpoint const& net_interface
, storage_mode_t m_storage_mode
, int block_size
, storage_constructor_type sc
, bool paused
, std::vector<char>* resume_data
, int seq
, bool auto_managed);
torrent(aux::session_impl& ses, tcp::endpoint const& net_interface
, int block_size, int seq, add_torrent_params const& p);
~torrent();
#ifndef TORRENT_DISABLE_ENCRYPTION
@@ -691,6 +664,34 @@ namespace libtorrent
int sequence_number() const { return m_sequence_number; }
bool seed_mode() const { return m_seed_mode; }
void leave_seed_mode(bool seed)
{
if (!m_seed_mode) return;
m_seed_mode = false;
// seed is false if we turned out not
// to be a seed after all
if (!seed) force_recheck();
m_num_verified = 0;
m_verified.free();
}
bool all_verified() const
{ return m_num_verified == m_torrent_file->num_pieces(); }
bool verified_piece(int piece) const
{
TORRENT_ASSERT(piece < int(m_verified.size()));
TORRENT_ASSERT(piece >= 0);
return m_verified.get_bit(piece);
}
void verified(int piece)
{
TORRENT_ASSERT(piece < int(m_verified.size()));
TORRENT_ASSERT(piece >= 0);
TORRENT_ASSERT(m_verified.get_bit(piece) == false);
++m_num_verified;
m_verified.set_bit(piece);
}
private:
void on_files_deleted(int ret, disk_io_job const& j);
@@ -866,6 +867,14 @@ namespace libtorrent
fs::path m_save_path;
// each bit represents a piece. a set bit means
// the piece has had its hash verified. This
// is only used in seed mode (when m_seed_mode
// is true)
bitfield m_verified;
// m_num_verified = m_verified.count()
int m_num_verified;
// determines the storage state for this torrent.
storage_mode_t m_storage_mode;
@@ -1029,6 +1038,12 @@ namespace libtorrent
// is in use. i.e. one or more trackers are waiting
// for a reannounce
bool m_waiting_tracker:1;
// this means we haven't verified the file content
// of the files we're seeding. the m_verified bitfield
// indicates which pieces have been verified and which
// haven't
bool m_seed_mode:1;
};
inline ptime torrent::next_announce() const

View File

@@ -121,6 +121,7 @@ namespace libtorrent
, last_scrape(0)
, has_incoming(false)
, sparse_regions(0)
, seed_mode(false)
{}
enum state_t
@@ -274,6 +275,9 @@ namespace libtorrent
// the number of "holes" in the torrent
int sparse_regions;
// is true if this torrent is (still) in seed_mode
bool seed_mode;
};
struct TORRENT_EXPORT block_info