added dummy storage class to disable disk I/O and an option to disable hash checking (for performance testing and simulation)
This commit is contained in:
parent
cc4084f943
commit
63368c1383
|
@ -3557,6 +3557,7 @@ session_settings
|
||||||
int write_cache_line_size;
|
int write_cache_line_size;
|
||||||
|
|
||||||
int optimistic_disk_retry;
|
int optimistic_disk_retry;
|
||||||
|
bool disable_hash_check;
|
||||||
};
|
};
|
||||||
|
|
||||||
``user_agent`` this is the client identification to the tracker.
|
``user_agent`` this is the client identification to the tracker.
|
||||||
|
@ -3975,6 +3976,12 @@ libtorrent will only do this automatically for auto managed torrents.
|
||||||
You can explicitly take a torrent out of upload only mode using
|
You can explicitly take a torrent out of upload only mode using
|
||||||
`set_upload_mode()`_.
|
`set_upload_mode()`_.
|
||||||
|
|
||||||
|
``disable_hash_check`` controls if downloaded pieces are verified against
|
||||||
|
the piece hashes in the torrent file or not. The default is false, i.e.
|
||||||
|
to verify all downloaded data. It may be useful to turn this off for performance
|
||||||
|
profiling and simulation scenarios. Do not disable the hash check for regular
|
||||||
|
bittorrent clients.
|
||||||
|
|
||||||
pe_settings
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,7 @@ namespace libtorrent
|
||||||
, read_cache_line_size(16)
|
, read_cache_line_size(16)
|
||||||
, write_cache_line_size(32)
|
, write_cache_line_size(32)
|
||||||
, optimistic_disk_retry(10 * 60)
|
, optimistic_disk_retry(10 * 60)
|
||||||
|
, disable_hash_checks(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// this is the user agent that will be sent to the tracker
|
// this is the user agent that will be sent to the tracker
|
||||||
|
@ -612,6 +613,14 @@ namespace libtorrent
|
||||||
// this is the number of seconds a disk failure
|
// this is the number of seconds a disk failure
|
||||||
// occurs until libtorrent will re-try.
|
// occurs until libtorrent will re-try.
|
||||||
int optimistic_disk_retry;
|
int optimistic_disk_retry;
|
||||||
|
|
||||||
|
// when set to true, all data downloaded from
|
||||||
|
// peers will be assumed to be correct, and not
|
||||||
|
// tested to match the hashes in the torrent
|
||||||
|
// this is only useful for simulation and
|
||||||
|
// testing purposes (typically combined with
|
||||||
|
// disabled_storage)
|
||||||
|
bool disable_hash_checks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
|
@ -195,6 +195,9 @@ namespace libtorrent
|
||||||
TORRENT_EXPORT storage_interface* default_storage_constructor(
|
TORRENT_EXPORT storage_interface* default_storage_constructor(
|
||||||
file_storage const&, file_storage const* mapped, fs::path const&, file_pool&);
|
file_storage const&, file_storage const* mapped, fs::path const&, file_pool&);
|
||||||
|
|
||||||
|
TORRENT_EXPORT storage_interface* disabled_storage_constructor(
|
||||||
|
file_storage const&, file_storage const* mapped, fs::path const&, file_pool&);
|
||||||
|
|
||||||
struct disk_io_thread;
|
struct disk_io_thread;
|
||||||
|
|
||||||
class TORRENT_EXPORT piece_manager
|
class TORRENT_EXPORT piece_manager
|
||||||
|
|
|
@ -1488,7 +1488,8 @@ namespace libtorrent
|
||||||
test_error(j);
|
test_error(j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = (j.storage->info()->hash_for_piece(j.piece) == h)?ret:-3;
|
if (!m_settings.disable_hash_checks)
|
||||||
|
ret = (j.storage->info()->hash_for_piece(j.piece) == h)?ret:-3;
|
||||||
if (ret == -3)
|
if (ret == -3)
|
||||||
{
|
{
|
||||||
j.storage->mark_failed(j.piece);
|
j.storage->mark_failed(j.piece);
|
||||||
|
@ -1656,6 +1657,11 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
if (m_settings.disable_hash_checks)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
|
sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
|
||||||
if (test_error(j))
|
if (test_error(j))
|
||||||
{
|
{
|
||||||
|
@ -1663,6 +1669,7 @@ namespace libtorrent
|
||||||
j.storage->mark_failed(j.piece);
|
j.storage->mark_failed(j.piece);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (j.storage->info()->hash_for_piece(j.piece) == h)?0:-2;
|
ret = (j.storage->info()->hash_for_piece(j.piece) == h)?0:-2;
|
||||||
if (ret == -2) j.storage->mark_failed(j.piece);
|
if (ret == -2) j.storage->mark_failed(j.piece);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -648,6 +648,7 @@ namespace aux {
|
||||||
|| m_settings.coalesce_writes != s.coalesce_writes
|
|| m_settings.coalesce_writes != s.coalesce_writes
|
||||||
|| m_settings.coalesce_reads != s.coalesce_reads
|
|| m_settings.coalesce_reads != s.coalesce_reads
|
||||||
|| m_settings.max_queued_disk_bytes != s.max_queued_disk_bytes
|
|| m_settings.max_queued_disk_bytes != s.max_queued_disk_bytes
|
||||||
|
|| m_settings.disable_hash_checks != s.disable_hash_checks
|
||||||
#ifndef TORRENT_DISABLE_MLOCK
|
#ifndef TORRENT_DISABLE_MLOCK
|
||||||
|| m_settings.lock_disk_cache != s.lock_disk_cache
|
|| m_settings.lock_disk_cache != s.lock_disk_cache
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1448,6 +1448,85 @@ ret:
|
||||||
return new storage(fs, mapped, path, fp);
|
return new storage(fs, mapped, path, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this storage implementation does not write anything to disk
|
||||||
|
// and it pretends to read, and just leaves garbage in the buffers
|
||||||
|
// this is useful when simulating many clients on the same machine
|
||||||
|
// or when running stress tests and want to take the cost of the
|
||||||
|
// disk I/O out of the picture. This cannot be used for any kind
|
||||||
|
// of normal bittorrent operation, since it will just send garbage
|
||||||
|
// to peers and throw away all the data it downloads. It would end
|
||||||
|
// up being banned immediately
|
||||||
|
class disabled_storage : public storage_interface, boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
disabled_storage(int piece_size) : m_piece_size(piece_size) {}
|
||||||
|
bool has_any_file() { return false; }
|
||||||
|
bool rename_file(int index, std::string const& new_filename) { return false; }
|
||||||
|
bool release_files() { return false; }
|
||||||
|
bool delete_files() { return false; }
|
||||||
|
bool initialize(bool allocate_files) { return false; }
|
||||||
|
bool move_storage(fs::path save_path) { return false; }
|
||||||
|
int read(char* buf, int slot, int offset, int size) { return size; }
|
||||||
|
int write(char const* buf, int slot, int offset, int size) { return size; }
|
||||||
|
int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs)
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
disk_buffer_pool* pool = disk_pool();
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
pool->m_disk_access_log << log_time() << " read "
|
||||||
|
<< (size_type(slot) * m_piece_size + offset) << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int ret = 0;
|
||||||
|
for (int i = 0; i < num_bufs; ++i)
|
||||||
|
ret += bufs[i].iov_len;
|
||||||
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
pool->m_disk_access_log << log_time() << " read_end "
|
||||||
|
<< (size_type(slot) * m_piece_size + offset + ret) << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs)
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
disk_buffer_pool* pool = disk_pool();
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
pool->m_disk_access_log << log_time() << " write "
|
||||||
|
<< (size_type(slot) * m_piece_size + offset) << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int ret = 0;
|
||||||
|
for (int i = 0; i < num_bufs; ++i)
|
||||||
|
ret += bufs[i].iov_len;
|
||||||
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
pool->m_disk_access_log << log_time() << " write_end "
|
||||||
|
<< (size_type(slot) * m_piece_size + offset + ret) << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool move_slot(int src_slot, int dst_slot) { return false; }
|
||||||
|
bool swap_slots(int slot1, int slot2) { return false; }
|
||||||
|
bool swap_slots3(int slot1, int slot2, int slot3) { return false; }
|
||||||
|
bool verify_resume_data(lazy_entry const& rd, error_code& error) { return false; }
|
||||||
|
bool write_resume_data(entry& rd) const { return false; }
|
||||||
|
|
||||||
|
int m_piece_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
storage_interface* disabled_storage_constructor(file_storage const& fs
|
||||||
|
, file_storage const* mapped, fs::path const& path, file_pool& fp)
|
||||||
|
{
|
||||||
|
return new disabled_storage(fs.piece_length());
|
||||||
|
}
|
||||||
|
|
||||||
// -- piece_manager -----------------------------------------------------
|
// -- piece_manager -----------------------------------------------------
|
||||||
|
|
||||||
piece_manager::piece_manager(
|
piece_manager::piece_manager(
|
||||||
|
|
Loading…
Reference in New Issue