📄 bttracker.cpp
字号:
#include <algorithm>#include <stdio.h>#include"BTTracker.h"#include "BTEvent.h"#include "BTGetRequest.h"#include "SimEventScheduler.h"#include "BTTrackerResponse.h"#include "BTTorrent.h"#include "BT.h"#include "BTPeer.h"#include "BTSession.h"#include "HandleError.h"#include "Sysparameter.h"#include "PowerLaw.h"#include "BTDocument.h"#include "Statistic.h"#include <math.h>BTTracker::~BTTracker(void){}BTTorrent* BTTracker::getTTorrent(string key){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find(key); if( aIt == mDocDB.end()) return NULL; else return aIt->second->mTorrent;}bool BTTracker::addTorrent(BTTorrent* tt){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find(tt->mKey); if( aIt != mDocDB.end()) return false; else{ BTDocRecord* ptr = new BTDocRecord; ptr->mTorrent = tt; ptr->mPeerList.clear(); ptr->mDownloadTimes = 0; ptr->mComPeerList.clear(); ptr->mEspWork = true; mDocDB.insert(map<string, BTDocRecord*>::value_type(tt->mKey, ptr)); mDocList.push_back( tt); return true; }}bool BTTracker::addNodeAssociateWithDoc(string key, BTPeer* peer){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find(key); if( aIt == mDocDB.end()) return false; else{ BTDocRecord* ptr = aIt->second; if( find( ptr->mPeerList.begin(), ptr->mPeerList.end(), peer) == ptr->mPeerList.end() ) ptr->mPeerList.push_back(peer); return true; }}BTTorrent* BTTracker:: getRandomTorrent(void){ if( mDocDB.size() == 0) return NULL;// random_shuffle( mDocList.begin(), mDocList.end()); BTTorrent* pTor = NULL; unsigned int i = zipf( mDocList.size()); if( i< 0 || i>= mDocList.size()){ printf("BTTracker::getRandomTorrent:wrong i %d\n", i); exit(-1); } pTor = mDocList[i]; BTDocRecord* docRec = mDocDB.find(pTor->mKey)->second; if( docRec == NULL){ printf("getRandomTorrent no doc\n"); exit(-1); } docRec->mDownloadTimes++; return pTor;}void BTTracker::handler(SimEvent* event){ switch( event->getType()){ case TRACKER_GET_REQUEST: handleGetRequest((BTEvent *) event); return; default: handleError("BTTracker::handler"); return; }}void BTTracker::handleGetRequest(BTEvent * event){ BTSession* peerSession = (BTSession*)(event->getParam()); BTPeer* peer = peerSession->getAgent(); BTGetRequest* btg = (BTGetRequest*)(event->getAddParam()); map<string, BTDocRecord*>::iterator aIt = mDocDB.find(btg->mDownloadHashKey); if( aIt == mDocDB.end()) handleFatalError("BTTracker::handleGetRequest:no doc in docdb"); BTDocRecord* btr = aIt->second; if( btg->mType == stop){ //should remove peer from peerlist of torrent vector<BTPeer*>::iterator aIt = find( btr->mPeerList.begin(), btr->mPeerList.end(), peer); if( aIt != btr->mPeerList.end() ) btr->mPeerList.erase(aIt); aIt = find( btr->mComPeerList.begin(), btr->mComPeerList.end(), peer); if( aIt != btr->mComPeerList.end()) btr->mComPeerList.erase(aIt); if( btr->mPeerList.size() < ESP_RETIRE_PEER_NUM ) sendEspRecover( btg->mDownloadHashKey ); delete event; return; } else if( btg->mType == complete || btg->mLeft == 0.0){ addComNode( btg->mDownloadHashKey, peer ); delete event; return; } if( btr->mPeerList.size() == 1) sendEspRecover( btg->mDownloadHashKey ); addNodeAssociateWithDoc(btg->mDownloadHashKey, peer); list<BTPeer*>* peerList = selectPeers( btr); BTTrackerResponse* response = new BTTrackerResponse( btg->mDownloadHashKey, peerList); //for compute the delay between peer and tracker double t = Scheduler.getCurrent() + bt.getAgentDelay( getID(), peer->getID()); if( t < Scheduler.getCurrent()){ printf("BTTracker::handleGetRequest t %f < current agentDelay %f\n", t, bt.getAgentDelay(getID(), peer->getID())); exit(-1); } BTEvent* bte = new BTEvent(SESSION_TRACKER_RESPONSE, t, peerSession, this); bte->setAddParam(response); Scheduler.enqueue(bte); delete btg; delete event;}list<BTPeer*>* BTTracker::selectPeers( BTDocRecord* btr){ vector<BTPeer*>* peerlist = &(btr->mPeerList); if( peerlist->size() == 0) return NULL; random_shuffle(peerlist->begin(), peerlist->end()); vector<BTPeer*>::iterator aIt = peerlist->begin(); BTPeer* peerPtr = NULL; list<BTPeer*>* newList = new list<BTPeer*>; newList->clear(); unsigned int i = 0; while( aIt != peerlist->end()){ peerPtr = *(aIt++); newList->push_back(peerPtr); if( i++ >= TRACKER_PEERNUMLIMIT) break; } if( ifEspRetire( btr->mTorrent->mKey) ){ if( find(newList->begin(), newList->end(), bt.mEspList.front()) != newList->end()){ newList->remove( bt.mEspList.front()); if( aIt != peerlist->end()) newList->push_back( *aIt); } } return newList;}bool BTTracker::addComNode( string key, BTPeer* peer){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find(key); if( aIt == mDocDB.end()) return false; else{ BTDocRecord* ptr = aIt->second; if( find( ptr->mComPeerList.begin(), ptr->mComPeerList.end(), peer) == ptr->mComPeerList.end()) ptr->mComPeerList.push_back(peer); return true; }};unsigned int BTTracker::getComNum( string key){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find(key); if( aIt == mDocDB.end()) return 0; else{ BTDocRecord* ptr = aIt->second; return ptr->mComPeerList.size(); }}void BTTracker::sendEspRetire( string key ){ map<string, BTDocRecord*>::iterator pIt = mDocDB.find( key ); if( !pIt->second->mEspWork ) return; list<BTPeer*>::iterator aIt = bt.mEspList.begin(); while( aIt != bt.mEspList.end() ){ string* hashKey = new string(key); BTEvent* bte = new BTEvent( ESP_RETIRE, Scheduler.getCurrent(), *aIt, hashKey); //Scheduler.enqueue( bte ); bte->dispatch(); aIt++; } pIt->second->mEspWork = false; statistic.addEspRetire(); printf("esp retire complete peer num %d\n", pIt->second->mComPeerList.size());}void BTTracker::sendEspRecover( string key){ map<string, BTDocRecord*>::iterator pIt = mDocDB.find( key ); if( pIt->second->mEspWork ) return; list<BTPeer*>::iterator aIt = bt.mEspList.begin(); while( aIt != bt.mEspList.end() ){ string* hashKey = new string(key); BTEvent* bte = new BTEvent( ESP_RECOVER, Scheduler.getCurrent(), *aIt, hashKey); //Scheduler.enqueue( bte ); bte->dispatch(); aIt++; } pIt->second->mEspWork = true; statistic.addEspRecover(); printf("esp recover file %s complete peer num%d peernum%d\n", key.c_str(), pIt->second->mComPeerList.size(), pIt->second->mPeerList.size() );}bool BTTracker::ifEspRetire( string key){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find( key ); if( aIt->second->mEspWork) return false; return true;}unsigned int BTTracker::getPeerNumSince(string key, float time){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find( key ); unsigned int peerNum = 0; BTDocRecord* rec = aIt->second; for( unsigned int i = 0; i< rec->mPeerList.size(); i++) if( rec->mPeerList[i]->mStartTime >= time) peerNum ++; return peerNum;}void BTTracker::setEspSate(string key, bool flag ){ map<string, BTDocRecord*>::iterator aIt = mDocDB.find( key ); aIt->second->mEspWork = flag;};string BTTracker::toString(void){ char buf[20] = {0}; sprintf(buf, "BTTracker:%d\n", getID()); return buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -