www.pudn.com > GGBT.rar > Choker.cpp
// 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::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::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::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 vPreferred;
for (int i=0; im_pUpload->is_interested())
{
vPreferred.push_back(CPreferItem(_rate(m_connections[i]), m_connections[i]));
}
sort(vPreferred.begin(), vPreferred.end(), greater());
if (vPreferred.size() > m_lMaxUploads)
vPreferred.erase(vPreferred.begin() + m_lMaxUploads, vPreferred.end());
long lCount = vPreferred.size();
/*
TRACE("\r\n_rechoke() {");
for_each(vPreferred.begin(), vPreferred.end(), printitem);
TRACE("}\r\n");
//*/
for (i=0; im_pUpload;
bool bfind = false;
for (int j=0; junchoke();
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; im_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("\r\n{");
for_each(m_connections.begin(), m_connections.end(), printl);
TRACE("}\r\n");
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("\r\n{");
for_each(m_connections.begin(), m_connections.end(), printl);
TRACE("}\r\n");//*/
/*
for (int i=0; i<100; i++)
{
Sleep(3000);
time_t td = round_robin();
TRACE("time delay %d\r\n", td);
}
int ii = 0;
//*/
// _rechoke();
}