diff --git a/docs/make_torrent.rst b/docs/make_torrent.rst index 575ac9010..fef6675c4 100644 --- a/docs/make_torrent.rst +++ b/docs/make_torrent.rst @@ -268,7 +268,7 @@ The ``create_torrent`` class has the following synopsis:: , calculate_file_hashes = 16 }; create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1 - , int flags = optimize); + , int flags = optimize, int alignment = 0x4000); create_torrent(torrent_info const& ti); entry generate() const; @@ -305,7 +305,7 @@ create_torrent() , calculate_file_hashes = 16 }; create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1 - , int flags = optimize); + , int flags = optimize, int alignment = 0x4000); create_torrent(torrent_info const& ti); The ``piece_size`` is the size of each piece in bytes. It must @@ -362,6 +362,10 @@ calculate_file_hashes with each file. Note that unless you use the `set_piece_hashes()`_ function, this flag will have no effect. +``alignment`` is used when pad files are enabled. This is the size eligible +files are aligned to. The default is the default bittorrent block size of +16 kiB. It is common to align to the piece size of the torrent. + generate() ---------- diff --git a/examples/dump_torrent.cpp b/examples/dump_torrent.cpp index 57aa7e553..f89e49c44 100644 --- a/examples/dump_torrent.cpp +++ b/examples/dump_torrent.cpp @@ -133,7 +133,8 @@ int main(int argc, char* argv[]) { int first = t.map_file(index, 0, 0).piece; int last = t.map_file(index, (std::max)(size_type(i->size)-1, size_type(0)), 0).piece; - printf(" %11"PRId64" %c%c%c%c [ %4d, %4d ] %7u %s %s %s%s\n" + printf(" %8"PRIx64" %11"PRId64" %c%c%c%c [ %5d, %5d ] %7u %s %s %s%s\n" + , i->offset , i->size , (i->pad_file?'p':'-') , (i->executable_attribute?'x':'-') diff --git a/include/libtorrent/create_torrent.hpp b/include/libtorrent/create_torrent.hpp index b40b5c77e..1ce86be7e 100644 --- a/include/libtorrent/create_torrent.hpp +++ b/include/libtorrent/create_torrent.hpp @@ -74,7 +74,7 @@ namespace libtorrent }; create_torrent(file_storage& fs, int piece_size = 0 - , int pad_file_limit = -1, int flags = optimize); + , int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000); create_torrent(torrent_info const& ti); ~create_torrent(); entry generate() const; diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index 7f2a2453d..e9d961b1d 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -244,7 +244,7 @@ namespace libtorrent // if pad_file_limit >= 0, files larger than // that limit will be padded, default is to // not add any padding - void optimize(int pad_file_limit = -1); + void optimize(int pad_file_limit = -1, int alignment = 0x10000); sha1_hash hash(int index) const; std::string const& symlink(int index) const; diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index a9dad6a85..69b4143d2 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -261,7 +261,7 @@ namespace libtorrent create_torrent::~create_torrent() {} - create_torrent::create_torrent(file_storage& fs, int piece_size, int pad_file_limit, int flags) + create_torrent::create_torrent(file_storage& fs, int piece_size, int pad_file_limit, int flags, int alignment) : m_files(fs) , m_creation_date(time(0)) , m_multifile(fs.num_files() > 1) @@ -310,7 +310,7 @@ namespace libtorrent #endif m_files.set_piece_length(piece_size); if (flags & optimize) - m_files.optimize(pad_file_limit); + m_files.optimize(pad_file_limit, alignment); m_files.set_num_pieces(static_cast( (m_files.total_size() + m_files.piece_length() - 1) / m_files.piece_length())); m_piece_hash.resize(m_files.num_pieces()); diff --git a/src/file_storage.cpp b/src/file_storage.cpp index f07deaee9..b8b0ad857 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -515,14 +515,16 @@ namespace libtorrent } } - void file_storage::optimize(int pad_file_limit) + void file_storage::optimize(int pad_file_limit, int alignment) { - // the main purpuse of padding is to optimize disk - // I/O. This is a conservative memory page size assumption - int alignment = 8*1024; - // it doesn't make any sense to pad files that - // are smaller than one piece + // are smaller than one block + if (pad_file_limit >= 0 && pad_file_limit < 0x4000) + pad_file_limit = 0x4000; + + // also, it doesn't make any sense to pad files + // that are smaller than the alignment, since they + // won't get aligned anyway; they are used as padding if (pad_file_limit >= 0 && pad_file_limit < alignment) pad_file_limit = alignment; @@ -615,9 +617,8 @@ namespace libtorrent reorder_file(index, cur_index); - // skip the pad file we just added and point - // at the current file again - ++i; + TORRENT_ASSERT((off & (alignment-1)) == 0); + continue; } i->offset = off; off += i->size;