From 10b64a7761dc11ec06a35c4d2bd0bb8366e6d93d Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 2 May 2012 18:55:58 +0000 Subject: [PATCH] add all_set() function on bitfield and automatically call inc_refcount_all or dec_refcount_all if all bits are set in a bitfield --- include/libtorrent/bitfield.hpp | 22 ++++++++++++++++++++++ include/libtorrent/torrent.hpp | 10 ++++++++-- test/test_primitives.cpp | 4 ++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/libtorrent/bitfield.hpp b/include/libtorrent/bitfield.hpp index f970c7257..b4288c5b7 100644 --- a/include/libtorrent/bitfield.hpp +++ b/include/libtorrent/bitfield.hpp @@ -81,6 +81,28 @@ namespace libtorrent m_bytes[index / 8] &= ~(0x80 >> (index & 7)); } + // returns true if all bits in the bitfield are set + bool all_set() const + { + const int num_words = m_size / 32; + const int num_bytes = m_size / 8; + boost::uint32_t* bits = (boost::uint32_t*)m_bytes; + for (int i = 0; i < num_words; ++i) + { + if (bits[i] != 0xffffffff) return false; + } + + for (int i = num_words * 4; i < num_bytes; ++i) + { + if (m_bytes[i] != 0xff) return false; + } + int rest = m_size - num_bytes * 8; + boost::uint8_t mask = 0xff << (8-rest); + if (rest > 0 && (m_bytes[num_bytes] & mask) != mask) + return false; + return true; + } + void set_bit(int index) { TORRENT_ASSERT(index >= 0); diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 3cc602bcc..f8f7251e0 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -539,7 +539,10 @@ namespace libtorrent { if (has_picker()) { - m_picker->inc_refcount(bits); + if (bits.all_set()) + m_picker->inc_refcount_all(); + else + m_picker->inc_refcount(bits); } #ifdef TORRENT_DEBUG else @@ -567,7 +570,10 @@ namespace libtorrent { if (has_picker()) { - m_picker->dec_refcount(bits); + if (bits.all_set()) + m_picker->dec_refcount_all(); + else + m_picker->dec_refcount(bits); } #ifdef TORRENT_DEBUG else diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index 79fd9f733..ad0d474d5 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -1797,6 +1797,7 @@ int test_main() test1.set_bit(1); test1.set_bit(9); TEST_CHECK(test1.count() == 3); + TEST_CHECK(test1.all_set() == false); test1.clear_bit(2); TEST_CHECK(test1.count() == 2); int distance = std::distance(test1.begin(), test1.end()); @@ -1818,6 +1819,9 @@ int test_main() test1.set_bit(1); test1.resize(1); TEST_CHECK(test1.count() == 1); + + test1.resize(100, true); + TEST_CHECK(test1.all_set() == true); return 0; }