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

📄 piecepickerimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                        timeAvailRebuild -=errors;
                    } else
                    	timeAvailRebuild++;
                }
                
                availabilityAsynch	= new_availability;
                
                availabilityDrift =0;
                availabilityChange++;
            } finally {availabilityMon.exit();}

        } else if (availabilityComputeChange >=availabilityChange){
            return;
        }

        try
        {	availabilityMon.enter();
            time_last_avail =now;
            availabilityComputeChange =availabilityChange;
    
            // take a snapshot of availabilityAsynch
            if ( availabilityAsynch != null ){
                availability 		= availabilityAsynch;
                availabilityAsynch	= null;
            }
        } finally {availabilityMon.exit();}

        int i;
        int allMin =Integer.MAX_VALUE;
        int rarestMin =Integer.MAX_VALUE;
        for (i =0; i <nbPieces; i++)
        {
            final int avail =availability[i];
            final DiskManagerPiece dmPiece =dmPieces[i];
            final PEPiece	pePiece = pePieces[i];
            
            if (avail >0 &&avail <rarestMin && dmPiece.isDownloadable() && (pePiece == null || pePiece.isRequestable())) 
                rarestMin =avail;	// most important targets for near future requests from others

            if (avail <allMin)
                allMin =avail;
        }
        // copy updated local variables into globals
        globalMin =allMin;
        globalMinOthers =rarestMin;

        int total =0;
        int rarestActive =0;
        long totalAvail =0;
        for (i =0; i <nbPieces; i++ )
        {
            final int avail =availability[i];
            final DiskManagerPiece dmPiece =dmPieces[i];
            final PEPiece	pePiece = pePieces[i];
            
            if (avail >0)
            {
                if (avail >allMin)
                    total++;
                if (avail <=rarestMin &&dmPiece.isDownloadable() && pePiece != null && !pePiece.isRequested())
                    rarestActive++;
                totalAvail +=avail;
            }
        }
        // copy updated local variables into globals
        globalAvail =(total /(float) nbPieces) +allMin;
        nbRarestActive =rarestActive;
        globalAvgAvail =totalAvail /(float)(nbPieces)
        /(1 +peerControl.getNbSeeds() +peerControl.getNbPeers());
    }
	
	private final int[] recomputeAvailability()
	{
	    if (availabilityDrift >0 &&availabilityDrift !=nbPieces &&Logger.isEnabled())
	        Logger.log(new LogEvent(diskManager.getTorrent(), LOGID, LogEvent.LT_INFORMATION,
	            "Recomputing availabiliy. Drift=" +availabilityDrift +":" +peerControl.getDisplayName()));
	    final List peers =peerControl.getPeers();
	    
	    final int[]	newAvailability = new int[nbPieces];
	    int j;
	    int i;
	    // first our pieces
	    for (j =0; j <nbPieces; j++)
	        newAvailability[j] =dmPieces[j].isDone() ?1 :0;
	    //for all peers
	    final int peersSize =peers.size();
	    for (i =0; i <peersSize; i++)
	    {	//get the peer connection
	        final PEPeer peer =(PEPeerTransport)peers.get(i);
	        if (peer !=null &&peer.getPeerState() ==PEPeer.TRANSFERING)
	        {
	            //cycle trhough the pieces they actually have
	            final BitFlags peerHavePieces =peer.getAvailable();
	            if (peerHavePieces !=null &&peerHavePieces.nbSet >0)
	            {
	                for (j =peerHavePieces.start; j <=peerHavePieces.end; j++)
	                {
	                    if (peerHavePieces.flags[j])
	                        ++newAvailability[j];
	                }
	            }
	        }
	    }
	    return newAvailability;
	}
	
	public int
	getNumberOfPieces()
	{
		return( nbPieces );
	}
	
	public final int[] getAvailability()
	{
		return availability;
	}

	public final int getAvailability(final int pieceNumber)
	{
		return availability[pieceNumber];
	}
	
	//this only gets called when the My Torrents view is displayed
	public final float getMinAvailability()
	{
		return globalAvail;
	}

	public final float getAvgAvail()
	{
		return globalAvgAvail;
	}


	/**
	 * Early-outs when finds a downloadable piece
	 * Either way sets hasNeededUndonePiece and neededUndonePieceChange if necessary 
	 */
	protected final void checkDownloadablePiece()
	{
		for (int i =0; i <nbPieces; i++)
		{
			if (dmPieces[i].isInteresting())
			{
				if (!hasNeededUndonePiece)
				{
					hasNeededUndonePiece =true;
					neededUndonePieceChange++;
				}
				return;
			}
		}
		if (hasNeededUndonePiece)
		{
			hasNeededUndonePiece =false;
			neededUndonePieceChange++;
		}
	}

	/**
	 * one reason requests don't stem from the individual peers is so the connections can be
	 * sorted by best uploaders, providing some ooprtunity to download the most important
	 * (ie; rarest and/or highest priority) pieces faster and more reliably
	 */
	public final void allocateRequests()
	{
		if (!hasNeededUndonePiece){
			return;
		}
		
		allocate_request_loop_count++;
		
		final List peers =peerControl.getPeers();
        final int peersSize =peers.size();

		final long[] upRates =new long[peersSize];
        final ArrayList bestUploaders =new ArrayList( peersSize );

		for (int i =0; i <peersSize; i++){
		
			final PEPeerTransport peer =(PEPeerTransport) peers.get(i);
			
			if ( peer.isDownloadPossible()){
			
				int	no_req_count 	= peer.getConsecutiveNoRequestCount();
	
				if ( 	no_req_count == 0 || 
						allocate_request_loop_count % ( no_req_count + 1 ) == 0 ){
					
					final long upRate = peer.getStats().getSmoothDataReceiveRate();
					
					UnchokerUtil.updateLargestValueFirstSort(upRate, upRates, peer, bestUploaders, 0);
					
				}
			}
		}
		
		final int uploadersSize = bestUploaders.size();

		if ( uploadersSize == 0 ){
			
				// no usable peers, bail out early
			return;
		}
		
		boolean	done_priorities = false;

		if ( priorityRTAexists ){
						
			LinkedList	block_time_order_peers = new LinkedList();
			
			block_time_order_peers.addAll( bestUploaders );
			
			Collections.sort( 
				block_time_order_peers,
				new Comparator()
				{
					public int 
					compare(
						Object arg1, 
						Object arg2) 
					{
						PEPeerTransport pt1	= (PEPeerTransport)arg1;
						PEPeerTransport pt2	= (PEPeerTransport)arg2;
						
						return( getNextBlockETAFromNow( pt1 ) - getNextBlockETAFromNow( pt2 ));
					}
				});		

			
			PEPeerTransport	best_uploader = (PEPeerTransport)bestUploaders.get(0);
			
				// give priority pieces the first look-in
				// we need to sort by how quickly the peer can get a block, not just its base speed
			
			boolean	allocated_request = true;
			
			Set	allocations_started	= new HashSet();
			
			try{
				while( allocated_request && priorityRTAexists ){
					
					allocated_request = false;
					
					Iterator	it = block_time_order_peers.iterator();
					
					while( it.hasNext()){
		
						final PEPeerTransport pt =(PEPeerTransport)it.next();
		
						if ( !pt.isDownloadPossible() || pt.isSnubbed()){
							
							it.remove();
							
							continue;
						}
	
							// ignore request number advice from peers in RTA mode, we gotta do what we can
			                
			            int maxRequests = REQUESTS_MIN +(int)( pt.getStats().getDataReceiveRate() /SLOPE_REQUESTS );
			                    
			            if ( maxRequests > REQUESTS_MAX || maxRequests < 0 ){
			                		
			            	maxRequests = REQUESTS_MAX;
			            }
		
						if ( pt.getNbRequests() <= maxRequests ){
							
							if ( !done_priorities ){
								
								done_priorities	= true;
										
								computeBasePriorities();
								
								if ( !priorityRTAexists ){
									
										// might have stopped RTA as this is calculated in computeBasePriorities
									
									break;
								}
							}
					
							if ( !allocations_started.contains( pt )){
								
								pt.requestAllocationStarts( startPriorities );
								
								allocations_started.add( pt );
							}
							
							if ( findRTAPieceToDownload( pt, pt == best_uploader )){
							
								allocated_request = true;
								
							}else{
								
								it.remove();
							}
						}else{
							
							it.remove();
						}
					}
				}
			}finally{
					
				Iterator	it = allocations_started.iterator();
				
				while( it.hasNext()){
					
					((PEPeerTransport)it.next()).requestAllocationComplete();
				}
			}
		}
		
		checkEndGameMode();
		
		for (int i =0; i <uploadersSize; i++){

			final PEPeerTransport pt =(PEPeerTransport) bestUploaders.get(i);
			
				// can we transfer something?
			
			if ( pt.isDownloadPossible()){
			
				int	peer_request_num = pt.getMaxNbRequests();
				
					// If request queue is too low, enqueue another request

				int maxRequests;
                
				if ( peer_request_num != -1 ){
					
					maxRequests = peer_request_num;
					
				}else{
	                if (!pt.isSnubbed()){
	                	
	                    if (!endGameMode){
	                        maxRequests =REQUESTS_MIN +(int) (pt.getStats().getDataReceiveRate() /SLOPE_REQUESTS);

⌨️ 快捷键说明

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