void peer_lost(int index) { if (m_picker.get()) { TORRENT_ASSERT(!is_seed()); m_picker->dec_refcount(index); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
// when we get a bitfield message, this is called for that piece void peer_has(bitfield const& bits) { if (m_picker.get()) { TORRENT_ASSERT(!is_seed()); m_picker->inc_refcount(bits); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
void peer_has_all() { if (m_picker.get()) { TORRENT_ASSERT(!is_seed()); m_picker->inc_refcount_all(); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
// when peer disconnects, this is called for every piece it had void peer_lost(int index) { if (m_picker.get()) { assert(!is_seed()); assert(index >= 0 && index < (signed)m_have_pieces.size()); m_picker->dec_refcount(index); } #ifndef NDEBUG else { assert(is_seed()); } #endif }
void reportReachableClasses(const Scope& scope, std::string reportFileName) { TRACE(PGR, 4, "Total numner of classes: %d\n", scope.size()); // Report classes that the reflection filter says can't be deleted. std::ofstream reportFileCanDelete(reportFileName + ".cant_delete"); for (auto const& cls : scope) { if (!can_delete(cls)) { reportFileCanDelete << cls->get_name()->c_str() << "\n"; } } reportFileCanDelete.close(); // Report classes that the reflection filter says can't be renamed. std::ofstream reportFileCanRename(reportFileName + ".cant_rename"); for (auto const& cls : scope) { if (!can_rename(cls)) { reportFileCanRename << cls->get_name()->c_str() << "\n"; } } reportFileCanRename.close(); // Report classes marked for keep from ProGuard flat file list. std::ofstream reportFileKeep(reportFileName + ".must_keep"); for (auto const& cls : scope) { if (is_seed(cls)) { reportFileKeep << cls->get_name()->c_str() << "\n"; } } reportFileKeep.close(); }
// 从peer队列中选择一个优化非阻塞peer int select_optunchoke_peer() { int count = 0, index, i = 0, j, ret; Peer *p = peer_head; // 获取peer队列中peer的总数 while(p != NULL) { count++; p = p->next; } // 如果peer总数太少(小于等于4),则没有必要选择优化非阻塞peer if(count <= UNCHOKE_COUNT) return 0; ret = get_rand_numbers(count); if(ret < 0) { printf("%s:%d get rand numbers error\n",__FILE__,__LINE__); return -1; } while(i < count) { // 随机选择一个数,该数在0~count-1之间 index = rand_num[i]; p = peer_head; j = 0; while(j < index && p != NULL) { p = p->next; j++; } if( is_in_unchoke_peers(p) != 1 && is_seed(p) != 1 && p->state == DATA && p != unchoke_peers.optunchkpeer && is_interested(bitmap,&(p->bitmap)) ) { if( (unchoke_peers.optunchkpeer) != NULL ) { Peer *temp = peer_head; while( temp != NULL ) { if(temp == unchoke_peers.optunchkpeer) break; temp = temp->next; } if(temp != NULL) { (unchoke_peers.optunchkpeer)->am_choking = 1; create_chock_interested_msg(0,unchoke_peers.optunchkpeer); } } p->am_choking = 0; create_chock_interested_msg(1,p); unchoke_peers.optunchkpeer = p; //printf("*** optunchoke:%s ***\n",p->ip); break; } i++; } if(rand_num != NULL) { free(rand_num); rand_num = NULL; } return 0; }
void peer_lost(int index, peer_connection const* peer) { if (has_picker()) { m_picker->dec_refcount(index, peer); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
void peer_has_all(peer_connection const* peer) { if (has_picker()) { m_picker->inc_refcount_all(peer); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
// when we get a have message, this is called for that piece void peer_has(int index) { if (has_picker()) { m_picker->inc_refcount(index); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
void peer_lost(bitfield const& bits, peer_connection const* peer) { if (has_picker()) { if (bits.all_set() && bits.size() > 0) m_picker->dec_refcount_all(peer); else m_picker->dec_refcount(bits, peer); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
void peer_lost(bitfield const& bits) { if (has_picker()) { if (bits.all_set()) m_picker->dec_refcount_all(); else m_picker->dec_refcount(bits); } #ifdef TORRENT_DEBUG else { TORRENT_ASSERT(is_seed()); } #endif }
// this is true if we have all the pieces that we want bool is_finished() const { if (is_seed()) return true; return valid_metadata() && m_torrent_file->num_pieces() - m_picker->num_have() - m_picker->num_filtered() == 0; }
bool super_seeding() const { // we're not super seeding if we're not a seed return m_super_seeding && is_seed(); }
bool torrent_handle::is_seed() const { INVARIANT_CHECK; TORRENT_FORWARD_RETURN(is_seed(), false); }
bool is_leech() const throw() { return !is_seed(); }
// 找出当前下载速度最快的4个peer,将其unchoke int select_unchoke_peer() { Peer* p; Peer* now_fast[UNCHOKE_COUNT]; Peer* force_choke[UNCHOKE_COUNT]; int unchoke_socket[UNCHOKE_COUNT], choke_socket[UNCHOKE_COUNT]; int i, j, index = 0, len = UNCHOKE_COUNT; int have_not_unchoke[UNCHOKE_COUNT]; //初始化变量 for(i = 0; i < len; i++) { now_fast[i] = NULL; force_choke[i] = NULL; unchoke_socket[i] = -1; choke_socket[i] = -1; have_not_unchoke[i] = -1; } // 将那些在过去10秒已断(被剔出peer表)开连接而又处于unchoke队列中的peer清除出unchoke队列 for(i = 0, j = 0; i < unchoke_peers.count; i++) { p = peer_head; while(p != NULL) { if(p == unchoke_peers.unchkpeer[i]) break; p = p->next; } if(p == NULL) //不在peer链表中,说明已经断开 { unchoke_peers.unchkpeer[i] = NULL; j++; } } if(j != 0) { unchoke_peers.count = unchoke_peers.count - j;//剩下非阻塞数组未断开的个数 for(i = 0, j = 0; i < len; i++) { if(unchoke_peers.unchkpeer[i] != NULL) { force_choke[j] = unchoke_peers.unchkpeer[i]; j++; } } for(i = 0; i < len; i++) {//有效的挪到数组前排 unchoke_peers.unchkpeer[i] = force_choke[i]; force_choke[i] = NULL; } } // unchoke队列中,将那些在过去10秒上传速度超过20KB/S而下载速度过小的peer强行阻塞 // 注意:up_rate和down_rate的单位是B/S而不是KB/S for(i = 0, j = -1; i < unchoke_peers.count; i++) { if( (unchoke_peers.unchkpeer)[i]->up_rate > 50*1024 && //到底是50k还是20k? (unchoke_peers.unchkpeer)[i]->down_rate < 0.1*1024 ) { j++; force_choke[j] = unchoke_peers.unchkpeer[i]; } } // 从当前所有Peer中选出下载速度最快的四个peer,存于now_fast中 p = peer_head; while(p != NULL) { if(p->state==DATA && is_interested(bitmap,&(p->bitmap)) && is_seed(p)!=1) {//state?交换数据? // p不应该在force_choke数组中 for(i = 0; i < len; i++) { if(p == force_choke[i]) break; } if(i == len) { if( index < UNCHOKE_COUNT ) { now_fast[index] = p; index++; } else { //数组满了 j = get_last_index(now_fast,UNCHOKE_COUNT); //找now_fast最慢的那个和这个比较 if(p->down_rate >= now_fast[j]->down_rate) now_fast[j] = p; } } } p = p->next; } /**************************以下一段需要改进**********************************/ /* // 假设now_fast中所有的peer都是要unchoke的,取出各自的socket for(i = 0; i < index; i++) { Peer* q = now_fast[i]; unchoke_socket[i] = q->socket; } // 假设unchoke_peers.unchkpeer中所有peer都是choke的,取出各自的socket for(i = 0; i < unchoke_peers.count; i++) { Peer* q = (unchoke_peers.unchkpeer)[i]; choke_socket[i] = q->socket; } // 如果now_fast某个元素已经存在于unchoke_peers.unchkpeer // 则没有必要进行choke或unckoke for(i = 0; i < index; i++) { if( is_in_unchoke_peers(now_fast[i]) == 1) {//在unchoke_peers.unchkpeer,不用阻塞 // for(j = 0; j < len; j++) { //index与len不一定对应=4//但循环是为什么 Peer* q = now_fast[i]; if(q->socket == unchoke_socket[i]) unchoke_socket[i] = -1; if(q->socket == choke_socket[i]) choke_socket[i] = -1; // } } } // 更新当前unchoke的peer for(i = 0; i < index; i++) { (unchoke_peers.unchkpeer)[i] = now_fast[i]; } unchoke_peers.count = index; // 状态变化后,要对peer的状态值重新赋值,并且创建choke、unchoke消息 p = peer_head; while(p != NULL) { for(i = 0; i < len; i++) { if(unchoke_socket[i]==p->socket && unchoke_socket[i]!=-1) { p->am_choking = 0;//非阻塞 create_chock_interested_msg(1,p); } if(choke_socket[i]==p->socket && unchoke_socket[i]!=-1) { p->am_choking = 1; cancel_requested_list(p); create_chock_interested_msg(0,p); } } p = p->next; } */ /*******************************改进后*************************/ for (i = 0; i < unchoke_peers.count; i++) { p = (unchoke_peers.unchkpeer)[i]; for (j = 0; j < index; j++) { if(p == now_fast[j]) { break; } } if(j == index) {//peer在非阻塞队列中,但不在刚选出的now_fast中,将它阻塞 p->am_choking = 1; cancel_requested_list(p); create_chock_interested_msg(0,p); } else { have_not_unchoke[j] = 1;//记下now_fast中不必unchoke的位置 } } for(i = 0; i < index; i++) { if(have_not_unchoke[i] != 1) { //说明now_fast对应位置要unchoke now_fast[i]->am_choking = 0;//转入非阻塞状态 create_chock_interested_msg(1,now_fast[i]); } } //更新unchoke_peers for(i = 0; i < index; i++) { (unchoke_peers.unchkpeer)[i] = now_fast[i]; } unchoke_peers.count = index; /*****************************改进结束**************************/ for(i = 0; i < unchoke_peers.count; i++) printf("unchoke peer:%s \n",(unchoke_peers.unchkpeer)[i]->ip); printf("***********************************************\n"); return 0; }