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:
Arvid Norberg 2009-08-02 06:40:45 +00:00
parent cc4084f943
commit 63368c1383
6 changed files with 107 additions and 1 deletions

View File

@ -3557,6 +3557,7 @@ session_settings
int write_cache_line_size;
int optimistic_disk_retry;
bool disable_hash_check;
};
``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
`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
===========

View File

@ -175,6 +175,7 @@ namespace libtorrent
, read_cache_line_size(16)
, write_cache_line_size(32)
, optimistic_disk_retry(10 * 60)
, disable_hash_checks(false)
{}
// 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
// occurs until libtorrent will re-try.
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

View File

@ -195,6 +195,9 @@ namespace libtorrent
TORRENT_EXPORT storage_interface* default_storage_constructor(
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;
class TORRENT_EXPORT piece_manager

View File

@ -1488,7 +1488,8 @@ namespace libtorrent
test_error(j);
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)
{
j.storage->mark_failed(j.piece);
@ -1656,6 +1657,11 @@ namespace libtorrent
}
}
l.unlock();
if (m_settings.disable_hash_checks)
{
ret = 0;
break;
}
sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
if (test_error(j))
{
@ -1663,6 +1669,7 @@ namespace libtorrent
j.storage->mark_failed(j.piece);
break;
}
ret = (j.storage->info()->hash_for_piece(j.piece) == h)?0:-2;
if (ret == -2) j.storage->mark_failed(j.piece);
break;

View File

@ -648,6 +648,7 @@ namespace aux {
|| m_settings.coalesce_writes != s.coalesce_writes
|| m_settings.coalesce_reads != s.coalesce_reads
|| m_settings.max_queued_disk_bytes != s.max_queued_disk_bytes
|| m_settings.disable_hash_checks != s.disable_hash_checks
#ifndef TORRENT_DISABLE_MLOCK
|| m_settings.lock_disk_cache != s.lock_disk_cache
#endif

View File

@ -1448,6 +1448,85 @@ ret:
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(