Add advance(int) to mxs::Buffer iterators
This makes iterating over packets in buffers faster while still maintaining the requirements for forward iterators. Not using operator+= makes it clear that this is not a random access iterator.
This commit is contained in:
@ -78,6 +78,42 @@ public:
|
|||||||
return &m_i;
|
return &m_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the iterator
|
||||||
|
*
|
||||||
|
* This provides similar behavior to random access iterators with operator+= but does it in
|
||||||
|
* non-constant time.
|
||||||
|
*
|
||||||
|
* @param i Number of steps to advance the iterator
|
||||||
|
*/
|
||||||
|
void advance(int i)
|
||||||
|
{
|
||||||
|
mxb_assert(m_i != m_end);
|
||||||
|
mxb_assert(i >= 0);
|
||||||
|
|
||||||
|
while (m_i && m_i + i >= m_end)
|
||||||
|
{
|
||||||
|
i -= m_end - m_i;
|
||||||
|
m_pBuffer = m_pBuffer->next;
|
||||||
|
|
||||||
|
if (m_pBuffer)
|
||||||
|
{
|
||||||
|
m_i = GWBUF_DATA(m_pBuffer);
|
||||||
|
m_end = m_i + GWBUF_LENGTH(m_pBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_i = NULL;
|
||||||
|
m_end = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_i)
|
||||||
|
{
|
||||||
|
m_i += i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
iterator_base(buf_type pBuffer = NULL)
|
iterator_base(buf_type pBuffer = NULL)
|
||||||
: m_pBuffer(pBuffer)
|
: m_pBuffer(pBuffer)
|
||||||
|
@ -196,19 +196,19 @@ Iter skip_encoded_int(Iter it)
|
|||||||
switch (*it)
|
switch (*it)
|
||||||
{
|
{
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
std::advance(it, 3);
|
it.advance(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xfd:
|
case 0xfd:
|
||||||
std::advance(it, 4);
|
it.advance(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xfe:
|
case 0xfe:
|
||||||
std::advance(it, 9);
|
it.advance(9);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::advance(it, 1);
|
++it;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +293,8 @@ void RWBackend::process_packets(GWBUF* result)
|
|||||||
len |= (*it++) << 16;
|
len |= (*it++) << 16;
|
||||||
++it; // Skip the sequence
|
++it; // Skip the sequence
|
||||||
mxb_assert(it != buffer.end());
|
mxb_assert(it != buffer.end());
|
||||||
auto end = std::next(it, len);
|
auto end = it;
|
||||||
|
end.advance(len);
|
||||||
uint8_t cmd = *it;
|
uint8_t cmd = *it;
|
||||||
|
|
||||||
// Ignore the tail end of a large packet large packet. Only resultsets can generate packets this large
|
// Ignore the tail end of a large packet large packet. Only resultsets can generate packets this large
|
||||||
|
Reference in New Issue
Block a user