⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trtrackerservertorrentimpl.java

📁 基于JXTA开发平台的下载软件开发源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	
	protected void
	removePeer(
		TRTrackerServerPeerImpl	peer )
	{
		removePeer( peer, -1 );
	}
		
	protected void
	removePeer(
		TRTrackerServerPeerImpl	peer,
		int						peer_list_index )	// -1 if not known
	{
		try{
			this_mon.enter();
		
			stats.removeLeft( peer.getAmountLeft());
			
			if ( peer_map.size() != peer_reuse_map.size()){
		
				if ( !map_size_diff_reported ){
					
					map_size_diff_reported	= true;
					
					Debug.out( "TRTrackerServerTorrent::removePeer: maps size different ( " + peer_map.size() + "/" + peer_reuse_map.size() +")");
				}
			}
			
			{
				Object o = peer_map.remove( peer.getPeerId());
				
				if ( o == null ){
					
					Debug.out(" TRTrackerServerTorrent::removePeer: peer_map doesn't contain peer");
				}
			}
			
			if ( peer_list_index == -1 ){
				
				int	peer_index = peer_list.indexOf( peer );
				
				if ( peer_index == -1){
					
					Debug.out(" TRTrackerServerTorrent::removePeer: peer_list doesn't contain peer");
				}else{
					
					peer_list.set( peer_index, null );
				}
			}else{
				
				if ( peer_list.get( peer_list_index ) == peer ){
					
					peer_list.set( peer_list_index, null );
					
				}else{
					
					Debug.out(" TRTrackerServerTorrent::removePeer: peer_list doesn't contain peer at index");
					
				}
			}
			
			peer_list_hole_count++;
				
			checkForPeerListCompaction( false );
			
			try{
				Object o = peer_reuse_map.remove( new String( peer.getIPAsRead(), Constants.BYTE_ENCODING ) + ":" + peer.getPort());
			
				if ( o == null ){
					
					Debug.out(" TRTrackerServerTorrent::removePeer: peer_reuse_map doesn't contain peer");
				}
				
			}catch( UnsupportedEncodingException e ){
			}	
			
			if ( peer.isSeed()){
				
				seed_count--;
			}
			
			removed_count++;
			
		}finally{
			
			this_mon.exit();
		}
	}
	
	public Map
	exportAnnounceToMap(
		HashMap						preprocess_map,
		TRTrackerServerPeerImpl		requesting_peer,		// maybe null for an initial announce from a stopped peer
		boolean						include_seeds,
		int							num_want,
		long						interval,
		long						min_interval,
		boolean						no_peer_id,
		boolean						compact )
	{
		try{
			this_mon.enter();
		
			long	now = SystemTime.getCurrentTime();
			
			// we have to force non-caching for nat_warnings responses as they include
			// peer-specific data
	
			boolean	nat_warning = requesting_peer != null && requesting_peer.getNATStatus() == TRTrackerServerPeerImpl.NAT_CHECK_FAILED;
			
			int		total_peers			= peer_map.size();
			int		cache_millis	 	= TRTrackerServerImpl.getAnnounceCachePeriod();
			
			boolean	send_peer_ids 		= TRTrackerServerImpl.getSendPeerIds();
			
				// override if client has explicitly not requested them
			
			if ( no_peer_id || compact ){
				
				send_peer_ids	= false;
			}
			
			boolean	add_to_cache	= false;
			
			int		max_peers	= TRTrackerServerImpl.getMaxPeersToSend();
			
				// num_want < 0 -> not supplied so give them max
			
			if ( num_want < 0 ){
				
				num_want = total_peers;
			}
			
				// trim back to max_peers if specified
			
			if ( max_peers > 0 && num_want > max_peers ){
				
				num_want	= max_peers;
			}
					
			if ( 	caching_enabled &&
					(!nat_warning) &&
					preprocess_map.size() == 0 &&	// don't cache if we've got pre-process stuff to add
					cache_millis > 0 &&
					num_want >= MIN_CACHE_ENTRY_SIZE &&
					total_peers >= TRTrackerServerImpl.getAnnounceCachePeerThreshold()){
							
					// note that we've got to select a cache entry that is somewhat 
					// relevant to the num_want param (but NOT greater than it)
				
					// remove stuff that's too old
							
				Iterator	it = announce_cache.keySet().iterator();
				
				while( it.hasNext() ){
					
					Integer	key = (Integer)it.next();
					
					announceCacheEntry	entry = (announceCacheEntry)announce_cache.get( key );
					
					if ( now - entry.getTime() > cache_millis ){
											
						it.remove();	
					}
				}
				
					// look for an entry with a reasonable num_want
					// e.g. for 100 look between 50 and 100
				
				for (int i=num_want/10;i>num_want/20;i--){
									
					announceCacheEntry	entry = (announceCacheEntry)announce_cache.get(new Integer(i));
					
					if( entry != null ){
				
						if ( now - entry.getTime() > cache_millis ){
							
							announce_cache.remove( new Integer(i));
							
						}else{
						
								// make sure this is compatible
							
							if ( 	entry.getSendPeerIds() == send_peer_ids &&
									entry.getCompact() == compact ){
							
								return( entry.getData());
							}
						}
					}
				}
			
				add_to_cache	= true;
			}
			
			
			List	rep_peers = new ArrayList();
			
	
			// System.out.println( "exportPeersToMap: num_want = " + num_want + ", max = " + max_peers );
			
				// if they want them all simply give them the set
			
			if ( num_want > 0 ){
							
				if ( num_want >= total_peers){
			
						// if they want them all simply give them the set
					
					for (int i=0;i<peer_list.size();i++){
									
						TRTrackerServerPeerImpl	peer = (TRTrackerServerPeerImpl)peer_list.get(i);
										
						if ( peer == null ){
													
						}else if ( now > peer.getTimeout()){
										
								// System.out.println( "removing timed out client '" + peer.getString());
							
							removePeer( peer, i );									
							
						}else if ( peer.getPort() == 0 ){
							
								// a port of 0 means that the peer definitely can't accept incoming connections
							
						}else if ( include_seeds || !peer.isSeed()){
											
							Map rep_peer = new HashMap(3);
				
							if ( send_peer_ids ){
								
								rep_peer.put( "peer id", peer.getPeerId().getHash());
							}
							
							if ( compact ){
								
								byte[]	peer_bytes = peer.getIPBytes();
								
								if ( peer_bytes == null ){
									
									continue;
								}
								
								rep_peer.put( "ip", peer_bytes );
							}else{
								rep_peer.put( "ip", peer.getIPAsRead() );
							}
							
							rep_peer.put( "port", new Long( peer.getPort()));
							
							rep_peers.add( rep_peer );
						}
					}
				}else{
					
					if ( num_want < total_peers*3 ){
						
						int	peer_list_size	= peer_list.size();
				
							// to avoid returning duplicates when doing the two-loop check
							// for nat selection we maintain an array of markers
						
						if ( duplicate_peer_checker.length < peer_list_size ){
							
							duplicate_peer_checker	= new byte[peer_list_size*2];
							
							duplicate_peer_checker_index	= 1;
							
						}else if ( duplicate_peer_checker.length > (peer_list_size*2)){
							
							duplicate_peer_checker	= new byte[(3*peer_list_size)/2];
							
							duplicate_peer_checker_index	= 1;
							
						}else{
							
							duplicate_peer_checker_index++;
							
							if ( duplicate_peer_checker_index == 0 ){
								
								Arrays.fill( duplicate_peer_checker, (byte)0);
								
								duplicate_peer_checker_index	= 1;
							}
						}
						
						boolean	peer_removed	= false;
								
						try{
								// got to suspend peer list compaction as we rely on the
								// list staying the same size during processing below
							
							peer_list_compaction_suspended	= true;
				
								// too costly to randomise as below. use more efficient but slightly less accurate
								// approach
							
								// two pass process if bad nat detection enabled
						
							int	added			= 0;
							//int	bad_nat_added	= 0;
	
							for (int bad_nat_loop=TRTrackerServerNATChecker.getSingleton().isEnabled()?0:1;bad_nat_loop<2;bad_nat_loop++){
		
								int	limit 	= num_want*2;	// some entries we find might not be usable
															// so in the limit search for more
								
								for (int i=0;i<limit && added < num_want;i++){
									
									int	index = random.nextInt(peer_list_size);
									
									TRTrackerServerPeerImpl	peer = (TRTrackerServerPeerImpl)peer_list.get(index);
					
									if ( peer == null ){
										
									}else if ( now > peer.getTimeout()){
										
										removePeer( peer );
										
										peer_removed	= true;
										
									}else if ( peer.getPort() == 0 ){
										
											// a port of 0 means that the peer definitely can't accept incoming connections
								
									}else if ( include_seeds || !peer.isSeed()){
								
										boolean	bad_nat = peer.isNATStatusBad();
										
										if ( 	( bad_nat_loop == 0 && !bad_nat ) ||
												( bad_nat_loop == 1 )){
											
											if ( duplicate_peer_checker[index] != duplicate_peer_checker_index ){
												
												duplicate_peer_checker[index] = duplicate_peer_checker_index;
										
												//if ( bad_nat ){
												//	
												//	bad_nat_added++;
												//}
												
												added++;
												
												Map rep_peer = new HashMap(3);
												
												if ( send_peer_ids ){
													
													rep_peer.put( "peer id", peer.getPeerId().getHash());
												}
												
												if ( compact ){
													
													byte[]	peer_bytes = peer.getIPBytes();
													
													if ( peer_bytes == null ){
																							
														continue;
													}
													
													rep_peer.put( "ip", peer_bytes );
													
												}else{
													
													rep_peer.put( "ip", peer.getIPAsRead() );
												}
												
												rep_peer.put( "port", new Long( peer.getPort()));	
												
												rep_peers.add( rep_peer );
											}
										}
									}
								}
							}
							
							// System.out.println( "num_want = " + num_want + ", added = " + added + ", bad_nat = " + bad_nat_added );
							
						}finally{
								
							peer_list_compaction_suspended	= false;
								
							if ( peer_removed ){
									
								checkForPeerListCompaction( false );
							}
						}
						
					}else{
						
							// randomly select the peers to return
						
						LinkedList	peers = new LinkedList( peer_map.keySet());
						
						int	added = 0;
						
						while( added < num_want && peers.size() > 0 ){
							
							String	key = (String)peers.remove(random.nextInt(peers.size()));
											
							TRTrackerServerPeerImpl	peer = (TRTrackerServerPeerImpl)peer_map.get(key);
							
							if ( now > peer.getTimeout()){
								
								removePeer( peer );
								
							}else if ( peer.getPort() == 0 ){
								
									// a port of 0 means that the peer definitely can't accept incoming connections
								
							}else if ( include_seeds || !peer.isSeed()){
								
								added++;
								
								Map rep_peer = new HashMap(3);	// don't use TreeMap as default is "compact"
																// so we never actually encode anyway
								
								if ( send_peer_ids ){
									
									rep_peer.put( "peer id", peer.getPeerId().getHash());
								}
								
								if ( compact ){
									
									byte[]	peer_bytes = peer.getIPBytes();
									
									if ( peer_bytes == null ){
										
										continue;
									}
									
									rep_peer.put( "ip", peer_bytes );
								}else{
									rep_peer.put( "ip", peer.getIPAsRead() );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -