📄 vconnection.cpp
字号:
#include "VConnection.h"
#include "Agent.h"
#include "VLink.h"
#include "Topology.h"
Topology *VConnection::mTopology = Topology::getInstance();
set<VConnection *> VConnection::mConnection;
set<VLink *> VConnection::mLinkAdjust;
ostream &operator<<(ostream &os, const VConnection &connection)
{
os << (connection.mActive ? "active" : "inactive") << '\t' << connection.mBandwidth << endl;
os << connection.mLink[0]->getBandwidth(true) <<": " << connection.mLink[0]->getAvailableBandwidth(true) <<'\t' << connection.mLink[0]->getActiveNumber(true) << '\t' << connection.mLink[1]->getBandwidth(false) << ": " <<connection.mLink[1]->getAvailableBandwidth(false) << '\t' <<connection.mLink[1]->getActiveNumber(false);
return os;
}
unsigned long VConnection::minAverageBandwidth()
{
unsigned long min = UINT_MAX;
unsigned long temp;
temp = mLink[0]->getAverageBandwidth(true);
if(min > temp)
min = temp;
temp = mLink[1]->getAverageBandwidth(false);
if(min > temp)
min = temp;
return min;
}
unsigned long VConnection::minAverageBandwidthA()
{
unsigned long min = UINT_MAX;
unsigned long temp;
temp = mLink[0]->getAverageBandwidthA(true);
if(min > temp)
min = temp;
temp = mLink[1]->getAverageBandwidthA(false);
if(min > temp)
min = temp;
return min;
}
unsigned long VConnection::minAvailableBandwidth()
{
unsigned long min = UINT_MAX;
unsigned long temp;
temp = mLink[0]->getAvailableBandwidth(true);
if(min > temp)
min = temp;
temp = mLink[1]->getAvailableBandwidth(false);
if(min > temp)
min = temp;
return min;
}
VConnection::VConnection(Agent *agent1, Agent *agent2): mActive(false), mBandwidth(0)
{
if(!agent1 || !agent2) {
cout << "error: null agent pointer" << endl;
exit(-1);
}
mLink = mTopology->getVLinkBetween(agent1, agent2);
if(mLink.empty()) {
cout << "error: incorrect agent pointer" << endl;
exit(-1);
}
addConnection();
mConnection.insert(this);
}
VConnection::~VConnection()
{
if(mActive)
inactivate();
removeConnection();
mConnection.erase(this);
}
void VConnection::addConnection()
{
mLink[0]->addConnection(true, this);
mLink[1]->addConnection(false, this);
}
void VConnection::removeConnection()
{
mLink[0]->removeConnection(true, this);
mLink[1]->removeConnection(false, this);
}
void VConnection::activate()
{
if(mActive)
return;
else
mActive = true;
unsigned long average = minAverageBandwidth();
unsigned long available = minAvailableBandwidth();
unsigned long value = average >= available ? average : available;
if(average > available) {
average = mLink[0]->getAverageBandwidth(true);
available = mLink[0]->getAvailableBandwidth(true);
unsigned long balance = value <= available ? 0 : value - available;
while(balance > 0)
{
VConnection *pc = mLink[0]->getMaxConnection(true);
unsigned long temp = pc->getBandwidth();
if(temp <= average) {
cout << "error: impossible" << endl;
exit(-1);
}
unsigned long last = balance;
balance = balance <= temp - average ? 0 : balance - temp + average;
pc->adjustBandwidth((long long)balance - last);
}
average = mLink[1]->getAverageBandwidth(false);
available = mLink[1]->getAvailableBandwidth(false);
balance = value <= available ? 0 : value - available;
while(balance > 0)
{
VConnection *pc = mLink[1]->getMaxConnection(false);
unsigned long temp = pc->getBandwidth();
if(temp <= average) {
cout << "error: impossible" << endl;
exit(-1);
}
unsigned long last = balance;
balance = balance <= temp - average ? 0 : balance - temp + average;
pc->adjustBandwidth((long long)balance - last);
}
}
mBandwidth = value;
mLink[0]->activateConnection(true, this);
mLink[1]->activateConnection(false, this);
reallocate();
}
void VConnection::inactivate()
{
if(!mActive)
return;
else
mActive = false;
mLink[0]->inactivateConnection(true, this);
mLink[1]->inactivateConnection(false, this);
mBandwidth = 0;
mLinkAdjust.insert(mLink[0]);
mLinkAdjust.insert(mLink[1]);
reallocate();
}
long long VConnection::adjustBandwidth(long long value)
{
if(!mActive)
return 0;
if(value < 0) {
if(mBandwidth + value < 0) {
cout << "error: negative value in adjustBandwidth()" << endl;
exit(-1);
}
mBandwidth += value;
mLink[0]->adjustDown(true, this, (unsigned long)(0 - value));
mLink[1]->adjustDown(false, this, (unsigned long)(0 - value));
}
else if(value > 0) {
unsigned long average = minAverageBandwidthA();
unsigned long available = minAvailableBandwidth();
if(value > available) {
if(mBandwidth >= average)
value = available;
else if(mBandwidth + value > average)
value = average - mBandwidth;
if(value > available) {
average = mLink[0]->getAverageBandwidthA(true);
available = mLink[0]->getAvailableBandwidth(true);
unsigned long balance = value <= available ? 0 : value - available;
while(balance > 0) {
VConnection *pc = mLink[0]->getMaxConnection(true);
unsigned long temp = pc->getBandwidth();
if(temp <= average) {
cout << "error: impossible" << endl;
exit(-1);
}
unsigned long last = balance;
balance = balance <= temp - average ? 0 : balance - temp + average;
pc->adjustBandwidth((long long)balance - last);
}
average = mLink[1]->getAverageBandwidthA(false);
available = mLink[1]->getAvailableBandwidth(false);
balance = value <= available ? 0 : value - available;
while(balance > 0) {
VConnection *pc = mLink[1]->getMaxConnection(false);
unsigned long temp = pc->getBandwidth();
if(temp <= average) {
cout << "error: impossible" << endl;
exit(-1);
}
unsigned long last = balance;
balance = balance <= temp - average ? 0 : balance - temp + average;
pc->adjustBandwidth((long long)balance - last);
}
}
}
mBandwidth += value;
mLink[0]->adjustUp(true, this, value);
mLink[1]->adjustUp(false, this, value);
}
if(value < 0) {
mLinkAdjust.insert(mLink[0]);
mLinkAdjust.insert(mLink[1]);
}
return value;
}
void VConnection::reallocate()
{
set<VLink *> temp;
set<VLink *>::iterator it;
while(!mLinkAdjust.empty()) {
temp = mLinkAdjust;
mLinkAdjust.clear();
for(it = temp.begin(); it != temp.end(); it++)
(*it)->reallocate();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -