added support for lazy bitfields

This commit is contained in:
Arvid Norberg 2007-05-26 22:27:40 +00:00
parent ea965431bf
commit 9fe77101ed
3 changed files with 61 additions and 4 deletions

View File

@ -101,6 +101,7 @@ namespace libtorrent
, ignore_limits_on_local_network(true)
, connection_speed(20)
, send_redundant_have(false)
, lazy_bitfields(true)
#ifndef TORRENT_DISABLE_DHT
, use_dht_as_fallback(true)
#endif
@ -219,6 +220,12 @@ namespace libtorrent
// for collecting statistics in some cases. Default is false.
bool send_redundant_have;
// if this is true, outgoing bitfields will never be fuil. If the
// client is seed, a few bits will be set to 0, and later filled
// in with have messages. This is to prevent certain ISPs
// from stopping people from seeding.
bool lazy_bitfields;
#ifndef TORRENT_DISABLE_DHT
// while this is true, the dht will note be used unless the
// tracker is online

View File

@ -775,19 +775,46 @@ namespace libtorrent
assert(m_sent_bitfield == false);
assert(t->valid_metadata());
int num_pieces = bitfield.size();
int lazy_pieces[50];
int num_lazy_pieces = 0;
int lazy_piece = 0;
assert(t->is_seed() == (std::count(bitfield.begin(), bitfield.end(), true) == num_pieces));
if (t->is_seed() && m_ses.settings().lazy_bitfields)
{
num_lazy_pieces = std::min(50, num_pieces / 10);
if (num_lazy_pieces < 1) num_lazy_pieces = 1;
for (int i = 0; i < num_pieces; ++i)
{
if (rand() % (num_pieces - i) >= num_lazy_pieces - lazy_piece) continue;
lazy_pieces[lazy_piece++] = i;
}
assert(lazy_piece == num_lazy_pieces);
lazy_piece = 0;
}
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() << " ==> BITFIELD ";
std::stringstream bitfield_string;
for (int i = 0; i < (int)get_bitfield().size(); ++i)
{
if (lazy_piece < num_lazy_pieces
&& lazy_pieces[lazy_piece] == i)
{
bitfield_string << "0";
++lazy_piece;
continue;
}
if (bitfield[i]) bitfield_string << "1";
else bitfield_string << "0";
}
bitfield_string << "\n";
(*m_logger) << bitfield_string.str();
lazy_piece = 0;
#endif
const int packet_size = ((int)bitfield.size() + 7) / 8 + 5;
const int packet_size = (num_pieces + 7) / 8 + 5;
buffer::interval i = allocate_send_buffer(packet_size);
@ -795,12 +822,31 @@ namespace libtorrent
detail::write_uint8(msg_bitfield, i.begin);
std::fill(i.begin, i.end, 0);
for (int c = 0; c < (int)bitfield.size(); ++c)
for (int c = 0; c < num_pieces; ++c)
{
if (lazy_piece < num_lazy_pieces
&& lazy_pieces[lazy_piece])
{
++lazy_piece;
continue;
}
if (bitfield[c])
i.begin[c >> 3] |= 1 << (7 - (c & 7));
}
assert(i.end - i.begin == ((int)bitfield.size() + 7) / 8);
assert(i.end - i.begin == (num_pieces + 7) / 8);
if (num_lazy_pieces > 0)
{
for (int i = 0; i < num_lazy_pieces; ++i)
{
write_have(lazy_pieces[i]);
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string()
<< " ==> HAVE [ piece: " << lazy_pieces[i] << "]\n";
#endif
}
}
#ifndef NDEBUG
m_sent_bitfield = true;
#endif

View File

@ -2581,6 +2581,10 @@ namespace libtorrent
d = time_now() - m_last_receive;
if (d > seconds(m_timeout)) return true;
// TODO: as long as we have less than 95% of the
// global (or local) connection limit, connections should
// never time out for another reason
// if the peer hasn't become interested and we haven't
// become interested in the peer for 10 minutes, it
// has also timed out.
@ -2636,7 +2640,7 @@ namespace libtorrent
bool peer_connection::is_seed() const
{
INVARIANT_CHECK;
// if m_num_pieces == 0, we probably doesn't have the
// if m_num_pieces == 0, we probably don't have the
// metadata yet.
return m_num_pieces == (int)m_have_piece.size() && m_num_pieces > 0;
}