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

📄 piecepickerimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	                        if (maxRequests >REQUESTS_MAX ||maxRequests <0)
	                            maxRequests =REQUESTS_MAX;
	                    }else{
	                        maxRequests =2;
	                    }
	                }else{
	                    maxRequests =1;
	                }
				}

					// Only loop when 3/5 of the queue is empty, in order to make more consecutive requests,
					// and improve cache efficiency
				
				if ( pt.getNbRequests() <=(maxRequests *3) /5){
				
					if ( !done_priorities ){
						
						done_priorities	= true;
						
						computeBasePriorities();
					}
					
					int	total_allocated = 0;
					
					try{
						boolean	peer_managing_requests = pt.requestAllocationStarts( startPriorities );
					
						while ( pt.isDownloadPossible() && pt.getNbRequests() < maxRequests ){
						
								// is there anything else to download?
							
							int	allocated;
							
	                        if ( peer_managing_requests || !endGameMode ){
	                        	
	                        	allocated = findPieceToDownload(pt, maxRequests );
	                            
	                        }else{
	                        	
	                        	allocated = findPieceInEndGameMode(pt, maxRequests);
	                        }
	                        
 	                        if ( allocated == 0 ){	                		
	                        	
	                        	break;
	                        	
	                        }else{
	                        	
	                        	total_allocated += allocated;
	                        }
						}
					}finally{
						
						pt.requestAllocationComplete();
					}
					
					if ( total_allocated == 0 ){
						
							// there are various reasons that we might not allocate any requests to a peer
							// such as them not having any pieces we're interested in. Keep track of the 
							// number of consecutive "no requests" outcomes so we can reduce the scheduling
							// frequency of such peers
						
						int	no_req_count = pt.getConsecutiveNoRequestCount();
						
						if ( no_req_count < NO_REQUEST_BACKOFF_MAX_LOOPS ){
							
							pt.setConsecutiveNoRequestCount( no_req_count + 2 );
						}
						
                		// System.out.println( pt.getIp() + ": nb=" + pt.getNbRequests() + ",max=" + maxRequests + ",nrc=" + no_req_count +",loop=" + allocate_request_loop_count); 

					}else{
						
						pt.setConsecutiveNoRequestCount( 0 );
					}
				}
			}
		}
	}
	
	
	protected int
	getNextBlockETAFromNow(
		PEPeerTransport	pt )
	{
		long upRate = pt.getStats().getDataReceiveRate();
		
		if ( upRate < 1 ){
			
			upRate = 1;
		}
		
		int	next_block_bytes = ( pt.getNbRequests() + 1 ) * DiskManager.BLOCK_SIZE;
		
		return((int)(( next_block_bytes * 1000 )/ upRate));
	}
	
    /** This computes the base priority for all pieces that need requesting if there's
     * been any availability change or user priority setting changes since the last
     * call, which will be most of the time since availability changes so dynamicaly
     * It will change startPriorities[] (unless there was nothing to do)
     */
    private final void 
    computeBasePriorities()
    {
        final long now = SystemTime.getCurrentTime();
                  
        if ( now < lastProviderRecalcTime || now - lastProviderRecalcTime > 1000 ){
        	
        	lastProviderRecalcTime = now;
        	
        	priorityRTAexists = computeProviderPriorities();
        }
        
        if ( !priorityRTAexists ){
	        if (startPriorities !=null &&((now >timeLastPriorities &&now <time_last_avail +TIME_MIN_PRIORITIES)
	            ||(priorityParamChange >=paramPriorityChange &&priorityFileChange >=filePriorityChange
	                &&priorityAvailChange >=availabilityChange)))
	            return;     // *somehow* nothing changed, so nothing to do
        }
        
            // store the latest change indicators before we start making dependent calculations so that a
            // further change while computing stuff doesn't get lost
        
        timeLastPriorities =now;
        priorityParamChange =paramPriorityChange;
        priorityFileChange =filePriorityChange;
        priorityAvailChange =availabilityChange;
        
        boolean     foundPieceToDownload =false;
        final int[]	newPriorities   =new int[nbPieces];

        // locals are a tiny bit faster
        final boolean firstPiecePriorityL =firstPiecePriority;
        final boolean completionPriorityL =completionPriority;
        
        try
        {
            final boolean rarestOverride =isRarestOverride();
            // calculate all base (starting) priorities for all pieces needing requesting
        	final int nbConnects =peerControl.getNbPeers() +peerControl.getNbSeeds();
            for (int i =0; i <nbPieces; i++)
            {
                final DiskManagerPiece dmPiece =dmPieces[i];
                if (dmPiece.isDone())
                    continue;   // nothing to do for pieces not needing requesting
                
                int priority =Integer.MIN_VALUE;
                int startPriority =Integer.MIN_VALUE;
                
                final DMPieceList pieceList =diskManager.getPieceList(dmPiece.getPieceNumber());
                final int pieceListSize =pieceList.size();
                for (int j =0; j <pieceListSize; j++)
                {
                    final DiskManagerFileInfoImpl fileInfo =pieceList.get(j).getFile();
                    final long downloaded =fileInfo.getDownloaded();
                    final long length =fileInfo.getLength();
                    if (length >0 &&downloaded <length &&!fileInfo.isSkipped())
                    {
                        priority =0;
                        // user option "prioritize first and last piece"
                        // TODO: should prioritize ~10% from edges of file
                        if (firstPiecePriorityL &&fileInfo.getNbPieces() >FIRST_PIECE_MIN_NB)
                        {
                        	/* backed out for the moment - reverting to old first/last piece only
                        	int lastFirstPiece = fileInfo.getFirstPieceNumber() + FIRST_PIECE_RANGE_PERCENT * (fileInfo.getLastPieceNumber() - fileInfo.getFirstPieceNumber()) / 100;
                            
                        	if ( (i >=fileInfo.getFirstPieceNumber() && i<= lastFirstPiece ) ) {
                                priority +=PRIORITY_W_FIRSTLAST + 10 * (lastFirstPiece - i) ;
                            }
                            
                             if( i ==fileInfo.getLastPieceNumber() ) {
                            	priority +=PRIORITY_W_FIRSTLAST;
                            }
                            */
                             if (i == fileInfo.getFirstPieceNumber() ||i == fileInfo.getLastPieceNumber())
                                 priority +=PRIORITY_W_FIRSTLAST;
                        }
                        // if the file is high-priority
                        // startPriority +=(1000 *fileInfo.getPriority()) /255;
                        if (fileInfo.isPriority())
                        {
                            priority +=PRIORITY_W_FILE;
                            if (completionPriorityL)
                            {
                                final long percent =(1000 *downloaded) /length;
                                if (percent >=900)
                                    priority +=(PRIORITY_W_COMPLETION *downloaded) /diskManager.getTotalLength();
                            }
                        }
                        if (priority >startPriority)
                            startPriority =priority;
                    }
                }
                
                if (startPriority >=0)
                {
                    dmPiece.setNeeded();
                    foundPieceToDownload =true;
                    final int avail =availability[i];
                    	// nbconnects is async calculate so may be wrong - make sure we don't decrease pri by accident
                    if (avail >0 && nbConnects > avail )
                    {   // boost priority for rarity
                        startPriority +=nbConnects -avail;
//                        startPriority +=(PRIORITY_W_RARE +peerControl.getNbPeers()) /avail;
                        // Boost priority even a little more if it's a globally rarest piece
                        if (!rarestOverride &&avail <=globalMinOthers)
                            startPriority +=nbConnects /avail;
                    }
                    
                    if ( provider_piece_rtas != null ){
                    	
                    	if ( provider_piece_rtas[i] > 0 ){
                    		
                    		startPriority 	= PRIORITY_REALTIME;
                    	}
                    }else if ( provider_piece_priorities != null ){
                    	
                    	startPriority += provider_piece_priorities[i];
                    }
                }else{
                	
                    dmPiece.clearNeeded();
                }
                
                newPriorities[i] =startPriority;
            }
        } catch (Throwable e)
        {
            Debug.printStackTrace(e);
        }
        
        if (foundPieceToDownload !=hasNeededUndonePiece)
        {
            hasNeededUndonePiece =foundPieceToDownload;
            neededUndonePieceChange++;
        }
        
        startPriorities = newPriorities;
    }
    

	private final boolean isRarestOverride()
    {
        final int nbSeeds =peerControl.getNbSeeds();
        final int nbPeers =peerControl.getNbPeers();
        final int nbMost =(nbPeers >nbSeeds ?nbPeers :nbSeeds);
        final int nbActive =peerControl.getNbActivePieces();
        
        // Dont seek rarest under a few circumstances, so that other factors work better
        // never seek rarest when bootstrapping torrent
        boolean rarestOverride =nbPiecesDone <4 ||endGameMode
        	||(globalMinOthers >1 &&(nbRarestActive >=nbMost ||nbActive >=nbMost));
        if (!rarestOverride &&nbRarestActive >1 &&globalMinOthers >1)
        {
            // if already getting some rarest, dont get more if swarm is healthy or too many pieces running
            rarestOverride =globalMinOthers >globalMin
            	||(globalMinOthers >=(2 *nbSeeds) &&(2 *globalMinOthers) >=nbPeers);
            // Interest in Rarest pieces (compared to user priority settings) could be influenced by several factors;
            // less demand closer to 0% and 100% of torrent completion/farther from 50% of torrent completion
            // less demand closer to 0% and 100% of peers interestd in us/farther from 50% of peers interested in us
            // less demand the more pieces are in progress (compared to swarm size)
            // less demand the farther ahead from absolute global minimum we're at already
            // less demand the healthier a swarm is (rarity compared to # seeds and # peers)
        }
        return rarestOverride;
    }
    
	/**
	 * @param pt the PEPeerTransport we're working on
	 * @return int # of blocks that were requested (0 if no requests were made)
	 */
	protected final int findPieceToDownload(PEPeerTransport pt, final int nbWanted)
	{
		final int pieceNumber =getRequestCandidate(pt);
		if (pieceNumber <0)
        {   // probaly should have found something since chose to try; probably not interested anymore
            // (or maybe Needed but not Done pieces are otherwise not requestable)
//            pt.checkInterested();
			return 0;
        }

		final int peerSpeed =(int) pt.getStats().getDataReceiveRate() /1000;

		PEPiece pePiece = pePieces[pieceNumber];
		
		if ( pePiece==null ){

			int[]	peer_priority_offsets = pt.getPriorityOffsets();
			
			int	this_offset = peer_priority_offsets==null?0:peer_priority_offsets[pieceNumber];
			
			   //create piece manually
			
			pePiece =new PEPieceImpl(pt.getManager(), dmPieces[pieceNumber], peerSpeed >>1);

			// Assign the created piece to the pieces array.
			peerControl.addPiece(pePiece, pieceNumber);
            if (startPriorities !=null){
                pePiece.setResumePriority(startPriorities[pieceNumber] + this_offset);
            }else{
            	 pePiece.setResumePriority( this_offset );
            }
			if (availability[pieceNumber] <=globalMinOthers)
				nbRarestActive++;
		}
	
		final int[] blocksFound =pePiece.getAndMarkBlocks(pt, nbWanted  );
		final int blockNumber =blocksFound[0];
		final int nbBlocks =blocksFound[1];

		if (nbBlocks <=0)
			return 0;

		int requested =0;
		// really try to send the request to the peer
		for (int i =0; i <nbBlocks; i++)
		{
			final int thisBlock =blockNumber +i;
			if (pt.request(pieceNumber, thisBlock *DiskManager.BLOCK_SIZE, pePiece.getBlockSize(thisBlock)) != null )
			{
				requested++;
				pt.setLastPiece(pieceNumber);

				pePiece.setLastRequestedPeerSpeed( peerSpeed );
				// have requested a block
			}
		}
		return requested;
	}


	
	protected final boolean 
	findRTAPieceToDownload(
		PEPeerTransport pt,
		boolean			best_uploader )
	{

⌨️ 快捷键说明

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