packet buffer comment fix and support for inserting NULLs

This commit is contained in:
Arvid Norberg 2011-01-30 19:35:20 +00:00
parent 19ae5440f2
commit ad87e84e47
2 changed files with 36 additions and 9 deletions

View File

@ -45,18 +45,19 @@ namespace libtorrent
// old elements are removed when new elements are inserted, // old elements are removed when new elements are inserted,
// the buffer will be resized. // the buffer will be resized.
// if m_mask is 0xf, m_array has 16 elements // m_capacity is the number of elements in m_array
// m_cursor is the lowest index that has an element // and must be an even 2^x.
// m_first is the lowest index that has an element
// it also determines which indices the other slots // it also determines which indices the other slots
// refers to. Since it's a circular buffer, it wraps // refers to. Since it's a circular buffer, it wraps
// around. For example // around. For example
// m_cursor = 9 // m_first = 9
// | refers to index 14 // | refers to index 14
// | | // | |
// V V // V V
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | | | | | | | | | | | | | | | | | m_mask = 0xf // | | | | | | | | | | | | | | | | | mask = (m_capacity-1)
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// ^ // ^
// | // |
@ -93,6 +94,10 @@ namespace libtorrent
index_type span() const index_type span() const
{ return (m_last - m_first) & 0xffff; } { return (m_last - m_first) & 0xffff; }
#ifdef TORRENT_DEBUG
void check_invariant() const;
#endif
private: private:
void** m_storage; void** m_storage;
std::size_t m_capacity; std::size_t m_capacity;

View File

@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h> // free and calloc #include <stdlib.h> // free and calloc
#include "libtorrent/packet_buffer.hpp" #include "libtorrent/packet_buffer.hpp"
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/invariant_check.hpp"
namespace libtorrent { namespace libtorrent {
@ -47,6 +48,18 @@ namespace libtorrent {
, m_last(0) , m_last(0)
{} {}
#ifdef TORRENT_DEBUG
void packet_buffer::check_invariant() const
{
int count = 0;
for (int i = 0; i < m_capacity; ++i)
{
count += m_storage[i] ? 1 : 0;
}
TORRENT_ASSERT(count == m_size);
}
#endif
packet_buffer::~packet_buffer() packet_buffer::~packet_buffer()
{ {
free(m_storage); free(m_storage);
@ -54,10 +67,14 @@ namespace libtorrent {
void* packet_buffer::insert(index_type idx, void* value) void* packet_buffer::insert(index_type idx, void* value)
{ {
INVARIANT_CHECK;
TORRENT_ASSERT_VAL(idx <= 0xffff, idx); TORRENT_ASSERT_VAL(idx <= 0xffff, idx);
// you're not allowed to insert NULLs! // you're not allowed to insert NULLs!
TORRENT_ASSERT(value); TORRENT_ASSERT(value);
if (value == 0) return remove(idx);
if (m_size != 0) if (m_size != 0)
{ {
if (compare_less_wrap(idx, m_first, 0xffff)) if (compare_less_wrap(idx, m_first, 0xffff))
@ -117,6 +134,7 @@ namespace libtorrent {
void* packet_buffer::at(index_type idx) const void* packet_buffer::at(index_type idx) const
{ {
INVARIANT_CHECK;
if (idx >= m_first + m_capacity) if (idx >= m_first + m_capacity)
return 0; return 0;
@ -125,11 +143,13 @@ namespace libtorrent {
return 0; return 0;
} }
return m_storage[idx & (m_capacity - 1)]; const int mask = (m_capacity - 1);
return m_storage[idx & mask];
} }
void packet_buffer::reserve(std::size_t size) void packet_buffer::reserve(std::size_t size)
{ {
INVARIANT_CHECK;
TORRENT_ASSERT_VAL(size <= 0xffff, size); TORRENT_ASSERT_VAL(size <= 0xffff, size);
std::size_t new_size = m_capacity == 0 ? 16 : m_capacity; std::size_t new_size = m_capacity == 0 ? 16 : m_capacity;
@ -152,6 +172,7 @@ namespace libtorrent {
void* packet_buffer::remove(index_type idx) void* packet_buffer::remove(index_type idx)
{ {
INVARIANT_CHECK;
// TODO: use compare_less_wrap for this comparison as well // TODO: use compare_less_wrap for this comparison as well
if (idx >= m_first + m_capacity) if (idx >= m_first + m_capacity)
return 0; return 0;
@ -159,8 +180,9 @@ namespace libtorrent {
if (compare_less_wrap(idx, m_first, 0xffff)) if (compare_less_wrap(idx, m_first, 0xffff))
return 0; return 0;
void* old_value = m_storage[idx & (m_capacity - 1)]; const int mask = (m_capacity - 1);
m_storage[idx & (m_capacity - 1)] = 0; void* old_value = m_storage[idx & mask];
m_storage[idx & mask] = 0;
if (old_value) if (old_value)
{ {
@ -170,13 +192,13 @@ namespace libtorrent {
if (idx == m_first && m_size != 0) if (idx == m_first && m_size != 0)
{ {
while (!m_storage[++m_first & (m_capacity - 1)]); while (!m_storage[++m_first & mask]);
m_first &= 0xffff; m_first &= 0xffff;
} }
if (((idx + 1) & 0xffff) == m_last && m_size != 0) if (((idx + 1) & 0xffff) == m_last && m_size != 0)
{ {
while (!m_storage[--m_last & (m_capacity - 1)]); while (!m_storage[--m_last & mask]);
++m_last; ++m_last;
m_last &= 0xffff; m_last &= 0xffff;
} }