From 735916ad44adc4329620b137805792ecfb5356d7 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 18 Jun 2014 06:22:01 +0000 Subject: [PATCH] remove restrictions on pad_file_limit and alignment when creating torrents. This makes the torrent creator more flexible to create all-padded files for instance --- include/libtorrent/create_torrent.hpp | 8 ++-- include/libtorrent/file_storage.hpp | 11 +++-- src/create_torrent.cpp | 3 +- src/file_storage.cpp | 64 +++++++++++++-------------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/include/libtorrent/create_torrent.hpp b/include/libtorrent/create_torrent.hpp index 150cbae45..e1983b28a 100644 --- a/include/libtorrent/create_torrent.hpp +++ b/include/libtorrent/create_torrent.hpp @@ -166,11 +166,11 @@ namespace libtorrent // The ``flags`` arguments specifies options for the torrent creation. It can // be any combination of the flags defined by create_torrent::flags_t. // - // ``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. + // ``alignment`` is used when pad files are enabled. This is the size + // eligible files are aligned to. The default is -1, which means the + // piece size of the torrent. create_torrent(file_storage& fs, int piece_size = 0 - , int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000); + , int pad_file_limit = -1, int flags = optimize, int alignment = -1); create_torrent(torrent_info const& ti); // internal diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index 8c626866c..a91b44027 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -402,10 +402,13 @@ namespace libtorrent swap(ti.m_piece_length, m_piece_length); } - // 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, int alignment = 0x10000); + // if pad_file_limit >= 0, files larger than that limit will be padded, + // default is to not add any padding (-1). The alignment specifies the + // alignment files should be padded to. This defaults to the piece size + // (-1) but it may also make sense to set it to 16 kiB, or something + // divisible by 16 kiB. + // If pad_file_limit is 0, every file will be padded (except empty ones). + void optimize(int pad_file_limit = -1, int alignment = -1); // These functions are used to query attributes of files at // a given index. diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index ca9f7c542..c814be8db 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -264,7 +264,8 @@ namespace libtorrent create_torrent::~create_torrent() {} - create_torrent::create_torrent(file_storage& fs, int piece_size, int pad_file_limit, int flags, int alignment) + 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) diff --git a/src/file_storage.cpp b/src/file_storage.cpp index 74eb5d598..59db97a58 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -681,23 +681,15 @@ namespace libtorrent void file_storage::optimize(int pad_file_limit, int alignment) { - // it doesn't make any sense to pad files that - // 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; + if (alignment == -1) + alignment = m_piece_length; size_type off = 0; int padding_file = 0; for (std::vector::iterator i = m_files.begin(); i != m_files.end(); ++i) { - if ((off & (alignment-1)) == 0) + if ((off % alignment) == 0) { // this file position is aligned, pick the largest // available file to put here @@ -721,32 +713,38 @@ namespace libtorrent // not piece-aligned and the file size exceeds the // limit, and it's not a padding file itself. // so add a padding file in front of it - int pad_size = alignment - (off & (alignment-1)); + int pad_size = alignment - (off % alignment); // find the largest file that fits in pad_size std::vector::iterator best_match = m_files.end(); - for (std::vector::iterator j = i+1; j < m_files.end(); ++j) - { - if (j->size > pad_size) continue; - if (best_match == m_files.end() || j->size > best_match->size) - best_match = j; - } - if (best_match != m_files.end()) + // if pad_file_limit is 0, it means all files are padded, there's + // no point in trying to find smaller files to use as filling + if (pad_file_limit > 0) { - // we found one - // We cannot have found i, because i->size > pad_file_limit - // which is forced to be no less than alignment. We only - // look for files <= pad_size, which never is greater than - // alignment - TORRENT_ASSERT(best_match != i); - int index = best_match - m_files.begin(); - int cur_index = i - m_files.begin(); - reorder_file(index, cur_index); - i = m_files.begin() + cur_index; - i->offset = off; - off += i->size; - continue; + for (std::vector::iterator j = i+1; j < m_files.end(); ++j) + { + if (j->size > pad_size) continue; + if (best_match == m_files.end() || j->size > best_match->size) + best_match = j; + } + + if (best_match != m_files.end()) + { + // we found one + // We cannot have found i, because i->size > pad_file_limit + // which is forced to be no less than alignment. We only + // look for files <= pad_size, which never is greater than + // alignment + TORRENT_ASSERT(best_match != i); + int index = best_match - m_files.begin(); + int cur_index = i - m_files.begin(); + reorder_file(index, cur_index); + i = m_files.begin() + cur_index; + i->offset = off; + off += i->size; + continue; + } } // we could not find a file that fits in pad_size @@ -780,7 +778,7 @@ namespace libtorrent reorder_file(index, cur_index); - TORRENT_ASSERT((off & (alignment-1)) == 0); + TORRENT_ASSERT((off % alignment) == 0); continue; } i->offset = off;