📄 list.cpp
字号:
if (m_iLastInsertPos == h) m_iLastInsertPos = -1; h = m_piNext[h]; } }}int CSndLossList::getLossLength(){ CGuard listguard(m_ListLock); return m_iLength;}int32_t CSndLossList::getLostSeq(){ if (0 == m_iLength) return -1; CGuard listguard(m_ListLock); if (0 == m_iLength) return -1; if (m_iLastInsertPos == m_iHead) m_iLastInsertPos = -1; // return the first loss seq. no. int32_t seqno = m_piData1[m_iHead]; // head moves to the next node if (-1 == m_piData2[m_iHead]) { //[3, -1] becomes [], and head moves to next node in the list m_piData1[m_iHead] = -1; m_iHead = m_piNext[m_iHead]; } else { // shift to next node, e.g., [3, 7] becomes [], [4, 7] int loc = (m_iHead + 1) % m_iSize; m_piData1[loc] = CSeqNo::incseq(seqno); if (CSeqNo::seqcmp(m_piData2[m_iHead], m_piData1[loc]) > 0) m_piData2[loc] = m_piData2[m_iHead]; m_piData1[m_iHead] = -1; m_piData2[m_iHead] = -1; m_piNext[loc] = m_piNext[m_iHead]; m_iHead = loc; } m_iLength --; return seqno;}////////////////////////////////////////////////////////////////////////////////CRcvLossList::CRcvLossList(const int& size):m_piData1(NULL),m_piData2(NULL),m_piNext(NULL),m_piPrior(NULL),m_iSize(size){ m_piData1 = new int32_t [m_iSize]; m_piData2 = new int32_t [m_iSize]; m_piNext = new int [m_iSize]; m_piPrior = new int [m_iSize]; // -1 means there is no data in the node for (int i = 0; i < size; ++ i) { m_piData1[i] = -1; m_piData2[i] = -1; } m_iLength = 0; m_iHead = -1; m_iTail = -1; m_TimeStamp = CTimer::getTime();}CRcvLossList::~CRcvLossList(){ delete [] m_piData1; delete [] m_piData2; delete [] m_piNext; delete [] m_piPrior;}void CRcvLossList::insert(const int32_t& seqno1, const int32_t& seqno2){ m_TimeStamp = CTimer::getTime(); // Data to be inserted must be larger than all those in the list // guaranteed by the UDT receiver if (0 == m_iLength) { // insert data into an empty list m_iHead = 0; m_iTail = 0; m_piData1[m_iHead] = seqno1; if (seqno2 != seqno1) m_piData2[m_iHead] = seqno2; m_piNext[m_iHead] = -1; m_piPrior[m_iHead] = -1; m_iLength += CSeqNo::seqlen(seqno1, seqno2); return; } // otherwise searching for the position where the node should be int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1); int loc = (m_iHead + offset) % m_iSize; if ((-1 != m_piData2[m_iTail]) && (CSeqNo::incseq(m_piData2[m_iTail]) == seqno1)) { // coalesce with prior node, e.g., [2, 5], [6, 7] becomes [2, 7] loc = m_iTail; m_piData2[loc] = seqno2; } else { // create new node m_piData1[loc] = seqno1; if (seqno2 != seqno1) m_piData2[loc] = seqno2; m_piNext[m_iTail] = loc; m_piPrior[loc] = m_iTail; m_piNext[loc] = -1; m_iTail = loc; } m_iLength += CSeqNo::seqlen(seqno1, seqno2);}bool CRcvLossList::remove(const int32_t& seqno){ m_TimeStamp = CTimer::getTime(); if (0 == m_iLength) return false; // locate the position of "seqno" in the list int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno); if (offset < 0) return false; int loc = (m_iHead + offset) % m_iSize; if (seqno == m_piData1[loc]) { // This is a seq. no. that starts the loss sequence if (-1 == m_piData2[loc]) { // there is only 1 loss in the sequence, delete it from the node if (m_iHead == loc) { m_iHead = m_piNext[m_iHead]; if (-1 != m_iHead) m_piPrior[m_iHead] = -1; } else { m_piNext[m_piPrior[loc]] = m_piNext[loc]; if (-1 != m_piNext[loc]) m_piPrior[m_piNext[loc]] = m_piPrior[loc]; else m_iTail = m_piPrior[loc]; } m_piData1[loc] = -1; } else { // there are more than 1 loss in the sequence // move the node to the next and update the starter as the next loss inSeqNo(seqno) // find next node int i = (loc + 1) % m_iSize; // remove the "seqno" and change the starter as next seq. no. m_piData1[i] = CSeqNo::incseq(m_piData1[loc]); // process the sequence end if (CSeqNo::seqcmp(m_piData2[loc], CSeqNo::incseq(m_piData1[loc])) > 0) m_piData2[i] = m_piData2[loc]; // remove the current node m_piData1[loc] = -1; m_piData2[loc] = -1; // update list pointer m_piNext[i] = m_piNext[loc]; m_piPrior[i] = m_piPrior[loc]; if (m_iHead == loc) m_iHead = i; else m_piNext[m_piPrior[i]] = i; if (m_iTail == loc) m_iTail = i; else m_piPrior[m_piNext[i]] = i; } m_iLength --; return true; } // There is no loss sequence in the current position // the "seqno" may be contained in a previous node // searching previous node int i = (loc - 1 + m_iSize) % m_iSize; while (-1 == m_piData1[i]) i = (i - 1 + m_iSize) % m_iSize; // not contained in this node, return if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(seqno, m_piData2[i]) > 0)) return false; if (seqno == m_piData2[i]) { // it is the sequence end if (seqno == CSeqNo::incseq(m_piData1[i])) m_piData2[i] = -1; else m_piData2[i] = CSeqNo::decseq(seqno); } else { // split the sequence // construct the second sequence from CSeqNo::incseq(seqno) to the original sequence end // located at "loc + 1" loc = (loc + 1) % m_iSize; m_piData1[loc] = CSeqNo::incseq(seqno); if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0) m_piData2[loc] = m_piData2[i]; // the first (original) sequence is between the original sequence start to CSeqNo::decseq(seqno) if (seqno == CSeqNo::incseq(m_piData1[i])) m_piData2[i] = -1; else m_piData2[i] = CSeqNo::decseq(seqno); // update the list pointer m_piNext[loc] = m_piNext[i]; m_piNext[i] = loc; m_piPrior[loc] = i; if (m_iTail == i) m_iTail = loc; else m_piPrior[m_piNext[loc]] = loc; } m_iLength --; return true;}bool CRcvLossList::remove(const int32_t& seqno1, const int32_t& seqno2){ if (seqno1 <= seqno2) { for (int32_t i = seqno1; i <= seqno2; ++ i) remove(i); } else { for (int32_t j = seqno1; j < CSeqNo::m_iMaxSeqNo; ++ j) remove(j); for (int32_t k = 0; k <= seqno2; ++ k) remove(k); } return true;}bool CRcvLossList::find(const int32_t& seqno1, const int32_t& seqno2) const{ if (0 == m_iLength) return false; int p = m_iHead; while (-1 != p) { if ((CSeqNo::seqcmp(m_piData1[p], seqno1) == 0) || ((CSeqNo::seqcmp(m_piData1[p], seqno1) > 0) && (CSeqNo::seqcmp(m_piData1[p], seqno2) <= 0)) || ((CSeqNo::seqcmp(m_piData1[p], seqno1) < 0) && (m_piData2[p] != -1) && CSeqNo::seqcmp(m_piData2[p], seqno1) >= 0)) return true; p = m_piNext[p]; } return false;}int CRcvLossList::getLossLength() const{ return m_iLength;}int CRcvLossList::getFirstLostSeq() const{ if (0 == m_iLength) return -1; return m_piData1[m_iHead];}void CRcvLossList::getLossArray(int32_t* array, int& len, const int& limit, const int& threshold){ len = 0; // do not feedback NAK unless no retransmission is received within a certain interval if (int(CTimer::getTime() - m_TimeStamp) < threshold) return; int i = m_iHead; while ((len < limit - 1) && (-1 != i)) { array[len] = m_piData1[i]; if (-1 != m_piData2[i]) { // there are more than 1 loss in the sequence array[len] |= 0x80000000; ++ len; array[len] = m_piData2[i]; } ++ len; i = m_piNext[i]; } m_TimeStamp = CTimer::getTime();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -