📄 connection.cpp
字号:
#include "Common.h"
#include "Connection.h"
#include "Topology.h"
#include "Node.h"
#include "Link.h"
#include "BandwidthManager.h"
#include "Agent.h"
Topology *Connection::mTopology = Topology::getInstance();
set<Connection *> Connection::mConnection;
set<Link *> Connection::mLinkAdjust;
ostream &operator<<(ostream &os, const Connection &connecion)
{
os << connecion.mSource->getNode()->getID() << " to " << connecion.mDestination->getNode()->getID() << ": " \
<< (connecion.mActive ? "active" : "inactive") << '\t' << connecion.mBandwidth << endl;
for(unsigned int i = 0; i < connecion.mLink.size(); i++) {
bool flag = connecion.mLink[i].first;
os << '(' << connecion.mLink[i].second->from() << ", " << connecion.mLink[i].second->to() << ')' << ": " \
<< connecion.mLink[i].second->getBandwidthManager().getBandwidth(flag) << ", " \
<< connecion.mLink[i].second->getBandwidthManager().getAvailableBandwidth(flag) << ", " \
<< connecion.mLink[i].second->getBandwidthManager().getActiveNumber(flag)<< (i % 2 == 1? '\n' : '\t');
}
return os;
}
/* ********** protect member ********** */
unsigned long Connection::minAverageBandwidthA()
{
unsigned long min = UINT_MAX;
vector< pair<bool, Link *> >::iterator it;
for(it = mLink.begin(); it != mLink.end(); it++)
{
bool flag = (*it).first;
Link *pl = (*it).second;
unsigned long temp = pl->getBandwidthManager().getAverageBandwidthA(flag);
if(min > temp)
min = temp;
}
return min;
}
unsigned long Connection::minAverageBandwidthB()
{
unsigned long min = UINT_MAX;
vector< pair<bool, Link *> >::iterator it;
for(it = mLink.begin(); it != mLink.end(); it++)
{
bool flag = (*it).first;
Link *pl = (*it).second;
unsigned long temp = pl->getBandwidthManager().getAverageBandwidthB(flag);
if(min > temp)
min = temp;
}
return min;
}
unsigned long Connection::minAvailableBandwidth()
{
unsigned long min = UINT_MAX;
vector< pair<bool, Link *> >::iterator it;
for(it = mLink.begin(); it != mLink.end(); it++)
{
bool flag = (*it).first;
Link *pl = (*it).second;
unsigned long temp = pl->getBandwidthManager().getAvailableBandwidth(flag);
if(min > temp)
min = temp;
}
return min;
}
/* ********** public member ********** */
Connection::Connection(Agent *agent1, Agent *agent2): mActive(false), mLock(false), mBandwidth(0), mBandwidthLock(0)
{
if(!agent1 || !agent2)
{ cout << "null pointer in Connection()" << endl; exit(-1); }
mSource = agent1;
mDestination = agent2;
int nodeid1 = agent1->getNode()->getID();
int nodeid2 = agent2->getNode()->getID();
int agentid1 = agent1->getID();
int agentid2 = agent2->getID();
vector<Link *> linkList = mTopology->getVLinkBetween(agent1, agent2);
vector<int> nodeidList(linkList.size() + 1);
if(linkList.empty())
{ cout << "null path" << endl; exit(-1); }
nodeidList[0] = agentid1;
nodeidList[1] = nodeid1;
for(unsigned int i = 1; i < linkList.size() - 1; i++) {
if(linkList[i]->from() == nodeidList[i])
nodeidList[i + 1] = linkList[i]->to();
else if(linkList[i]->to() == nodeidList[i])
nodeidList[i + 1] = linkList[i]->from();
else
{ cout << "error in organizing path in Connection()" << endl; exit(-1); }
}
nodeidList[linkList.size()] = agentid2;
/*
cout << "-------------" << endl;
cout << "link list agent agent: " << agentid1 << '\t' << agentid2 << endl;
cout << linkList.size() << endl;
for(unsigned int i = 0; i < linkList.size(); i++)
cout << *linkList[i] << endl;
*/
if(nodeidList[linkList.size() - 1] != nodeid2)
{ cout << "last node not equal to node id 2 in Connection()" << endl; exit(-1); }
/*
cout << "id list" << endl;
for(unsigned int i = 0; i < nodeidList.size(); i++)
cout << nodeidList[i] << '\t';
cout << endl;
*/
for(unsigned int i = 0; i < linkList.size(); i++)
{
if(nodeidList[i] < nodeidList[i + 1]) {
if(linkList[i]->getType() == VIR_LIN || linkList[i]->getType() == STU_TRA)
mLink.push_back(pair<bool, Link *>(true, linkList[i]));
}
else if(nodeidList[i] > nodeidList[i + 1]) {
if(linkList[i]->getType() == VIR_LIN || linkList[i]->getType() == STU_TRA)
mLink.push_back(pair<bool, Link *>(false, linkList[i]));
}
else {
if(i == 0)
mLink.push_back(pair<bool, Link *>(false, linkList[i]));
else if(i == linkList.size() - 1)
mLink.push_back(pair<bool, Link *>(true, linkList[i]));
else
{ cout << "impossible in Connection()" << endl; exit(-1); }
}
}
/*
for(unsigned int i = 0; i < mLink.size(); i++)
cout << (mLink[i].first ? "front" : "back") << '\t' << *mLink[i].second << endl;
*/
addConnection();
mConnection.insert(this);
}
Connection::~Connection()
{
if(mActive)
inactivate();
removeConnection();
mConnection.erase(this);
}
bool Connection::isActive()
{ return mActive; }
unsigned long Connection::getBandwidth()
{ return mBandwidth; }
unsigned long Connection::getAvailableBandwidth(bool flag)
{
if(flag)
return mLink[0].second->getBandwidthManager().getAvailableBandwidth(mLink[0].first);
else
return mLink[mLink.size() - 1].second->getBandwidthManager().getAvailableBandwidth(mLink[mLink.size() - 1].first);
}
set<Connection *> Connection::getAllConnection()
{ return mConnection; }
void Connection::addConnection()
{
vector< pair<bool, Link *> >::iterator it;
for(it = mLink.begin(); it != mLink.end(); it++) {
bool flag = (*it).first;
Link *pl = (*it).second;
pl->getBandwidthManager().addConnection(flag, this);
}
}
void Connection::removeConnection()
{
vector< pair<bool, Link *> >::iterator it;
for(it = mLink.begin(); it != mLink.end(); it++) {
bool flag = (*it).first;
Link *pl = (*it).second;
pl->getBandwidthManager().removeConnection(flag, this);
}
}
void Connection::activate(unsigned long limit)
{
if(mActive)
return;
else
mActive = true;
bool flag;
unsigned long average = minAverageBandwidthB();
unsigned long available = minAvailableBandwidth();
unsigned long value = average >= available ? average : available;
Link *pl;
vector< pair<bool, Link *> >::iterator it;
value = value <= limit ? value : limit;
if(value > available)
{
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
average = pl->getBandwidthManager().getAverageBandwidthB(flag);
available = pl->getBandwidthManager().getAvailableBandwidth(flag);
unsigned long balance = value <= available ? 0 : value - available;
while(balance > 0)
{
Connection *pc = pl->getBandwidthManager().getMaxConnection(flag);
unsigned long temp = pc->getBandwidth();
if(temp <= average)
{ cout << "impossible in activate()" << endl; exit(-1); }
unsigned long last = balance;
balance = balance <= temp - average ? 0 : balance - temp + average;
pc->adjustBandwidth((long long)balance - last, true);
}
}
}
mBandwidth = value;
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
pl->getBandwidthManager().activateConnection(flag, this);
}
mBandwidthLock = limit;
mLock = mBandwidth < mBandwidthLock ? false : true;
reallocate();
}
void Connection::inactivate()
{
if(!mActive)
return;
else
mActive = false;
vector< pair<bool, Link *> >::iterator it;
for(it = mLink.begin(); it != mLink.end(); it++) {
bool flag = (*it).first;
Link *pl = (*it).second;
pl->getBandwidthManager().inactivateConnection(flag, this);
}
mLock = false;
mBandwidth = 0;
mBandwidthLock = 0;
for(it = mLink.begin(); it != mLink.end(); it++)
mLinkAdjust.insert((*it).second);
reallocate();
}
long long Connection::adjustBandwidth(long long value, bool internal)
{
if(!mActive)
return 0;
bool flag;
Link *pl;
vector< pair<bool, Link *> >::iterator it;
if(value < 0) {
if(mBandwidth + value < 0)
{ cout << "error: negative value in adjustBandwidth()" << endl; exit(-1); }
mBandwidth += value;
if(!internal) {
mBandwidthLock = mBandwidth;
mLock = true;
}
else
mLock = false;
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
pl->getBandwidthManager().adjustDown(flag, this, 0 - value);
}
}
else if(value > 0)
{
if(!internal)
mBandwidthLock = mBandwidth + value;
if(internal && mLock)
return 0;
value = value <= mBandwidthLock - mBandwidth ? value : mBandwidthLock - mBandwidth;
unsigned long average = minAverageBandwidthA();
unsigned long available = minAvailableBandwidth();
if(value > available)
{
if(mBandwidth + available >= average)
value = available;
else if(mBandwidth + value > average)
value = average - mBandwidth;
if(value > available)
{
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
average = pl->getBandwidthManager().getAverageBandwidthA(flag);
available = pl->getBandwidthManager().getAvailableBandwidth(flag);
unsigned long balance = value <= available ? 0 : value - available;
while(balance > 0)
{
Connection *pc = pl->getBandwidthManager().getMaxConnection(flag);
unsigned long temp = pc->getBandwidth();
if(temp <= average)
{ cout << "impossible in adjustBandwidth()" << endl; exit(-1); }
unsigned long last = balance;
balance = balance <= temp - average ? 0 : balance - temp + average;
pc->adjustBandwidth((long long)balance - last, true);
}
}
}
}
mBandwidth += value;
if(mBandwidth == mBandwidthLock)
mLock = true;
else
mLock = false;
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
pl->getBandwidthManager().adjustUp(flag, this, value);
}
}
if(value < 0)
for(it = mLink.begin(); it != mLink.end(); it++)
mLinkAdjust.insert((*it).second);
if(!internal)
reallocate();
return value;
}
void Connection::reallocate()
{
set<Link *> temp;
set<Link *>::iterator it;
while(!mLinkAdjust.empty()) {
temp = mLinkAdjust;
mLinkAdjust.clear();
for(it = temp.begin(); it != temp.end(); it++)
(*it)->getBandwidthManager().reallocate();
}
}
void Connection::check()
{
vector< pair<bool, Link *> >::iterator it;
int i = 0;
if(mActive)
cout << "active" << endl;
else
cout << "inactive" << endl;
cout << "link address:" << endl;
for(it = mLink.begin(); it != mLink.end(); it++)
{
printf("%8.8x%c", (unsigned int)(*it).second, (i % 10 == 9 ? '\n' : ' '));
i++;
}
cout << endl;
i = 0;
bool flag;
Link *pl;
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
set<Connection *> aset = pl->getBandwidthManager().getActiveConnectionSet(flag);
if(aset.find(this) != aset.end())
cout << '(' << pl->from() << ", " << pl->to() << "): a" << (i % 4 == 3 ? '\n' : '\t');
i++;
}
cout << endl;
i = 0;
for(it = mLink.begin(); it != mLink.end(); it++)
{
flag = (*it).first;
pl = (*it).second;
set<Connection *> iset = pl->getBandwidthManager().getInactiveConnectionSet(flag);
if(iset.find(this) != iset.end())
cout << '(' << pl->from() << ", " << pl->to() << "): i" << (i % 4 == 3 ? '\n' : '\t');
i++;
}
cout << endl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -