A Discrete-Event Network Simulator
API
queue.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 University of Washington
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17 
18 // The queue base class has a limit on its size, in terms of number of
19 // packets or number of bytes depending on the operating mode.
20 // The base class implements tracing and basic statistics calculations.
21 
22 #ifndef QUEUE_H
23 #define QUEUE_H
24 
25 #include "ns3/log.h"
26 #include "ns3/object.h"
27 #include "ns3/packet.h"
28 #include "ns3/queue-fwd.h"
29 #include "ns3/queue-item.h"
30 #include "ns3/queue-size.h"
31 #include "ns3/traced-callback.h"
32 #include "ns3/traced-value.h"
33 
34 #include <sstream>
35 #include <string>
36 #include <type_traits>
37 
38 namespace ns3
39 {
40 
53 class QueueBase : public Object
54 {
55  public:
60  static TypeId GetTypeId();
61 
62  QueueBase();
63  ~QueueBase() override;
64 
84  static void AppendItemTypeIfNotPresent(std::string& typeId, const std::string& itemType);
85 
89  bool IsEmpty() const;
90 
94  uint32_t GetNPackets() const;
95 
99  uint32_t GetNBytes() const;
100 
105  QueueSize GetCurrentSize() const;
106 
112  uint32_t GetTotalReceivedBytes() const;
113 
119  uint32_t GetTotalReceivedPackets() const;
120 
126  uint32_t GetTotalDroppedBytes() const;
127 
133  uint32_t GetTotalDroppedBytesBeforeEnqueue() const;
134 
140  uint32_t GetTotalDroppedBytesAfterDequeue() const;
141 
147  uint32_t GetTotalDroppedPackets() const;
148 
154  uint32_t GetTotalDroppedPacketsBeforeEnqueue() const;
155 
161  uint32_t GetTotalDroppedPacketsAfterDequeue() const;
162 
167  void ResetStatistics();
168 
176  void SetMaxSize(QueueSize size);
177 
181  QueueSize GetMaxSize() const;
182 
190  bool WouldOverflow(uint32_t nPackets, uint32_t nBytes) const;
191 
192 #if 0
193  // average calculation requires keeping around
194  // a buffer with the date of arrival of past received packets
195  // which are within the average window
196  // so, it is quite costly to do it all the time.
197  // Hence, it is disabled by default and must be explicitly
198  // enabled with this method which specifies the size
199  // of the average window in time units.
200  void EnableRunningAverage(Time averageWindow);
201  void DisableRunningAverage();
202  // average
203  double GetQueueSizeAverage();
204  double GetReceivedBytesPerSecondAverage();
205  double GetReceivedPacketsPerSecondAverage();
206  double GetDroppedBytesPerSecondAverage();
207  double GetDroppedPacketsPerSecondAverage();
208  // variance
209  double GetQueueSizeVariance();
210  double GetReceivedBytesPerSecondVariance();
211  double GetReceivedPacketsPerSecondVariance();
212  double GetDroppedBytesPerSecondVariance();
213  double GetDroppedPacketsPerSecondVariance();
214 #endif
215 
216  protected:
227 
229 };
230 
265 template <typename Item, typename Container>
266 class Queue : public QueueBase
267 {
268  public:
273  static TypeId GetTypeId();
274 
275  Queue();
276  ~Queue() override;
277 
283  virtual bool Enqueue(Ptr<Item> item) = 0;
284 
290  virtual Ptr<Item> Dequeue() = 0;
291 
297  virtual Ptr<Item> Remove() = 0;
298 
304  virtual Ptr<const Item> Peek() const = 0;
305 
311  void Flush();
312 
314  typedef Item ItemType;
315 
316  protected:
318  typedef typename Container::const_iterator ConstIterator;
320  typedef typename Container::iterator Iterator;
321 
327  const Container& GetContainer() const;
328 
336 
344  bool DoEnqueue(ConstIterator pos, Ptr<Item> item, Iterator& ret);
345 
352 
359 
366 
376 
386 
388  void DoDispose() override;
389 
390  private:
398  template <class, class = void>
399  struct MakeGetItem
400  {
405  static Ptr<Item> GetItem(const Container&, const ConstIterator it)
406  {
407  return *it;
408  }
409  };
410 
417  template <class T>
418  struct MakeGetItem<
419  T,
420  std::void_t<decltype(std::declval<T>().GetItem(std::declval<ConstIterator>()))>>
421  {
427  static Ptr<Item> GetItem(const Container& container, const ConstIterator it)
428  {
429  return container.GetItem(it);
430  }
431  };
432 
435 
446 };
447 
452 template <typename Item, typename Container>
453 TypeId
455 {
456  std::string name = GetTemplateClassName<Queue<Item, Container>>();
457  auto startPos = name.find('<') + 1;
458  auto endPos = name.find_first_of(",>", startPos);
459  std::string tcbName = "ns3::" + name.substr(startPos, endPos - startPos) + "::TracedCallback";
460 
461  static TypeId tid =
462  TypeId(name)
463  .SetParent<QueueBase>()
464  .SetGroupName("Network")
465  .AddTraceSource("Enqueue",
466  "Enqueue a packet in the queue.",
468  tcbName)
469  .AddTraceSource("Dequeue",
470  "Dequeue a packet from the queue.",
472  tcbName)
473  .AddTraceSource("Drop",
474  "Drop a packet (for whatever reason).",
476  tcbName)
477  .AddTraceSource(
478  "DropBeforeEnqueue",
479  "Drop a packet before enqueue.",
481  tcbName)
482  .AddTraceSource(
483  "DropAfterDequeue",
484  "Drop a packet after dequeue.",
486  tcbName);
487  return tid;
488 }
489 
490 template <typename Item, typename Container>
492  : NS_LOG_TEMPLATE_DEFINE("Queue")
493 {
494 }
495 
496 template <typename Item, typename Container>
498 {
499 }
500 
501 template <typename Item, typename Container>
502 const Container&
504 {
505  return m_packets;
506 }
507 
508 template <typename Item, typename Container>
509 bool
511 {
512  Iterator ret;
513  return DoEnqueue(pos, item, ret);
514 }
515 
516 template <typename Item, typename Container>
517 bool
519 {
520  NS_LOG_FUNCTION(this << item);
521 
522  if (GetCurrentSize() + item > GetMaxSize())
523  {
524  NS_LOG_LOGIC("Queue full -- dropping pkt");
525  DropBeforeEnqueue(item);
526  return false;
527  }
528 
529  ret = m_packets.insert(pos, item);
530 
531  uint32_t size = item->GetSize();
532  m_nBytes += size;
533  m_nTotalReceivedBytes += size;
534 
535  m_nPackets++;
536  m_nTotalReceivedPackets++;
537 
538  NS_LOG_LOGIC("m_traceEnqueue (p)");
539  m_traceEnqueue(item);
540 
541  return true;
542 }
543 
544 template <typename Item, typename Container>
545 Ptr<Item>
547 {
548  NS_LOG_FUNCTION(this);
549 
550  if (m_nPackets.Get() == 0)
551  {
552  NS_LOG_LOGIC("Queue empty");
553  return nullptr;
554  }
555 
556  Ptr<Item> item = MakeGetItem<Container>::GetItem(m_packets, pos);
557 
558  if (item)
559  {
560  m_packets.erase(pos);
561  NS_ASSERT(m_nBytes.Get() >= item->GetSize());
562  NS_ASSERT(m_nPackets.Get() > 0);
563 
564  m_nBytes -= item->GetSize();
565  m_nPackets--;
566 
567  NS_LOG_LOGIC("m_traceDequeue (p)");
568  m_traceDequeue(item);
569  }
570  return item;
571 }
572 
573 template <typename Item, typename Container>
574 Ptr<Item>
576 {
577  NS_LOG_FUNCTION(this);
578 
579  if (m_nPackets.Get() == 0)
580  {
581  NS_LOG_LOGIC("Queue empty");
582  return nullptr;
583  }
584 
585  Ptr<Item> item = MakeGetItem<Container>::GetItem(m_packets, pos);
586 
587  if (item)
588  {
589  m_packets.erase(pos);
590  NS_ASSERT(m_nBytes.Get() >= item->GetSize());
591  NS_ASSERT(m_nPackets.Get() > 0);
592 
593  m_nBytes -= item->GetSize();
594  m_nPackets--;
595 
596  // packets are first dequeued and then dropped
597  NS_LOG_LOGIC("m_traceDequeue (p)");
598  m_traceDequeue(item);
599 
600  DropAfterDequeue(item);
601  }
602  return item;
603 }
604 
605 template <typename Item, typename Container>
606 void
608 {
609  NS_LOG_FUNCTION(this);
610  while (!IsEmpty())
611  {
612  Remove();
613  }
614 }
615 
616 template <typename Item, typename Container>
617 void
619 {
620  NS_LOG_FUNCTION(this);
621  m_packets.clear();
623 }
624 
625 template <typename Item, typename Container>
628 {
629  NS_LOG_FUNCTION(this);
630 
631  if (m_nPackets.Get() == 0)
632  {
633  NS_LOG_LOGIC("Queue empty");
634  return nullptr;
635  }
636 
637  return MakeGetItem<Container>::GetItem(m_packets, pos);
638 }
639 
640 template <typename Item, typename Container>
641 void
643 {
644  NS_LOG_FUNCTION(this << item);
645 
646  m_nTotalDroppedPackets++;
647  m_nTotalDroppedPacketsBeforeEnqueue++;
648  m_nTotalDroppedBytes += item->GetSize();
649  m_nTotalDroppedBytesBeforeEnqueue += item->GetSize();
650 
651  NS_LOG_LOGIC("m_traceDropBeforeEnqueue (p)");
652  m_traceDrop(item);
653  m_traceDropBeforeEnqueue(item);
654 }
655 
656 template <typename Item, typename Container>
657 void
659 {
660  NS_LOG_FUNCTION(this << item);
661 
662  m_nTotalDroppedPackets++;
663  m_nTotalDroppedPacketsAfterDequeue++;
664  m_nTotalDroppedBytes += item->GetSize();
665  m_nTotalDroppedBytesAfterDequeue += item->GetSize();
666 
667  NS_LOG_LOGIC("m_traceDropAfterDequeue (p)");
668  m_traceDrop(item);
669  m_traceDropAfterDequeue(item);
670 }
671 
672 // The following explicit template instantiation declarations prevent all the
673 // translation units including this header file to implicitly instantiate the
674 // Queue<Packet> class and the Queue<QueueDiscItem> class. The unique instances
675 // of these classes are explicitly created through the macros
676 // NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,Packet) and
677 // NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,QueueDiscItem), which are included in queue.cc
678 extern template class Queue<Packet>;
679 extern template class Queue<QueueDiscItem>;
680 
681 } // namespace ns3
682 
683 #endif /* QUEUE_H */
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Introspection did not find any typical Config paths.
Abstract base class for packet Queues.
Definition: queue.h:54
uint32_t m_nTotalDroppedBytesBeforeEnqueue
Total dropped bytes before enqueue.
Definition: queue.h:222
uint32_t GetTotalDroppedPacketsAfterDequeue() const
Definition: queue.cc:178
TracedValue< uint32_t > m_nPackets
Number of packets in the queue.
Definition: queue.h:219
uint32_t GetTotalDroppedPacketsBeforeEnqueue() const
Definition: queue.cc:170
uint32_t m_nTotalDroppedPacketsAfterDequeue
Total dropped packets after dequeue.
Definition: queue.h:226
uint32_t m_nTotalReceivedPackets
Total received packets.
Definition: queue.h:220
uint32_t GetTotalDroppedBytesAfterDequeue() const
Definition: queue.cc:154
QueueSize GetMaxSize() const
Definition: queue.cc:217
uint32_t GetTotalReceivedBytes() const
Definition: queue.cc:122
bool WouldOverflow(uint32_t nPackets, uint32_t nBytes) const
Check if the queue would overflow with additional bytes or packets Note: the check is performed accor...
Definition: queue.cc:224
void ResetStatistics()
Resets the counts for dropped packets, dropped bytes, received packets, and received bytes.
Definition: queue.cc:186
bool IsEmpty() const
Definition: queue.cc:82
static void AppendItemTypeIfNotPresent(std::string &typeId, const std::string &itemType)
Append the item type to the provided type ID if the latter does not end with '>'.
Definition: queue.cc:73
uint32_t GetTotalDroppedBytes() const
Definition: queue.cc:138
static TypeId GetTypeId()
Get the type ID.
Definition: queue.cc:35
uint32_t GetTotalDroppedBytesBeforeEnqueue() const
Definition: queue.cc:146
uint32_t m_nTotalDroppedBytes
Total dropped bytes.
Definition: queue.h:221
uint32_t GetNBytes() const
Definition: queue.cc:98
uint32_t m_nTotalDroppedPacketsBeforeEnqueue
Total dropped packets before enqueue.
Definition: queue.h:225
QueueSize m_maxSize
max queue size
Definition: queue.h:228
uint32_t m_nTotalDroppedPackets
Total dropped packets.
Definition: queue.h:224
uint32_t GetNPackets() const
Definition: queue.cc:90
void SetMaxSize(QueueSize size)
Set the maximum size of this queue.
Definition: queue.cc:200
uint32_t GetTotalReceivedPackets() const
Definition: queue.cc:130
TracedValue< uint32_t > m_nBytes
Number of bytes in the queue.
Definition: queue.h:217
~QueueBase() override
Definition: queue.cc:67
uint32_t m_nTotalDroppedBytesAfterDequeue
Total dropped bytes after dequeue.
Definition: queue.h:223
uint32_t GetTotalDroppedPackets() const
Definition: queue.cc:162
uint32_t m_nTotalReceivedBytes
Total received bytes.
Definition: queue.h:218
QueueSize GetCurrentSize() const
Definition: queue.cc:106
Template class for packet Queues.
Definition: queue.h:267
Ptr< Item > DoRemove(ConstIterator pos)
Pull the item to drop from the queue.
Definition: queue.h:575
~Queue() override
Definition: queue.h:497
bool DoEnqueue(ConstIterator pos, Ptr< Item > item, Iterator &ret)
Push an item in the queue.
Definition: queue.h:518
virtual Ptr< const Item > Peek() const =0
Get a copy of an item in the queue (each subclass defines the position) without removing it.
TracedCallback< Ptr< const Item > > m_traceDrop
Traced callback: fired when a packet is dropped.
Definition: queue.h:441
Ptr< Item > DoDequeue(ConstIterator pos)
Pull the item to dequeue from the queue.
Definition: queue.h:546
void Flush()
Flush the queue by calling Remove() on each item enqueued.
Definition: queue.h:607
Container m_packets
the items in the queue
Definition: queue.h:433
TracedCallback< Ptr< const Item > > m_traceDropAfterDequeue
Traced callback: fired when a packet is dropped after dequeue.
Definition: queue.h:445
bool DoEnqueue(ConstIterator pos, Ptr< Item > item)
Push an item in the queue.
Definition: queue.h:510
Ptr< const Item > DoPeek(ConstIterator pos) const
Peek the front item in the queue.
Definition: queue.h:627
Queue()
Definition: queue.h:491
void DropAfterDequeue(Ptr< Item > item)
Drop a packet after dequeue.
Definition: queue.h:658
void DoDispose() override
Destructor implementation.
Definition: queue.h:618
TracedCallback< Ptr< const Item > > m_traceEnqueue
Traced callback: fired when a packet is enqueued.
Definition: queue.h:437
virtual bool Enqueue(Ptr< Item > item)=0
Place an item into the Queue (each subclass defines the position)
const Container & GetContainer() const
Get a const reference to the container of queue items.
Definition: queue.h:503
TracedCallback< Ptr< const Item > > m_traceDequeue
Traced callback: fired when a packet is dequeued.
Definition: queue.h:439
virtual Ptr< Item > Remove()=0
Remove an item from the Queue (each subclass defines the position), counting it and tracing it as bot...
void DropBeforeEnqueue(Ptr< Item > item)
Drop a packet before enqueue.
Definition: queue.h:642
static TypeId GetTypeId()
Get the type ID.
Definition: queue.h:454
Container::iterator Iterator
Iterator.
Definition: queue.h:320
TracedCallback< Ptr< const Item > > m_traceDropBeforeEnqueue
Traced callback: fired when a packet is dropped before enqueue.
Definition: queue.h:443
Container::const_iterator ConstIterator
Const iterator.
Definition: queue.h:318
Item ItemType
Define ItemType as the type of the stored elements.
Definition: queue.h:314
NS_LOG_TEMPLATE_DECLARE
the log component
Definition: queue.h:434
virtual Ptr< Item > Dequeue()=0
Remove an item from the Queue (each subclass defines the position), counting it and tracing it as deq...
Class for representing queue sizes.
Definition: queue-size.h:96
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Forward calls to a chain of Callback.
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:236
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static Ptr< Item > GetItem(const Container &container, const ConstIterator it)
Definition: queue.h:427
Struct providing a static method returning the object stored within the queue that is included in the...
Definition: queue.h:400
static Ptr< Item > GetItem(const Container &, const ConstIterator it)
Definition: queue.h:405