676 lines
21 KiB
C++
676 lines
21 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/*
|
|
* Copyright (c) 2007 University of Washington
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation;
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
// The queue base class has a limit on its size, in terms of number of
|
|
// packets or number of bytes depending on the operating mode.
|
|
// The base class implements tracing and basic statistics calculations.
|
|
|
|
#ifndef QUEUE_H
|
|
#define QUEUE_H
|
|
|
|
#include "ns3/packet.h"
|
|
#include "ns3/object.h"
|
|
#include "ns3/traced-callback.h"
|
|
#include "ns3/traced-value.h"
|
|
#include "ns3/log.h"
|
|
#include "ns3/queue-size.h"
|
|
#include "ns3/queue-item.h"
|
|
#include "ns3/queue-fwd.h"
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <type_traits>
|
|
|
|
namespace ns3 {
|
|
|
|
/**
|
|
* \ingroup network
|
|
* \defgroup queue Queue
|
|
*/
|
|
|
|
/**
|
|
* \ingroup queue
|
|
* \brief Abstract base class for packet Queues
|
|
*
|
|
* This class defines the subset of the base APIs for packet queues in the ns-3 system
|
|
* that is independent of the type of enqueued objects
|
|
*/
|
|
class QueueBase : public Object
|
|
{
|
|
public:
|
|
/**
|
|
* \brief Get the type ID.
|
|
* \return the object TypeId
|
|
*/
|
|
static TypeId GetTypeId ();
|
|
|
|
QueueBase ();
|
|
~QueueBase () override;
|
|
|
|
/**
|
|
* \brief Append the item type to the provided type ID if the latter does not
|
|
* end with '>'
|
|
*
|
|
* \param typeId the type ID
|
|
* \param itemType the item type
|
|
*
|
|
* This method is meant to be invoked by helpers to save users from
|
|
* specifying the type of items stored in a queue. For instance,
|
|
* PointToPointHelper::SetQueue calls
|
|
*
|
|
* \code
|
|
* QueueBase::AppendItemTypeIfNotPresent (type, "Packet");
|
|
* \endcode
|
|
*
|
|
* where type specifies the queue type (e.g., "ns3::DropTailQueue").
|
|
* This allows users to call SetQueue ("ns3::DropTailQueue")
|
|
* instead of SetQueue ("ns3::DropTailQueue<Packet>")
|
|
*/
|
|
static void AppendItemTypeIfNotPresent (std::string& typeId, const std::string& itemType);
|
|
|
|
/**
|
|
* \return true if the queue is empty; false otherwise
|
|
*/
|
|
bool IsEmpty () const;
|
|
|
|
/**
|
|
* \return The number of packets currently stored in the Queue
|
|
*/
|
|
uint32_t GetNPackets () const;
|
|
|
|
/**
|
|
* \return The number of bytes currently occupied by the packets in the Queue
|
|
*/
|
|
uint32_t GetNBytes () const;
|
|
|
|
/**
|
|
* \return The current size of the Queue in terms of packets, if the maximum
|
|
* size is specified in packets, or bytes, otherwise
|
|
*/
|
|
QueueSize GetCurrentSize () const;
|
|
|
|
/**
|
|
* \return The total number of bytes received by this Queue since the
|
|
* simulation began, or since ResetStatistics was called, according to
|
|
* whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalReceivedBytes () const;
|
|
|
|
/**
|
|
* \return The total number of packets received by this Queue since the
|
|
* simulation began, or since ResetStatistics was called, according to
|
|
* whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalReceivedPackets () const;
|
|
|
|
/**
|
|
* \return The total number of bytes dropped by this Queue since the
|
|
* simulation began, or since ResetStatistics was called, according to
|
|
* whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalDroppedBytes () const;
|
|
|
|
/**
|
|
* \return The total number of bytes dropped before enqueue by this Queue
|
|
* since the simulation began, or since ResetStatistics was called, according
|
|
* to whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalDroppedBytesBeforeEnqueue () const;
|
|
|
|
/**
|
|
* \return The total number of bytes dropped after dequeue by this Queue
|
|
* since the simulation began, or since ResetStatistics was called, according
|
|
* to whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalDroppedBytesAfterDequeue () const;
|
|
|
|
/**
|
|
* \return The total number of packets dropped by this Queue since the
|
|
* simulation began, or since ResetStatistics was called, according to
|
|
* whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalDroppedPackets () const;
|
|
|
|
/**
|
|
* \return The total number of packets dropped before enqueue by this Queue
|
|
* since the simulation began, or since ResetStatistics was called, according
|
|
* to whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalDroppedPacketsBeforeEnqueue () const;
|
|
|
|
/**
|
|
* \return The total number of packets dropped after dequeue by this Queue
|
|
* since the simulation began, or since ResetStatistics was called, according
|
|
* to whichever happened more recently
|
|
*/
|
|
uint32_t GetTotalDroppedPacketsAfterDequeue () const;
|
|
|
|
/**
|
|
* Resets the counts for dropped packets, dropped bytes, received packets, and
|
|
* received bytes.
|
|
*/
|
|
void ResetStatistics ();
|
|
|
|
/**
|
|
* \brief Set the maximum size of this queue
|
|
*
|
|
* Trying to set a null size has no effect.
|
|
*
|
|
* \param size the maximum size
|
|
*/
|
|
void SetMaxSize (QueueSize size);
|
|
|
|
/**
|
|
* \return the maximum size of this queue
|
|
*/
|
|
QueueSize GetMaxSize () const;
|
|
|
|
/**
|
|
* \brief Check if the queue would overflow with additional bytes or packets
|
|
* Note: the check is performed according to the queue's operating mode (bytes or packets).
|
|
* \param nPackets number of additional packets
|
|
* \param nBytes number of additional bytes
|
|
* \return true if the queue should overflow, false otherwise.
|
|
*/
|
|
bool WouldOverflow (uint32_t nPackets, uint32_t nBytes) const;
|
|
|
|
#if 0
|
|
// average calculation requires keeping around
|
|
// a buffer with the date of arrival of past received packets
|
|
// which are within the average window
|
|
// so, it is quite costly to do it all the time.
|
|
// Hence, it is disabled by default and must be explicitly
|
|
// enabled with this method which specifies the size
|
|
// of the average window in time units.
|
|
void EnableRunningAverage (Time averageWindow);
|
|
void DisableRunningAverage (void);
|
|
// average
|
|
double GetQueueSizeAverage (void);
|
|
double GetReceivedBytesPerSecondAverage (void);
|
|
double GetReceivedPacketsPerSecondAverage (void);
|
|
double GetDroppedBytesPerSecondAverage (void);
|
|
double GetDroppedPacketsPerSecondAverage (void);
|
|
// variance
|
|
double GetQueueSizeVariance (void);
|
|
double GetReceivedBytesPerSecondVariance (void);
|
|
double GetReceivedPacketsPerSecondVariance (void);
|
|
double GetDroppedBytesPerSecondVariance (void);
|
|
double GetDroppedPacketsPerSecondVariance (void);
|
|
#endif
|
|
|
|
protected:
|
|
TracedValue<uint32_t> m_nBytes; //!< Number of bytes in the queue
|
|
uint32_t m_nTotalReceivedBytes; //!< Total received bytes
|
|
TracedValue<uint32_t> m_nPackets; //!< Number of packets in the queue
|
|
uint32_t m_nTotalReceivedPackets; //!< Total received packets
|
|
uint32_t m_nTotalDroppedBytes; //!< Total dropped bytes
|
|
uint32_t m_nTotalDroppedBytesBeforeEnqueue; //!< Total dropped bytes before enqueue
|
|
uint32_t m_nTotalDroppedBytesAfterDequeue; //!< Total dropped bytes after dequeue
|
|
uint32_t m_nTotalDroppedPackets; //!< Total dropped packets
|
|
uint32_t m_nTotalDroppedPacketsBeforeEnqueue; //!< Total dropped packets before enqueue
|
|
uint32_t m_nTotalDroppedPacketsAfterDequeue; //!< Total dropped packets after dequeue
|
|
|
|
QueueSize m_maxSize; //!< max queue size
|
|
};
|
|
|
|
|
|
/**
|
|
* \ingroup queue
|
|
* \brief Template class for packet Queues
|
|
*
|
|
* This class defines the subset of the base APIs for packet queues in the ns-3 system
|
|
* that is dependent on the type of enqueued objects.
|
|
*
|
|
* Queue is a template class. The type of the objects stored within the queue
|
|
* is specified by the type parameter, which can be any class providing a
|
|
* GetSize () method (e.g., Packet, QueueDiscItem, etc.). Subclasses need to
|
|
* implement the Enqueue, Dequeue, Remove and Peek methods, and are
|
|
* encouraged to leverage the DoEnqueue, DoDequeue, DoRemove, and DoPeek
|
|
* methods in doing so, to ensure that appropriate trace sources are called
|
|
* and statistics are maintained. The template parameter specifies the type of
|
|
* container used internally to store queue items. The container type must provide
|
|
* the methods insert(), erase() and clear() and define the iterator and const_iterator
|
|
* types, following the usual syntax of C++ containers. The default container type
|
|
* is std::list (as defined in queue-fwd.h). In case the container is such that
|
|
* an object stored within the queue is obtained from a container element through
|
|
* an operation other than dereferencing an iterator pointing to the container
|
|
* element, the container has to provide a public method named GetItem that
|
|
* returns the object stored within the queue that is included in the container
|
|
* element pointed to by a given const iterator.
|
|
*
|
|
* Users of the Queue template class usually hold a queue through a smart pointer,
|
|
* hence forward declaration is recommended to avoid pulling the implementation
|
|
* of the templates included in this file. Thus, include queue-fwd.h, which
|
|
* provides a forward declaration for the Queue class that defines the default
|
|
* value for the template template parameter, instead of queue.h in your .h file.
|
|
* Then, include queue.h in the corresponding .cc file.
|
|
*
|
|
* \tparam Item \explicit Type of the objects stored within the queue
|
|
* \tparam Container \explicit Type of the container that stores queue items
|
|
*/
|
|
template <typename Item, typename Container>
|
|
class Queue : public QueueBase
|
|
{
|
|
public:
|
|
/**
|
|
* \brief Get the type ID.
|
|
* \return the object TypeId
|
|
*/
|
|
static TypeId GetTypeId ();
|
|
|
|
Queue ();
|
|
~Queue () override;
|
|
|
|
/**
|
|
* Place an item into the Queue (each subclass defines the position)
|
|
* \param item item to enqueue
|
|
* \return True if the operation was successful; false otherwise
|
|
*/
|
|
virtual bool Enqueue (Ptr<Item> item) = 0;
|
|
|
|
/**
|
|
* Remove an item from the Queue (each subclass defines the position),
|
|
* counting it and tracing it as dequeued
|
|
* \return 0 if the operation was not successful; the item otherwise.
|
|
*/
|
|
virtual Ptr<Item> Dequeue () = 0;
|
|
|
|
/**
|
|
* Remove an item from the Queue (each subclass defines the position),
|
|
* counting it and tracing it as both dequeued and dropped
|
|
* \return 0 if the operation was not successful; the item otherwise.
|
|
*/
|
|
virtual Ptr<Item> Remove () = 0;
|
|
|
|
/**
|
|
* Get a copy of an item in the queue (each subclass defines the position)
|
|
* without removing it
|
|
* \return 0 if the operation was not successful; the item otherwise.
|
|
*/
|
|
virtual Ptr<const Item> Peek () const = 0;
|
|
|
|
/**
|
|
* Flush the queue by calling Remove() on each item enqueued. Note that
|
|
* this operation will cause dequeue and drop counts to be incremented and
|
|
* traces to be triggered for each Remove() action.
|
|
*/
|
|
void Flush ();
|
|
|
|
/// Define ItemType as the type of the stored elements
|
|
typedef Item ItemType;
|
|
|
|
protected:
|
|
/// Const iterator.
|
|
typedef typename Container::const_iterator ConstIterator;
|
|
/// Iterator.
|
|
typedef typename Container::iterator Iterator;
|
|
|
|
/**
|
|
* Get a const reference to the container of queue items.
|
|
*
|
|
* \return a const reference to the container of queue items
|
|
*/
|
|
const Container& GetContainer () const;
|
|
|
|
/**
|
|
* Push an item in the queue
|
|
* \param pos the position before which the item will be inserted
|
|
* \param item the item to enqueue
|
|
* \return true if success, false if the packet has been dropped.
|
|
*/
|
|
bool DoEnqueue (ConstIterator pos, Ptr<Item> item);
|
|
|
|
/**
|
|
* Push an item in the queue
|
|
* \param pos the position before which the item will be inserted
|
|
* \param item the item to enqueue
|
|
* \param[out] ret an iterator pointing to the inserted value
|
|
* \return true if success, false if the packet has been dropped.
|
|
*/
|
|
bool DoEnqueue (ConstIterator pos, Ptr<Item> item, Iterator& ret);
|
|
|
|
/**
|
|
* Pull the item to dequeue from the queue
|
|
* \param pos the position of the item to dequeue
|
|
* \return the item.
|
|
*/
|
|
Ptr<Item> DoDequeue (ConstIterator pos);
|
|
|
|
/**
|
|
* Pull the item to drop from the queue
|
|
* \param pos the position of the item to remove
|
|
* \return the item.
|
|
*/
|
|
Ptr<Item> DoRemove (ConstIterator pos);
|
|
|
|
/**
|
|
* Peek the front item in the queue
|
|
* \param pos the position of the item to peek
|
|
* \return the item.
|
|
*/
|
|
Ptr<const Item> DoPeek (ConstIterator pos) const;
|
|
|
|
/**
|
|
* \brief Drop a packet before enqueue
|
|
* \param item item that was dropped
|
|
*
|
|
* This method is called by the base class when a packet is dropped because
|
|
* the queue is full and by the subclasses to notify parent (this class) that
|
|
* a packet has been dropped for other reasons before being enqueued.
|
|
*/
|
|
void DropBeforeEnqueue (Ptr<Item> item);
|
|
|
|
/**
|
|
* \brief Drop a packet after dequeue
|
|
* \param item item that was dropped
|
|
*
|
|
* This method is called by the base class when a Remove operation is requested
|
|
* and by the subclasses to notify parent (this class) that a packet has been
|
|
* dropped for other reasons after being dequeued.
|
|
*/
|
|
void DropAfterDequeue (Ptr<Item> item);
|
|
|
|
/** \copydoc ns3::Object::DoDispose */
|
|
void DoDispose () override;
|
|
|
|
private:
|
|
/**
|
|
* Struct providing a static method returning the object stored within the queue
|
|
* that is included in the container element pointed to by the given const iterator.
|
|
* This method is used when the container does not define a GetItem method and
|
|
* assumes that an object stored in the queue can be obtained by dereferencing the
|
|
* iterator pointing to the container element that includes such an object.
|
|
*/
|
|
template <class, class = void>
|
|
struct MakeGetItem
|
|
{
|
|
/**
|
|
* \param it the given const iterator
|
|
* \return the item included in the element pointed to by the given iterator
|
|
*/
|
|
static Ptr<Item> GetItem (const Container&, const ConstIterator it)
|
|
{
|
|
return *it;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Struct providing a static method returning the object stored within the queue
|
|
* that is included in the container element pointed to by the given const iterator.
|
|
* This method is used when the container defines a GetItem method and is simply a
|
|
* wrapper to invoke such a method.
|
|
*/
|
|
template <class T>
|
|
struct MakeGetItem<T, std::void_t<decltype (std::declval<T> ().GetItem (std::declval<ConstIterator> ()))> >
|
|
{
|
|
/**
|
|
* \param container the container
|
|
* \param it the given const iterator
|
|
* \return the item included in the element pointed to by the given iterator
|
|
*/
|
|
static Ptr<Item> GetItem (const Container& container, const ConstIterator it)
|
|
{
|
|
return container.GetItem (it);
|
|
}
|
|
};
|
|
|
|
Container m_packets; //!< the items in the queue
|
|
NS_LOG_TEMPLATE_DECLARE; //!< the log component
|
|
|
|
/// Traced callback: fired when a packet is enqueued
|
|
TracedCallback<Ptr<const Item> > m_traceEnqueue;
|
|
/// Traced callback: fired when a packet is dequeued
|
|
TracedCallback<Ptr<const Item> > m_traceDequeue;
|
|
/// Traced callback: fired when a packet is dropped
|
|
TracedCallback<Ptr<const Item> > m_traceDrop;
|
|
/// Traced callback: fired when a packet is dropped before enqueue
|
|
TracedCallback<Ptr<const Item> > m_traceDropBeforeEnqueue;
|
|
/// Traced callback: fired when a packet is dropped after dequeue
|
|
TracedCallback<Ptr<const Item> > m_traceDropAfterDequeue;
|
|
};
|
|
|
|
|
|
/**
|
|
* Implementation of the templates declared above.
|
|
*/
|
|
|
|
template <typename Item, typename Container>
|
|
TypeId
|
|
Queue<Item, Container>::GetTypeId ()
|
|
{
|
|
std::string name = GetTemplateClassName<Queue<Item, Container>> ();
|
|
auto startPos = name.find ('<') + 1;
|
|
auto endPos = name.find_first_of (",>", startPos);
|
|
std::string tcbName = "ns3::" + name.substr (startPos, endPos - startPos) + "::TracedCallback";
|
|
|
|
static TypeId tid = TypeId (name)
|
|
.SetParent<QueueBase> ()
|
|
.SetGroupName ("Network")
|
|
.AddTraceSource ("Enqueue", "Enqueue a packet in the queue.",
|
|
MakeTraceSourceAccessor (&Queue<Item, Container>::m_traceEnqueue),
|
|
tcbName)
|
|
.AddTraceSource ("Dequeue", "Dequeue a packet from the queue.",
|
|
MakeTraceSourceAccessor (&Queue<Item, Container>::m_traceDequeue),
|
|
tcbName)
|
|
.AddTraceSource ("Drop", "Drop a packet (for whatever reason).",
|
|
MakeTraceSourceAccessor (&Queue<Item, Container>::m_traceDrop),
|
|
tcbName)
|
|
.AddTraceSource ("DropBeforeEnqueue", "Drop a packet before enqueue.",
|
|
MakeTraceSourceAccessor (&Queue<Item, Container>::m_traceDropBeforeEnqueue),
|
|
tcbName)
|
|
.AddTraceSource ("DropAfterDequeue", "Drop a packet after dequeue.",
|
|
MakeTraceSourceAccessor (&Queue<Item, Container>::m_traceDropAfterDequeue),
|
|
tcbName)
|
|
;
|
|
return tid;
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
Queue<Item, Container>::Queue ()
|
|
: NS_LOG_TEMPLATE_DEFINE ("Queue")
|
|
{
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
Queue<Item, Container>::~Queue ()
|
|
{
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
const Container&
|
|
Queue<Item, Container>::GetContainer () const
|
|
{
|
|
return m_packets;
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
bool
|
|
Queue<Item, Container>::DoEnqueue (ConstIterator pos, Ptr<Item> item)
|
|
{
|
|
Iterator ret;
|
|
return DoEnqueue (pos, item, ret);
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
bool
|
|
Queue<Item, Container>::DoEnqueue (ConstIterator pos, Ptr<Item> item, Iterator& ret)
|
|
{
|
|
NS_LOG_FUNCTION (this << item);
|
|
|
|
if (GetCurrentSize () + item > GetMaxSize ())
|
|
{
|
|
NS_LOG_LOGIC ("Queue full -- dropping pkt");
|
|
DropBeforeEnqueue (item);
|
|
return false;
|
|
}
|
|
|
|
ret = m_packets.insert (pos, item);
|
|
|
|
uint32_t size = item->GetSize ();
|
|
m_nBytes += size;
|
|
m_nTotalReceivedBytes += size;
|
|
|
|
m_nPackets++;
|
|
m_nTotalReceivedPackets++;
|
|
|
|
NS_LOG_LOGIC ("m_traceEnqueue (p)");
|
|
m_traceEnqueue (item);
|
|
|
|
return true;
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
Ptr<Item>
|
|
Queue<Item, Container>::DoDequeue (ConstIterator pos)
|
|
{
|
|
NS_LOG_FUNCTION (this);
|
|
|
|
if (m_nPackets.Get () == 0)
|
|
{
|
|
NS_LOG_LOGIC ("Queue empty");
|
|
return 0;
|
|
}
|
|
|
|
Ptr<Item> item = MakeGetItem<Container>::GetItem (m_packets, pos);
|
|
|
|
if (item)
|
|
{
|
|
m_packets.erase (pos);
|
|
NS_ASSERT (m_nBytes.Get () >= item->GetSize ());
|
|
NS_ASSERT (m_nPackets.Get () > 0);
|
|
|
|
m_nBytes -= item->GetSize ();
|
|
m_nPackets--;
|
|
|
|
NS_LOG_LOGIC ("m_traceDequeue (p)");
|
|
m_traceDequeue (item);
|
|
}
|
|
return item;
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
Ptr<Item>
|
|
Queue<Item, Container>::DoRemove (ConstIterator pos)
|
|
{
|
|
NS_LOG_FUNCTION (this);
|
|
|
|
if (m_nPackets.Get () == 0)
|
|
{
|
|
NS_LOG_LOGIC ("Queue empty");
|
|
return 0;
|
|
}
|
|
|
|
Ptr<Item> item = MakeGetItem<Container>::GetItem (m_packets, pos);
|
|
|
|
if (item)
|
|
{
|
|
m_packets.erase (pos);
|
|
NS_ASSERT (m_nBytes.Get () >= item->GetSize ());
|
|
NS_ASSERT (m_nPackets.Get () > 0);
|
|
|
|
m_nBytes -= item->GetSize ();
|
|
m_nPackets--;
|
|
|
|
// packets are first dequeued and then dropped
|
|
NS_LOG_LOGIC ("m_traceDequeue (p)");
|
|
m_traceDequeue (item);
|
|
|
|
DropAfterDequeue (item);
|
|
}
|
|
return item;
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
void
|
|
Queue<Item, Container>::Flush ()
|
|
{
|
|
NS_LOG_FUNCTION (this);
|
|
while (!IsEmpty ())
|
|
{
|
|
Remove ();
|
|
}
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
void
|
|
Queue<Item, Container>::DoDispose ()
|
|
{
|
|
NS_LOG_FUNCTION (this);
|
|
m_packets.clear ();
|
|
Object::DoDispose ();
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
Ptr<const Item>
|
|
Queue<Item, Container>::DoPeek (ConstIterator pos) const
|
|
{
|
|
NS_LOG_FUNCTION (this);
|
|
|
|
if (m_nPackets.Get () == 0)
|
|
{
|
|
NS_LOG_LOGIC ("Queue empty");
|
|
return 0;
|
|
}
|
|
|
|
return MakeGetItem<Container>::GetItem (m_packets, pos);
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
void
|
|
Queue<Item, Container>::DropBeforeEnqueue (Ptr<Item> item)
|
|
{
|
|
NS_LOG_FUNCTION (this << item);
|
|
|
|
m_nTotalDroppedPackets++;
|
|
m_nTotalDroppedPacketsBeforeEnqueue++;
|
|
m_nTotalDroppedBytes += item->GetSize ();
|
|
m_nTotalDroppedBytesBeforeEnqueue += item->GetSize ();
|
|
|
|
NS_LOG_LOGIC ("m_traceDropBeforeEnqueue (p)");
|
|
m_traceDrop (item);
|
|
m_traceDropBeforeEnqueue (item);
|
|
}
|
|
|
|
template <typename Item, typename Container>
|
|
void
|
|
Queue<Item, Container>::DropAfterDequeue (Ptr<Item> item)
|
|
{
|
|
NS_LOG_FUNCTION (this << item);
|
|
|
|
m_nTotalDroppedPackets++;
|
|
m_nTotalDroppedPacketsAfterDequeue++;
|
|
m_nTotalDroppedBytes += item->GetSize ();
|
|
m_nTotalDroppedBytesAfterDequeue += item->GetSize ();
|
|
|
|
NS_LOG_LOGIC ("m_traceDropAfterDequeue (p)");
|
|
m_traceDrop (item);
|
|
m_traceDropAfterDequeue (item);
|
|
}
|
|
|
|
// The following explicit template instantiation declarations prevent all the
|
|
// translation units including this header file to implicitly instantiate the
|
|
// Queue<Packet> class and the Queue<QueueDiscItem> class. The unique instances
|
|
// of these classes are explicitly created through the macros
|
|
// NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,Packet) and
|
|
// NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,QueueDiscItem), which are included in queue.cc
|
|
extern template class Queue<Packet>;
|
|
extern template class Queue<QueueDiscItem>;
|
|
|
|
} // namespace ns3
|
|
|
|
#endif /* QUEUE_H */
|