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 "queue-fwd.h"
26 #include "queue-item.h"
27 #include "queue-size.h"
28 
29 #include "ns3/log.h"
30 #include "ns3/object.h"
31 #include "ns3/packet.h"
32 #include "ns3/traced-callback.h"
33 #include "ns3/traced-value.h"
34 
35 #include <sstream>
36 #include <string>
37 #include <type_traits>
38 
39 namespace ns3
40 {
41 
54 class QueueBase : public Object
55 {
56  public:
61  static TypeId GetTypeId();
62 
63  QueueBase();
64  ~QueueBase() override;
65 
85  static void AppendItemTypeIfNotPresent(std::string& typeId, const std::string& itemType);
86 
90  bool IsEmpty() const;
91 
95  uint32_t GetNPackets() const;
96 
100  uint32_t GetNBytes() const;
101 
106  QueueSize GetCurrentSize() const;
107 
113  uint32_t GetTotalReceivedBytes() const;
114 
120  uint32_t GetTotalReceivedPackets() const;
121 
127  uint32_t GetTotalDroppedBytes() const;
128 
134  uint32_t GetTotalDroppedBytesBeforeEnqueue() const;
135 
141  uint32_t GetTotalDroppedBytesAfterDequeue() const;
142 
148  uint32_t GetTotalDroppedPackets() const;
149 
155  uint32_t GetTotalDroppedPacketsBeforeEnqueue() const;
156 
162  uint32_t GetTotalDroppedPacketsAfterDequeue() const;
163 
168  void ResetStatistics();
169 
177  void SetMaxSize(QueueSize size);
178 
182  QueueSize GetMaxSize() const;
183 
191  bool WouldOverflow(uint32_t nPackets, uint32_t nBytes) const;
192 
193 #if 0
194  // average calculation requires keeping around
195  // a buffer with the date of arrival of past received packets
196  // which are within the average window
197  // so, it is quite costly to do it all the time.
198  // Hence, it is disabled by default and must be explicitly
199  // enabled with this method which specifies the size
200  // of the average window in time units.
201  void EnableRunningAverage(Time averageWindow);
202  void DisableRunningAverage();
203  // average
204  double GetQueueSizeAverage();
205  double GetReceivedBytesPerSecondAverage();
206  double GetReceivedPacketsPerSecondAverage();
207  double GetDroppedBytesPerSecondAverage();
208  double GetDroppedPacketsPerSecondAverage();
209  // variance
210  double GetQueueSizeVariance();
211  double GetReceivedBytesPerSecondVariance();
212  double GetReceivedPacketsPerSecondVariance();
213  double GetDroppedBytesPerSecondVariance();
214  double GetDroppedPacketsPerSecondVariance();
215 #endif
216 
217  protected:
228 
230 };
231 
266 template <typename Item, typename Container>
267 class Queue : public QueueBase
268 {
269  public:
274  static TypeId GetTypeId();
275 
276  Queue();
277  ~Queue() override;
278 
284  virtual bool Enqueue(Ptr<Item> item) = 0;
285 
291  virtual Ptr<Item> Dequeue() = 0;
292 
298  virtual Ptr<Item> Remove() = 0;
299 
305  virtual Ptr<const Item> Peek() const = 0;
306 
312  void Flush();
313 
315  typedef Item ItemType;
316 
317  protected:
319  typedef typename Container::const_iterator ConstIterator;
321  typedef typename Container::iterator Iterator;
322 
328  const Container& GetContainer() const;
329 
337 
345  bool DoEnqueue(ConstIterator pos, Ptr<Item> item, Iterator& ret);
346 
353 
360 
367 
377 
387 
389  void DoDispose() override;
390 
391  private:
399  template <class, class = void>
400  struct MakeGetItem
401  {
406  static Ptr<Item> GetItem(const Container&, const ConstIterator it)
407  {
408  return *it;
409  }
410  };
411 
418  template <class T>
419  struct MakeGetItem<
420  T,
421  std::void_t<decltype(std::declval<T>().GetItem(std::declval<ConstIterator>()))>>
422  {
428  static Ptr<Item> GetItem(const Container& container, const ConstIterator it)
429  {
430  return container.GetItem(it);
431  }
432  };
433 
434  Container m_packets;
436 
447 };
448 
453 template <typename Item, typename Container>
454 TypeId
456 {
457  std::string name = GetTemplateClassName<Queue<Item, Container>>();
458  auto startPos = name.find('<') + 1;
459  auto endPos = name.find_first_of(",>", startPos);
460  std::string tcbName = "ns3::" + name.substr(startPos, endPos - startPos) + "::TracedCallback";
461 
462  static TypeId tid =
463  TypeId(name)
464  .SetParent<QueueBase>()
465  .SetGroupName("Network")
466  .AddTraceSource("Enqueue",
467  "Enqueue a packet in the queue.",
469  tcbName)
470  .AddTraceSource("Dequeue",
471  "Dequeue a packet from the queue.",
473  tcbName)
474  .AddTraceSource("Drop",
475  "Drop a packet (for whatever reason).",
477  tcbName)
478  .AddTraceSource(
479  "DropBeforeEnqueue",
480  "Drop a packet before enqueue.",
482  tcbName)
483  .AddTraceSource(
484  "DropAfterDequeue",
485  "Drop a packet after dequeue.",
487  tcbName);
488  return tid;
489 }
490 
491 template <typename Item, typename Container>
493  : NS_LOG_TEMPLATE_DEFINE("Queue")
494 {
495 }
496 
497 template <typename Item, typename Container>
499 {
500 }
501 
502 template <typename Item, typename Container>
503 const Container&
505 {
506  return m_packets;
507 }
508 
509 template <typename Item, typename Container>
510 bool
512 {
513  Iterator ret;
514  return DoEnqueue(pos, item, ret);
515 }
516 
517 template <typename Item, typename Container>
518 bool
520 {
521  NS_LOG_FUNCTION(this << item);
522 
523  if (GetCurrentSize() + item > GetMaxSize())
524  {
525  NS_LOG_LOGIC("Queue full -- dropping pkt");
526  DropBeforeEnqueue(item);
527  return false;
528  }
529 
530  ret = m_packets.insert(pos, item);
531 
532  uint32_t size = item->GetSize();
533  m_nBytes += size;
534  m_nTotalReceivedBytes += size;
535 
536  m_nPackets++;
537  m_nTotalReceivedPackets++;
538 
539  NS_LOG_LOGIC("m_traceEnqueue (p)");
540  m_traceEnqueue(item);
541 
542  return true;
543 }
544 
545 template <typename Item, typename Container>
546 Ptr<Item>
548 {
549  NS_LOG_FUNCTION(this);
550 
551  if (m_nPackets.Get() == 0)
552  {
553  NS_LOG_LOGIC("Queue empty");
554  return nullptr;
555  }
556 
557  Ptr<Item> item = MakeGetItem<Container>::GetItem(m_packets, pos);
558 
559  if (item)
560  {
561  m_packets.erase(pos);
562  NS_ASSERT(m_nBytes.Get() >= item->GetSize());
563  NS_ASSERT(m_nPackets.Get() > 0);
564 
565  m_nBytes -= item->GetSize();
566  m_nPackets--;
567 
568  NS_LOG_LOGIC("m_traceDequeue (p)");
569  m_traceDequeue(item);
570  }
571  return item;
572 }
573 
574 template <typename Item, typename Container>
575 Ptr<Item>
577 {
578  NS_LOG_FUNCTION(this);
579 
580  if (m_nPackets.Get() == 0)
581  {
582  NS_LOG_LOGIC("Queue empty");
583  return nullptr;
584  }
585 
586  Ptr<Item> item = MakeGetItem<Container>::GetItem(m_packets, pos);
587 
588  if (item)
589  {
590  m_packets.erase(pos);
591  NS_ASSERT(m_nBytes.Get() >= item->GetSize());
592  NS_ASSERT(m_nPackets.Get() > 0);
593 
594  m_nBytes -= item->GetSize();
595  m_nPackets--;
596 
597  // packets are first dequeued and then dropped
598  NS_LOG_LOGIC("m_traceDequeue (p)");
599  m_traceDequeue(item);
600 
601  DropAfterDequeue(item);
602  }
603  return item;
604 }
605 
606 template <typename Item, typename Container>
607 void
609 {
610  NS_LOG_FUNCTION(this);
611  while (!IsEmpty())
612  {
613  Remove();
614  }
615 }
616 
617 template <typename Item, typename Container>
618 void
620 {
621  NS_LOG_FUNCTION(this);
622  m_packets.clear();
624 }
625 
626 template <typename Item, typename Container>
629 {
630  NS_LOG_FUNCTION(this);
631 
632  if (m_nPackets.Get() == 0)
633  {
634  NS_LOG_LOGIC("Queue empty");
635  return nullptr;
636  }
637 
638  return MakeGetItem<Container>::GetItem(m_packets, pos);
639 }
640 
641 template <typename Item, typename Container>
642 void
644 {
645  NS_LOG_FUNCTION(this << item);
646 
647  m_nTotalDroppedPackets++;
648  m_nTotalDroppedPacketsBeforeEnqueue++;
649  m_nTotalDroppedBytes += item->GetSize();
650  m_nTotalDroppedBytesBeforeEnqueue += item->GetSize();
651 
652  NS_LOG_LOGIC("m_traceDropBeforeEnqueue (p)");
653  m_traceDrop(item);
654  m_traceDropBeforeEnqueue(item);
655 }
656 
657 template <typename Item, typename Container>
658 void
660 {
661  NS_LOG_FUNCTION(this << item);
662 
663  m_nTotalDroppedPackets++;
664  m_nTotalDroppedPacketsAfterDequeue++;
665  m_nTotalDroppedBytes += item->GetSize();
666  m_nTotalDroppedBytesAfterDequeue += item->GetSize();
667 
668  NS_LOG_LOGIC("m_traceDropAfterDequeue (p)");
669  m_traceDrop(item);
670  m_traceDropAfterDequeue(item);
671 }
672 
673 // The following explicit template instantiation declarations prevent all the
674 // translation units including this header file to implicitly instantiate the
675 // Queue<Packet> class and the Queue<QueueDiscItem> class. The unique instances
676 // of these classes are explicitly created through the macros
677 // NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,Packet) and
678 // NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,QueueDiscItem), which are included in queue.cc
679 extern template class Queue<Packet>;
680 extern template class Queue<QueueDiscItem>;
681 
682 } // namespace ns3
683 
684 #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:352
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Abstract base class for packet Queues.
Definition: queue.h:55
uint32_t m_nTotalDroppedBytesBeforeEnqueue
Total dropped bytes before enqueue.
Definition: queue.h:223
uint32_t GetTotalDroppedPacketsAfterDequeue() const
Definition: queue.cc:178
TracedValue< uint32_t > m_nPackets
Number of packets in the queue.
Definition: queue.h:220
uint32_t GetTotalDroppedPacketsBeforeEnqueue() const
Definition: queue.cc:170
uint32_t m_nTotalDroppedPacketsAfterDequeue
Total dropped packets after dequeue.
Definition: queue.h:227
uint32_t m_nTotalReceivedPackets
Total received packets.
Definition: queue.h:221
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:222
uint32_t GetNBytes() const
Definition: queue.cc:98
uint32_t m_nTotalDroppedPacketsBeforeEnqueue
Total dropped packets before enqueue.
Definition: queue.h:226
QueueSize m_maxSize
max queue size
Definition: queue.h:229
uint32_t m_nTotalDroppedPackets
Total dropped packets.
Definition: queue.h:225
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:218
~QueueBase() override
Definition: queue.cc:67
uint32_t m_nTotalDroppedBytesAfterDequeue
Total dropped bytes after dequeue.
Definition: queue.h:224
uint32_t GetTotalDroppedPackets() const
Definition: queue.cc:162
uint32_t m_nTotalReceivedBytes
Total received bytes.
Definition: queue.h:219
QueueSize GetCurrentSize() const
Definition: queue.cc:106
Template class for packet Queues.
Definition: queue.h:268
Ptr< Item > DoRemove(ConstIterator pos)
Pull the item to drop from the queue.
Definition: queue.h:576
~Queue() override
Definition: queue.h:498
bool DoEnqueue(ConstIterator pos, Ptr< Item > item, Iterator &ret)
Push an item in the queue.
Definition: queue.h:519
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:442
Ptr< Item > DoDequeue(ConstIterator pos)
Pull the item to dequeue from the queue.
Definition: queue.h:547
void Flush()
Flush the queue by calling Remove() on each item enqueued.
Definition: queue.h:608
Container m_packets
the items in the queue
Definition: queue.h:434
TracedCallback< Ptr< const Item > > m_traceDropAfterDequeue
Traced callback: fired when a packet is dropped after dequeue.
Definition: queue.h:446
bool DoEnqueue(ConstIterator pos, Ptr< Item > item)
Push an item in the queue.
Definition: queue.h:511
Ptr< const Item > DoPeek(ConstIterator pos) const
Peek the front item in the queue.
Definition: queue.h:628
Queue()
Definition: queue.h:492
void DropAfterDequeue(Ptr< Item > item)
Drop a packet after dequeue.
Definition: queue.h:659
void DoDispose() override
Destructor implementation.
Definition: queue.h:619
TracedCallback< Ptr< const Item > > m_traceEnqueue
Traced callback: fired when a packet is enqueued.
Definition: queue.h:438
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:504
TracedCallback< Ptr< const Item > > m_traceDequeue
Traced callback: fired when a packet is dequeued.
Definition: queue.h:440
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:643
static TypeId GetTypeId()
Get the type ID.
Definition: queue.h:455
Container::iterator Iterator
Iterator.
Definition: queue.h:321
TracedCallback< Ptr< const Item > > m_traceDropBeforeEnqueue
Traced callback: fired when a packet is dropped before enqueue.
Definition: queue.h:444
Container::const_iterator ConstIterator
Const iterator.
Definition: queue.h:319
Item ItemType
Define ItemType as the type of the stored elements.
Definition: queue.h:315
NS_LOG_TEMPLATE_DECLARE
the log component
Definition: queue.h:435
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#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.
typename make_void< Ts... >::type void_t
Definition: json.h:2821
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Forward declaration of template class Queue.
static Ptr< Item > GetItem(const Container &container, const ConstIterator it)
Definition: queue.h:428
Struct providing a static method returning the object stored within the queue that is included in the...
Definition: queue.h:401
static Ptr< Item > GetItem(const Container &, const ConstIterator it)
Definition: queue.h:406