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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1997 University of Southern 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 Information Sciences
  16.  *      Institute of the University of Southern California.
  17.  * 4. Neither the name of the University nor of the Institute 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/netgraph.cc,v 1.12 2000/05/18 18:06:32 klan Exp $ (LBL)
  34.  */
  35. #include <stdlib.h>
  36. #include <ctype.h>
  37. #include <math.h>
  38. #include "config.h"
  39. #include "graphview.h"
  40. #include "netgraph.h"
  41. #include "paint.h"
  42. #include "sincos.h"
  43. #include "state.h"
  44. #include "bbox.h"
  45. #include <float.h>
  46. extern int lineno;
  47. //static int next_pat;
  48. /*XXX */
  49. class NetworkGraphClass : public TclClass {
  50.  public:
  51. NetworkGraphClass() : TclClass("NetworkGraph") {}
  52. TclObject* create(int /*argc*/, const char*const* /*argv*/) {
  53. return (new NetGraph);
  54. }
  55. } networkgraph_class;
  56. class EnergyNetworkGraphClass : public TclClass {
  57.  public:
  58. EnergyNetworkGraphClass() : TclClass("EnergyNetworkGraph") {}
  59. TclObject* create(int /*argc*/, const char*const* /*argv*/) {
  60. return (new EnergyNetGraph);
  61. }
  62. } energynetworkgraph_class;
  63. class LinkNetworkGraphClass : public TclClass {
  64.  public:
  65. LinkNetworkGraphClass() : TclClass("LinkNetworkGraph") {}
  66. TclObject* create(int /*argc*/, const char*const* /*argv*/) {
  67. return (new LinkNetGraph);
  68. }
  69. } linknetworkgraph_class;
  70. class FeatureNetworkGraphClass : public TclClass {
  71.  public:
  72. FeatureNetworkGraphClass() : TclClass("FeatureNetworkGraph") {}
  73. TclObject* create(int /*argc*/, const char*const* /*argv*/) {
  74. return (new FeatureNetGraph);
  75. }
  76. } featurenetworkgraph_class;
  77. NetGraph::NetGraph()
  78. : views_(NULL), minx_(0), maxx_(0), miny_(0.0), maxy_(0.0), 
  79.   time_(0.0), tix_(-1)
  80. {
  81. int i;
  82. for (i = 0; i < MAX_GRAPH; i++)
  83. graphdata_[i]=0.0;
  84. Paint *paint = Paint::instance();
  85.         int p = paint->thin();
  86.         ncolors_ = 8;
  87.         paint_ = new int[ncolors_];
  88.         for (i = 0; i < ncolors_; ++i)
  89.                 paint_[i] = p;
  90. paint_[1]=paint->lookup("red",1);
  91. }
  92. EnergyNetGraph::EnergyNetGraph()
  93.   : NetGraph()
  94. {
  95. }
  96. LinkNetGraph::LinkNetGraph()
  97.   : NetGraph(), src_(-1), dst_(-1)
  98. {
  99. }
  100. NetGraph::~NetGraph()
  101. {
  102. }
  103. EnergyNetGraph::~EnergyNetGraph()
  104. {
  105. }
  106. LinkNetGraph::~LinkNetGraph()
  107. {
  108. }
  109. void NetGraph::update(double /*now*/)
  110. {
  111. }
  112. void NetGraph::update(double /*now*/, Animation* /*a*/)
  113. {
  114. }
  115. /* Reset all animations and queues to time 'now'. */
  116. void NetGraph::reset(double /*now*/)
  117. {
  118. }
  119. void NetGraph::render(GraphView* view)
  120. {
  121.   int i;
  122.   if (miny_!=maxy_)
  123.     {
  124.       for(i=0;i<maxx_-minx_;i++)
  125. {
  126.   if (scaleddata_[i]!=0)
  127.     view->line(i, 0, i, scaleddata_[i], paint_[0]);
  128. }
  129.       //draw the current time line
  130.       view->line(tix_, 0, tix_, maxy_, paint_[1]);
  131.     }
  132.   else
  133.     {
  134.       view->string((double)minx_, 0.5, 0.5, "No such events found in tracefile.", ANCHOR_WEST);
  135.     }
  136. }
  137.  
  138. void NetGraph::BoundingBox(BBox& bb)
  139. {
  140.   int i;
  141.   minx_=int(bb.xmin);
  142.   maxx_=int(bb.xmax);
  143.   int newtix=int(time_*(maxx_-minx_)/(maxtime_-mintime_));
  144.   if (newtix!=tix_) {
  145.     tix_=newtix;
  146.   }
  147.   for(i=0;i<maxx_-minx_;i++)
  148.     {
  149.       scaleddata_[i]=0.0;
  150.     }
  151.   maxy_=0.0;
  152.   /*Note: storing the data in an array like this is quick, but introduces
  153.     some aliasing effects in the scaling process.  I think they're 
  154.     negligable for this purpose but if we really want to remove them
  155.     we must store the unscaled data in a list instead*/
  156.   for(i=0;i<MAX_GRAPH;i++)
  157.     {
  158.       int ix = int(((float)(i*(maxx_-minx_)))/MAX_GRAPH);
  159.       scaleddata_[ix]+=graphdata_[i];
  160.       if (scaleddata_[ix]>maxy_)
  161. maxy_=scaleddata_[ix];
  162.     }
  163.   if (miny_!=maxy_)
  164.     {
  165.       bb.ymin=miny_;
  166.       bb.ymax=maxy_;
  167.     }
  168.   else 
  169.     {
  170.       bb.ymin=0.0;
  171.       bb.ymax=1.0;
  172.     }
  173. }
  174. /* Trace event handler. */
  175. void NetGraph::handle(const TraceEvent& e, double /*now*/, int /*direction*/)
  176. {
  177.   switch (e.tt) 
  178.     {
  179.     case 'v': /* 'variable' -- just execute it as a tcl command */
  180.       break;
  181.     case 'h':
  182.       printf("hopn");
  183.       break;
  184.     case 'a':
  185.       printf("agentn");
  186.       break;
  187.     case 'f':
  188.       printf("featuren");
  189.       break;
  190.     case 'r':
  191.       printf("receiven");
  192.       break;
  193.     case '+':
  194.       printf("enqueuen");
  195.       break;
  196.     case '-':
  197.       printf("dequeuen");
  198.       break;
  199.     case 'l':
  200.       printf("linkn");
  201.       break;
  202.     case 'n':
  203.       printf("noden");
  204.       break;
  205.     case 'R':
  206.       printf("Routen");
  207.       break;
  208.     case 'd':
  209.       printf("dropn");
  210.       break;
  211.     }
  212. }
  213. /* Trace event handler. */
  214. void EnergyNetGraph::handle(const TraceEvent& e, double /*now*/, int /*direction*/)
  215. {
  216.   switch (e.tt)
  217.     {
  218.     case 'g':
  219.   int timeix = int(((e.time-mintime_)*MAX_GRAPH)/(maxtime_-mintime_));
  220.   for (int i=timeix; i< MAX_GRAPH ; i++) graphdata_[i]+=1;
  221.   if (graphdata_[timeix]>maxy_)
  222.     maxy_=graphdata_[timeix];
  223.       break;
  224.     }
  225. }
  226. /* Trace event handler. */
  227. void LinkNetGraph::handle(const TraceEvent& e, double /*now*/, int /*direction*/)
  228. {
  229.   switch (e.tt)
  230.     {
  231.     case 'h':
  232.       if (gtype_==GR_BW) {
  233. if ((e.pe.src==src_) && (e.pe.dst==dst_)) {
  234.   int timeix = int(((e.time-mintime_)*MAX_GRAPH)/(maxtime_-mintime_));
  235.   graphdata_[timeix]+=e.pe.pkt.size;
  236.   if (graphdata_[timeix]>maxy_)
  237.     maxy_=graphdata_[timeix];
  238. }
  239.       }
  240.       break;
  241.     case 'd':
  242.       fflush(stdout);
  243.       if (gtype_==GR_LOSS) {
  244. if ((e.pe.src==src_) && (e.pe.dst==dst_)) {
  245.   fflush(stdout);
  246.   int timeix = int(((e.time-mintime_)*MAX_GRAPH)/(maxtime_-mintime_));
  247.   graphdata_[timeix]+=1;
  248.   if (graphdata_[timeix]>maxy_)
  249.     maxy_=graphdata_[timeix];
  250. }
  251.       }
  252.       break;
  253.     }
  254. }
  255. int NetGraph::command(int argc, const char *const *argv)
  256. {
  257.   Tcl& tcl = Tcl::instance();
  258.   if (argc == 3) {
  259.     if (strcmp(argv[1], "view") == 0) {
  260.       /*
  261.        * <net> view <viewName>
  262.        * Create the window for the network layout/topology.
  263.        */
  264.       GraphView *v = new GraphView(argv[2], this);
  265.       v->next_ = views_;
  266.       views_ = v;
  267.       return (TCL_OK);
  268.     }
  269.     if (strcmp(argv[1], "settime") == 0) {
  270.       if (argc == 3) {
  271. time_=atof(argv[2]);
  272. GraphView *view = views_;
  273. int newtix=int(time_*(maxx_-minx_)/(maxtime_-mintime_));
  274. if (newtix!=tix_) {
  275.   while(view!=NULL) {
  276.     view->draw();
  277.     view=view->next_;
  278.   }
  279.   tix_=newtix;
  280. }
  281. return (TCL_OK);
  282.       } else {
  283. tcl.resultf(""%s": arg mismatch", argv[0]);
  284. return (TCL_ERROR);
  285.       }
  286.     }
  287.     
  288.   }
  289.   if (argc == 4 && strcmp(argv[1], "timerange") == 0) {
  290.     mintime_=atof(argv[2]);
  291.     maxtime_=atof(argv[3]);
  292.     return (TCL_OK);
  293.   }
  294.   /* If no NetModel commands matched, try the Object commands. */
  295.   return (TclObject::command(argc, argv));
  296. }
  297. int EnergyNetGraph::command(int argc, const char *const *argv)
  298. {
  299.   return (NetGraph::command(argc, argv));
  300. }
  301. int LinkNetGraph::command(int argc, const char *const *argv)
  302. {
  303.   //Tcl& tcl = Tcl::instance();
  304.   if (argc == 4) {
  305. //      printf("command: %s %s %sn", argv[1],argv[2],argv[3]);
  306.     if (strcmp(argv[1], "bw") == 0) {
  307.       src_=atoi(argv[2]);
  308.       dst_=atoi(argv[3]);
  309.       gtype_=GR_BW;
  310.       return (TCL_OK);
  311.     }
  312.     if (strcmp(argv[1], "loss") == 0) {
  313.       src_=atoi(argv[2]);
  314.       dst_=atoi(argv[3]);
  315.       gtype_=GR_LOSS;
  316.       return (TCL_OK);
  317.     }
  318.   }
  319.   /* If no NetModel commands matched, try the Object commands. */
  320.   return (NetGraph::command(argc, argv));
  321. }
  322. /************/
  323. FeatureNetGraph::FeatureNetGraph()
  324.   : NetGraph(), src_(-1), aname_(0), vname_(0), lastix_(0)
  325. {
  326. }
  327. FeatureNetGraph::~FeatureNetGraph()
  328. {
  329. }
  330. int FeatureNetGraph::command(int argc, const char *const *argv)
  331. {
  332.   if (argc == 5) {
  333.     if (strcmp(argv[1], "feature") == 0) {
  334.       src_ = atoi(argv[2]);
  335.       aname_ = new char[strlen(argv[3]) + 1];
  336.       strcpy(aname_, argv[3]);
  337.       vname_ = new char[strlen(argv[4]) + 1];
  338.       strcpy(vname_, argv[4]);
  339.       return(TCL_OK);
  340.     }
  341.   }
  342.   return (NetGraph::command(argc, argv));
  343. }
  344. void FeatureNetGraph::handle(const TraceEvent& e, double /*now*/, int /*direction*/)
  345. {
  346.   switch (e.tt) {
  347.   case 'f':
  348.     // print the source, the agent, name, value
  349.     // print records we care about 
  350.     if (src_ == e.fe.src && (strcmp(aname_, e.fe.feature.agent) == 0) &&
  351. (strcmp(vname_, e.fe.feature.name) == 0)) {
  352.             /* printf("Feature %d %s %s %sn", 
  353.    e.fe.src, e.fe.feature.agent, 
  354.    e.fe.feature.name, e.fe.feature.value); */
  355.     /* start out doing what is done in LinkNetGraph::handle */
  356.     int timeix = int(((e.time-mintime_)*MAX_GRAPH)/(maxtime_-mintime_));
  357.     graphdata_[timeix]+=atof(e.fe.feature.value);
  358.     // printf("%d %gn", timeix, graphdata_[timeix]);
  359.     if (graphdata_[timeix]>maxy_)
  360.       maxy_=graphdata_[timeix];
  361.     /* fill in any points we may have missed */
  362.     int i;
  363.     double lastval = graphdata_[lastix_];
  364.     for (i = lastix_ + 1; i < timeix; i++) {
  365.       graphdata_[i] = lastval;
  366.     }
  367.     lastix_ = timeix;
  368.     }
  369.     break;
  370.   default:
  371.     break;
  372.   }
  373. }
  374. /* following is a hack to get around the aliasing effects referred to
  375.  * in the comments in NetGraph::BoundingBox.  It works for those data
  376.  * sets I've tested it with, but it could produce undesired results
  377.  * in some cases.
  378.  */
  379. void FeatureNetGraph::BoundingBox(BBox& bb)
  380. {
  381.   int i;
  382.   minx_=int(bb.xmin);
  383.   maxx_=int(bb.xmax);
  384.   int newtix=int(time_*(maxx_-minx_)/(maxtime_-mintime_));
  385.   if (newtix!=tix_) {
  386.     tix_=newtix;
  387.   }
  388.   for(i=0;i<maxx_-minx_;i++)
  389.     {
  390.       scaleddata_[i]=0.0;
  391.     }
  392.   maxy_=1.0;
  393.   /*Note: storing the data in an array like this is quick, but introduces
  394.     some aliasing effects in the scaling process.  I think they're 
  395.     negligable for this purpose but if we really want to remove them
  396.     we must store the unscaled data in a list instead*/
  397.   for(i=0;i<MAX_GRAPH;i++)
  398.     {
  399.       int ix = int(((float)(i*(maxx_-minx_)))/MAX_GRAPH);
  400.       scaleddata_[ix]=graphdata_[i];
  401.       if (scaleddata_[ix]>maxy_)
  402. maxy_=scaleddata_[ix];
  403.     }
  404.   if (miny_!=maxy_)
  405.     {
  406.       bb.ymin=miny_;
  407.       bb.ymax=maxy_;
  408.     }
  409.   else 
  410.     {
  411.       bb.ymin=0.0;
  412.       bb.ymax=1.0;
  413.     }
  414. }