public override bool remove(int seqno)
{
CGuard listguard = new CGuard(m_ListLock);
if (0 == m_iLength)
return false;
// Remove all from the head pointer to a node with a larger seq. no. or the list is empty
int offset = CSeqNo.seqoff(m_piData1[m_iHead], seqno);
int loc = (m_iHead + offset + m_iSize) % m_iSize;
if (0 == offset)
{
// It is the head. Remove the head and point to the next node
loc = (loc + 1) % m_iSize;
if (-1 == m_piData2[m_iHead])
loc = m_piNext[m_iHead];
else
{
m_piData1[loc] = CSeqNo.incseq(seqno);
if (CSeqNo.seqcmp(m_piData2[m_iHead], CSeqNo.incseq(seqno)) > 0)
m_piData2[loc] = m_piData2[m_iHead];
m_piData2[m_iHead] = -1;
m_piNext[loc] = m_piNext[m_iHead];
}
m_piData1[m_iHead] = -1;
if (m_iLastInsertPos == m_iHead)
m_iLastInsertPos = -1;
m_iHead = loc;
m_iLength--;
}
else if (offset > 0)
{
int h = m_iHead;
if (seqno == m_piData1[loc])
{
// target node is not empty, remove part/all of the seqno in the node.
int temp = loc;
loc = (loc + 1) % m_iSize;
if (-1 == m_piData2[temp])
m_iHead = m_piNext[temp];
else
{
// remove part, e.g., [3, 7] becomes [], [4, 7] after remove(3)
m_piData1[loc] = CSeqNo.incseq(seqno);
if (CSeqNo.seqcmp(m_piData2[temp], m_piData1[loc]) > 0)
m_piData2[loc] = m_piData2[temp];
m_iHead = loc;
m_piNext[loc] = m_piNext[temp];
m_piNext[temp] = loc;
m_piData2[temp] = -1;
}
}
else
{
// target node is empty, check prior node
int i = m_iHead;
while ((-1 != m_piNext[i]) && (CSeqNo.seqcmp(m_piData1[m_piNext[i]], seqno) < 0))
i = m_piNext[i];
loc = (loc + 1) % m_iSize;
if (-1 == m_piData2[i])
m_iHead = m_piNext[i];
else if (CSeqNo.seqcmp(m_piData2[i], seqno) > 0)
{
// remove part/all seqno in the prior node
m_piData1[loc] = CSeqNo.incseq(seqno);
if (CSeqNo.seqcmp(m_piData2[i], m_piData1[loc]) > 0)
m_piData2[loc] = m_piData2[i];
m_piData2[i] = seqno;
m_piNext[loc] = m_piNext[i];
m_piNext[i] = loc;
m_iHead = loc;
}
else
m_iHead = m_piNext[i];
}
// Remove all nodes prior to the new head
while (h != m_iHead)
{
if (m_piData2[h] != -1)
{
m_iLength -= CSeqNo.seqlen(m_piData1[h], m_piData2[h]);
m_piData2[h] = -1;
}
else
m_iLength--;
m_piData1[h] = -1;
if (m_iLastInsertPos == h)
m_iLastInsertPos = -1;
h = m_piNext[h];
}
}
return true;
}