FileDocCategorySizeDatePackage
DiskManagerChannelImpl.javaAPI DocAzureus 3.0.3.418266Wed May 09 17:40:32 BST 2007org.gudy.azureus2.pluginsimpl.local.disk

DiskManagerChannelImpl

public class DiskManagerChannelImpl extends Object implements org.gudy.azureus2.core3.disk.DiskManagerFileInfoListener, org.gudy.azureus2.core3.download.DownloadManagerPeerListener, org.gudy.azureus2.plugins.disk.DiskManagerChannel, com.aelitis.azureus.core.peermanager.piecepicker.PieceRTAProvider

Fields Summary
private static int
BUFFER_MILLIS
private static int
MIN_PIECES_TO_BUFFER
private static final boolean
TRACE
private static final int
COMPACT_DELAY
private static final int
MAX_READ_CHUNK
private static final Comparator
comparator
private static final String
channel_key
private static int
channel_id_next
private static com.aelitis.azureus.core.util.CopyOnWriteList
listeners
private org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl
download
private org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl
plugin_file
private org.gudy.azureus2.core3.disk.DiskManagerFileInfo
core_file
private Set
data_written
private int
compact_delay
private List
waiters
private long
file_offset_in_torrent
private long
piece_size
private org.gudy.azureus2.core3.util.Average
byte_rate
private long
start_position
private long
start_time
private long
current_position
private request
current_request
private long
buffer_millis
private org.gudy.azureus2.core3.peer.PEPeerManager
peer_manager
private long[]
rtas
private int
channel_id
Constructors Summary
protected DiskManagerChannelImpl(org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl _download, org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl _plugin_file)

	
	
	
																	
				 
	
		download		= _download;
		plugin_file		= _plugin_file;
		
		core_file		= plugin_file.getCore();
		
		synchronized( DiskManagerChannelImpl.class ){
			
			channel_id = channel_id_next++;
		}
				
		TOTorrentFile	tf = core_file.getTorrentFile();
		
		TOTorrent 	torrent = tf.getTorrent();
		
		TOTorrentFile[]	tfs = torrent.getFiles();

		rtas	= new long[torrent.getNumberOfPieces()];
		
		core_file.getDownloadManager().addPeerListener(this);
			
		for (int i=0;i<core_file.getIndex();i++){
				
			file_offset_in_torrent += tfs[i].getLength();
		}
			
		piece_size	= tf.getTorrent().getPieceLength();
		
		core_file.addListener( this );
		
		reportCreated( this );
	
Methods Summary
public static voidaddListener(org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerChannelImpl$channelCreateListener l)

	
	   
	
				 
	
		listeners.add( l );
	
public org.gudy.azureus2.plugins.disk.DiskManagerRequestcreateRequest()

		if ( core_file.getDownloaded() != core_file.getLength()){
			
			if ( core_file.isSkipped()){
				
				core_file.setSkipped( false );
			}
			
			boolean	force_start = download.isForceStart();
			
			if ( !force_start ){
				
				synchronized( download ){
					
					Map	dl_state = (Map)download.getDownload().getData( channel_key );
					
					if ( dl_state == null ){
						
						dl_state = new HashMap();
						
						download.getDownload().setData( channel_key, dl_state );
					}
					
					dl_state.put( ""+channel_id, "" );
				}
				
				download.setForceStart( true );
			}
		}
		
		current_request = new request();
		
		return( current_request );
	
public voiddataChecked(long offset, long length)

		// System.out.println( "data checked:" + offset + "/" + length );
	
public voiddataWritten(long offset, long length)

		if ( TRACE ){
			System.out.println( "data written:" + offset + "/" + length );
		}
		
		dataEntry	entry = new dataEntry( offset, length );
		
		synchronized( data_written ){
			
			data_written.add( entry );
			
			compact_delay--;
			
			if ( compact_delay == 0 ){
				
				compact_delay	= COMPACT_DELAY;
				
				Iterator	it = data_written.iterator();
				
				dataEntry	prev_e	= null;
				
				while( it.hasNext()){
					
					dataEntry	this_e = (dataEntry)it.next();
					
					if ( prev_e == null ){
						
						prev_e = this_e;
						
					}else{
						
						long	prev_offset = prev_e.getOffset();
						long	prev_length	= prev_e.getLength();
						long	this_offset = this_e.getOffset();
						long	this_length	= this_e.getLength();
						
						if ( this_offset <= prev_offset + prev_length ){
							
							if ( TRACE ){	
								System.out.println( "merging: " + prev_e.getString()  + "/" + this_e.getString());
							}
							
							it.remove();
							
							prev_e.setLength( Math.max( prev_offset + prev_length, this_offset + this_length ) - prev_offset );
						
							if ( TRACE ){	
								System.out.println( "    -> " + prev_e.getString());
							}

						}else{
							
							prev_e = this_e;
						}
					}
				}
			}
		
			for (int i=0;i<waiters.size();i++){
					
				((AESemaphore)waiters.get(i)).release();
			}
		}
	
public voiddestroy()

		core_file.removeListener( this );
		
		core_file.getDownloadManager().removePeerListener(this);
		
		if ( peer_manager != null ){
			
			peer_manager.getPiecePicker().removeRTAProvider( this );
		}
		
		boolean	stop_force_start = false;
		
		synchronized( download ){
			
			Map	dl_state = (Map)download.getDownload().getData( channel_key );
			
			if ( dl_state != null ){
				
				dl_state.remove( "" + channel_id );
				
				if ( dl_state.size() == 0 ){
					
					stop_force_start	= true;
				}
			}
		}
		
		if ( stop_force_start ){
			
			download.setForceStart( false );
		}
	
public longgetBlockingPosition()

		request r = current_request;
		
		if ( r == null ){
			
			return( current_position );
		}
		
		return( current_position + r.getAvailableBytes());
	
public longgetCurrentPosition()

		return( current_position );
	
public org.gudy.azureus2.plugins.disk.DiskManagerFileInfogetFile()

		return( plugin_file );
	
public longgetStartPosition()

   		return( start_position );
   	
public longgetStartTime()

   		return( start_time );
   	
public java.lang.StringgetUserAgent()

		request r = current_request;
		
		if ( r == null ){
			
			return( null );
		}
		
		return( r.getUserAgent());
	
public voidpeerAdded(org.gudy.azureus2.core3.peer.PEPeer peer)

	
public voidpeerManagerAdded(org.gudy.azureus2.core3.peer.PEPeerManager manager)

		peer_manager = manager;
		
		manager.getPiecePicker().addRTAProvider( this );
	
public voidpeerManagerRemoved(org.gudy.azureus2.core3.peer.PEPeerManager manager)

		peer_manager = null;
		
		manager.getPiecePicker().removeRTAProvider( this );
	
public voidpeerManagerWillBeAdded(org.gudy.azureus2.core3.peer.PEPeerManager manager)

	
public voidpeerRemoved(org.gudy.azureus2.core3.peer.PEPeer peer)

	
public voidpieceAdded(org.gudy.azureus2.core3.peer.PEPiece piece)

	
public voidpieceRemoved(org.gudy.azureus2.core3.peer.PEPiece piece)

	
public static voidremoveListener(org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerChannelImpl$channelCreateListener l)

		listeners.remove( l );
	
protected static voidreportCreated(org.gudy.azureus2.plugins.disk.DiskManagerChannel channel)

		Iterator it = listeners.iterator();
		
		while( it.hasNext()){
			
			try{
				((channelCreateListener)it.next()).channelCreated( channel );
				
			}catch( Throwable e ){
				
				Debug.printStackTrace(e);
			}
		}
	
public voidsetBufferMillis(long millis)

		buffer_millis = millis;
	
public long[]updateRTAs(com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker picker)

   		long	overall_pos = current_position + file_offset_in_torrent;
   		
   		int	first_piece = (int)( overall_pos / piece_size );
   		
   		long	rate = byte_rate.getAverage();
   		
   		long	buffer_bytes = ( BUFFER_MILLIS * rate ) / 1000;
   		
   		int	pieces_to_buffer = (int)( buffer_bytes / piece_size );
   		
   		if ( pieces_to_buffer < 1 ){
   			
   			pieces_to_buffer	= 1;
   		}
   		
   		int	millis_per_piece = BUFFER_MILLIS/pieces_to_buffer; 

   		if ( pieces_to_buffer < MIN_PIECES_TO_BUFFER ){
   			
   			pieces_to_buffer = MIN_PIECES_TO_BUFFER;
   		}
   		   		
   		// System.out.println( "rate = " + rate + ", buffer_bytes = " + buffer_bytes + ", pieces = " + pieces_to_buffer + ", millis_per_piece = " + millis_per_piece );
   		
   		Arrays.fill( rtas, 0 );
   		 
   		long	now = SystemTime.getCurrentTime();
   		
   		now += buffer_millis;
   		
   		for (int i=first_piece;i<first_piece+pieces_to_buffer&&i<rtas.length;i++){
   			
   			rtas[i]	= now + (( i - first_piece ) * millis_per_piece );
   		}
   		
   		return( rtas );