diff --git a/ChangeLog b/ChangeLog index 65ce1c155..4ffc7267c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * optimized the torrent creator optimizer to scale significantly better with more files * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP diff --git a/src/file_storage.cpp b/src/file_storage.cpp index c59d286ef..f07deaee9 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -494,43 +494,24 @@ namespace libtorrent TORRENT_ASSERT(dst < int(m_files.size())); TORRENT_ASSERT(dst < index); - internal_file_entry e = m_files[index]; - m_files.erase(m_files.begin() + index); - m_files.insert(m_files.begin() + dst, e); + std::iter_swap(m_files.begin() + index, m_files.begin() + dst); if (!m_mtime.empty()) { TORRENT_ASSERT(m_mtime.size() == m_files.size()); - time_t mtime = 0; - if (int(m_mtime.size()) > index) - { - mtime = m_mtime[index]; - m_mtime.erase(m_mtime.begin() + index); - } - if (dst > int(m_mtime.size())) m_mtime.resize(dst, 0); - m_mtime.insert(m_mtime.begin() + dst, mtime); + if (int(m_mtime.size()) < index) m_mtime.resize(index+1, 0); + std::iter_swap(m_mtime.begin() + dst, m_mtime.begin() + index); } if (!m_file_hashes.empty()) { TORRENT_ASSERT(m_file_hashes.size() == m_files.size()); - char const* fh = 0; - if (int(m_file_hashes.size()) > index) - { - fh = m_file_hashes[index]; - m_file_hashes.erase(m_file_hashes.begin() + index); - } - if (int(m_file_hashes.size()) < dst) m_file_hashes.resize(dst, NULL); - m_file_hashes.insert(m_file_hashes.begin() + dst, fh); + if (int(m_file_hashes.size()) < index) m_file_hashes.resize(index + 1, NULL); + std::iter_swap(m_file_hashes.begin() + dst, m_file_hashes.begin() + index); } if (!m_file_base.empty()) { TORRENT_ASSERT(m_file_base.size() == m_files.size()); - size_type base = 0; - if (int(m_file_base.size()) > index) - { - base = m_file_base[index]; - m_file_base.erase(m_file_base.begin() + index); - } - m_file_base.insert(m_file_base.begin() + dst, base); + if (int(m_file_base.size()) < index) m_file_base.resize(index + 1, NULL); + std::iter_swap(m_file_base.begin() + dst, m_file_base.begin() + index); } } @@ -608,27 +589,31 @@ namespace libtorrent // note that i will be set to point to the // new pad file. Once we're done adding it, we need // to increment i to point to the current file again - internal_file_entry e; + // first add the pad file to the end of the file list + // then swap it in place. This minimizes the amount + // of copying of internal_file_entry, which is somewhat + // expensive (until we have move semantics) int cur_index = file_index(*i); - i = m_files.insert(i, e); - i->size = pad_size; - i->offset = off; + int index = m_files.size(); + m_files.push_back(internal_file_entry()); + internal_file_entry& e = m_files.back(); + // i may have been invalidated, refresh it + i = m_files.begin() + cur_index; + e.size = pad_size; + e.offset = off; char name[30]; snprintf(name, sizeof(name), ".____padding_file/%d", padding_file); std::string path = combine_path(m_name, name); - i->set_name(path.c_str()); - i->pad_file = true; + e.set_name(path.c_str()); + e.pad_file = true; off += pad_size; ++padding_file; - if (int(m_mtime.size()) > cur_index) - m_mtime.insert(m_mtime.begin() + cur_index, 0); + if (!m_mtime.empty()) m_mtime.resize(index + 1, 0); + if (!m_file_hashes.empty()) m_file_hashes.resize(index + 1, NULL); + if (!m_file_base.empty()) m_file_base.resize(index + 1, 0); - if (int(m_file_hashes.size()) > cur_index) - m_file_hashes.insert(m_file_hashes.begin() + cur_index, NULL); - - if (int(m_file_base.size()) > cur_index) - m_file_base.insert(m_file_base.begin() + cur_index, 0); + reorder_file(index, cur_index); // skip the pad file we just added and point // at the current file again