diff --git a/docs/manual.rst b/docs/manual.rst index b99d713f7..7e6804388 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -394,10 +394,6 @@ The file format is a bencoded dictionary containing the following fields: | | means it is free, that there's no piece there. If it is -1, | | | means the slot isn't allocated on disk yet. The pieces have | | | to meet the following requirement: | -| | | -| | If there's a slot at the position of the piece index, | -| | the piece must be located in that slot. | -| | | +--------------------------+--------------------------------------------------------------+ | ``total_uploaded`` | integer. The number of bytes that have been uploaded in | | | total for this torrent. | @@ -579,61 +575,6 @@ The benefits of this mode are: * No risk of a download failing because of a full disk during download, once all files have been created. -compact allocation ------------------- - -.. note:: - Support for compact allocation has been removed from libttorrent - -The compact allocation will only allocate as much storage as it needs to keep -the pieces downloaded so far. This means that pieces will be moved around to be -placed at their final position in the files while downloading (to make sure the -completed download has all its pieces in the correct place). So, the main -drawbacks are: - - * More disk operations while downloading since pieces are moved around. - - * Potentially more fragmentation in the filesystem. - - * Cannot be used while having files with priority 0. - -The benefits though, are: - - * No startup delay, since the files don't need allocating. - - * The download will not use unnecessary disk space. - - * Disk caches perform much better than in full allocation and raises the - download speed limit imposed by the disk. - - * Works well on filesystems that don't support sparse files. - -The algorithm that is used when allocating pieces and slots isn't very -complicated. For the interested, a description follows. - -storing a piece: - -1. let **A** be a newly downloaded piece, with index **n**. -2. let **s** be the number of slots allocated in the file we're - downloading to. (the number of pieces it has room for). -3. if **n** >= **s** then allocate a new slot and put the piece there. -4. if **n** < **s** then allocate a new slot, move the data at - slot **n** to the new slot and put **A** in slot **n**. - -allocating a new slot: - -1. if there's an unassigned slot (a slot that doesn't - contain any piece), return that slot index. -2. append the new slot at the end of the file (or find an unused slot). -3. let **i** be the index of newly allocated slot -4. if we have downloaded piece index **i** already (to slot **j**) then - - 1. move the data at slot **j** to slot **i**. - 2. return slot index **j** as the newly allocated free slot. - -5. return **i** as the newly allocated slot. - - HTTP seeding ============ diff --git a/docs/storage.diagram b/docs/storage.diagram index 895607642..616d4f754 100644 --- a/docs/storage.diagram +++ b/docs/storage.diagram @@ -7,7 +7,7 @@ v +--------------------------+ | "piece_manager" | -| "(maps pieces to slots)" | +| "disk job fence logic" | +--------------------------+ ^ | @@ -15,13 +15,13 @@ /----------------------------\ +-------------------+ | "storage" |<---->| "file_pool" | | | | "open file cache" | -| "(maps slots to file and" | +-------------------+ +| "(maps pieces to file and" | +-------------------+ | "offset. reads and writes" | -| "to disk)" | +--------------------+ -| |<-----+ "file_storage" | -\----------------------------/ | "standard slot to" | - ^ | "file mapping" | - | +--------------------+ +| "to disk)" | +---------------------+ +| |<-----+ "file_storage" | +\----------------------------/ | "standard piece to" | + ^ | "file mapping" | + | +---------------------+ v +--------------------------+ | "file" | diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 50a7f6e31..c60cf11c1 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -90,9 +90,9 @@ POSSIBILITY OF SUCH DAMAGE. // temp_storage(file_storage const& fs) : m_files(fs) {} // virtual bool initialize(storage_error& se) { return false; } // virtual bool has_any_file() { return false; } -// virtual int read(char* buf, int slot, int offset, int size) +// virtual int read(char* buf, int piece, int offset, int size) // { -// std::map >::const_iterator i = m_file_data.find(slot); +// std::map >::const_iterator i = m_file_data.find(piece); // if (i == m_file_data.end()) return 0; // int available = i->second.size() - offset; // if (available <= 0) return 0; @@ -100,9 +100,9 @@ POSSIBILITY OF SUCH DAMAGE. // memcpy(buf, &i->second[offset], available); // return available; // } -// virtual int write(const char* buf, int slot, int offset, int size) +// virtual int write(const char* buf, int piece, int offset, int size) // { -// std::vector& data = m_file_data[slot]; +// std::vector& data = m_file_data[piece]; // if (data.size() < offset + size) data.resize(offset + size); // std::memcpy(&data[offset], buf, size); // return size; @@ -114,15 +114,15 @@ POSSIBILITY OF SUCH DAMAGE. // , std::vector const* links // , storage_error& error) { return false; } // virtual bool write_resume_data(entry& rd) const { return false; } -// virtual boost::int64_t physical_offset(int slot, int offset) -// { return slot * m_files.piece_length() + offset; }; -// virtual sha1_hash hash_for_slot(int slot, partial_hash& ph, int piece_size) +// virtual boost::int64_t physical_offset(int piece, int offset) +// { return piece * m_files.piece_length() + offset; }; +// virtual sha1_hash hash_for_slot(int piece, partial_hash& ph, int piece_size) // { // int left = piece_size - ph.offset; // assert(left >= 0); // if (left > 0) // { -// std::vector& data = m_file_data[slot]; +// std::vector& data = m_file_data[piece]; // // if there are padding files, those blocks will be considered // // completed even though they haven't been written to the storage. // // in this case, just extend the piece buffer to its full size @@ -202,9 +202,10 @@ namespace libtorrent // but modifies some particular behavior, for instance encrypting the data // before it's written to disk, and decrypting it when it's read again. // - // The storage interface is based on slots, each slot is 'piece_size' number + // The storage interface is based on pieces. Avery read and write operation + // happens in the piece-space. Each piece fits 'piece_size' number // of bytes. All access is done by writing and reading whole or partial - // slots. One slot is one piece in the torrent. + // pieces. // // libtorrent comes with two built-in storage implementations; // ``default_storage`` and ``disabled_storage``. Their constructor functions @@ -466,7 +467,7 @@ namespace libtorrent }; void delete_one_file(std::string const& p, error_code& ec); - int readwritev(file::iovec_t const* bufs, int slot, int offset + int readwritev(file::iovec_t const* bufs, int piece, int offset , int num_bufs, fileop const& op, storage_error& ec); void need_partfile(); @@ -477,7 +478,7 @@ namespace libtorrent // in order to avoid calling stat() on each file multiple times // during startup, cache the results in here, and clear it all // out once the torrent starts (to avoid getting stale results) - // each slot represents the size and timestamp of the file + // each entry represents the size and timestamp of the file mutable stat_cache m_stat_cache; // helper function to open a file in the file pool with the right mode diff --git a/src/storage.cpp b/src/storage.cpp index 7a19b649d..076f7f384 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -714,12 +714,12 @@ namespace libtorrent } } - int default_storage::sparse_end(int slot) const + int default_storage::sparse_end(int piece) const { - TORRENT_ASSERT(slot >= 0); - TORRENT_ASSERT(slot < files().num_pieces()); + TORRENT_ASSERT(piece >= 0); + TORRENT_ASSERT(piece < files().num_pieces()); - boost::int64_t file_offset = boost::int64_t(slot) * files().piece_length(); + boost::int64_t file_offset = boost::int64_t(piece) * files().piece_length(); int file_index = 0; for (;;) @@ -734,7 +734,7 @@ namespace libtorrent error_code ec; file_handle handle = open_file_impl(file_index, file::read_only, ec); - if (ec) return slot; + if (ec) return piece; boost::int64_t data_start = handle->sparse_end(file_offset); return int((data_start + files().piece_length() - 1) / files().piece_length()); @@ -1096,7 +1096,7 @@ namespace libtorrent } int default_storage::readv(file::iovec_t const* bufs, int num_bufs - , int slot, int offset, int flags, storage_error& ec) + , int piece, int offset, int flags, storage_error& ec) { fileop op = { &file::readv , file::read_only | flags }; @@ -1104,15 +1104,15 @@ namespace libtorrent boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(1000)); #endif - return readwritev(bufs, slot, offset, num_bufs, op, ec); + return readwritev(bufs, piece, offset, num_bufs, op, ec); } int default_storage::writev(file::iovec_t const* bufs, int num_bufs - , int slot, int offset, int flags, storage_error& ec) + , int piece, int offset, int flags, storage_error& ec) { fileop op = { &file::writev , file::read_write | flags }; - return readwritev(bufs, slot, offset, num_bufs, op, ec); + return readwritev(bufs, piece, offset, num_bufs, op, ec); } // much of what needs to be done when reading and writing @@ -1121,12 +1121,12 @@ namespace libtorrent // is a template, and the fileop decides what to do with the // file and the buffers. int default_storage::readwritev(file::iovec_t const* const bufs - , const int slot, const int offset + , const int piece, const int offset , const int num_bufs, fileop const& op, storage_error& ec) { TORRENT_ASSERT(bufs != 0); - TORRENT_ASSERT(slot >= 0); - TORRENT_ASSERT(slot < m_files.num_pieces()); + TORRENT_ASSERT(piece >= 0); + TORRENT_ASSERT(piece < m_files.num_pieces()); TORRENT_ASSERT(offset >= 0); TORRENT_ASSERT(num_bufs > 0); @@ -1135,7 +1135,7 @@ namespace libtorrent TORRENT_ASSERT(files().is_loaded()); // find the file iterator and file offset - boost::uint64_t torrent_offset = slot * boost::uint64_t(m_files.piece_length()) + offset; + boost::uint64_t torrent_offset = piece * boost::uint64_t(m_files.piece_length()) + offset; int file_index = files().file_index_at_offset(torrent_offset); TORRENT_ASSERT(torrent_offset >= files().file_offset(file_index)); TORRENT_ASSERT(torrent_offset < files().file_offset(file_index) + files().file_size(file_index)); @@ -1229,13 +1229,13 @@ namespace libtorrent // the fileop object. // write bytes_transferred = m_part_file->writev(tmp_bufs, num_tmp_bufs - , slot, offset, e); + , piece, offset, e); } else { // read bytes_transferred = m_part_file->readv(tmp_bufs, num_tmp_bufs - , slot, offset, e); + , piece, offset, e); } if (e) {