deprecated compact storage allocation

This commit is contained in:
Arvid Norberg 2011-08-22 00:51:14 +00:00
parent a2e24faa01
commit 51ed06304e
8 changed files with 49 additions and 37 deletions

View File

@ -1,3 +1,4 @@
* deprecated compact storage allocation
* close files in separate thread on systems where close() may block (Mac OS X for instance)
* don't create all directories up front when adding torrents
* support DHT scrape

View File

@ -431,7 +431,9 @@ void bind_session()
enum_<storage_mode_t>("storage_mode_t")
.value("storage_mode_allocate", storage_mode_allocate)
.value("storage_mode_sparse", storage_mode_sparse)
#ifndef TORRENT_NO_DEPRECATE
.value("storage_mode_compact", storage_mode_compact)
#endif
;
enum_<session::options_t>("options_t")

View File

@ -69,8 +69,6 @@ disk management
* queues torrents for file check, instead of checking all of them in parallel.
* does not have any requirements on the piece order in a torrent that it
resumes. This means it can resume a torrent downloaded by any client.
* supports both sparse files and compact file allocation (where pieces
are kept consolidated on disk)
* seed mode, where the files on disk are assumed to be complete, and each
piece's hash is verified the first time it is requested.

View File

@ -462,6 +462,7 @@ storage_mode_allocate
``fallocate()`` and similar calls. This mode minimizes fragmentation.
storage_mode_compact
**this mode is deprecated and will be removed in future versions of libtorrent**
The storage will grow as more pieces are downloaded, and pieces
are rearranged to finally be in their correct places once the entire torrent has been
downloaded.
@ -8470,7 +8471,7 @@ libtorrent starts 2 or 3 threads.
storage allocation
==================
There are three modes in which storage (files on disk) are allocated in libtorrent.
There are two modes in which storage (files on disk) are allocated in libtorrent.
1. The traditional *full allocation* mode, where the entire files are filled up with
zeros before anything is downloaded. libtorrent will look for sparse files support
@ -8478,12 +8479,13 @@ There are three modes in which storage (files on disk) are allocated in libtorre
zero fill support if present. This means that on NTFS, full allocation mode will
only allocate storage for the downloaded pieces.
2. The *compact allocation* mode, where only files are allocated for actual
pieces that have been downloaded.
3. The *sparse allocation*, sparse files are used, and pieces are downloaded directly
2. The *sparse allocation*, sparse files are used, and pieces are downloaded directly
to where they belong. This is the recommended (and default) mode.
In previous versions of libtorrent, a 3rd mode was supported, *compact allocation*.
Support for this is deprecated and will be removed in future versions of libtorrent.
It's still described in here for completeness.
The allocation mode is selected when a torrent is started. It is passed as an
argument to ``session::add_torrent()`` (see `add_torrent()`_).
@ -8539,6 +8541,9 @@ The benefits of this mode are:
compact allocation
------------------
Note that support for compact allocation is deprecated in libttorrent, and will
be removed in future versions.
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

View File

@ -1036,7 +1036,7 @@ int main(int argc, char* argv[])
#endif
" -l <limit> sets the listen socket queue size\n"
"\n DISK OPTIONS\n"
" -a <mode> sets the allocation mode. [compact|full]\n"
" -a <mode> sets the allocation mode. [sparse|full]\n"
" -R <num blocks> number of blocks per read cache line\n"
" -C <limit> sets the max cache size. Specified in 16kB blocks\n"
" -O Disallow disk job reordering\n"
@ -1161,7 +1161,7 @@ int main(int argc, char* argv[])
case 'S': settings.unchoke_slots_limit = atoi(arg); break;
case 'a':
if (strcmp(arg, "allocate") == 0) allocation_mode = storage_mode_allocate;
if (strcmp(arg, "compact") == 0) allocation_mode = storage_mode_compact;
if (strcmp(arg, "sparse") == 0) allocation_mode = storage_mode_sparse;
break;
case 's': save_path = arg; break;
case 'U': torrent_upload_limit = atoi(arg) * 1000; break;

View File

@ -409,8 +409,10 @@ namespace libtorrent
// this function returns true if the checking is complete
int check_files(int& current_slot, int& have_piece, error_code& error);
#ifndef TORRENT_NO_DEPRECATE
bool compact_allocation() const
{ return m_storage_mode == storage_mode_compact; }
#endif
#ifdef TORRENT_DEBUG
std::string name() const { return m_info->name(); }

View File

@ -47,7 +47,11 @@ namespace libtorrent
{
storage_mode_allocate = 0,
storage_mode_sparse,
storage_mode_compact
// this is here for internal use
internal_storage_mode_compact_deprecated,
#ifndef TORRENT_NO_DEPRECATE
storage_mode_compact = internal_storage_mode_compact_deprecated
#endif
};
typedef boost::function<storage_interface*(file_storage const&, file_storage const*

View File

@ -1735,7 +1735,7 @@ ret:
m_storage->write_resume_data(rd);
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
entry::list_type& slots = rd["slots"].list();
slots.clear();
@ -1764,7 +1764,7 @@ ret:
INVARIANT_CHECK;
if (m_storage_mode != storage_mode_compact) return;
if (m_storage_mode != internal_storage_mode_compact_deprecated) return;
TORRENT_ASSERT(piece_index >= 0 && piece_index < (int)m_piece_to_slot.size());
int slot_index = m_piece_to_slot[piece_index];
@ -1984,7 +1984,7 @@ ret:
// that piece as unassigned, since this slot
// is the correct place for the piece.
m_slot_to_piece[other_slot] = unassigned;
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
m_free_slots.push_back(other_slot);
}
TORRENT_ASSERT(m_piece_to_slot[piece_index] != current_slot);
@ -2036,7 +2036,7 @@ ret:
m_piece_to_slot.resize(m_files.num_pieces(), has_no_slot);
m_slot_to_piece.clear();
m_slot_to_piece.resize(m_files.num_pieces(), unallocated);
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
m_unallocated_slots.clear();
m_free_slots.clear();
@ -2046,7 +2046,7 @@ ret:
}
}
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
// in compact mode without checking, we need to
// populate the unallocated list
@ -2073,7 +2073,7 @@ ret:
m_state = state_finished;
m_scratch_buffer.reset();
m_scratch_buffer2.reset();
if (m_storage_mode != storage_mode_compact)
if (m_storage_mode != internal_storage_mode_compact_deprecated)
{
// if no piece is out of place
// since we're in full allocation mode, we can
@ -2119,7 +2119,7 @@ ret:
return check_no_fastresume(error);
}
storage_mode_t storage_mode = storage_mode_compact;
storage_mode_t storage_mode = internal_storage_mode_compact_deprecated;
if (rd.dict_find_string_value("allocation") != "compact")
storage_mode = storage_mode_sparse;
@ -2132,7 +2132,7 @@ ret:
// if we don't have a piece map, we need the slots
// if we're in compact mode, we also need the slots map
if (storage_mode == storage_mode_compact || rd.dict_find("pieces") == 0)
if (storage_mode == internal_storage_mode_compact_deprecated || rd.dict_find("pieces") == 0)
{
// read slots map
lazy_entry const* slots = rd.dict_find_list("slots");
@ -2148,7 +2148,7 @@ ret:
return check_no_fastresume(error);
}
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
int num_pieces = int(m_files.num_pieces());
m_slot_to_piece.resize(num_pieces, unallocated);
@ -2176,13 +2176,13 @@ ret:
}
else if (index == unassigned)
{
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
m_free_slots.push_back(i);
}
else
{
TORRENT_ASSERT(index == unallocated);
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
m_unallocated_slots.push_back(i);
}
}
@ -2213,7 +2213,7 @@ ret:
// by check_pieces.
// m_storage->shuffle();
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
if (m_unallocated_slots.empty()) switch_to_full_mode();
}
@ -2235,7 +2235,7 @@ ret:
}
}
else if (m_storage_mode == storage_mode_compact)
else if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
// read piece map
lazy_entry const* pieces = rd.dict_find("pieces");
@ -2423,7 +2423,7 @@ ret:
// piece overlapping with a sparse region. We should skip 'skip' number
// of pieces
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
for (int i = m_current_slot; i < m_current_slot + skip - 1; ++i)
{
@ -2447,7 +2447,7 @@ ret:
// clear the memory we've been using
std::multimap<sha1_hash, int>().swap(m_hash_to_piece);
if (m_storage_mode != storage_mode_compact)
if (m_storage_mode != internal_storage_mode_compact_deprecated)
{
if (!m_out_of_place)
{
@ -2612,7 +2612,7 @@ ret:
std::vector<int>::iterator i =
std::find(m_free_slots.begin(), m_free_slots.end(), other_slot);
TORRENT_ASSERT(i != m_free_slots.end());
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
m_free_slots.erase(i);
m_free_slots.push_back(m_current_slot);
@ -2645,7 +2645,7 @@ ret:
m_piece_to_slot[other_piece] = m_current_slot;
if (piece_index == unassigned
&& m_storage_mode == storage_mode_compact)
&& m_storage_mode == internal_storage_mode_compact_deprecated)
m_free_slots.push_back(other_slot);
bool ret = false;
@ -2726,7 +2726,7 @@ ret:
std::vector<int>::iterator i =
std::find(m_free_slots.begin(), m_free_slots.end(), slot1);
TORRENT_ASSERT(i != m_free_slots.end());
if (m_storage_mode == storage_mode_compact)
if (m_storage_mode == internal_storage_mode_compact_deprecated)
{
m_free_slots.erase(i);
m_free_slots.push_back(slot2);
@ -2761,7 +2761,7 @@ ret:
// the slot was identified as piece 'piece_index'
if (piece_index != unassigned)
m_piece_to_slot[piece_index] = m_current_slot;
else if (m_storage_mode == storage_mode_compact)
else if (m_storage_mode == internal_storage_mode_compact_deprecated)
m_free_slots.push_back(m_current_slot);
m_slot_to_piece[m_current_slot] = piece_index;
@ -2785,7 +2785,7 @@ ret:
void piece_manager::switch_to_full_mode()
{
TORRENT_ASSERT(m_storage_mode == storage_mode_compact);
TORRENT_ASSERT(m_storage_mode == internal_storage_mode_compact_deprecated);
TORRENT_ASSERT(m_unallocated_slots.empty());
// we have allocated all slots, switch to
// full allocation mode in order to free
@ -2801,7 +2801,7 @@ ret:
{
mutex::scoped_lock lock(m_mutex);
if (m_storage_mode != storage_mode_compact) return piece_index;
if (m_storage_mode != internal_storage_mode_compact_deprecated) return piece_index;
INVARIANT_CHECK;
@ -2922,7 +2922,7 @@ ret:
#endif
TORRENT_ASSERT(!m_unallocated_slots.empty());
TORRENT_ASSERT(m_storage_mode == storage_mode_compact);
TORRENT_ASSERT(m_storage_mode == internal_storage_mode_compact_deprecated);
bool written = false;
@ -2954,7 +2954,7 @@ ret:
int piece_manager::slot_for(int piece) const
{
if (m_storage_mode != storage_mode_compact) return piece;
if (m_storage_mode != internal_storage_mode_compact_deprecated) return piece;
TORRENT_ASSERT(piece < int(m_piece_to_slot.size()));
TORRENT_ASSERT(piece >= 0);
return m_piece_to_slot[piece];
@ -2962,7 +2962,7 @@ ret:
int piece_manager::piece_for(int slot) const
{
if (m_storage_mode != storage_mode_compact) return slot;
if (m_storage_mode != internal_storage_mode_compact_deprecated) return slot;
TORRENT_ASSERT(slot < int(m_slot_to_piece.size()));
TORRENT_ASSERT(slot >= 0);
return m_slot_to_piece[slot];
@ -2977,17 +2977,17 @@ ret:
&& m_free_slots.empty()
&& m_state == state_finished)
{
TORRENT_ASSERT(m_storage_mode != storage_mode_compact
TORRENT_ASSERT(m_storage_mode != internal_storage_mode_compact_deprecated
|| m_files.num_pieces() == 0);
}
if (m_storage_mode != storage_mode_compact)
if (m_storage_mode != internal_storage_mode_compact_deprecated)
{
TORRENT_ASSERT(m_unallocated_slots.empty());
TORRENT_ASSERT(m_free_slots.empty());
}
if (m_storage_mode != storage_mode_compact
if (m_storage_mode != internal_storage_mode_compact_deprecated
&& m_state != state_expand_pieces
&& m_state != state_full_check)
{