00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "ident-tree.h"
00038 #include "rate-limit.h"
00039
00040
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
00083
00084
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
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) {
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) {
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
00162
00163 double targetRate = linkBW/(1 - TARGET_DROPRATE);
00164 double excessRate = arrRate - targetRate;
00166
00167
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
00176
00177 if (clusterList[id+1].prefix_==-1) {
00178
00179
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
00300
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
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
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
00353
00354 }
00355
00356 void
00357 IdentStruct::traverse() {
00358 dstTree_->traverse();
00359
00360
00361 }
00362
00363 void
00364 IdentStruct::registerDrop(Packet *p) {
00365
00366 hdr_ip * iph = hdr_ip::access(p);
00367
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
00380
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
00410
00411 }
00412