30 for (
int ctx =
comtreeMap->firstId(); ctx != 0;
35 pthread_cond_destroy(&
comtree[ctx].busyCond);
38 pthread_mutex_destroy(&
mapLock);
43 if (pthread_mutex_init(&
mapLock,NULL) != 0)
return false;
46 if (pthread_cond_init(&
comtree[ctx].busyCond,NULL) != 0)
61 if (ctx == 0) { unlockMap();
return 0; }
66 pthread_cond_signal(&
comtree[ctx].busyCond);
67 unlockMap();
return 0;
82 pthread_cond_signal(&
comtree[ctx].busyCond);
93 if (ctx == 0) { unlockMap();
return 0; }
98 pthread_cond_signal(&
comtree[ctx].busyCond);
99 unlockMap();
return 0;
118 pthread_cond_signal(&
comtree[ctx].busyCond);
122 while (
comtree[nuCtx].busyBit) {
127 pthread_cond_signal(&
comtree[ctx].busyCond);
128 pthread_cond_signal(&
comtree[nuCtx].busyCond);
135 pthread_cond_signal(&
comtree[ctx].busyCond);
149 if (ctx == 0) { unlockMap();
return 0; }
171 unlockMap();
return false;
191 map<fAdr_t,ComtRtrInfo>::iterator rp;
193 if (rp !=
comtree[ctx].rtrMap->end())
return true;
194 pair<fAdr_t,ComtRtrInfo> newPair;
196 newPair.second.plnk = 0;
200 map<fAdr_t,ComtLeafInfo>::iterator lp;
202 if (lp !=
comtree[ctx].leafMap->end())
return true;
203 pair<fAdr_t,ComtLeafInfo> newPair;
224 map<fAdr_t,ComtRtrInfo>::iterator np;
226 if (np !=
comtree[ctx].rtrMap->end()) {
227 int plnk = np->second.plnk;
228 if ((plnk == 0 && np->second.lnkCnt != 0) ||
229 (plnk != 0 && np->second.lnkCnt != 1))
233 map<fAdr_t,ComtRtrInfo>::iterator pp;
241 map<fAdr_t,ComtLeafInfo>::iterator lp;
243 map<fAdr_t,ComtRtrInfo>::iterator pp;
261 map<fAdr_t,ComtRtrInfo>::iterator rp;
265 rp->second.subtreeRates.add(rs);
266 if (rp->second.plnk == 0)
return true;
270 cerr <<
"ComtInfo::adjustSubtreeRates: excessively "
271 "long path detected in comtree "
308 if (!Util::skipBlank(in) || Util::verify(in,
';'))
break;
309 if (!Util::readWord(in, s)) {
310 cerr <<
"NetInfo:: read: syntax error: expected "
311 "(;) or keyword (router,leaf,link)\n";
314 if (s ==
"comtree") {
316 cerr <<
"ComtInfo::read: error when attempting "
317 " to read " << comtNum <<
"-th comtree "
318 "(" << errMsg <<
")\n";
322 cerr <<
"ComtInfo::read: unrecognized word " << s
323 <<
" when attempting to read "
324 << comtNum <<
"-th comtree\n";
346 int core; vector<int> coreNodes;
347 bool autoConfig;
RateSpec bbRates, leafRates;
350 if (!Util::verify(in,
'(',50)) {
351 errMsg =
"syntax error, expected left paren";
357 if (in.fail() || !Util::verify(in,
',',20)) {
358 errMsg =
"could not read comtree number";
364 if (!Util::readWord(in,s) || !Util::verify(in,
',',20) ||
366 errMsg =
"could not read owner name";
371 if (!Util::readWord(in,s) || !Util::verify(in,
',',20) ||
373 errMsg =
"could not read root node name";
378 if (!Util::readWord(in,s)) {
379 errMsg =
"could not read backbone configuration mode";
382 if (s ==
"auto") autoConfig =
true;
383 else if (s ==
"manual") autoConfig =
false;
385 errMsg =
"invalid backbone configuration mode " + s;
390 if (!Util::verify(in,
',',20) || !
readRateSpec(in,bbRates)) {
391 errMsg =
"could not backbone default rates";
395 if (!Util::verify(in,
',',20) || !
readRateSpec(in,leafRates)) {
396 errMsg =
"could not read leaf default rates";
401 if (Util::verify(in,
',',20)) {
403 if (Util::verify(in,
'(',20)) {
404 if (!Util::verify(in,
')',20)) {
408 if (!Util::readWord(in,s)) {
409 errMsg =
"could not read core "
414 errMsg =
"invalid core node "
418 coreNodes.push_back(core);
419 if (Util::verify(in,
')',20))
break;
420 if (!Util::verify(in,
',',20)) {
421 errMsg =
"syntax error in list "
431 vector<LinkMod> links;
434 if (Util::verify(in,
',',20)) {
437 if (!
readLink(in,lnk,rs,child,errMsg))
return 0;
438 lm.set(lnk,child,rs);
440 while (Util::verify(in,
',',20)) {
442 if (!
readLink(in,lnk,rs,child,errMsg))
return 0;
443 lm.set(lnk,child,rs);
447 if (!Util::verify(in,
')',20)) {
448 errMsg =
"syntax error at end of link list, expected "
454 errMsg =
"could not allocate new comtree";
465 errMsg =
"could not configure comtree";
473 errMsg =
"could not add root to comtree";
476 for (
unsigned int i = 0; i < coreNodes.size(); i++) {
479 errMsg =
"could not add core node to comtree";
484 for (
unsigned int i = 0; i < links.size(); i++) {
485 int lnk = links[i].lnk;
486 int child = links[i].child;
494 map<fAdr_t,ComtLeafInfo>::iterator cp;
497 cp->second.plnkRates = rs;
499 map<fAdr_t,ComtRtrInfo>::iterator cp;
501 cp->second.plnk = lnk; cp->second.lnkCnt++;
503 else cp->second.frozen =
true;
504 cp->second.plnkRates = rs;
505 rs = cp->second.subtreeRates;
508 map<fAdr_t,ComtRtrInfo>::iterator pp;
522 int bru, brd, pru, prd;
523 if (!Util::verify(in,
'(',50))
return false;
524 in >> bru;
if (in.fail())
return false;
525 if (!Util::verify(in,
',',20))
return false;
526 in >> brd;
if (in.fail())
return false;
527 if (!Util::verify(in,
',',20))
return false;
528 in >> pru;
if (in.fail())
return false;
529 if (!Util::verify(in,
',',20))
return false;
530 in >> prd;
if (in.fail())
return false;
531 if (!Util::verify(in,
')',20))
return false;
532 rs.
set(bru,brd,pru,prd);
548 string nameL, nameR;
int numL, numR;
552 if (!Util::verify(in,
'(',50) ||
554 errMsg =
"could not first link endpoint";
558 errMsg =
"could not read second link endpoint";
563 errMsg =
"invalid name for link endpoint " + nameL;
568 errMsg =
"invalid name for link endpoint " + nameR;
572 errMsg =
"invalid link: first node must be child in comtree";
578 ss <<
"detected invalid link (" << nameL;
579 if (numL != 0) ss <<
"." << numL;
581 if (numR != 0) ss <<
"." << numR;
586 if (Util::verify(in,
',',20)) {
588 errMsg =
"could not read rate specification for link";
592 if (!Util::verify(in,
')',20)) {
593 errMsg =
"syntax error, expected right paren";
606 if (!Util::readWord(in,name))
return false;
608 if (Util::verify(in,
'.')) {
610 if (in.fail() || num < 1)
return false;
626 map<fAdr_t,ComtLeafInfo>::iterator lp;
627 for (lp =
comtree[ctx].leafMap->begin();
634 cerr <<
"ComtInfo::check: comtree " << comt
635 <<
" has leaf " << leafName <<
" whose "
636 "parent is not a router in comtree\n";
642 map<fAdr_t,ComtRtrInfo>::iterator rp;
644 for (rp =
comtree[ctx].rtrMap->begin();
646 if (
getParent(ctx,rp->first) == 0) cnt++;
649 cerr <<
"ComtInfo::check: comtree " << comt
650 <<
" has " << cnt <<
" routers with no parent\n";
659 queue<int> pending; pending.push(root);
660 map<fAdr_t,int> plink; plink[root] = 0;
663 unsigned int nodeCount = 0;
664 while (!pending.empty()) {
665 int u = pending.front(); pending.pop();
668 bool foundCycle =
false;
676 if (
getPlink(ctx,vAdr) != lnk)
continue;
677 if (lnk == plink[u])
continue;
679 if (plink.find(v) != plink.end()) {
680 cerr <<
"ComtInfo::check: "
682 <<
" contains a cycle\n";
692 cerr <<
"ComtInfo::check: comtree "
693 << comt <<
" contains a core node "
695 <<
" whose parent is not a "
702 if (zipSet.find(vzip) != zipSet.end()) {
703 cerr <<
"ComtInfo::check: zip "
705 " is non-contiguous in "
714 if (foundCycle) { status =
false;
break; }
716 if (nodeCount !=
comtree[ctx].rtrMap->size()) {
717 cerr <<
"ComtInfo::check: comtree " << comt
718 <<
" not connected\n";
725 bool ComtInfo::checkLinkCounts(
int ctx) {
727 int *lnkCounts =
new int[n+1];
730 for (
int i = 1; i <= n; i++) lnkCounts[i] = 0;
735 map<fAdr_t,ComtLeafInfo>::iterator lp;
736 for (lp =
comtree[ctx].leafMap->begin();
743 map<fAdr_t,ComtRtrInfo>::iterator rp;
744 for (rp =
comtree[ctx].rtrMap->begin();
749 if (padr == 0)
continue;
756 for (rp =
comtree[ctx].rtrMap->begin();
760 if (lnkCounts[rtr] != rp->second.lnkCnt) {
763 <<
" has " << lnkCounts[rtr]
764 <<
" links in comtree " << comt
765 <<
", but recorded lnkCnt is "
766 << rp->second.lnkCnt;
773 bool ComtInfo::checkSubtreeRates(
int ctx) {
775 RateSpec *subtreeRates =
new RateSpec[n+1];
778 for (
int i = 1; i <= n; i++) subtreeRates[i].set(0);
786 map<fAdr_t,ComtLeafInfo>::iterator lp;
787 for (lp =
comtree[ctx].leafMap->begin();
789 RateSpec& prates = lp->second.plnkRates;
790 if (prates.bitRateUp <= 0 || prates.bitRateDown <= 0 ||
791 prates.pktRateUp <= 0 || prates.pktRateDown <= 0) {
796 cerr <<
"detected non-positive comtree link rate for "
798 <<
" rateSpec=" << prates.toString(s2) << endl;
804 subtreeRates[rtr].add(prates);
805 if (rtr == root)
break;
811 map<fAdr_t,ComtRtrInfo>::iterator rp;
812 for (rp =
comtree[ctx].rtrMap->begin();
816 if (!subtreeRates[rtr].equals(rp->second.subtreeRates)) {
819 <<
" has subtree rate "
820 << subtreeRates[rtr].toString(s2)
821 <<
" in comtree " << comt <<
", but recorded"
823 << rp->second.subtreeRates.toString(s3) << endl;
830 bool ComtInfo::checkLinkRates(
int ctx) {
837 map<fAdr_t,ComtRtrInfo>::iterator rp;
839 RateSpec& rootRates = rp->second.subtreeRates;
841 for (rp =
comtree[ctx].rtrMap->begin();
843 if (rp->second.frozen)
continue;
844 int lnk = rp->second.plnk;
845 if (lnk == 0)
continue;
848 RateSpec& srates = rp->second.subtreeRates;
849 RateSpec trates = rootRates; trates.subtract(srates);
851 rs.set( srates.bitRateUp,trates.bitRateUp,
852 srates.pktRateUp,trates.pktRateUp);
854 rs.set( srates.bitRateUp,
855 min(srates.bitRateDown,trates.bitRateUp),
857 min(srates.pktRateDown,trates.pktRateUp));
859 if (!rs.equals(rp->second.plnkRates)) {
861 cerr <<
"detected inconsistent comtree link rates in "
863 <<
" computed rates: " << rs.toString(s2)
864 <<
" and stored rates: "
865 << rp->second.plnkRates.toString(s3) << endl;
896 cerr <<
"network lacks capacity for comtree "
912 map<fAdr_t,ComtRtrInfo>::iterator rp;
914 RateSpec& rootRates = rp->second.subtreeRates;
915 for (rp =
comtree[ctx].rtrMap->begin();
917 if (rp->second.frozen)
continue;
918 int lnk = rp->second.plnk;
919 if (lnk == 0)
continue;
921 RateSpec& rs = rp->second.plnkRates;
922 RateSpec& srates = rp->second.subtreeRates;
946 map<fAdr_t,ComtRtrInfo>::iterator rp;
947 for (rp =
comtree[ctx].rtrMap->begin();
949 fAdr_t rtr = rp->first;
int lnk = rp->second.plnk;
950 if (lnk == 0)
continue;
954 if (!rs.
leq(availRates)) {
return false; }
957 map<fAdr_t,ComtLeafInfo>::iterator lp;
958 for (lp =
comtree[ctx].leafMap->begin();
960 fAdr_t leafAdr = lp->first;
962 if (leaf == 0)
continue;
967 if (!rs.
leq(availRates)) {
return false; }
980 map<fAdr_t,ComtRtrInfo>::iterator rp;
981 for (rp =
comtree[ctx].rtrMap->begin();
983 fAdr_t rtr = rp->first;
int lnk = rp->second.plnk;
984 if (lnk == 0)
continue;
990 map<fAdr_t,ComtLeafInfo>::iterator lp;
991 for (lp =
comtree[ctx].leafMap->begin();
993 fAdr_t leafAdr = lp->first;
995 if (leaf == 0)
continue;
1009 map<fAdr_t,ComtRtrInfo>::iterator rp;
1010 for (rp =
comtree[ctx].rtrMap->begin();
1012 fAdr_t rtr = rp->first;
int lnk = rp->second.plnk;
1013 if (lnk == 0)
continue;
1014 RateSpec rs = rp->second.plnkRates;
1018 map<fAdr_t,ComtLeafInfo>::iterator lp;
1019 for (lp =
comtree[ctx].leafMap->begin();
1021 fAdr_t leafAdr = lp->first;
1023 if (leaf == 0)
continue;
1025 RateSpec rs = lp->second.plnkRates;
1055 Heap h(n);
int d[n+1];
1058 plnk[r] = 0; d[r] = BIGINT;
1062 h.insert(src,d[src]);
1063 while (!h.empty()) {
1064 fAdr_t r = h.deletemin();
1067 if (lnk == plnk[r])
continue;
1074 if (!rs.
leq(availRates))
continue;
1078 for (
int pl = plnk[u]; pl != 0; pl = plnk[u]) {
1081 path.push_front(lm);
1089 if (h.member(peer)) h.changekey(peer,d[peer]);
1090 else h.insert(peer,d[peer]);
1134 Heap h(n);
int d[n+1];
1137 plnk[r] = 0; d[r] = BIGINT;
1141 h.insert(src,d[src]);
1142 while (!h.empty()) {
1143 fAdr_t r = h.deletemin();
1146 if (lnk == plnk[r])
continue;
1153 if (!rs.
leq(availRates))
continue;
1159 for (
int pl = plnk[u]; pl != 0; pl = plnk[u]) {
1163 int i = len-1; u = peer;
1164 for (
int pl = plnk[u]; pl != 0; pl = plnk[u]) {
1182 if (h.member(peer)) h.changekey(peer,d[peer]);
1183 else h.insert(peer,d[peer]);
1201 if (path.begin() == path.end())
return;
1202 list<LinkMod>::iterator pp;
1203 for (pp = path.begin(); pp != path.end(); pp++) {
1205 int child = pp->child;
int lnk = pp->lnk;
1227 if (path.begin() == path.end())
return;
1228 list<LinkMod>::iterator pp;
1229 for (pp = path.begin(); pp != path.end(); pp++) {
1252 map<fAdr_t,ComtRtrInfo>::iterator rp;
1255 bool status =
computeMods(ctx,root,rp->second.subtreeRates,modList);
1276 list<LinkMod>& modList) {
1279 map<fAdr_t,ComtRtrInfo>::iterator rp;
1281 int plnk = rp->second.plnk;
1282 if (plnk != 0 && !
isFrozen(ctx,radr)) {
1285 nuMod.
child = rnum; nuMod.
lnk = plnk;
1286 RateSpec& srates = rp->second.subtreeRates;
1298 if (nuMod.
rs.
isZero())
return true;
1301 if (!nuMod.
rs.
leq(availRates))
return false;
1302 modList.push_back(nuMod);
1308 for (rp =
comtree[ctx].rtrMap->begin();
1310 if (radr !=
getParent(ctx,rp->first))
continue;
1311 if (!
computeMods(ctx,rp->first,rootRates,modList))
1327 list<LinkMod>::iterator mlp;
1329 for (mlp = modList.begin(); mlp != modList.end(); mlp++) {
1331 int plnk = mlp->lnk; delta = mlp->rs;
1332 map<fAdr_t,ComtRtrInfo>::iterator rp;
1334 rp->second.plnkRates.add(delta);
1348 list<LinkMod>::iterator mlp;
1350 for (mlp = modList.begin(); mlp != modList.end(); mlp++) {
1352 int plnk = mlp->lnk; delta = mlp->rs;
1353 map<fAdr_t,ComtRtrInfo>::iterator rp;
1355 rp->second.plnkRates.add(delta);
1398 map<fAdr_t,ComtRtrInfo>::iterator rp;
1400 rs = rp->second.plnkRates;
1402 map<fAdr_t,ComtLeafInfo>::iterator lp;
1404 rs = lp->second.plnkRates;
1424 map<fAdr_t,ComtLeafInfo>::iterator lp;
1429 ss <<
"," <<
net->
getNodeName(parent,s) <<
"." << lp->second.llnk;
1430 ss <<
"," << lp->second.plnkRates.toString(s) <<
")";
1454 if (numNodes <= 1) {
1455 ss <<
")\n"; s = ss.str();
return s;
1456 }
else if (
comtree[ctx].coreSet->size() > 1) {
1461 if (c ==
getRoot(ctx))
continue;
1462 if (first) first =
false;
1470 if (numNodes <= 1) {
1474 int num2go = numNodes - 1;
1477 map<fAdr_t,ComtRtrInfo>::iterator rp;
1478 for (rp =
comtree[ctx].rtrMap->begin();
1480 if (rp->second.plnk == 0)
continue;
1482 if (++numDone < num2go) ss <<
",";
1486 map<fAdr_t,ComtLeafInfo>::iterator lp;
1487 for (lp =
comtree[ctx].leafMap->begin();
1491 if (++numDone < num2go) ss <<
",";
1520 if (numNodes <= 1) {
1521 ss <<
")\n"; s = ss.str();
return s;
1522 }
else if (
comtree[ctx].coreSet->size() > 1) {
1527 if (c ==
getRoot(ctx))
continue;
1528 if (first) first =
false;
1536 if (numNodes <= 1) {
1542 map<fAdr_t,ComtLeafInfo>::iterator lp;
1543 for (lp =
comtree[ctx].leafMap->begin();
1550 map<fAdr_t,ComtRtrInfo>::iterator rp;
1551 for (rp =
comtree[ctx].rtrMap->begin();
1556 if (rp->second.plnk == 0) {
1558 << rp->second.lnkCnt;
1560 int parent =
net->
getPeer(rtr,rp->second.plnk);
1565 <<
"," << rp->second.plnkRates.toString(s)
1566 <<
"," << rp->second.lnkCnt;
1569 if (++numDone < num2go) ss <<
",";
1573 for (lp =
comtree[ctx].leafMap->begin();
1577 if (leaf == 0)
continue;
1582 << lp->second.llnk ;
1583 ss <<
"," << lp->second.plnkRates.toString(s) <<
")";
1584 if (++numDone < num2go) ss <<
",";
1593 string& ComtInfo::comtStatus22string(
int ctx,
string& s)
const {
1605 if (numNodes <= 1) {
1606 ss <<
")\n"; s = ss.str();
return s;
1607 }
else if (
comtree[ctx].coreSet->size() > 1) {
1612 if (c ==
getRoot(ctx))
continue;
1613 if (first) first =
false;
1621 if (numNodes <= 1) {
1627 map<fAdr_t,ComtLeafInfo>::iterator lp;
1628 for (lp =
comtree[ctx].leafMap->begin();
1635 map<fAdr_t,ComtRtrInfo>::iterator rp;
1636 for (rp =
comtree[ctx].rtrMap->begin();
1641 if (rp->second.plnk == 0) {
1643 << rp->second.lnkCnt;
1645 int parent =
net->
getPeer(rtr,rp->second.plnk);
1650 <<
"," << rp->second.plnkRates.toString(s);
1651 ss <<
"," << rp->second.subtreeRates.toString(s)
1652 <<
"," << rp->second.lnkCnt;
1655 if (++numDone < num2go) ss <<
",";
1659 for (lp =
comtree[ctx].leafMap->begin();
1663 if (leaf == 0)
continue;
1668 << lp->second.llnk ;
1669 ss <<
"," << lp->second.plnkRates.toString(s) <<
")";
1670 if (++numDone < num2go) ss <<
",";