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

📄 btalgorithmrechoke.cpp

📁 模拟P2P各种网络环境的,适合新手们的学习,不错的源码.
💻 CPP
字号:
#include <algorithm>
#include "BTAlgorithmRechoke.h"
#include "BTEvent.h"
#include "BTSocket.h"
#include "SimEventScheduler.h"
#include "BTPeer.h"
#include "BTEvent.h"
#include "BTSession.h"
#include "Sysparameter.h"
#include "Debug.h"
#include "BT.h"
#include "BTTracker.h"
#include "Topology.h"


BTAlgorithmRechoke::BTAlgorithmRechoke( BTSession* session){
		mSession = session;
		mRechokeInterval = RECHOKE_INTERVAL;
		mOptimisticInterval = OPTIMISTIC_INTERVAL;
		mSnubDetectInterval = SNUB_CHECK_INTERVAL;
		mSnubUnchokeNum = SNUB_UNCHOKE_NUM;
		mUnchokeNum = MAX_UNCHOKE_NUM;
		mOptimisticLastRunningTime = 0;
		mSnubDetectLastRunningTime = 0;
};

bool InCompare::operator()(BTSocket* const & peer1, BTSocket* const & peer2) const{
       double timestamp = Scheduler.getCurrent() - 2*RECHOKE_INTERVAL;
	double num1 = peer1->calcInAverageBandwidthSince( timestamp);
	double num2 = peer2->calcInAverageBandwidthSince(timestamp);
	if( num1 > num2)
		return true;
	else
		return false;
};

bool OutCompare::operator()(BTSocket* const &  peer1, BTSocket* const &  peer2) const{
	double timestamp = Scheduler.getCurrent() - 2*RECHOKE_INTERVAL;
	double num1 = peer1->calcOutAverageBandwidthSince( timestamp);
	double num2 = peer2->calcOutAverageBandwidthSince(timestamp);
	if( num1 > num2)
		return true;
	else 
		return false;
};

void BTAlgorithmRechoke::handler(SimEvent* event){
	if( mSession->mState == stopped || !mSession->mActive){
		delete event;
		return;
	}
	//check if seed should retire
	if( mSession->mAgent->mType == superseed ) 
		if( mSession->checkRetire())
			return;
		
	//session check timout
	mSession->checkTimeout();

	//if peer is superseed should compute the unchoke number first
	unsigned int avlConNum = mUnchokeNum;
	if( mSession->mAgent->mType == superseed)
		 avlConNum = mSession->mAgent->getAvalConNum();
	
	vector< BTSocket*>* connections = mSession->getConnections();
	if( connections->size() == 0){
		delete connections;
		if( mRechoke != NULL ){
			delete event;
			mRechoke = NULL;
		}
		return;
	}
	set<BTPeer*>*  unchokepeerlist = mSession->getUnchoklist();
	unchokepeerlist->clear();

	if( mSession->getDocument()->isWhole())
		sort( connections->begin(), connections->end(), OutCompare());
	else
		sort(connections->begin(), connections->end(), InCompare());
	  //for debug

       DEBUG(RECHOKEDEBUGLEVEL){
	   	printf("in peer %d rechoke before algorithm sessionnum %d\n", mSession->getAgent()->getID(), mSession->mAgent->getActiveSessionNum());
       	print();
		printCon(connections);
       }
	
	BTSocket* con = NULL;
	BTPeer* peer = NULL;
	unsigned int unchokeNum =0;
	unsigned int i = 0;
	for( ; i< (connections->size()) && unchokeNum < avlConNum; i++){
		con = (*connections)[i];
		peer = con->mCounterPart->mSession->getAgent();
		if( mSession->getDocument()->isWhole() ||(!mSession->getDocument()->isWhole()&&con->mPeerInsterested ) ){
			mSession->sendChoke(false, con);
			mSession->removePeerFromCandidates(peer);
			unchokepeerlist->insert(peer);
			unchokeNum++;
						
		}
		
	}

	if( connections->size() > i){	
		for(unsigned  int j = i+1; j< connections->size(); j++){
			con = (*connections)[j];
			peer = con->mCounterPart->mSession->getAgent();
			if( con->mPeerInsterested){
				mSession->sendChoke(true, con);
				if( !mSession->inCandidate( peer))
					mSession->addPeerCandidates(peer);
					
			}
			
		}
	}
	
	//for debug
	DEBUG(RECHOKEDEBUGLEVEL) {
       	printf("in peer %d rechoke after rechoke algorithm\n", mSession->getAgent()->getID());
      		print();
	}
	//for debug
	optimisticUnchoke();
	snubDetect();
	nextSchedule();
	delete connections;
	delete event;
	
};

void BTAlgorithmRechoke::nextSchedule(void){
	BTEvent* bte = new BTEvent( RECHOCK, Scheduler.getCurrent() + mRechokeInterval, this, NULL);
	Scheduler.enqueue(bte);
	mRechoke = bte;
};

void BTAlgorithmRechoke::optimisticUnchoke(void){
	if( mSession->mDocument->isWhole() )
		return;
	//first running
	if( mOptimisticLastRunningTime == 0){
		vector<BTPeer*>* peerCandidates = mSession->getPeerCandidates();
		mOptimisticLastRunningTime = Scheduler.getCurrent();
		if( peerCandidates->size() > 0){
			BTPeer* peer = *(peerCandidates->begin());
			mSession->connectTo( peer, false );
			return;
		}
		return;
	}
	//interval time not enough do nothing
	if( Scheduler.getCurrent() - mOptimisticLastRunningTime < mOptimisticInterval)
		return;
	//interval time pass chose one peer to unchoke
	vector<BTPeer*>* peerCandidates = mSession->getPeerCandidates();
	mOptimisticLastRunningTime = Scheduler.getCurrent();
	if( peerCandidates->size() > 0){
			BTPeer* peer = *(peerCandidates->begin());
			mSession->connectTo( peer, false );
	}
       mOptimisticLastRunningTime = Scheduler.getCurrent();
};

void BTAlgorithmRechoke::snubDetect(void){
	if( Scheduler.getCurrent() - mSnubDetectLastRunningTime < mSnubDetectInterval)
		return;
	if( mSession->getDocument()->isWhole())
		return;
	if( mSession->getAmountBetweenSnubDect() == 0){
		if( mSession->ifNoAvailablePeer()){
			bt.mTracker->sendEspRecover( mSession->mDocument->mkey );
			mSession->requestEsp();
			return;
		}
		vector<BTSocket*>* connectionlist = mSession->getConnections();
		random_shuffle(connectionlist->begin(), connectionlist->end());
		BTPeer* peer = NULL;
		unsigned int i = 0;
		for(; i< mSnubUnchokeNum && i < connectionlist->size() ; i++ ){
			peer = (*connectionlist)[i]->mSession->getAgent();
			if( !mSession->inUnchokeList( peer))
				mSession->connectTo( peer, false);
		};
		mSession->setAmountBetweenSnubDect( 0 );
		delete  connectionlist;
	}
	mSession->setAmountBetweenSnubDect( 0 );
	mSnubDetectLastRunningTime = Scheduler.getCurrent();
	
};

void BTAlgorithmRechoke::print(void){
	BTPeer* peer = NULL;
       set<BTPeer*>::iterator aIt = mSession->getUnchoklist()->begin();

	printf(" unchokepeerlist: \n");
	while( aIt != mSession->getUnchoklist()->end()){
		peer = *(aIt++);
		printf("peer %d", peer->getID());
	}
	printf("\n");
	printf(" peercandidates: \n");
	vector<BTPeer*>::iterator pIt = mSession->getPeerCandidates()->begin();
	while( pIt != mSession->getPeerCandidates()->end()){
		peer = *(pIt ++);
		printf("peer %d", peer->getID());
	}
	printf("\n");
}

void BTAlgorithmRechoke::printCon( vector<BTSocket*>* conlist){
	BTSocket* peer;
	for( unsigned int i = 0; i< conlist->size(); i++){
		peer = (*conlist)[i];
		printf("con to peer %d inbandwidth %f outbandwidth%f\n", peer->mCounterPart->mSession->getAgent()->getID(), peer->calcInAverageBandwidthSince( Scheduler.getCurrent()- 2*RECHOKE_INTERVAL), peer->calcOutAverageBandwidthSince(Scheduler.getCurrent()- 2*RECHOKE_INTERVAL));
	}

}

void BTAlgorithmRechoke::cancelRechoke(void){
	if( mRechoke == NULL)
		return;
	Scheduler.cancel( mRechoke);
	delete mRechoke;
	mRechoke = NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -