Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

ident-tree.cc

Go to the documentation of this file.
00001 //* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 2000  International Computer Science Institute
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by ACIRI, the AT&T 
00017  *      Center for Internet Research at ICSI (the International Computer
00018  *      Science Institute).
00019  * 4. Neither the name of ACIRI nor of ICSI may be used
00020  *    to endorse or promote products derived from this software without
00021  *    specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY ICSI AND CONTRIBUTORS ``AS IS'' AND
00024  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED.  IN NO EVENT SHALL ICSI OR CONTRIBUTORS BE LIABLE
00027  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00028  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00029  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00032  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00033  * SUCH DAMAGE.
00034  *
00035  */
00036 
00037 #include "ident-tree.h"
00038 #include "rate-limit.h"
00039 
00040 // ############################ PrefixTree Methods ####################
00041 
00042 PrefixTree::PrefixTree() {
00043 
00044   for (int i=0; i<=getLastIndex(); i++) {
00045     countArray[i]=0;
00046   }
00047 } 
00048 
00049 void
00050 PrefixTree::reset() {
00051 
00052   for (int i=0; i<=getLastIndex(); i++) {
00053     countArray[i]=0;
00054   }
00055 }
00056 
00057 void
00058 PrefixTree::traverse() {
00059   printf("Traversal \n");
00060   for (int i=0; i<=getLastIndex(); i++) {
00061     printf("%d/%d %d\n",getPrefixFromIndex(i), getNoBitsFromIndex(i), countArray[i]);
00062   }
00063 }
00064 
00065 void
00066 PrefixTree::registerDrop(int address, int size) {
00067 
00068   if (address > getMaxAddress()) {
00069     printf("ERROR: Address out of Range\n");
00070     exit(EXIT_FAILURE);
00071   }
00072 
00073   for (int i=0; i<=NO_BITS; i++) {
00074     int index = getIndexFromAddress(address, i);
00075     countArray[index]+=size;
00076   }
00077 }
00078 
00079 AggReturn *
00080 PrefixTree::calculateLowerBound() {
00081   
00082   //bulk of this code is taken from identifyAggregate.
00083         // bad idea - but quick.
00084         // better way - to make the common code into a separate function.
00085   int sum = 0; int count=0; int i;
00086   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
00087     if (countArray[i]!=0) {
00088       sum+=countArray[i];
00089       count++;
00090     }
00091   }
00092 
00093   //  printf("CLB: sum: %d count: %d\n",sum, count);
00094 
00095   if (count < 2) return NULL;
00096 
00097   cluster *clusterList = (cluster *)malloc(sizeof(cluster)*MAX_CLUSTER);
00098   
00099   for (i=0; i < MAX_CLUSTER; i++) {
00100     clusterList[i].prefix_=-1;
00101     clusterList[i].count_=0;
00102   }
00103   
00104   double mean = sum/count;
00105   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
00106     if (countArray[i] >= mean/2) { //using mean/2 helps in trivial simulations.
00107       insertCluster(clusterList, i, countArray[i], CLUSTER_LEVEL);
00108     }
00109   }
00110   
00111   for (i=0; i<MAX_CLUSTER; i++) {
00112     if (clusterList[i].prefix_==-1) {
00113       break;
00114     }
00115     goDownCluster(clusterList, i);
00116   }
00117   int lastIndex = i-1;
00118   
00119   sortCluster(clusterList, lastIndex);
00120   
00121   return new AggReturn(clusterList, 0, lastIndex, countArray[0]);
00122 }
00123 
00124 AggReturn *  
00125 PrefixTree::identifyAggregate(double arrRate, double linkBW) {
00126   
00127   int sum = 0; int count=0; int i;
00128   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
00129     if (countArray[i]!=0) {
00130       sum+=countArray[i];
00131       count++;
00132     }
00133   }
00134 
00135   if (count == 0) return NULL;
00136 
00137   cluster *clusterList = (cluster *)malloc(sizeof(cluster)*MAX_CLUSTER);
00138   
00139   for (i=0; i < MAX_CLUSTER; i++) {
00140     clusterList[i].prefix_=-1;
00141     clusterList[i].count_=0;
00142   }
00143   
00144   double mean = sum/count;
00145   for (i=getFirstIndexOfBit(NO_BITS); i<=getLastIndexOfBit(NO_BITS); i++) {
00146     if (countArray[i] >= mean/2) { //using mean/2 helps in trivial simulations.
00147       insertCluster(clusterList, i, countArray[i], CLUSTER_LEVEL);
00148     }
00149   }
00150   
00151   for (i=0; i<MAX_CLUSTER; i++) {
00152     if (clusterList[i].prefix_==-1) {
00153       break;
00154     }
00155     goDownCluster(clusterList, i);
00156   }
00157   int lastIndex = i-1;
00158   
00159   sortCluster(clusterList, lastIndex);
00160   
00161   //check for natural rifts here, if you want to.
00162   
00163   double targetRate = linkBW/(1 - TARGET_DROPRATE);
00164   double excessRate = arrRate - targetRate;
00166   //printf("arrRate: %5.2f targetRate: %5.2f excessRate %5.2f\n",
00167   //   arrRate, targetRate, excessRate);
00169   double rateTillNow = 0;
00170   double requiredBottom;
00171   int id=0;
00172   for (; id<=lastIndex; id++) {
00173     rateTillNow+=clusterList[id].count_*(arrRate/countArray[0]);
00174     requiredBottom = (rateTillNow - excessRate)/(id+1);
00175     //printf("id: %d excessRate: %5.2f rateTillNow: %5.2f requiredBottom: %5.2f\n",
00176     //id, excessRate, rateTillNow, requiredBottom);
00177     if (clusterList[id+1].prefix_==-1) {
00178       // I think that this means that no viable set of aggregates was found.
00179       // Shouldn't it return failure in this case?  - Sally 
00180       break;
00181     }
00182     if (clusterList[id+1].count_* (arrRate/countArray[0]) < requiredBottom) break;
00183   }
00184 
00185   return new AggReturn(clusterList, requiredBottom, id, countArray[0]);
00186 }
00187     
00188 void
00189 PrefixTree::insertCluster(cluster * clusterList, int index, int count, int noBits) {
00190   
00191   int address = getPrefixFromIndex(index);
00192   int prefix = (address >> (NO_BITS - noBits)) << (NO_BITS - noBits);
00193   int breakCode=0;
00194   for (int i=0;i<MAX_CLUSTER; i++) {
00195     if (clusterList[i].prefix_ == prefix && clusterList[i].bits_ == noBits) {
00196       clusterList[i].count_+=count;
00197       breakCode=1;
00198       break;
00199     }
00200     if (clusterList[i].prefix_ == -1) {
00201       clusterList[i].prefix_ = prefix;
00202       clusterList[i].bits_ = noBits;
00203       clusterList[i].count_=count;
00204       breakCode=2;
00205       break;
00206     }
00207   }
00208   
00209   if (breakCode==0) {
00210     printf("Error: Too Small MAX_CLUSTER. Increase and Recompile\n");
00211     exit(-1);
00212   }
00213 }
00214 
00215 void
00216 PrefixTree::goDownCluster(cluster * clusterList, int index) {
00217   
00218   int noBits = clusterList[index].bits_;
00219   int prefix = clusterList[index].prefix_;
00220   
00221   int treeIndex = getIndexFromPrefix(prefix, noBits);
00222   int maxIndex = treeIndex;
00223   while (1) {
00224     int leftIndex = 2*maxIndex+1;
00225     if (leftIndex > getLastIndex()) break;
00226     int leftCount = countArray[leftIndex];
00227     int rightCount = countArray[leftIndex+1];
00228     if (leftCount > 9*rightCount) {
00229       maxIndex = leftIndex;
00230     } 
00231     else if (rightCount > 9*leftCount) {
00232       maxIndex = leftIndex+1;
00233     }
00234     else {
00235       break;
00236     }
00237   }
00238 
00239   clusterList[index].prefix_=getPrefixFromIndex(maxIndex);
00240   clusterList[index].bits_=getNoBitsFromIndex(maxIndex);
00241   clusterList[index].count_=countArray[maxIndex];
00242 }
00243 
00244 void PrefixTree::sortCluster(cluster * clusterList, int lastIndex) 
00245 {
00246   int i, j;
00247 
00248   for (i=0; i<=lastIndex; i++) {
00249     for (j=i+1; j<=lastIndex; j++) {
00250       if (clusterList[i].count_ < clusterList[j].count_) {
00251         swapCluster(clusterList, i, j);
00252       }
00253     }
00254   }
00255 }
00256  
00257 void 
00258 PrefixTree::swapCluster(cluster * clusterList, int id1, int id2) {
00259   
00260   int tempP = clusterList[id1].prefix_;
00261   int tempB = clusterList[id1].bits_;
00262   int tempC = clusterList[id1].count_;
00263 
00264   clusterList[id1].prefix_ = clusterList[id2].prefix_;
00265   clusterList[id1].bits_   = clusterList[id2].bits_;
00266   clusterList[id1].count_  = clusterList[id2].count_;
00267 
00268   clusterList[id2].prefix_ = tempP;
00269   clusterList[id2].bits_   = tempB;
00270   clusterList[id2].count_  = tempC;
00271 }
00272 
00273 int
00274 PrefixTree::getMaxAddress() {
00275   return (1 << NO_BITS) - 1;
00276 }
00277 
00278 int
00279 PrefixTree::getBitI(int address, int i) {
00280 
00281   int andAgent = 1 << (NO_BITS - i);
00282   int bitI = address & andAgent;
00283   if (bitI) 
00284     return 1;
00285   else 
00286     return 0;
00287 }
00288 
00289 int
00290 PrefixTree::getIndexFromPrefix(int prefix, int noBits) {
00291   int base = (1 << noBits) - 1;
00292   return base + (prefix >> (NO_BITS - noBits));
00293 }
00294 
00295 int
00296 PrefixTree::getIndexFromAddress(int address, int noBits) {
00297   
00298   int base = (1 << noBits) - 1;
00299 //   int andAgent = address >> (NO_BITS - noBits);
00300 //   int additive = base & andAgent;
00301   int additive = address >> (NO_BITS - noBits);
00302     
00303   return base + additive;
00304 }
00305 
00306 int 
00307 PrefixTree::getPrefixFromIndex(int index) {
00308   
00309   int noBits = getNoBitsFromIndex(index);
00310   int base = (1 << noBits) - 1;
00311   int prefix = (index - base) << (NO_BITS - noBits);
00312     
00313   return prefix;
00314 }
00315 
00316 
00317 int 
00318 PrefixTree::getPrefixBits(int prefix, int noBits) {
00319   return (prefix >> (NO_BITS - noBits)) << (NO_BITS - noBits);
00320 }
00321   
00322 int 
00323 PrefixTree::getNoBitsFromIndex(int index) {
00324  
00325   //using 1.2 is an ugly hack to get precise floating point calculation.
00326   int noBits = (int) floor(log(index+1.2)/log(2));
00327   return noBits;
00328 }
00329 
00330 int 
00331 PrefixTree::getFirstIndexOfBit(int noBits) {
00332   return ( 1 << noBits) - 1;
00333 }
00334 
00335 int 
00336 PrefixTree::getLastIndexOfBit(int noBits) {
00337   return ( 1 << (noBits+1)) - 2;
00338 }
00339 
00340 // ######################## IdentStruct Methods ########################
00341 
00342 IdentStruct::IdentStruct() {
00343   dstTree_ = new PrefixTree();
00344   srcTree_ = new PrefixTree();
00345   dropHash_ = new DropHashTable();
00346   lowerBound_ = 0;
00347 }
00348 
00349 void
00350 IdentStruct::reset() {
00351   dstTree_->reset();
00352   //  srcTree_->reset();
00353   //  dropHash_->reset();
00354 }
00355   
00356 void 
00357 IdentStruct::traverse() {
00358   dstTree_->traverse();
00359   //  srcTree_->traverse();
00360   //  dropHash_->traverse();
00361 }
00362 
00363 void 
00364 IdentStruct::registerDrop(Packet *p) {
00365    
00366   hdr_ip * iph = hdr_ip::access(p);
00367   //  ns_addr_t src = iph->src();
00368   ns_addr_t dst = iph->dst();
00369   int fid = iph->flowid();
00370   
00371   hdr_cmn* hdr  = HDR_CMN(p);
00372   int size = hdr->size();
00373 
00374  if (AGGREGATE_CLASSIFICATION_MODE_FID)
00375    dstTree_->registerDrop(fid, size);
00376  else 
00377   dstTree_->registerDrop(dst.addr_, size);
00378   
00379   //  srcTree_->registerDrop(src.addr_, size);
00380   //  dropHash_->insert(p, size);
00381 }
00382 
00383 AggReturn * 
00384 IdentStruct::identifyAggregate(double arrRate, double linkBW) {
00385   return dstTree_->identifyAggregate(arrRate, linkBW);
00386 }
00387 
00388 AggReturn * 
00389 IdentStruct::calculateLowerBound() {
00390    return dstTree_->calculateLowerBound();
00391 }
00392 
00393 void
00394 IdentStruct::setLowerBound(double bound, int averageIt) {
00395        
00396         double alpha = 0.5;
00397         if (lowerBound_ == 0) 
00398                 lowerBound_ = bound;
00399         else if (averageIt == 0) {
00400                 if (bound < lowerBound_) 
00401                         lowerBound_ = bound;
00402                 else
00403                         lowerBound_ = alpha * lowerBound_ + (1 - alpha) * bound;
00404         }
00405         else {
00406            lowerBound_ = alpha * lowerBound_ + (1 - alpha) * bound;
00407         }
00408 
00409         //printf("lower bound: new = %g avg = %g\n", bound, lowerBound_);
00410         //fflush(stdout);
00411 }
00412 

Generated on Tue Apr 20 12:14:20 2004 for NS2.26SourcesOriginal by doxygen 1.3.3