#ifndef INC_SRT_LIST_H
#define INC_SRT_LIST_H
#include "udt.h"
#include "common.h"
class CSndLossList
{
public:
CSndLossList(int size = 1024);
~CSndLossList();
int insert(int32_t seqno1, int32_t seqno2);
void removeUpTo(int32_t seqno);
int getLossLength() const;
int32_t popLostSeq();
void traceState() const;
private:
struct Seq
{
int32_t seqstart; int32_t seqend; int inext; } * m_caSeq;
int m_iHead; int m_iLength; const int m_iSize; int m_iLastInsertPos;
mutable srt::sync::Mutex m_ListLock;
private:
void insertHead(int pos, int32_t seqno1, int32_t seqno2);
void insertAfter(int pos, int pos_after, int32_t seqno1, int32_t seqno2);
void coalesce(int loc);
bool updateElement(int pos, int32_t seqno1, int32_t seqno2);
private:
CSndLossList(const CSndLossList&);
CSndLossList& operator=(const CSndLossList&);
};
class CRcvLossList
{
public:
CRcvLossList(int size = 1024);
~CRcvLossList();
void insert(int32_t seqno1, int32_t seqno2);
bool remove(int32_t seqno);
bool remove(int32_t seqno1, int32_t seqno2);
bool find(int32_t seqno1, int32_t seqno2) const;
int getLossLength() const;
int32_t getFirstLostSeq() const;
void getLossArray(int32_t* array, int& len, int limit);
private:
struct Seq
{
int32_t seqstart; int32_t seqend; int inext; int iprior; } * m_caSeq;
int m_iHead; int m_iTail; int m_iLength; int m_iSize;
private:
CRcvLossList(const CRcvLossList&);
CRcvLossList& operator=(const CRcvLossList&);
public:
struct iterator
{
int32_t head;
Seq* seq;
iterator(Seq* str, int32_t v)
: head(v)
, seq(str)
{
}
iterator next() const
{
if (head == -1)
return *this;
return iterator(seq, seq[head].inext);
}
iterator& operator++()
{
*this = next();
return *this;
}
iterator operator++(int)
{
iterator old(seq, head);
*this = next();
return old;
}
bool operator==(const iterator& second) const
{
return head == second.head;
}
bool operator!=(const iterator& second) const { return !(*this == second); }
std::pair<int32_t, int32_t> operator*() { return std::make_pair(seq[head].seqstart, seq[head].seqend); }
};
iterator begin() { return iterator(m_caSeq, m_iHead); }
iterator end() { return iterator(m_caSeq, -1); }
};
struct CRcvFreshLoss
{
int32_t seq[2];
int ttl;
srt::sync::steady_clock::time_point timestamp;
CRcvFreshLoss(int32_t seqlo, int32_t seqhi, int initial_ttl);
#ifdef DELETE
#undef DELETE
#endif
enum Emod
{
NONE, STRIPPED, SPLIT, DELETE };
Emod revoke(int32_t sequence);
Emod revoke(int32_t lo, int32_t hi);
};
#endif