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,
// the buffer will be resized.
// if m_mask is 0xf, m_array has 16 elements
// m_cursor is the lowest index that has an element
// m_capacity is the number of elements in m_array
// 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
// refers to. Since it's a circular buffer, it wraps
// around. For example
// m_cursor = 9
// m_first = 9
// | refers to index 14
// | |
// V V
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | | | | | | | | | | | | | | | | | m_mask = 0xf
// | | | | | | | | | | | | | | | | | mask = (m_capacity-1)
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// ^
// |
@ -93,6 +94,10 @@ namespace libtorrent
index_type span() const
{ return (m_last - m_first) & 0xffff; }
#ifdef TORRENT_DEBUG
void check_invariant() const;
#endif
private:
void** m_storage;
std::size_t m_capacity;

View File

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