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

📄 connection.cpp

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