Classes | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes

TCPVirtualDataRcvQueue Class Reference

#include <TCPVirtualDataRcvQueue.h>

Inheritance diagram for TCPVirtualDataRcvQueue:
TCPReceiveQueue TCPMsgBasedRcvQueue

List of all members.

Classes

struct  Region

Public Member Functions

 TCPVirtualDataRcvQueue ()
virtual ~TCPVirtualDataRcvQueue ()
virtual void init (uint32 startSeq)
virtual std::string info () const
virtual uint32 insertBytesFromSegment (TCPSegment *tcpseg)
virtual cPacket * extractBytesUpTo (uint32 seq)
virtual uint32 getAmountOfBufferedBytes ()
virtual uint32 getAmountOfFreeBytes (uint32 maxRcvBuffer)
virtual uint32 getQueueLength ()
virtual void getQueueStatus ()
virtual uint32 getLE (uint32 fromSeqNum)
virtual uint32 getRE (uint32 toSeqNum)

Protected Types

typedef std::list< RegionRegionList

Protected Member Functions

void merge (uint32 segmentBegin, uint32 segmentEnd)
ulong extractTo (uint32 toSeq)

Protected Attributes

uint32 rcv_nxt
RegionList regionList

Detailed Description

Receive queue that manages "virtual bytes", that is, byte counts only.

See also:
TCPVirtualDataSendQueue

Definition at line 32 of file TCPVirtualDataRcvQueue.h.


Member Typedef Documentation

typedef std::list<Region> TCPVirtualDataRcvQueue::RegionList [protected]

Definition at line 42 of file TCPVirtualDataRcvQueue.h.


Constructor & Destructor Documentation

TCPVirtualDataRcvQueue::TCPVirtualDataRcvQueue (  ) 

Ctor.

Definition at line 26 of file queues/TCPVirtualDataRcvQueue.cc.

                                               : TCPReceiveQueue()
{
}

TCPVirtualDataRcvQueue::~TCPVirtualDataRcvQueue (  )  [virtual]

Virtual dtor.

Definition at line 30 of file queues/TCPVirtualDataRcvQueue.cc.

{
}


Member Function Documentation

cPacket * TCPVirtualDataRcvQueue::extractBytesUpTo ( uint32  seq  )  [virtual]

Should create a packet to be passed up to the app, up to (but NOT including) the given sequence no (usually rcv_nxt). It should return NULL if there's no more data to be passed up -- this method is called several times until it returns NULL.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

Definition at line 129 of file queues/TCPVirtualDataRcvQueue.cc.

{
    ulong numBytes = extractTo(seq);
    if (numBytes==0)
        return NULL;

    cPacket *msg = new cPacket("data");
    msg->setByteLength(numBytes);
    return msg;
}

ulong TCPVirtualDataRcvQueue::extractTo ( uint32  toSeq  )  [protected]

Definition at line 140 of file queues/TCPVirtualDataRcvQueue.cc.

Referenced by extractBytesUpTo(), and TCPMsgBasedRcvQueue::extractBytesUpTo().

{
    ASSERT(seqLE(seq,rcv_nxt));

    RegionList::iterator i = regionList.begin();
    if (i==regionList.end())
        return 0;

    ASSERT(seqLess(i->begin,i->end)); // empty regions cannot exist

    // seq below 1st region
    if (seqLE(seq,i->begin))
        return 0;

    if (seqLess(seq,i->end))
    {
        // part of 1st region
        ulong octets = seq - i->begin;
        i->begin = seq;
        return octets;
    }
    else
    {
        // full 1st region
        ulong octets = i->end - i->begin;
        regionList.erase(i);
        return octets;
    }
}

uint32 TCPVirtualDataRcvQueue::getAmountOfBufferedBytes (  )  [virtual]

Returns the number of bytes (out-of-order-segments) currently buffered in queue.

Implements TCPReceiveQueue.

Definition at line 170 of file queues/TCPVirtualDataRcvQueue.cc.

Referenced by getAmountOfFreeBytes().

{
    uint32 bytes=0;

    RegionList::iterator i = regionList.begin();
    if (i==regionList.end()) // is queue empty?
        return 0;

    while (i!=regionList.end())
    {
        bytes = bytes + (i->end - i->begin);
        i++;
    }
    return bytes;
}

uint32 TCPVirtualDataRcvQueue::getAmountOfFreeBytes ( uint32  maxRcvBuffer  )  [virtual]

Returns the number of bytes currently free (=available) in queue. freeRcvBuffer = maxRcvBuffer - usedRcvBuffer

Implements TCPReceiveQueue.

Definition at line 186 of file queues/TCPVirtualDataRcvQueue.cc.

{
    uint32 usedRcvBuffer = getAmountOfBufferedBytes();
    uint32 freeRcvBuffer = maxRcvBuffer - usedRcvBuffer;
    return freeRcvBuffer;
}

uint32 TCPVirtualDataRcvQueue::getLE ( uint32  fromSeqNum  )  [virtual]

Returns left edge of enqueued region.

Implements TCPReceiveQueue.

Definition at line 204 of file queues/TCPVirtualDataRcvQueue.cc.

{
    RegionList::iterator i = regionList.begin();
    while (i!=regionList.end())
    {
        if (seqLE(i->begin, fromSeqNum) && seqLE(fromSeqNum, i->end))
        {
//            tcpEV << "Enqueued region: [" << i->begin << ".." << i->end << ")\n";
            if (seqLess(i->begin, fromSeqNum))
                return i->begin;
            return fromSeqNum;
        }
        i++;
    }
    return fromSeqNum;
}

uint32 TCPVirtualDataRcvQueue::getQueueLength (  )  [virtual]

Returns the number of blocks currently buffered in queue.

Implements TCPReceiveQueue.

Definition at line 193 of file queues/TCPVirtualDataRcvQueue.cc.

{
    return regionList.size();
}

void TCPVirtualDataRcvQueue::getQueueStatus (  )  [virtual]

Shows current queue status.

Implements TCPReceiveQueue.

Definition at line 198 of file queues/TCPVirtualDataRcvQueue.cc.

{
    tcpEV << "receiveQLength=" << regionList.size() << " " << info() << "\n";
}

uint32 TCPVirtualDataRcvQueue::getRE ( uint32  toSeqNum  )  [virtual]

Returns right edge of enqueued region.

Implements TCPReceiveQueue.

Definition at line 221 of file queues/TCPVirtualDataRcvQueue.cc.

{
    RegionList::iterator i = regionList.begin();
    while (i!=regionList.end())
    {
        if (seqLE(i->begin, toSeqNum) && seqLE(toSeqNum, i->end))
        {
//            tcpEV << "Enqueued region: [" << i->begin << ".." << i->end << ")\n";
            if (seqLess(toSeqNum, i->end))
                return i->end;
            return toSeqNum;
        }
        i++;
    }
    return toSeqNum;
}

std::string TCPVirtualDataRcvQueue::info (  )  const [virtual]

Returns a string with region stored.

Reimplemented in TCPMsgBasedRcvQueue.

Definition at line 39 of file queues/TCPVirtualDataRcvQueue.cc.

Referenced by getQueueStatus().

{
    std::string res;
    char buf[32];
    sprintf(buf, "rcv_nxt=%u ", rcv_nxt);
    res = buf;

    for (RegionList::const_iterator i=regionList.begin(); i!=regionList.end(); ++i)
    {
        sprintf(buf, "[%u..%u) ", i->begin, i->end);
        res+=buf;
    }
    return res;
}

void TCPVirtualDataRcvQueue::init ( uint32  startSeq  )  [virtual]

Set initial receive sequence number.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

Definition at line 34 of file queues/TCPVirtualDataRcvQueue.cc.

{
    rcv_nxt = startSeq;
}

uint32 TCPVirtualDataRcvQueue::insertBytesFromSegment ( TCPSegment tcpseg  )  [virtual]

Called when a TCP segment arrives. Returns sequence number for ACK.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

Definition at line 54 of file queues/TCPVirtualDataRcvQueue.cc.

{
    merge(tcpseg->getSequenceNo(), tcpseg->getSequenceNo()+tcpseg->getPayloadLength());
    if (seqGE(rcv_nxt, regionList.begin()->begin))
        rcv_nxt = regionList.begin()->end;
    return rcv_nxt;
}

void TCPVirtualDataRcvQueue::merge ( uint32  segmentBegin,
uint32  segmentEnd 
) [protected]

Definition at line 62 of file queues/TCPVirtualDataRcvQueue.cc.

Referenced by insertBytesFromSegment().

{
    // Here we have to update our existing regions with the octet range
    // tcpseg represents. We either have to insert tcpseg as a separate region
    // somewhere, or (if it overlaps with an existing region) extend
    // existing regions; we also may have to merge existing regions if
    // they become overlapping (or touching) after adding tcpseg.

    Region seg;
    seg.begin = segmentBegin;
    seg.end = segmentEnd;

    RegionList::iterator i = regionList.begin();
    if (i==regionList.end())
    {
        // insert as first and only region
        regionList.insert(regionList.begin(), seg);
        return;
    }

    // skip regions which fall entirely before seg (no overlap or touching)
    while (i!=regionList.end() && seqLess(i->end,seg.begin))
    {
        ++i;
    }

    if (i==regionList.end())
    {
        // seg is entirely past last region: insert as separate region at end
        regionList.insert(regionList.end(), seg);
        return;
    }

    if (seqLess(seg.end,i->begin))
    {
        // segment entirely before region "i": insert as separate region before "i"
        regionList.insert(i, seg);
        return;
    }

    if (seqLess(seg.begin,i->begin))
    {
        // segment starts before region "i": extend region
        i->begin = seg.begin;
    }

    if (seqLess(i->end,seg.end))
    {
        // segment ends past end of region "i": extend region
        i->end = seg.end;

        // maybe we have to merge region "i" with next one(s)
        RegionList::iterator j = i;
        ++j;
        while (j!=regionList.end() && seqGE(i->end,j->begin)) // while there's overlap
        {
            // if "j" is longer: extend "i"
            if (seqLess(i->end,j->end))
                i->end = j->end;

            // erase "j" (it was merged into "i")
            RegionList::iterator oldj = j++;
            regionList.erase(oldj);
        }
    }
}


Member Data Documentation


The documentation for this class was generated from the following files: