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

📄 pepieceimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * File    : PEPieceImpl.java
 * Created : 15-Oct-2003
 * By      : Olivier
 * 
 * Azureus - a Java Bittorrent client
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details ( see the LICENSE file ).
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.gudy.azureus2.core3.peer.impl;

/**
 * @author parg
 * @author MjrTom
 *			2005/Oct/08: numerous changes for new piece-picking
 *			2006/Jan/02: refactoring piece picking to elsewhere, and consolidations
 */

import java.util.*;

import org.gudy.azureus2.core3.disk.*;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.peer.*;
import org.gudy.azureus2.core3.util.*;


public class PEPieceImpl
    implements PEPiece
{
	private static final LogIDs LOGID = LogIDs.PIECES;
	
	private final DiskManagerPiece	dmPiece;
	private final PEPeerManager		manager;
	
	private final int       nbBlocks;       // number of blocks in this piece
    private long            creationTime;


	private final String[]	requested;
	private boolean			fully_requested;
	
	private final boolean[]	downloaded;
	private boolean			fully_downloaded;
	private long        	time_last_download;

	private final String[] 	writers;
	private List 			writes;
	
	private String			reservedBy;	// using address for when they send bad/disconnect/reconnect
	
	//In end game mode, this limitation isn't used
    private int             speed;      //slower peers dont slow down fast pieces too much
    
    private int             resumePriority;
      
    private Object			real_time_data;
    
	// experimental class level lock
	protected static final AEMonitor 	class_mon	= new AEMonitor( "PEPiece:class");
	
    /** piece for tracking partially downloaded pieces
     * @param _manager the PEPeerManager
     * @param _dm_piece the backing dmPiece
     * @param _pieceSpeed the speed threshold for potential new requesters
     */
	public PEPieceImpl(
		PEPeerManager 		_manager, 
		DiskManagerPiece	_dm_piece,
        int                 _pieceSpeed)
	{
        creationTime =SystemTime.getCurrentTime();
		manager =_manager;
		dmPiece =_dm_piece;
        speed =_pieceSpeed;

		nbBlocks =dmPiece.getNbBlocks();

		requested =new String[nbBlocks];
        
        final boolean[] written =dmPiece.getWritten();
		if (written ==null)
			downloaded =new boolean[nbBlocks];
		else
			downloaded =(boolean[])written.clone();

        writers =new String[nbBlocks];
		writes =new ArrayList(0);
	}

    public DiskManagerPiece getDMPiece()
    {
        return dmPiece;
    }

    public long getCreationTime()
    {
        final long now =SystemTime.getCurrentTime();
        if (now >=creationTime &&creationTime >0)
            return creationTime;
        creationTime =now;
        return now;
    }
    
    public long getTimeSinceLastActivity()
    {
        final long now =SystemTime.getCurrentTime();
        final long lastWriteTime =getLastDownloadTime(now);
        if (time_last_download >0 &&now >=time_last_download)
            return now -time_last_download;
        if (creationTime >0 &&now >=creationTime)
            return now -creationTime;
        creationTime =now;
        return 0;
    }
    
	public long getLastDownloadTime(final long now)
	{
		if (time_last_download <=now)
			return time_last_download;
		return time_last_download =now;
	}

	/** Tells if a block has been requested
	 * @param blockNumber the block in question
	 * @return true if the block is Requested already
	 */
	public boolean isRequested(int blockNumber)
	{
		return requested[blockNumber] !=null;
	}
	
	/** Tells if a block has been downloaded
	 * @param blockNumber the block in question
	 * @return true if the block is downloaded already
	 */
	public boolean isDownloaded(int blockNumber)
	{
		return downloaded[blockNumber];
	}
	
	/** This flags the block at the given offset as having been downloaded
     * If all blocks are now downloaed, sets the dmPiece as downloaded
	 * @param blockNumber
	 */
	public void setDownloaded(int offset)
	{
		time_last_download =SystemTime.getCurrentTime();
		downloaded[offset /DiskManager.BLOCK_SIZE] =true;
        for (int i =0; i <nbBlocks; i++)
        {
            if (!downloaded[i])
                return;
        }
        
        fully_downloaded	= true;
        fully_requested		= false;
	}
	
    /** This flags the block at the given offset as NOT having been downloaded
     * and the whole piece as not having been fully downloaded
     * @param blockNumber
     */
    public void clearDownloaded(int offset)
    {
        downloaded[offset /DiskManager.BLOCK_SIZE] =false;
       
        fully_downloaded	= false;
    }
    
    public boolean		
    isDownloaded()
    {
    	return( fully_downloaded );
    }
    
    public boolean[]	
    getDownloaded()
    {
    	return( downloaded );
    }
    
    public boolean
    hasUndownloadedBlock()
    {
    	for (int i =0; i <nbBlocks; i++ ){
    		
			if (!downloaded[i]){
				
				return( true );
			}
		}
    	
    	return( false );
    }
    
	/** This marks a given block as having been written by the given peer
	 * @param peer the PEPeer that sent the data
	 * @param blockNumber the block we're operating on
	 */
	public void setWritten(PEPeer peer, int blockNumber)
	{
		writers[blockNumber] =peer.getIp();
		dmPiece.setWritten(blockNumber);
	}
	
	/** This method clears the requested information for the given block
     * unless the block has already been downloaded, in which case the writer's
     * IP is recorded as a request for the block.
	 */
	public void clearRequested(int blockNumber)
	{
		requested[blockNumber] =downloaded[blockNumber] ?writers[blockNumber] :null;
		
		fully_requested = false;
	}
	
	public boolean      
	isRequested()
	{
		return( fully_requested );
	}
	    
	public void			
	setRequested()
	{
		fully_requested	= true;
	}

	/** This will scan each block looking for requested blocks. For each one, it'll verify
	 * if the PEPeer for it still exists and is still willing and able to upload data.
	 * If not, it'll unmark the block as requested.
	 * @return int of how many were cleared (0 to nbBlocks)
	 */
    /*
	public int checkRequests()
	{
        if (getTimeSinceLastActivity() <30 *1000)
            return 0;
		int cleared =0;
		boolean nullPeer =false;
		for (int i =0; i <nbBlocks; i++)
		{
			if (!downloaded[i] &&!dmPiece.isWritten(i))
			{
				final String			requester =requested[i];
				final PEPeerTransport	pt;
				if (requester !=null)
				{
					pt =manager.getTransportFromAddress(requester);
					if (pt !=null)
					{
						pt.setSnubbed(true);
						if (!pt.isDownloadPossible())
						{
                            clearRequested(i);
							cleared++;
						}
					} else
					{
						nullPeer =true;
                        clearRequested(i);
						cleared++;
					}
				}
			}
		}
		if (cleared >0)
		{
			dmPiece.clearRequested();
            if (Logger.isEnabled())
                Logger.log(new LogEvent(dmPiece.getManager().getTorrent(), LOGID, LogEvent.LT_WARNING,
                        "checkRequests(): piece #" +getPieceNumber()+" cleared " +cleared +" requests."
                        + (nullPeer ?" Null peer was detected." :"")));
		}
		return cleared;
	}
	*/
    
	/** @return true if the piece has any blocks that are not;
	 *  Downloaded, Requested, or Written
	 */
	public boolean hasUnrequestedBlock()
	{
		final boolean[] written =dmPiece.getWritten();
		for (int i =0; i <nbBlocks; i++ )
		{
			if (!downloaded[i] &&requested[i] ==null &&(written ==null ||!written[i]))
				return true;
		}
		return false;
	}

	/**
	 * This method scans a piece for the first unrequested block.  Upon finding it,
	 * it counts how many are unrequested up to nbWanted.
	 * The blocks are marked as requested by the PEPeer
	 * Assumption - single threaded access to this
	 * TODO: this should return the largest span equal or smaller than nbWanted
	 * OR, probably a different method should do that, so this one can support 'more sequential' picking
	 */
	public int[] getAndMarkBlocks(PEPeer peer, int nbWanted )
	{
		final String ip =peer.getIp();
        final boolean[] written =dmPiece.getWritten();
		int blocksFound =0;
		// scan piece to find first free block
		for (int i =0; i <nbBlocks; i++)
		{
			while (blocksFound <nbWanted &&(i +blocksFound) <nbBlocks &&!downloaded[i +blocksFound]
			    &&requested[i +blocksFound] ==null &&(written ==null ||!written[i]))
			{
				requested[i +blocksFound] =ip;
				blocksFound++;
			}
			if (blocksFound >0)
				return new int[] {i, blocksFound};
		}
		return new int[] {-1, 0};
	}
	
	public void getAndMarkBlock(PEPeer peer, int index )
	{
		requested[index] = peer.getIp();
		
		if ( getNbUnrequested() <= 0 ){
			
			setRequested();
		}
	}
	
    public int getNbRequests()
    {
        int result =0;
        for (int i =0; i <nbBlocks; i++)
        {
            if (!downloaded[i] &&requested[i] !=null)
                result++;
        }
        return result;
    }

⌨️ 快捷键说明

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