FileDocCategorySizeDatePackage
TransferProcessor.javaAPI DocAzureus 3.0.3.411950Sat Mar 03 22:11:08 GMT 2007com.aelitis.azureus.core.networkmanager.impl

TransferProcessor

public class TransferProcessor extends Object

Fields Summary
public static final int
TYPE_UPLOAD
public static final int
TYPE_DOWNLOAD
private final com.aelitis.azureus.core.networkmanager.LimitedRateGroup
max_rate
private final ByteBucket
main_bucket
private final EntityHandler
main_controller
private final HashMap
group_buckets
private final HashMap
connections
private final org.gudy.azureus2.core3.util.AEMonitor
connections_mon
Constructors Summary
public TransferProcessor(int processor_type, com.aelitis.azureus.core.networkmanager.LimitedRateGroup max_rate_limit)
Create new transfer processor for the given read/write type, limited to the given max rate.

param
processor_type read or write processor
param
max_rate_limit to use


  
                              
         
    this.max_rate = max_rate_limit;
    
    connections_mon = new AEMonitor( "TransferProcessor:" +processor_type );

    main_bucket = new ByteBucket( max_rate.getRateLimitBytesPerSecond() ); 

    main_controller = new EntityHandler( processor_type, new RateHandler() {
      public int getCurrentNumBytesAllowed() {
        if( main_bucket.getRate() != max_rate.getRateLimitBytesPerSecond() ) { //sync rate
          main_bucket.setRate( max_rate.getRateLimitBytesPerSecond() );
        }
        return main_bucket.getAvailableByteCount();
      }
      
      public void bytesProcessed( int num_bytes_written ) {
        main_bucket.setBytesUsed( num_bytes_written );
      }
    });
  
Methods Summary
public voidaddRateLimiter(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection, com.aelitis.azureus.core.networkmanager.LimitedRateGroup group)

	  try{ 
		  connections_mon.enter();
	  
	      ConnectionData conn_data = (ConnectionData)connections.get( connection );
	      
	      if ( conn_data != null ){
	    	 
			  LimitedRateGroup[]	groups 		= conn_data.groups;

			  for (int i=0;i<groups.length;i++){
				  
				  if ( groups[i] == group ){
					  
					  return;
				  }
			  }
			  
	    	  GroupData group_data = (GroupData)group_buckets.get( group );
	    	  
		      if ( group_data == null ){
		    	  
		    	  int limit = NetworkManagerUtilities.getGroupRateLimit( group );

		    	  group_data = new GroupData( new ByteBucket( limit ) );

		    	  group_buckets.put( group, group_data );
		      }
		      
		      group_data.group_size++;
		   
			  GroupData[]			group_datas = conn_data.group_datas; 

		      int	len = groups.length;

		      LimitedRateGroup[]	new_groups = new LimitedRateGroup[ len + 1 ];
		      
		      System.arraycopy( groups, 0, new_groups, 0, len );
		      new_groups[len] = group;
		      
		      conn_data.groups 		= new_groups;
		      
		      GroupData[]	new_group_datas = new GroupData[ len + 1 ];
		      
		      System.arraycopy( group_datas, 0, new_group_datas, 0, len );
		      new_group_datas[len] = group_data;

		      conn_data.group_datas = new_group_datas;
	      }
	  }finally{
		 
		  connections_mon.exit();
	  }
  
public voidderegisterPeerConnection(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection)
Cancel upload handling for the given peer connection.

param
connection to cancel

    try{ connections_mon.enter();
      ConnectionData conn_data = (ConnectionData)connections.remove( connection );
      
      if( conn_data != null ) {
    	  
    	GroupData[]	group_datas = conn_data.group_datas;
    	
  			//do groups de-registration
    	 
    	for (int i=0;i<group_datas.length;i++){
    		
    		GroupData	group_data = group_datas[i];
    		
    		if( group_data.group_size == 1 ) {  //last of the group
          
    			group_buckets.remove( conn_data.groups[i] ); //so remove
    			
    		}else {
    		
    			group_data.group_size--;
    		}
        }
      }
    }
    finally{ connections_mon.exit(); }
    

    main_controller.cancelPeerConnection( connection );
  
public voiddowngradePeerConnection(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection)
Downgrade the given connection back to a normal-speed transfer handler.

param
connection to downgrade

    ConnectionData conn_data = null;
    
    try{ connections_mon.enter();
      conn_data = (ConnectionData)connections.get( connection );
    }
    finally{ connections_mon.exit(); }
    
    if( conn_data != null && conn_data.state == ConnectionData.STATE_UPGRADED ) {
      main_controller.downgradePeerConnection( connection );
      conn_data.state = ConnectionData.STATE_NORMAL;
    }
  
public booleanisRegistered(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection)

    try{ connections_mon.enter();
      return( connections.containsKey( connection ));
    }
    finally{ connections_mon.exit(); }
  
public voidregisterPeerConnection(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection, boolean upload)
Register peer connection for upload handling. NOTE: The given max rate limit is ignored until the connection is upgraded.

param
connection to register
param
group rate limit group

    final ConnectionData conn_data = new ConnectionData();

    try {  connections_mon.enter();
    
      LimitedRateGroup[]	groups = connection.getRateLimiters( upload );
      //do group registration
      GroupData[]	group_datas = new GroupData[groups.length];
    
      for (int i=0;i<groups.length;i++){
    	  LimitedRateGroup group = groups[i];
    	  GroupData group_data = (GroupData)group_buckets.get( group );
	      if( group_data == null ) {
	        int limit = NetworkManagerUtilities.getGroupRateLimit( group );
	        group_data = new GroupData( new ByteBucket( limit ) );
	        group_buckets.put( group, group_data );
	      }
	      group_data.group_size++;
	      
	      group_datas[i] = group_data;
      }
      conn_data.groups = groups;
      conn_data.group_datas = group_datas;
      conn_data.state = ConnectionData.STATE_NORMAL;
     
      connections.put( connection, conn_data );
    }
    finally {  connections_mon.exit();  }
    
    main_controller.registerPeerConnection( connection );
  
public voidremoveRateLimiter(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection, com.aelitis.azureus.core.networkmanager.LimitedRateGroup group)

	   try{ 
		   connections_mon.enter();
		   
		   ConnectionData conn_data = (ConnectionData)connections.get( connection );
	      
		   if ( conn_data != null ){
	    	  
			   LimitedRateGroup[]	groups 		= conn_data.groups;
			   GroupData[]			group_datas = conn_data.group_datas; 
			   
			   int	len = groups.length;

			   if ( len == 0 ){
				   
				   return;
			   }
			   
			   LimitedRateGroup[]	new_groups 		= new LimitedRateGroup[ len - 1 ];
			   GroupData[]			new_group_datas = new GroupData[ len - 1 ];

			   int	pos = 0;
			   
			   for (int i=0;i<groups.length;i++){
	    		
				   if ( groups[i] == group ){
					   
					   GroupData	group_data = conn_data.group_datas[i];
	    		
					   if ( group_data.group_size == 1 ){  //last of the group
	          
						   group_buckets.remove( conn_data.groups[i] ); //so remove
	    			
					   }else {
	    		
						   group_data.group_size--;
					   }
				   }else{
					   
					   if ( pos == new_groups.length ){
						   
						   return;
					   }
					   
					   new_groups[pos]		= groups[i];
					   new_group_datas[pos]	= group_datas[i];
					   
					   pos++;
				   }
			   }
			   
			   conn_data.groups 		= new_groups;
			   conn_data.group_datas 	= new_group_datas;
		   }
	   }finally{ 
		   
		   connections_mon.exit(); 
	   } 
  
public voidupgradePeerConnection(com.aelitis.azureus.core.networkmanager.NetworkConnectionBase connection)
Upgrade the given connection to a high-speed transfer handler.

param
connection to upgrade

    ConnectionData connection_data = null;
    
    try{ connections_mon.enter();
      connection_data = (ConnectionData)connections.get( connection );
    }
    finally{ connections_mon.exit(); }
    
    if( connection_data != null && connection_data.state == ConnectionData.STATE_NORMAL ) {
      final ConnectionData conn_data = connection_data;
      
      main_controller.upgradePeerConnection( connection, new RateHandler() {
        public int getCurrentNumBytesAllowed() {          
          // sync global rate
          if( main_bucket.getRate() != max_rate.getRateLimitBytesPerSecond() ) {
            main_bucket.setRate( max_rate.getRateLimitBytesPerSecond() );
          }
          
          int allowed = main_bucket.getAvailableByteCount();

          // reserve bandwidth for the general pool
          allowed -= connection.getMssSize();
          
          if ( allowed < 0 )allowed = 0;
          
          	// only apply group rates to non-lan local connections 
          
          if ( !( connection.isLANLocal() && NetworkManager.isLANRateEnabled())){
	          // sync group rates
	          
	          try{
		           for (int i=0;i<conn_data.group_datas.length;i++){
			          int group_rate = NetworkManagerUtilities.getGroupRateLimit( conn_data.groups[i] );
			          
			          ByteBucket group_bucket = conn_data.group_datas[i].bucket;
			          
			          if ( group_bucket.getRate() != group_rate ){
			        	  
			        	  group_bucket.setRate( group_rate );
			          }
			          
			          int 	group_allowed = group_bucket.getAvailableByteCount();
			          
			          if ( group_allowed < allowed ){
			        	  
			        	  allowed = group_allowed;
			          }
		           }
	          }catch( Throwable e ){
	        	  // conn_data.group stuff is not synchronized for speed but can cause borkage if new
	        	  // limiters added so trap here
	        	  
	        	  if (!( e instanceof IndexOutOfBoundsException )){
	        		  
	        		  Debug.printStackTrace(e);
	        	  }
	          }
          }
                  	            
           return allowed;
        }

        public void bytesProcessed( int num_bytes_written ) {
          if ( !( connection.isLANLocal() && NetworkManager.isLANRateEnabled())){
	          for (int i=0;i<conn_data.group_datas.length;i++){
	        	  conn_data.group_datas[i].bucket.setBytesUsed( num_bytes_written );
	          }
          }
          main_bucket.setBytesUsed( num_bytes_written );
        }
      });
      
      conn_data.state = ConnectionData.STATE_UPGRADED;
    }