⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vconnection.cpp

📁 模拟P2P各种网络环境的,适合新手们的学习,不错的源码.
💻 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 + -