queue.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:8k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1991,1993 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *  This product includes software developed by the Computer Systems
  16.  *  Engineering Group at Lawrence Berkeley Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  * @(#) $Header: /cvsroot/nsnam/nam-1/queue.cc,v 1.18 2001/04/18 00:14:16 mehringe Exp $ (LBL)
  34.  */
  35. #ifdef WIN32
  36. #include <windows.h>
  37. #endif
  38. #include "netview.h"
  39. #include "psview.h"
  40. #include "queue.h"
  41. #include "drop.h"
  42. #include "monitor.h"
  43. #include "sincos.h"
  44. QueueItem::QueueItem(const PacketAttr& p, double tim, long offset) :
  45.   Animation(tim, offset),
  46.   qnext_(0) {
  47.   pkt_ = p;
  48. }
  49. QueueItem::~QueueItem()
  50. {
  51.   if (monitor_!=NULL) {
  52.     monitor_->delete_monitor_object(this);
  53.   }
  54. }
  55. //----------------------------------------------------------------------
  56. // void 
  57. // QueueItem::draw(View* nv, double time )
  58. //   - Draws a packet queue on a link next to the node  
  59. //   - only draw things that are within the bounding
  60. //     box... otherwise, we might hang the display :( -kfall
  61. //
  62. //   - note: this is an incomplete fix; there remains
  63. //           a bug where the packets in the queue aren't erased
  64. //           properly when this case triggers 8/8/99
  65. //
  66. //           I believe I fixed this bug. It was due to th bounding 
  67. //           box for the view was not being calculated properly so
  68. //           queues would be cut off before they reached their proper
  69. //           height.   -John Mehringer
  70. //----------------------------------------------------------------------
  71. void 
  72. QueueItem::draw(View* nv, double time ) {
  73.   BBox bb;
  74.   nv->BoundingBox(bb);
  75.   if (bb.inside(bb_)) {
  76.     nv->fill(px_, py_, 4, paint_);
  77.     if (monitor_ != NULL)
  78.         monitor_->draw(nv, px_[0],py_[0]);
  79.   }
  80. }
  81. float QueueItem::distance(float x, float y) const 
  82. {
  83.   float cx, cy;
  84.   cx = (bb_.xmin + bb_.xmax) / 2;
  85.   cy = (bb_.ymin + bb_.ymax) / 2;
  86.   return ((cx-x) * (cx-x) + (cy-y)*(cy-y));
  87. }
  88. //---------------------------------------------------------------------
  89. // void
  90. // QueueItem::position(float& x, float& y)
  91. //   - Gets the position (left corner) of the queue item and puts
  92. //     it into x and y. 
  93. //---------------------------------------------------------------------
  94. void
  95. QueueItem::position(float& x, float& y) {
  96.   // Need to find out where px_ and py_ are being set.
  97.   // Look at locate and Queue relocate.
  98.   x = px_[0];
  99.   y = py_[0];
  100. }
  101. void QueueItem::update_bb()
  102. {
  103.   bb_.xmin = bb_.xmax = px_[0];
  104.   bb_.ymin = bb_.ymax = py_[0];
  105.   for (int i = 0; i < 4; i++) {
  106.     if (px_[i] < bb_.xmin)
  107.       bb_.xmin = px_[i];
  108.     if (px_[i] > bb_.xmax)
  109.       bb_.xmax = px_[i];
  110.     if (py_[i] < bb_.ymin)
  111.       bb_.ymin = py_[i];
  112.     if (py_[i] < bb_.ymax)
  113.       bb_.ymax = py_[i];
  114.   }
  115. }
  116. //----------------------------------------------------------------------
  117. // void 
  118. // QueueItem::locate(float x, float y, float dx, float dy)
  119. //   - Place a queue item with it's bottom left corner at x,y.
  120. //   - dx, dy are the width and height of the diagonal of the diamond
  121. //     drawn to represent the queue item.
  122. //   - In a vertical queue dx is 0 due to the way the Queue::place()
  123. //     calculates packet height and width.
  124. //----------------------------------------------------------------------
  125. void
  126. QueueItem::locate(float x, float y, float dx, float dy) {
  127.   // Bottom Left Corner
  128.   px_[0] = x;
  129.   py_[0] = y;
  130.   // Bottom Right Corner 
  131.   x += dy;
  132.   y -= dx;
  133.   px_[1] = x;
  134.   py_[1] = y;
  135.   // Top Right Corner
  136.   x += dx;
  137.   y += dy;
  138.   px_[2] = x;
  139.   py_[2] = y;
  140.   // Top  Left Corner
  141.   x -= dy;
  142.   y += dx;
  143.   px_[3] = x;
  144.   py_[3] = y;
  145.   update_bb();
  146. }
  147. const char* QueueItem::info() const
  148. {
  149.   static char text[128];
  150.   sprintf(text, "%s %d: %sn   %d bytesn",
  151.     pkt_.type, pkt_.id, pkt_.convid, pkt_.size);
  152.   return (text);
  153. }
  154. const char* QueueItem::getname() const
  155. {
  156.   static char text[128];
  157.   sprintf(text, "p");
  158.   return (text);
  159. }
  160. void QueueItem::monitor(Monitor *m, double /*now*/, char *result, int /*len*/)
  161. {
  162.   monitor_=m;
  163.   sprintf(result, "%s %d: %sn   %d bytesn",
  164.                 pkt_.type, pkt_.id, pkt_.convid, pkt_.size);
  165. }
  166. MonState *QueueItem::monitor_state()
  167. {
  168.   // return any state we wish the monitor to remember after we're gone
  169.   MonState *ms=new MonState;
  170.   ms->type=MON_PACKET;
  171.   ms->pkt.id=pkt_.id;
  172.   return ms;
  173. }
  174. Queue::Queue(float angle)
  175.   : cnt_(0), psize_(0.), nb_(0), angle_(angle)
  176. {
  177.   head_ = 0;
  178.   tail_ = &head_;
  179. }
  180. void Queue::place(double psize, double x, double y) {
  181.   psize_ = psize;
  182.   double qc, qs;
  183.   SINCOSPI(angle_, &qs, &qc);
  184.   dx_ = qc * psize_;
  185.   dy_ = qs * psize_;
  186.   px_ = 3 * dx_ / 4;
  187.   py_ = 3 * dy_ / 4;
  188.   qx_ = x + 2 * dx_;
  189.   qy_ = y + 2 * dy_;
  190. }
  191. void Queue::relocate()
  192. {
  193.   float x = qx_, y = qy_;
  194.   for (QueueItem *q = head_; q != 0; q = q->qnext_) {
  195.     q->locate(x, y, px_, py_);
  196.     x += dx_;
  197.     y += dy_;
  198.   }
  199. }
  200. QueueItem *Queue::remove(const PacketAttr& p, int& pos)
  201. {
  202.   QueueItem* q;
  203.   pos = 0;
  204.   for (QueueItem **pp = &head_; (q = *pp) != 0; pp = &q->qnext_) {
  205.     ++pos;
  206.     if (q->pkt_.id == p.id
  207.         /* kfall && q->pkt_.attr == p.attr, see below */
  208.         && q->pkt_.size == p.size
  209.         && strcmp(q->pkt_.convid, p.convid) == 0
  210.         && strcmp(q->pkt_.type, p.type)== 0) {
  211.       --cnt_;
  212.       nb_ -= q->pkt_.size;
  213.       *pp = q->qnext_;
  214.       if (*pp == 0)
  215.         tail_ = pp;
  216.       relocate();
  217.       return (q);
  218.     }
  219.   }
  220.   return (0);
  221.   /* 
  222.    * the removal of the attr comparison is needed
  223.    * because when RED marks packets, the "-" records
  224.    * have a different attrib than the corresponding "r" or
  225.    * "+" records.  If one looks for matching attribs,
  226.    * then all of the packets drained from the queue
  227.    * that have ecn marks on them are never actually
  228.    * erased, leaving curious packets laying around
  229.    * in the queue even when the outgoing link is idle
  230.    * -kfall 8/8/99
  231.    */
  232. }
  233. void Queue::enque(QueueItem *q, int mode)
  234. {
  235.   /*add to the tail if time is running forwards, else add to the head*/
  236.   if (mode==QUEUE_TAIL) {
  237.     *tail_ = q;
  238.     tail_ = &q->qnext_;
  239.     q->qnext_ = 0;
  240.     ++cnt_;
  241.     nb_ += q->pkt_.size;
  242.     relocate();
  243.   } else if (mode==QUEUE_HEAD) {
  244.     q->qnext_=head_;
  245.     head_=q;
  246.     ++cnt_;
  247.     nb_ += q->pkt_.size;
  248.     relocate();
  249.   }
  250. }
  251. void Queue::reset(double /*now*/)
  252. {
  253.   while (head_ != 0) {
  254.     QueueItem *n = head_->qnext_;
  255.     delete head_;
  256.     head_ = n;
  257.   }
  258.   head_ = 0;
  259.   tail_ = &head_;
  260.   cnt_ = 0;
  261.   nb_ = 0;
  262. }