00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "list.h"
00042
00043 CSndLossList::CSndLossList(int size):
00044 m_piData1(NULL),
00045 m_piData2(NULL),
00046 m_piNext(NULL),
00047 m_iHead(-1),
00048 m_iLength(0),
00049 m_iSize(size),
00050 m_iLastInsertPos(-1),
00051 m_ListLock()
00052 {
00053 m_piData1 = new int32_t [m_iSize];
00054 m_piData2 = new int32_t [m_iSize];
00055 m_piNext = new int [m_iSize];
00056
00057
00058 for (int i = 0; i < size; ++ i)
00059 {
00060 m_piData1[i] = -1;
00061 m_piData2[i] = -1;
00062 }
00063
00064
00065 #ifndef WIN32
00066 pthread_mutex_init(&m_ListLock, 0);
00067 #else
00068 m_ListLock = CreateMutex(NULL, false, NULL);
00069 #endif
00070 }
00071
00072 CSndLossList::~CSndLossList()
00073 {
00074 delete [] m_piData1;
00075 delete [] m_piData2;
00076 delete [] m_piNext;
00077
00078 #ifndef WIN32
00079 pthread_mutex_destroy(&m_ListLock);
00080 #else
00081 CloseHandle(m_ListLock);
00082 #endif
00083 }
00084
00085 int CSndLossList::insert(int32_t seqno1, int32_t seqno2)
00086 {
00087 CGuard listguard(m_ListLock);
00088
00089 if (0 == m_iLength)
00090 {
00091
00092
00093 m_iHead = 0;
00094 m_piData1[m_iHead] = seqno1;
00095 if (seqno2 != seqno1)
00096 m_piData2[m_iHead] = seqno2;
00097
00098 m_piNext[m_iHead] = -1;
00099 m_iLastInsertPos = m_iHead;
00100
00101 m_iLength += CSeqNo::seqlen(seqno1, seqno2);
00102
00103 return m_iLength;
00104 }
00105
00106
00107 int origlen = m_iLength;
00108 int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1);
00109 int loc = (m_iHead + offset + m_iSize) % m_iSize;
00110
00111 if (offset < 0)
00112 {
00113
00114
00115 m_piData1[loc] = seqno1;
00116 if (seqno2 != seqno1)
00117 m_piData2[loc] = seqno2;
00118
00119
00120 m_piNext[loc] = m_iHead;
00121 m_iHead = loc;
00122 m_iLastInsertPos = loc;
00123
00124 m_iLength += CSeqNo::seqlen(seqno1, seqno2);
00125 }
00126 else if (offset > 0)
00127 {
00128 if (seqno1 == m_piData1[loc])
00129 {
00130 m_iLastInsertPos = loc;
00131
00132
00133 if (-1 == m_piData2[loc])
00134 {
00135 if (seqno2 != seqno1)
00136 {
00137 m_iLength += CSeqNo::seqlen(seqno1, seqno2) - 1;
00138 m_piData2[loc] = seqno2;
00139 }
00140 }
00141 else if (CSeqNo::seqcmp(seqno2, m_piData2[loc]) > 0)
00142 {
00143
00144 m_iLength += CSeqNo::seqlen(m_piData2[loc], seqno2) - 1;
00145 m_piData2[loc] = seqno2;
00146 }
00147 else
00148
00149 return 0;
00150 }
00151 else
00152 {
00153
00154 int i;
00155 if ((-1 != m_iLastInsertPos) && (CSeqNo::seqcmp(m_piData1[m_iLastInsertPos], seqno1) < 0))
00156 i = m_iLastInsertPos;
00157 else
00158 i = m_iHead;
00159
00160 while ((-1 != m_piNext[i]) && (CSeqNo::seqcmp(m_piData1[m_piNext[i]], seqno1) < 0))
00161 i = m_piNext[i];
00162
00163 if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(m_piData2[i], seqno1) < 0))
00164 {
00165 m_iLastInsertPos = loc;
00166
00167
00168 m_piData1[loc] = seqno1;
00169 if (seqno2 != seqno1)
00170 m_piData2[loc] = seqno2;
00171
00172 m_piNext[loc] = m_piNext[i];
00173 m_piNext[i] = loc;
00174
00175 m_iLength += CSeqNo::seqlen(seqno1, seqno2);
00176 }
00177 else
00178 {
00179 m_iLastInsertPos = i;
00180
00181
00182 if (CSeqNo::seqcmp(m_piData2[i], seqno2) < 0)
00183 {
00184 m_iLength += CSeqNo::seqlen(m_piData2[i], seqno2) - 1;
00185 m_piData2[i] = seqno2;
00186
00187 loc = i;
00188 }
00189 else
00190 return 0;
00191 }
00192 }
00193 }
00194 else
00195 {
00196 m_iLastInsertPos = m_iHead;
00197
00198
00199 if (seqno2 != seqno1)
00200 {
00201 if (-1 == m_piData2[loc])
00202 {
00203 m_iLength += CSeqNo::seqlen(seqno1, seqno2) - 1;
00204 m_piData2[loc] = seqno2;
00205 }
00206 else if (CSeqNo::seqcmp(seqno2, m_piData2[loc]) > 0)
00207 {
00208 m_iLength += CSeqNo::seqlen(m_piData2[loc], seqno2) - 1;
00209 m_piData2[loc] = seqno2;
00210 }
00211 else
00212 return 0;
00213 }
00214 else
00215 return 0;
00216 }
00217
00218
00219 while ((-1 != m_piNext[loc]) && (-1 != m_piData2[loc]))
00220 {
00221 int i = m_piNext[loc];
00222
00223 if (CSeqNo::seqcmp(m_piData1[i], CSeqNo::incseq(m_piData2[loc])) <= 0)
00224 {
00225
00226 if (-1 != m_piData2[i])
00227 {
00228 if (CSeqNo::seqcmp(m_piData2[i], m_piData2[loc]) > 0)
00229 {
00230 if (CSeqNo::seqcmp(m_piData2[loc], m_piData1[i]) >= 0)
00231 m_iLength -= CSeqNo::seqlen(m_piData1[i], m_piData2[loc]);
00232
00233 m_piData2[loc] = m_piData2[i];
00234 }
00235 else
00236 m_iLength -= CSeqNo::seqlen(m_piData1[i], m_piData2[i]);
00237 }
00238 else
00239 {
00240 if (m_piData1[i] == CSeqNo::incseq(m_piData2[loc]))
00241 m_piData2[loc] = m_piData1[i];
00242 else
00243 m_iLength --;
00244 }
00245
00246 m_piData1[i] = -1;
00247 m_piData2[i] = -1;
00248 m_piNext[loc] = m_piNext[i];
00249 }
00250 else
00251 break;
00252 }
00253
00254 return m_iLength - origlen;
00255 }
00256
00257 void CSndLossList::remove(int32_t seqno)
00258 {
00259 CGuard listguard(m_ListLock);
00260
00261 if (0 == m_iLength)
00262 return;
00263
00264
00265 int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno);
00266 int loc = (m_iHead + offset + m_iSize) % m_iSize;
00267
00268 if (0 == offset)
00269 {
00270
00271 loc = (loc + 1) % m_iSize;
00272
00273 if (-1 == m_piData2[m_iHead])
00274 loc = m_piNext[m_iHead];
00275 else
00276 {
00277 m_piData1[loc] = CSeqNo::incseq(seqno);
00278 if (CSeqNo::seqcmp(m_piData2[m_iHead], CSeqNo::incseq(seqno)) > 0)
00279 m_piData2[loc] = m_piData2[m_iHead];
00280
00281 m_piData2[m_iHead] = -1;
00282
00283 m_piNext[loc] = m_piNext[m_iHead];
00284 }
00285
00286 m_piData1[m_iHead] = -1;
00287
00288 if (m_iLastInsertPos == m_iHead)
00289 m_iLastInsertPos = -1;
00290
00291 m_iHead = loc;
00292
00293 m_iLength --;
00294 }
00295 else if (offset > 0)
00296 {
00297 int h = m_iHead;
00298
00299 if (seqno == m_piData1[loc])
00300 {
00301
00302 int temp = loc;
00303 loc = (loc + 1) % m_iSize;
00304
00305 if (-1 == m_piData2[temp])
00306 m_iHead = m_piNext[temp];
00307 else
00308 {
00309
00310 m_piData1[loc] = CSeqNo::incseq(seqno);
00311 if (CSeqNo::seqcmp(m_piData2[temp], m_piData1[loc]) > 0)
00312 m_piData2[loc] = m_piData2[temp];
00313 m_iHead = loc;
00314 m_piNext[loc] = m_piNext[temp];
00315 m_piNext[temp] = loc;
00316 m_piData2[temp] = -1;
00317 }
00318 }
00319 else
00320 {
00321
00322 int i = m_iHead;
00323 while ((-1 != m_piNext[i]) && (CSeqNo::seqcmp(m_piData1[m_piNext[i]], seqno) < 0))
00324 i = m_piNext[i];
00325
00326 loc = (loc + 1) % m_iSize;
00327
00328 if (-1 == m_piData2[i])
00329 m_iHead = m_piNext[i];
00330 else if (CSeqNo::seqcmp(m_piData2[i], seqno) > 0)
00331 {
00332
00333 m_piData1[loc] = CSeqNo::incseq(seqno);
00334 if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0)
00335 m_piData2[loc] = m_piData2[i];
00336
00337 m_piData2[i] = seqno;
00338
00339 m_piNext[loc] = m_piNext[i];
00340 m_piNext[i] = loc;
00341
00342 m_iHead = loc;
00343 }
00344 else
00345 m_iHead = m_piNext[i];
00346 }
00347
00348
00349 while (h != m_iHead)
00350 {
00351 if (m_piData2[h] != -1)
00352 {
00353 m_iLength -= CSeqNo::seqlen(m_piData1[h], m_piData2[h]);
00354 m_piData2[h] = -1;
00355 }
00356 else
00357 m_iLength --;
00358
00359 m_piData1[h] = -1;
00360
00361 if (m_iLastInsertPos == h)
00362 m_iLastInsertPos = -1;
00363
00364 h = m_piNext[h];
00365 }
00366 }
00367 }
00368
00369 int CSndLossList::getLossLength()
00370 {
00371 CGuard listguard(m_ListLock);
00372
00373 return m_iLength;
00374 }
00375
00376 int32_t CSndLossList::getLostSeq()
00377 {
00378 if (0 == m_iLength)
00379 return -1;
00380
00381 CGuard listguard(m_ListLock);
00382
00383 if (0 == m_iLength)
00384 return -1;
00385
00386 if (m_iLastInsertPos == m_iHead)
00387 m_iLastInsertPos = -1;
00388
00389
00390 int32_t seqno = m_piData1[m_iHead];
00391
00392
00393 if (-1 == m_piData2[m_iHead])
00394 {
00395
00396 m_piData1[m_iHead] = -1;
00397 m_iHead = m_piNext[m_iHead];
00398 }
00399 else
00400 {
00401
00402 int loc = (m_iHead + 1) % m_iSize;
00403
00404 m_piData1[loc] = CSeqNo::incseq(seqno);
00405 if (CSeqNo::seqcmp(m_piData2[m_iHead], m_piData1[loc]) > 0)
00406 m_piData2[loc] = m_piData2[m_iHead];
00407
00408 m_piData1[m_iHead] = -1;
00409 m_piData2[m_iHead] = -1;
00410
00411 m_piNext[loc] = m_piNext[m_iHead];
00412 m_iHead = loc;
00413 }
00414
00415 m_iLength --;
00416
00417 return seqno;
00418 }
00419
00421
00422 CRcvLossList::CRcvLossList(int size):
00423 m_piData1(NULL),
00424 m_piData2(NULL),
00425 m_piNext(NULL),
00426 m_piPrior(NULL),
00427 m_iHead(-1),
00428 m_iTail(-1),
00429 m_iLength(0),
00430 m_iSize(size)
00431 {
00432 m_piData1 = new int32_t [m_iSize];
00433 m_piData2 = new int32_t [m_iSize];
00434 m_piNext = new int [m_iSize];
00435 m_piPrior = new int [m_iSize];
00436
00437
00438 for (int i = 0; i < size; ++ i)
00439 {
00440 m_piData1[i] = -1;
00441 m_piData2[i] = -1;
00442 }
00443 }
00444
00445 CRcvLossList::~CRcvLossList()
00446 {
00447 delete [] m_piData1;
00448 delete [] m_piData2;
00449 delete [] m_piNext;
00450 delete [] m_piPrior;
00451 }
00452
00453 void CRcvLossList::insert(int32_t seqno1, int32_t seqno2)
00454 {
00455
00456
00457
00458 if (0 == m_iLength)
00459 {
00460
00461 m_iHead = 0;
00462 m_iTail = 0;
00463 m_piData1[m_iHead] = seqno1;
00464 if (seqno2 != seqno1)
00465 m_piData2[m_iHead] = seqno2;
00466
00467 m_piNext[m_iHead] = -1;
00468 m_piPrior[m_iHead] = -1;
00469 m_iLength += CSeqNo::seqlen(seqno1, seqno2);
00470
00471 return;
00472 }
00473
00474
00475 int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1);
00476 int loc = (m_iHead + offset) % m_iSize;
00477
00478 if ((-1 != m_piData2[m_iTail]) && (CSeqNo::incseq(m_piData2[m_iTail]) == seqno1))
00479 {
00480
00481 loc = m_iTail;
00482 m_piData2[loc] = seqno2;
00483 }
00484 else
00485 {
00486
00487 m_piData1[loc] = seqno1;
00488
00489 if (seqno2 != seqno1)
00490 m_piData2[loc] = seqno2;
00491
00492 m_piNext[m_iTail] = loc;
00493 m_piPrior[loc] = m_iTail;
00494 m_piNext[loc] = -1;
00495 m_iTail = loc;
00496 }
00497
00498 m_iLength += CSeqNo::seqlen(seqno1, seqno2);
00499 }
00500
00501 bool CRcvLossList::remove(int32_t seqno)
00502 {
00503 if (0 == m_iLength)
00504 return false;
00505
00506
00507 int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno);
00508 if (offset < 0)
00509 return false;
00510
00511 int loc = (m_iHead + offset) % m_iSize;
00512
00513 if (seqno == m_piData1[loc])
00514 {
00515
00516
00517 if (-1 == m_piData2[loc])
00518 {
00519
00520 if (m_iHead == loc)
00521 {
00522 m_iHead = m_piNext[m_iHead];
00523 if (-1 != m_iHead)
00524 m_piPrior[m_iHead] = -1;
00525 }
00526 else
00527 {
00528 m_piNext[m_piPrior[loc]] = m_piNext[loc];
00529 if (-1 != m_piNext[loc])
00530 m_piPrior[m_piNext[loc]] = m_piPrior[loc];
00531 else
00532 m_iTail = m_piPrior[loc];
00533 }
00534
00535 m_piData1[loc] = -1;
00536 }
00537 else
00538 {
00539
00540
00541
00542
00543 int i = (loc + 1) % m_iSize;
00544
00545
00546 m_piData1[i] = CSeqNo::incseq(m_piData1[loc]);
00547
00548
00549 if (CSeqNo::seqcmp(m_piData2[loc], CSeqNo::incseq(m_piData1[loc])) > 0)
00550 m_piData2[i] = m_piData2[loc];
00551
00552
00553 m_piData1[loc] = -1;
00554 m_piData2[loc] = -1;
00555
00556
00557 m_piNext[i] = m_piNext[loc];
00558 m_piPrior[i] = m_piPrior[loc];
00559
00560 if (m_iHead == loc)
00561 m_iHead = i;
00562 else
00563 m_piNext[m_piPrior[i]] = i;
00564
00565 if (m_iTail == loc)
00566 m_iTail = i;
00567 else
00568 m_piPrior[m_piNext[i]] = i;
00569 }
00570
00571 m_iLength --;
00572
00573 return true;
00574 }
00575
00576
00577
00578
00579
00580 int i = (loc - 1 + m_iSize) % m_iSize;
00581 while (-1 == m_piData1[i])
00582 i = (i - 1 + m_iSize) % m_iSize;
00583
00584
00585 if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(seqno, m_piData2[i]) > 0))
00586 return false;
00587
00588 if (seqno == m_piData2[i])
00589 {
00590
00591
00592 if (seqno == CSeqNo::incseq(m_piData1[i]))
00593 m_piData2[i] = -1;
00594 else
00595 m_piData2[i] = CSeqNo::decseq(seqno);
00596 }
00597 else
00598 {
00599
00600
00601
00602
00603 loc = (loc + 1) % m_iSize;
00604
00605 m_piData1[loc] = CSeqNo::incseq(seqno);
00606 if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0)
00607 m_piData2[loc] = m_piData2[i];
00608
00609
00610 if (seqno == CSeqNo::incseq(m_piData1[i]))
00611 m_piData2[i] = -1;
00612 else
00613 m_piData2[i] = CSeqNo::decseq(seqno);
00614
00615
00616 m_piNext[loc] = m_piNext[i];
00617 m_piNext[i] = loc;
00618 m_piPrior[loc] = i;
00619
00620 if (m_iTail == i)
00621 m_iTail = loc;
00622 else
00623 m_piPrior[m_piNext[loc]] = loc;
00624 }
00625
00626 m_iLength --;
00627
00628 return true;
00629 }
00630
00631 bool CRcvLossList::remove(int32_t seqno1, int32_t seqno2)
00632 {
00633 if (seqno1 <= seqno2)
00634 {
00635 for (int32_t i = seqno1; i <= seqno2; ++ i)
00636 remove(i);
00637 }
00638 else
00639 {
00640 for (int32_t j = seqno1; j < CSeqNo::m_iMaxSeqNo; ++ j)
00641 remove(j);
00642 for (int32_t k = 0; k <= seqno2; ++ k)
00643 remove(k);
00644 }
00645
00646 return true;
00647 }
00648
00649 bool CRcvLossList::find(int32_t seqno1, int32_t seqno2) const
00650 {
00651 if (0 == m_iLength)
00652 return false;
00653
00654 int p = m_iHead;
00655
00656 while (-1 != p)
00657 {
00658 if ((CSeqNo::seqcmp(m_piData1[p], seqno1) == 0) ||
00659 ((CSeqNo::seqcmp(m_piData1[p], seqno1) > 0) && (CSeqNo::seqcmp(m_piData1[p], seqno2) <= 0)) ||
00660 ((CSeqNo::seqcmp(m_piData1[p], seqno1) < 0) && (m_piData2[p] != -1) && CSeqNo::seqcmp(m_piData2[p], seqno1) >= 0))
00661 return true;
00662
00663 p = m_piNext[p];
00664 }
00665
00666 return false;
00667 }
00668
00669 int CRcvLossList::getLossLength() const
00670 {
00671 return m_iLength;
00672 }
00673
00674 int CRcvLossList::getFirstLostSeq() const
00675 {
00676 if (0 == m_iLength)
00677 return -1;
00678
00679 return m_piData1[m_iHead];
00680 }
00681
00682 void CRcvLossList::getLossArray(int32_t* array, int& len, int limit)
00683 {
00684 len = 0;
00685
00686 int i = m_iHead;
00687
00688 while ((len < limit - 1) && (-1 != i))
00689 {
00690 array[len] = m_piData1[i];
00691 if (-1 != m_piData2[i])
00692 {
00693
00694 array[len] |= 0x80000000;
00695 ++ len;
00696 array[len] = m_piData2[i];
00697 }
00698
00699 ++ len;
00700
00701 i = m_piNext[i];
00702 }
00703 }