queue.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:8k
- /*
- * Copyright (c) 1991,1993 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /cvsroot/nsnam/nam-1/queue.cc,v 1.18 2001/04/18 00:14:16 mehringe Exp $ (LBL)
- */
- #ifdef WIN32
- #include <windows.h>
- #endif
- #include "netview.h"
- #include "psview.h"
- #include "queue.h"
- #include "drop.h"
- #include "monitor.h"
- #include "sincos.h"
- QueueItem::QueueItem(const PacketAttr& p, double tim, long offset) :
- Animation(tim, offset),
- qnext_(0) {
- pkt_ = p;
- }
- QueueItem::~QueueItem()
- {
- if (monitor_!=NULL) {
- monitor_->delete_monitor_object(this);
- }
- }
- //----------------------------------------------------------------------
- // void
- // QueueItem::draw(View* nv, double time )
- // - Draws a packet queue on a link next to the node
- // - only draw things that are within the bounding
- // box... otherwise, we might hang the display :( -kfall
- //
- // - note: this is an incomplete fix; there remains
- // a bug where the packets in the queue aren't erased
- // properly when this case triggers 8/8/99
- //
- // I believe I fixed this bug. It was due to th bounding
- // box for the view was not being calculated properly so
- // queues would be cut off before they reached their proper
- // height. -John Mehringer
- //----------------------------------------------------------------------
- void
- QueueItem::draw(View* nv, double time ) {
- BBox bb;
- nv->BoundingBox(bb);
- if (bb.inside(bb_)) {
- nv->fill(px_, py_, 4, paint_);
- if (monitor_ != NULL)
- monitor_->draw(nv, px_[0],py_[0]);
- }
- }
- float QueueItem::distance(float x, float y) const
- {
- float cx, cy;
- cx = (bb_.xmin + bb_.xmax) / 2;
- cy = (bb_.ymin + bb_.ymax) / 2;
- return ((cx-x) * (cx-x) + (cy-y)*(cy-y));
- }
- //---------------------------------------------------------------------
- // void
- // QueueItem::position(float& x, float& y)
- // - Gets the position (left corner) of the queue item and puts
- // it into x and y.
- //---------------------------------------------------------------------
- void
- QueueItem::position(float& x, float& y) {
- // Need to find out where px_ and py_ are being set.
- // Look at locate and Queue relocate.
- x = px_[0];
- y = py_[0];
- }
- void QueueItem::update_bb()
- {
- bb_.xmin = bb_.xmax = px_[0];
- bb_.ymin = bb_.ymax = py_[0];
- for (int i = 0; i < 4; i++) {
- if (px_[i] < bb_.xmin)
- bb_.xmin = px_[i];
- if (px_[i] > bb_.xmax)
- bb_.xmax = px_[i];
- if (py_[i] < bb_.ymin)
- bb_.ymin = py_[i];
- if (py_[i] < bb_.ymax)
- bb_.ymax = py_[i];
- }
- }
- //----------------------------------------------------------------------
- // void
- // QueueItem::locate(float x, float y, float dx, float dy)
- // - Place a queue item with it's bottom left corner at x,y.
- // - dx, dy are the width and height of the diagonal of the diamond
- // drawn to represent the queue item.
- // - In a vertical queue dx is 0 due to the way the Queue::place()
- // calculates packet height and width.
- //----------------------------------------------------------------------
- void
- QueueItem::locate(float x, float y, float dx, float dy) {
- // Bottom Left Corner
- px_[0] = x;
- py_[0] = y;
- // Bottom Right Corner
- x += dy;
- y -= dx;
- px_[1] = x;
- py_[1] = y;
- // Top Right Corner
- x += dx;
- y += dy;
- px_[2] = x;
- py_[2] = y;
- // Top Left Corner
- x -= dy;
- y += dx;
- px_[3] = x;
- py_[3] = y;
- update_bb();
- }
- const char* QueueItem::info() const
- {
- static char text[128];
- sprintf(text, "%s %d: %sn %d bytesn",
- pkt_.type, pkt_.id, pkt_.convid, pkt_.size);
- return (text);
- }
- const char* QueueItem::getname() const
- {
- static char text[128];
- sprintf(text, "p");
- return (text);
- }
- void QueueItem::monitor(Monitor *m, double /*now*/, char *result, int /*len*/)
- {
- monitor_=m;
- sprintf(result, "%s %d: %sn %d bytesn",
- pkt_.type, pkt_.id, pkt_.convid, pkt_.size);
- }
- MonState *QueueItem::monitor_state()
- {
- // return any state we wish the monitor to remember after we're gone
- MonState *ms=new MonState;
- ms->type=MON_PACKET;
- ms->pkt.id=pkt_.id;
- return ms;
- }
- Queue::Queue(float angle)
- : cnt_(0), psize_(0.), nb_(0), angle_(angle)
- {
- head_ = 0;
- tail_ = &head_;
- }
- void Queue::place(double psize, double x, double y) {
- psize_ = psize;
- double qc, qs;
- SINCOSPI(angle_, &qs, &qc);
- dx_ = qc * psize_;
- dy_ = qs * psize_;
- px_ = 3 * dx_ / 4;
- py_ = 3 * dy_ / 4;
- qx_ = x + 2 * dx_;
- qy_ = y + 2 * dy_;
- }
- void Queue::relocate()
- {
- float x = qx_, y = qy_;
- for (QueueItem *q = head_; q != 0; q = q->qnext_) {
- q->locate(x, y, px_, py_);
- x += dx_;
- y += dy_;
- }
- }
- QueueItem *Queue::remove(const PacketAttr& p, int& pos)
- {
- QueueItem* q;
- pos = 0;
- for (QueueItem **pp = &head_; (q = *pp) != 0; pp = &q->qnext_) {
- ++pos;
- if (q->pkt_.id == p.id
- /* kfall && q->pkt_.attr == p.attr, see below */
- && q->pkt_.size == p.size
- && strcmp(q->pkt_.convid, p.convid) == 0
- && strcmp(q->pkt_.type, p.type)== 0) {
- --cnt_;
- nb_ -= q->pkt_.size;
- *pp = q->qnext_;
- if (*pp == 0)
- tail_ = pp;
- relocate();
- return (q);
- }
- }
- return (0);
- /*
- * the removal of the attr comparison is needed
- * because when RED marks packets, the "-" records
- * have a different attrib than the corresponding "r" or
- * "+" records. If one looks for matching attribs,
- * then all of the packets drained from the queue
- * that have ecn marks on them are never actually
- * erased, leaving curious packets laying around
- * in the queue even when the outgoing link is idle
- * -kfall 8/8/99
- */
- }
- void Queue::enque(QueueItem *q, int mode)
- {
- /*add to the tail if time is running forwards, else add to the head*/
- if (mode==QUEUE_TAIL) {
- *tail_ = q;
- tail_ = &q->qnext_;
- q->qnext_ = 0;
- ++cnt_;
- nb_ += q->pkt_.size;
- relocate();
- } else if (mode==QUEUE_HEAD) {
- q->qnext_=head_;
- head_=q;
- ++cnt_;
- nb_ += q->pkt_.size;
- relocate();
- }
- }
- void Queue::reset(double /*now*/)
- {
- while (head_ != 0) {
- QueueItem *n = head_->qnext_;
- delete head_;
- head_ = n;
- }
- head_ = 0;
- tail_ = &head_;
- cnt_ = 0;
- nb_ = 0;
- }