Choker.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:5k
源码类别:
P2P编程
开发平台:
Visual C++
- // Choker.cpp: implementation of the CChoker class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "testbt.h"
- #include "Choker.h"
- #include "Connection.h"
- #include "Upload.h"
- #include "SingleDownload.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- #define TIME_ROUND_ROBIN 10 //number of seconds to pause between round_robin.
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CChoker::CChoker(long lMaxUploads, HANDLE hevDone)
- {
- m_lMaxUploads = lMaxUploads;
- m_hevDone = hevDone;
- m_lCount = 0;
- time(&m_tRoundRobin);
- _test();
- }
- CChoker::~CChoker()
- {
- }
- void CChoker::connection_made(CConnection *pConnection)
- {
- m_connections.push_back(pConnection);
- _rechoke();
- }
- void CChoker::connection_lost(CConnection *pConnection)
- {
- vector<CConnection*>::iterator it = find(m_connections.begin(), m_connections.end(), pConnection);
- assert(it != m_connections.end());
- m_connections.erase(it);
- if ((*it)->m_pUpload->is_interested() && !(*it)->m_pUpload->is_choked())
- _rechoke();
- }
- void CChoker::interested(CConnection *pConnection)
- {
- vector<CConnection*>::iterator it = find(m_connections.begin(), m_connections.end(), pConnection);
- assert(it != m_connections.end());
- if (!(*it)->m_pUpload->is_choked())
- _rechoke();
- }
- void CChoker::not_interested(CConnection *pConnection)
- {
- vector<CConnection*>::iterator it = find(m_connections.begin(), m_connections.end(), pConnection);
- assert(it != m_connections.end());
- if (!(*it)->m_pUpload->is_choked())
- _rechoke();
- }
- bool CChoker::_snubbed(CConnection *pConnection)
- {
- if (IsEventSet(m_hevDone))
- return false;
- return pConnection->m_pDownload->is_snubbed();
- }
- long CChoker::_rate(CConnection *pConnection)
- {
- if (IsEventSet(m_hevDone))
- return pConnection->m_pUpload->get_rate();
- else
- return pConnection->m_pDownload->get_rate();
- }
- void CChoker::printitem(CPreferItem& item)
- {
- TRACE("(%d,%d)", item.m_lrate, item.m_pConnection);
- }
- void CChoker::_rechoke()
- {
- vector<CPreferItem> vPreferred;
- for (int i=0; i<m_connections.size(); i++)
- if (!_snubbed(m_connections[i]) && m_connections[i]->m_pUpload->is_interested())
- {
- vPreferred.push_back(CPreferItem(_rate(m_connections[i]), m_connections[i]));
- }
- sort(vPreferred.begin(), vPreferred.end(), greater<CPreferItem&>());
- if (vPreferred.size() > m_lMaxUploads)
- vPreferred.erase(vPreferred.begin() + m_lMaxUploads, vPreferred.end());
- long lCount = vPreferred.size();
- /*
- TRACE("rn_rechoke() {");
- for_each(vPreferred.begin(), vPreferred.end(), printitem);
- TRACE("}rn");
- //*/
- for (i=0; i<m_connections.size(); i++)
- {
- CUpload* pu = m_connections[i]->m_pUpload;
- bool bfind = false;
- for (int j=0; j<vPreferred.size(); j++)
- if (m_connections[i] == vPreferred[j].m_pConnection)
- {
- bfind = true;
- break;
- }
- if (bfind)
- pu->unchoke();
- else
- {
- if (lCount < m_lMaxUploads)
- {
- pu->unchoke();
- if (pu->is_interested())
- lCount ++;
- }
- else
- pu->choke();
- }
- }
- }
- time_t CChoker::round_robin()
- {
- time_t t;
- time(&t);
- time_t tspan = t - m_tRoundRobin;
- assert(tspan >= 0);
- if (tspan < 0)
- m_tRoundRobin = t;
- if (tspan < TIME_ROUND_ROBIN)
- return TIME_ROUND_ROBIN - tspan;
- // TRACE("round_robin() ");
- _round_robin();
- time(&m_tRoundRobin);
- return TIME_ROUND_ROBIN;
- }
- void CChoker::_round_robin()
- {
- m_lCount++;
- if (m_lCount%3 == 0)
- {
- for (int i=0; i<m_connections.size(); i++)
- {
- CUpload* pu = m_connections[i]->m_pUpload;
- if (pu->is_choked() && pu->is_interested())
- {
- rotate(m_connections.begin(), m_connections.begin() + i, m_connections.end());
- break;
- }
- }
- }
- _rechoke();
- }
- void CChoker::SetMaxUploads(long lMaxUploads)
- {
- if (lMaxUploads <= 0)
- {
- assert(false);
- return;
- }
- m_lMaxUploads = lMaxUploads;
- }
- void printl(CConnection* l)
- {
- TRACE("%d, ", l);
- }
- void CChoker::_test()
- {
- /*
- for (int i=0; i<5; i++)
- {
- m_connections.push_back((CConnection*)i);
- }
- TRACE("rn{");
- for_each(m_connections.begin(), m_connections.end(), printl);
- TRACE("}rn");
- rotate(m_connections.begin(), m_connections.begin() + 2, m_connections.end());
- // iter_swap(m_connections.begin() + 4, m_connections.begin() + 2);
- /*
- CConnection* pold = m_connections[4];
- m_connections[4] = m_connections[2];
- m_connections[2] = pold;
- TRACE("rn{");
- for_each(m_connections.begin(), m_connections.end(), printl);
- TRACE("}rn");//*/
- /*
- for (int i=0; i<100; i++)
- {
- Sleep(3000);
- time_t td = round_robin();
- TRACE("time delay %drn", td);
- }
- int ii = 0;
- //*/
- // _rechoke();
- }