18 #include <util/bitset.h> 
   19 #include <peer/chunkcounter.h> 
   20 #include <diskio/chunkmanager.h> 
   21 #include <interfaces/piecedownloader.h> 
   22 #include <peer/peer.h> 
   23 #include <peer/peermanager.h> 
   24 #include <download/downloader.h> 
   34     RareCmp(ChunkManager & cman,ChunkCounter & cc,
bool warmup) : cman(cman),cc(cc),warmup(warmup) {}
 
   36     bool operator()(Uint32 a,Uint32 b)
 
   38         if (a >= cman.getNumChunks() || b >= cman.getNumChunks())
 
   41         Priority pa = cman.getChunk(a)->getPriority();
 
   42         Priority pb = cman.getChunk(b)->getPriority();
 
   44             return normalCmp(a,b); 
 
   51     bool normalCmp(Uint32 a,Uint32 b)
 
   55             return cc.get(a) < cc.get(b);
 
   57             return cc.get(a) > cc.get(b);
 
   62 : ChunkSelectorInterface(cman,downer,pman)
 
   64     std::vector<Uint32> tmp;
 
   65     for (Uint32 i = 0;i < cman.getNumChunks();++i)
 
   67         if (!cman.getBitSet().get(i))
 
   72     std::random_shuffle(tmp.begin(),tmp.end());
 
   75     chunks.insert(chunks.begin(),tmp.begin(),tmp.end());
 
   84 Uint32 BTChunkSelector::leastPeers(
const std::list<Uint32> & lp)
 
   86     Uint32 sel = lp.front();
 
   87     Uint32 cnt = downer.numDownloadersForChunk(sel);
 
   88     std::list<Uint32>::const_iterator itEnd = lp.end();
 
   89     for (std::list<Uint32>::const_iterator i = lp.begin();i != itEnd;++i)
 
   91         Uint32 cnt_i = downer.numDownloadersForChunk(*i);
 
  103     const BitSet & bs = cman.getBitSet();
 
  105     std::list<Uint32> preview;
 
  106     std::list<Uint32> normal;
 
  107     std::list<Uint32> first;
 
  108     Uint32 sel = cman.getNumChunks() + 1;
 
  111     if (sort_timer.getElapsedSinceUpdate() > 2000)
 
  113         bool warmup = cman.getNumChunks() - cman.chunksLeft() <= 4;
 
  114         chunks.sort(RareCmp(cman,pman.getChunkCounter(),warmup));
 
  118     std::list<Uint32>::iterator itr;
 
  119     std::list<Uint32>::iterator itrEnd = chunks.end();
 
  120     for (itr = chunks.begin(); itr != itrEnd; )
 
  122         const Uint32 i = *itr;
 
  123         Chunk* c = cman.getChunk(i);
 
  128             itr = chunks.erase(itr);
 
  133             if (pd->hasChunk(i) && !c->isExcluded() && !c->isExcludedForDownloading())
 
  135                 if (!downer.areWeDownloading(i))
 
  142                 switch (cman.getChunk(i)->getPriority())
 
  144                     case PREVIEW_PRIORITY:
 
  145                         preview.push_back(i);
 
  150                     case NORMAL_PRIORITY:
 
  161     if (sel >= cman.getNumChunks())
 
  165     switch (cman.getChunk(sel)->getPriority())
 
  167         case PREVIEW_PRIORITY:
 
  171             if (preview.size() > 0)
 
  173                 chunk = leastPeers(preview);
 
  182         case NORMAL_PRIORITY:
 
  183             if (preview.size() > 0)
 
  185                 chunk = leastPeers(preview);
 
  188             else if (first.size() > 0)
 
  190                 chunk = leastPeers(first);
 
  200             if (preview.size() > 0)
 
  202                 chunk = leastPeers(preview);
 
  205             else if (first.size() > 0)
 
  207                 chunk = leastPeers(first);
 
  210             else if (normal.size() > 0)
 
  212                 chunk = leastPeers(normal);
 
  231     for (Uint32 i = 0;i < ok_chunks.getNumBits();++i)
 
  233         bool in_chunks = std::find(chunks.begin(),chunks.end(),i) != chunks.end();
 
  234         if (in_chunks && ok_chunks.get(i))
 
  239         else if (!in_chunks && !ok_chunks.get(i))
 
  250     if (from >= cman.getNumChunks() || to >= cman.getNumChunks())
 
  252         Out(SYS_DIO|LOG_NOTICE) << 
"Internal error in chunkselector" << endl;
 
  256     for (Uint32 i = from;i <= to;++i)
 
  258         bool in_chunks = std::find(chunks.begin(),chunks.end(),i) != chunks.end();
 
  259         if (!in_chunks && cman.getChunk(i)->getStatus() != Chunk::ON_DISK)
 
  269     bool in_chunks = std::find(chunks.begin(),chunks.end(),chunk) != chunks.end();
 
  271         chunks.push_back(chunk);
 
  281     bool in_chunks = std::find(chunks.begin(),chunks.end(),chunk) != chunks.end();
 
  283         chunks.remove(chunk);
 
  301 #include "btchunkselector.moc" 
virtual void exclude(bt::Uint32 chunk)
 
virtual void reinsert(bt::Uint32 chunk)
 
virtual void reincluded(bt::Uint32 from, bt::Uint32 to)
 
~BTChunkSelectorFactory()
 
virtual void excludeAll()
 
void selectorAdded(BTChunkSelector *selector)
 
virtual void dataChecked(const bt::BitSet &ok_chunks)
 
virtual bool select(bt::PieceDownloader *pd, bt::Uint32 &chunk)
 
bt::ChunkSelectorInterface * createChunkSelector(bt::ChunkManager &cman, bt::Downloader &downer, bt::PeerManager &pman)
 
BTChunkSelector(bt::ChunkManager &cman, bt::Downloader &downer, bt::PeerManager &pman)