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

通讯编程

开发平台:

Visual C++

  1. //* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 2000  International Computer Science Institute
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by ACIRI, the AT&T 
  17.  *      Center for Internet Research at ICSI (the International Computer
  18.  *      Science Institute).
  19.  * 4. Neither the name of ACIRI nor of ICSI may be used
  20.  *    to endorse or promote products derived from this software without
  21.  *    specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY ICSI AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL ICSI OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  *
  35.  */
  36. #include "ident-tree.h"
  37. #include "rate-limit.h"
  38. // ############################ PrefixTree Methods ####################
  39. PrefixTree::PrefixTree() {
  40.   for (int i=0; i<=getLastIndex(); i++) {
  41.     countArray[i]=0;
  42.   }
  43. void
  44. PrefixTree::reset() {
  45.   for (int i=0; i<=getLastIndex(); i++) {
  46.     countArray[i]=0;
  47.   }
  48. }
  49. void
  50. PrefixTree::traverse() {
  51.   printf("Traversal n");
  52.   for (int i=0; i<=getLastIndex(); i++) {
  53.     printf("%d/%d %dn",getPrefixFromIndex(i), getNoBitsFromIndex(i), countArray[i]);
  54.   }
  55. }
  56. void
  57. PrefixTree::registerDrop(int address, int size) {
  58.   if (address > getMaxAddress()) {
  59.     printf("ERROR: Address out of Rangen");
  60.     exit(EXIT_FAILURE);
  61.   }
  62.   for (int i=0; i<=NO_BITS; i++) {
  63.     int index = getIndexFromAddress(address, i);
  64.     countArray[index]+=size;
  65.   }
  66. }
  67. AggReturn *
  68. PrefixTree::calculateLowerBound() {
  69.   
  70.   //bulk of this code is taken from identifyAggregate.
  71. // bad idea - but quick.
  72. // better way - to make the common code into a separate function.
  73.   int sum = 0; int count=0; int i;
  74.   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
  75.     if (countArray[i]!=0) {
  76.       sum+=countArray[i];
  77.       count++;
  78.     }
  79.   }
  80.   //  printf("CLB: sum: %d count: %dn",sum, count);
  81.   if (count < 2) return NULL;
  82.   cluster *clusterList = (cluster *)malloc(sizeof(cluster)*MAX_CLUSTER);
  83.   
  84.   for (i=0; i < MAX_CLUSTER; i++) {
  85.     clusterList[i].prefix_=-1;
  86.     clusterList[i].count_=0;
  87.   }
  88.   
  89.   double mean = sum/count;
  90.   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
  91.     if (countArray[i] >= mean/2) { //using mean/2 helps in trivial simulations.
  92.       insertCluster(clusterList, i, countArray[i], CLUSTER_LEVEL);
  93.     }
  94.   }
  95.   
  96.   for (i=0; i<MAX_CLUSTER; i++) {
  97.     if (clusterList[i].prefix_==-1) {
  98.       break;
  99.     }
  100.     goDownCluster(clusterList, i);
  101.   }
  102.   int lastIndex = i-1;
  103.   
  104.   sortCluster(clusterList, lastIndex);
  105.   
  106.   return new AggReturn(clusterList, 0, lastIndex, countArray[0]);
  107. }
  108. AggReturn *  
  109. PrefixTree::identifyAggregate(double arrRate, double linkBW) {
  110.   
  111.   int sum = 0; int count=0; int i;
  112.   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
  113.     if (countArray[i]!=0) {
  114.       sum+=countArray[i];
  115.       count++;
  116.     }
  117.   }
  118.   if (count == 0) return NULL;
  119.   cluster *clusterList = (cluster *)malloc(sizeof(cluster)*MAX_CLUSTER);
  120.   
  121.   for (i=0; i < MAX_CLUSTER; i++) {
  122.     clusterList[i].prefix_=-1;
  123.     clusterList[i].count_=0;
  124.   }
  125.   
  126.   double mean = sum/count;
  127.   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
  128.     if (countArray[i] >= mean/2) { //using mean/2 helps in trivial simulations.
  129.       insertCluster(clusterList, i, countArray[i], CLUSTER_LEVEL);
  130.     }
  131.   }
  132.   
  133.   for (i=0; i<MAX_CLUSTER; i++) {
  134.     if (clusterList[i].prefix_==-1) {
  135.       break;
  136.     }
  137.     goDownCluster(clusterList, i);
  138.   }
  139.   int lastIndex = i-1;
  140.   
  141.   sortCluster(clusterList, lastIndex);
  142.   
  143.   //check for natural rifts here, if you want to.
  144.   
  145.   double targetRate = linkBW/(1 - TARGET_DROPRATE);
  146.   double excessRate = arrRate - targetRate;
  147.   ////////////////
  148.   //printf("arrRate: %5.2f targetRate: %5.2f excessRate %5.2fn",
  149.   //   arrRate, targetRate, excessRate);
  150.   /////////////////
  151.   double rateTillNow = 0;
  152.   double requiredBottom;
  153.   int id=0;
  154.   for (; id<=lastIndex; id++) {
  155.     rateTillNow+=clusterList[id].count_*(arrRate/countArray[0]);
  156.     requiredBottom = (rateTillNow - excessRate)/(id+1);
  157.     //printf("id: %d excessRate: %5.2f rateTillNow: %5.2f requiredBottom: %5.2fn",
  158.     //id, excessRate, rateTillNow, requiredBottom);
  159.     if (clusterList[id+1].prefix_==-1) {
  160.       // I think that this means that no viable set of aggregates was found.
  161.       // Shouldn't it return failure in this case?  - Sally 
  162.       break;
  163.     }
  164.     if (clusterList[id+1].count_* (arrRate/countArray[0]) < requiredBottom) break;
  165.   }
  166.   return new AggReturn(clusterList, requiredBottom, id, countArray[0]);
  167. }
  168.     
  169. void
  170. PrefixTree::insertCluster(cluster * clusterList, int index, int count, int noBits) {
  171.   
  172.   int address = getPrefixFromIndex(index);
  173.   int prefix = (address >> (NO_BITS - noBits)) << (NO_BITS - noBits);
  174.   int breakCode=0;
  175.   for (int i=0;i<MAX_CLUSTER; i++) {
  176.     if (clusterList[i].prefix_ == prefix && clusterList[i].bits_ == noBits) {
  177.       clusterList[i].count_+=count;
  178.       breakCode=1;
  179.       break;
  180.     }
  181.     if (clusterList[i].prefix_ == -1) {
  182.       clusterList[i].prefix_ = prefix;
  183.       clusterList[i].bits_ = noBits;
  184.       clusterList[i].count_=count;
  185.       breakCode=2;
  186.       break;
  187.     }
  188.   }
  189.   
  190.   if (breakCode==0) {
  191.     printf("Error: Too Small MAX_CLUSTER. Increase and Recompilen");
  192.     exit(-1);
  193.   }
  194. }
  195. void
  196. PrefixTree::goDownCluster(cluster * clusterList, int index) {
  197.   
  198.   int noBits = clusterList[index].bits_;
  199.   int prefix = clusterList[index].prefix_;
  200.   
  201.   int treeIndex = getIndexFromPrefix(prefix, noBits);
  202.   int maxIndex = treeIndex;
  203.   while (1) {
  204.     int leftIndex = 2*maxIndex+1;
  205.     if (leftIndex > getLastIndex()) break;
  206.     int leftCount = countArray[leftIndex];
  207.     int rightCount = countArray[leftIndex+1];
  208.     if (leftCount > 9*rightCount) {
  209.       maxIndex = leftIndex;
  210.     } 
  211.     else if (rightCount > 9*leftCount) {
  212.       maxIndex = leftIndex+1;
  213.     }
  214.     else {
  215.       break;
  216.     }
  217.   }
  218.   clusterList[index].prefix_=getPrefixFromIndex(maxIndex);
  219.   clusterList[index].bits_=getNoBitsFromIndex(maxIndex);
  220.   clusterList[index].count_=countArray[maxIndex];
  221. }
  222. void PrefixTree::sortCluster(cluster * clusterList, int lastIndex) 
  223. {
  224.   int i, j;
  225.   for (i=0; i<=lastIndex; i++) {
  226.     for (j=i+1; j<=lastIndex; j++) {
  227.       if (clusterList[i].count_ < clusterList[j].count_) {
  228. swapCluster(clusterList, i, j);
  229.       }
  230.     }
  231.   }
  232. }
  233.  
  234. void 
  235. PrefixTree::swapCluster(cluster * clusterList, int id1, int id2) {
  236.   
  237.   int tempP = clusterList[id1].prefix_;
  238.   int tempB = clusterList[id1].bits_;
  239.   int tempC = clusterList[id1].count_;
  240.   clusterList[id1].prefix_ = clusterList[id2].prefix_;
  241.   clusterList[id1].bits_   = clusterList[id2].bits_;
  242.   clusterList[id1].count_  = clusterList[id2].count_;
  243.   clusterList[id2].prefix_ = tempP;
  244.   clusterList[id2].bits_   = tempB;
  245.   clusterList[id2].count_  = tempC;
  246. }
  247. int
  248. PrefixTree::getMaxAddress() {
  249.   return (1 << NO_BITS) - 1;
  250. }
  251. int
  252. PrefixTree::getBitI(int address, int i) {
  253.   int andAgent = 1 << (NO_BITS - i);
  254.   int bitI = address & andAgent;
  255.   if (bitI) 
  256.     return 1;
  257.   else 
  258.     return 0;
  259. }
  260. int
  261. PrefixTree::getIndexFromPrefix(int prefix, int noBits) {
  262.   int base = (1 << noBits) - 1;
  263.   return base + (prefix >> (NO_BITS - noBits));
  264. }
  265. int
  266. PrefixTree::getIndexFromAddress(int address, int noBits) {
  267.   
  268.   int base = (1 << noBits) - 1;
  269. //   int andAgent = address >> (NO_BITS - noBits);
  270. //   int additive = base & andAgent;
  271.   int additive = address >> (NO_BITS - noBits);
  272.     
  273.   return base + additive;
  274. }
  275. int 
  276. PrefixTree::getPrefixFromIndex(int index) {
  277.   
  278.   int noBits = getNoBitsFromIndex(index);
  279.   int base = (1 << noBits) - 1;
  280.   int prefix = (index - base) << (NO_BITS - noBits);
  281.     
  282.   return prefix;
  283. }
  284. int 
  285. PrefixTree::getPrefixBits(int prefix, int noBits) {
  286.   return (prefix >> (NO_BITS - noBits)) << (NO_BITS - noBits);
  287. }
  288.   
  289. int 
  290. PrefixTree::getNoBitsFromIndex(int index) {
  291.  
  292.   //using 1.2 is an ugly hack to get precise floating point calculation.
  293.   int noBits = (int) floor(log(index+1.2)/log(2));
  294.   return noBits;
  295. }
  296. int 
  297. PrefixTree::getFirstIndexOfBit(int noBits) {
  298.   return ( 1 << noBits) - 1;
  299. }
  300. int 
  301. PrefixTree::getLastIndexOfBit(int noBits) {
  302.   return ( 1 << (noBits+1)) - 2;
  303. }
  304. // ######################## IdentStruct Methods ########################
  305. IdentStruct::IdentStruct() {
  306.   dstTree_ = new PrefixTree();
  307.   srcTree_ = new PrefixTree();
  308.   dropHash_ = new DropHashTable();
  309.   lowerBound_ = 0;
  310. }
  311. void
  312. IdentStruct::reset() {
  313.   dstTree_->reset();
  314.   //  srcTree_->reset();
  315.   //  dropHash_->reset();
  316. }
  317.   
  318. void 
  319. IdentStruct::traverse() {
  320.   dstTree_->traverse();
  321.   //  srcTree_->traverse();
  322.   //  dropHash_->traverse();
  323. }
  324. void 
  325. IdentStruct::registerDrop(Packet *p) {
  326.    
  327.   hdr_ip * iph = hdr_ip::access(p);
  328.   //  ns_addr_t src = iph->src();
  329.   ns_addr_t dst = iph->dst();
  330.   int fid = iph->flowid();
  331.   
  332.   hdr_cmn* hdr  = HDR_CMN(p);
  333.   int size = hdr->size();
  334.  if (AGGREGATE_CLASSIFICATION_MODE_FID)
  335.    dstTree_->registerDrop(fid, size);
  336.  else 
  337.   dstTree_->registerDrop(dst.addr_, size);
  338.   
  339.   //  srcTree_->registerDrop(src.addr_, size);
  340.   //  dropHash_->insert(p, size);
  341. }
  342. AggReturn * 
  343. IdentStruct::identifyAggregate(double arrRate, double linkBW) {
  344.   return dstTree_->identifyAggregate(arrRate, linkBW);
  345. }
  346. AggReturn * 
  347. IdentStruct::calculateLowerBound() {
  348.    return dstTree_->calculateLowerBound();
  349. }
  350. void
  351. IdentStruct::setLowerBound(double bound, int averageIt) {
  352.        
  353. double alpha = 0.5;
  354. if (lowerBound_ == 0) 
  355. lowerBound_ = bound;
  356. else if (averageIt == 0) {
  357. if (bound < lowerBound_) 
  358. lowerBound_ = bound;
  359. else
  360. lowerBound_ = alpha * lowerBound_ + (1 - alpha) * bound;
  361. }
  362. else {
  363.    lowerBound_ = alpha * lowerBound_ + (1 - alpha) * bound;
  364. }
  365. //printf("lower bound: new = %g avg = %gn", bound, lowerBound_);
  366. //fflush(stdout);
  367. }