Package com.aelitis.azureus.core.dht.netcoords

Source Code of com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionManager

/*
* Created on 24-Apr-2006
* Created by Paul Gardner
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* 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, or (at your option) any later version.
* 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.
* 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.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/

package com.aelitis.azureus.core.dht.netcoords;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.gudy.azureus2.core3.util.Debug;

import com.aelitis.azureus.core.dht.DHTStorageAdapter;
import com.aelitis.azureus.core.dht.impl.DHTLog;
import com.aelitis.azureus.core.util.CopyOnWriteList;

public class
DHTNetworkPositionManager
{
  private static DHTNetworkPositionProvider[]  providers = new DHTNetworkPositionProvider[0];
 
  private static DHTStorageAdapter  storage_adapter = null;
 
  private static CopyOnWriteList<DHTNetworkPositionProviderListener>  provider_listeners = new CopyOnWriteList<DHTNetworkPositionProviderListener>();
  private static CopyOnWriteList<DHTNetworkPositionListener>      position_listeners;
 
  public static void
  initialise(
    DHTStorageAdapter    adapter )
  {
    synchronized( providers ){
     
      if ( storage_adapter == null ){
       
        storage_adapter  = adapter;
       
        for (int i=0;i<providers.length;i++){
       
          DHTNetworkPositionProvider  provider = providers[i];

          try{
            startUp( provider );
           
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
        }
      }
    }
  }
 
  private static void
  startUp(
    DHTNetworkPositionProvider  provider )
  {
    byte[] data = null;
   
    if ( storage_adapter != null ){
     
      data = storage_adapter.getStorageForKey( "NPP:" + provider.getPositionType());
    }
   
    if ( data == null ){
     
      data = new byte[0];
    }
   
    try{
      provider.startUp( new DataInputStream( new ByteArrayInputStream( data )));
     
    }catch( Throwable e ){
     
      Debug.printStackTrace( e );
    }
  }
 
  private static void
  shutDown(
    DHTNetworkPositionProvider  provider )
  {
    try{     
      ByteArrayOutputStream  baos = new ByteArrayOutputStream();
     
      DataOutputStream  dos = new DataOutputStream( baos );
     
      provider.shutDown( dos );
     
      dos.flush();
     
      byte[]  data = baos.toByteArray();
     
      storage_adapter.setStorageForKey( "NPP:" + provider.getPositionType(), data );
     
    }catch( Throwable e ){
     
      Debug.printStackTrace( e );
    }
  }
 
  public static void
  destroy(
    DHTStorageAdapter    adapter )
  {
    synchronized( providers ){
     
      if ( storage_adapter == adapter ){

        for (int i=0;i<providers.length;i++){

          shutDown( providers[i] );
        }
       
        storage_adapter  = null;
      }
    }
  }
 
  public static DHTNetworkPositionProviderInstance
  registerProvider(
    final DHTNetworkPositionProvider  provider )
  {
    boolean  fire_added = false;
   
    synchronized( providers ){
 
      boolean            found     = false;
      DHTNetworkPositionProvider  type_found  = null;
     
      for ( DHTNetworkPositionProvider p: providers ){
       
        if ( p == provider ){
         
          found = true;
         
          break;
         
        }else if ( p.getPositionType() == provider.getPositionType()){
         
          type_found = p;
        }
      }
     
      if ( !found ){
       
        if ( type_found != null ){
         
          Debug.out( "Registration of " + provider + " found previous provider for same position type, removing it" );
         
          unregisterProviderSupport( type_found );
        }
       
        DHTNetworkPositionProvider[]  new_providers = new DHTNetworkPositionProvider[providers.length + 1 ];
       
        System.arraycopy( providers, 0, new_providers, 0, providers.length );
       
        new_providers[providers.length] = provider;
       
        providers  = new_providers;
       
        if ( storage_adapter != null ){
       
          startUp( provider );
        }
       
        fire_added = true;
      }
    }
   
    if ( fire_added ){
     
      for ( DHTNetworkPositionProviderListener l: provider_listeners ){
       
        try{
         
          l.providerAdded( provider );
         
        }catch( Throwable e ){
         
          Debug.out( e );
        }
      }
    }
   
    return( new DHTNetworkPositionProviderInstance()
        { 
          public void
          log(
            String    log )
          {
            DHTLog.log("NetPos " + provider.getPositionType() + ": " + log );
          }
        });
  }
 
  public static void
  unregisterProvider(
    DHTNetworkPositionProvider  provider )
  {
    if ( unregisterProviderSupport( provider )){
     
      for ( DHTNetworkPositionProviderListener l: provider_listeners ){
       
        try{
         
          l.providerRemoved( provider );
         
        }catch( Throwable e ){
         
          Debug.out( e );
        }
      }
    }
  }
 
  private static boolean
  unregisterProviderSupport(
    DHTNetworkPositionProvider  provider )
  {
    boolean  removed = false;
   
    synchronized( providers ){
 
      if ( providers.length == 0 ){
       
        return( false );
      }
     
      DHTNetworkPositionProvider[]  new_providers = new DHTNetworkPositionProvider[providers.length - 1 ];

      int  pos = 0;
     
      for ( int i=0;i<providers.length;i++){
       
        if ( providers[i] == provider ){
         
          if ( storage_adapter != null ){
           
            shutDown( provider );
          }
        }else{
         
          new_providers[pos++] = providers[i];
        }
      }
      if ( pos == new_providers.length ){
     
        providers = new_providers;
       
        removed = true;
      }
    }

    return( removed );
  }
 
  public static DHTNetworkPositionProvider
  getProvider(
    byte    type )
  {
    synchronized( providers ){

      for (int i=0;i<providers.length;i++){
       
        if ( providers[i].getPositionType() == type ){
         
          return( providers[i] );
        }
      }
    }
   
    return( null );
  }
 
  public static DHTNetworkPosition[]
  getLocalPositions()
  {
    DHTNetworkPositionProvider[]  prov = providers;
   
    List<DHTNetworkPosition> res = new ArrayList<DHTNetworkPosition>();
   
    for (int i=0;i<prov.length;i++){
     
      try{
        DHTNetworkPosition  pos = prov[i].getLocalPosition();
       
        if ( pos != null ){
         
          res.add( pos );
        }
      }catch( Throwable e ){
       
        Debug.printStackTrace(e);
      }
    }
   
    return( res.toArray(new DHTNetworkPosition[res.size()]));

  }
 
  public static DHTNetworkPosition
  getBestLocalPosition()
  {
    DHTNetworkPosition  best_position = null;
   
    DHTNetworkPosition[]  positions = getLocalPositions();
   
    byte  best_provider = DHTNetworkPosition.POSITION_TYPE_NONE;

    for (int i=0;i<positions.length;i++){
     
      DHTNetworkPosition  position = positions[i];
     
      int  type = position.getPositionType();
     
      if ( type > best_provider ){
       
        best_position = position;
      }
    }
   
    return( best_position );
  }
 
  public static DHTNetworkPosition[]
  createPositions(
    byte[]    ID,
    boolean    is_local )
  {
    DHTNetworkPositionProvider[]  prov = providers;
   
    DHTNetworkPosition[]  res = new DHTNetworkPosition[prov.length];
   
    int  skipped  = 0;
   
    for (int i=0;i<res.length;i++){
     
      try{
        res[i] = prov[i].create( ID, is_local );
       
      }catch( Throwable e ){
       
        Debug.printStackTrace(e);
       
        skipped++;
      }
    }
   
    if  ( skipped > 0 ){
     
      DHTNetworkPosition[] x  = new DHTNetworkPosition[ res.length - skipped ];
     
      int  pos = 0;
     
      for (int i=0;i<res.length;i++){
       
        if ( res[i] != null ){
         
          x[pos++] = res[i];
        }
      }
     
      res  = x;
     
      if ( res.length == 0 ){
       
        Debug.out( "hmm" );
      }
    }
   
    return( res );
  }
 
  public static float
  estimateRTT(
    DHTNetworkPosition[]    p1s,
    DHTNetworkPosition[]    p2s )
  {
    byte  best_provider = DHTNetworkPosition.POSITION_TYPE_NONE;
   
    float  best_result  = Float.NaN;
   
    for (int i=0;i<p1s.length;i++){
     
      DHTNetworkPosition  p1 = p1s[i];
     
      byte  p1_type = p1.getPositionType();
     
      for (int j=0;j<p2s.length;j++){
       
        DHTNetworkPosition  p2 = p2s[j];
       
        if ( p1_type == p2.getPositionType()){
         
          try{
            float  f = p1.estimateRTT( p2 );
           
            if ( !Float.isNaN( f )){
             
              if ( p1_type > best_provider ){
               
                best_result    = f;
                best_provider  = p1_type;
              }
            }
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
         
          break;
        }
      }
    }
   
    return( best_result );
  }
 
  public static void
  update(
    DHTNetworkPosition[]  local_positions,
    byte[]          remote_id,
    DHTNetworkPosition[]  remote_positions,
    float          rtt )
  { 
    for (int i=0;i<local_positions.length;i++){
     
      DHTNetworkPosition  p1 = local_positions[i];
           
      for (int j=0;j<remote_positions.length;j++){
       
        DHTNetworkPosition  p2 = remote_positions[j];
       
        if ( p1.getPositionType() == p2.getPositionType()){
         
          try{
            p1.update( remote_id, p2, rtt );
           
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
         
          break;
        }
      }
    }
  }
 
  public static byte[]
  serialisePosition(
    DHTNetworkPosition  pos )
 
    throws IOException
  {
    ByteArrayOutputStream  baos = new ByteArrayOutputStream();
   
    DataOutputStream  dos = new DataOutputStream( baos );
 
    dos.writeByte( 1 )// version
    dos.writeByte( pos.getPositionType());
   
    pos.serialise( dos );
   
    dos.close();
   
    return( baos.toByteArray());
  }
 
  public static DHTNetworkPosition
     deserialisePosition(
       InetAddress        originator,
       byte[]          bytes )
    
       throws IOException
     {
       ByteArrayInputStream  bais = new ByteArrayInputStream( bytes );
      
       DataInputStream  dis = new DataInputStream( bais );
    
       dis.readByte()// version
      
       byte  position_type = dis.readByte();
      
       return( deserialise( originator, position_type, dis ));
     }
 
  public static DHTNetworkPosition
  deserialise(
    InetAddress        originator,
    byte          position_type,
    DataInputStream      is )
 
    throws IOException
  {
    DHTNetworkPositionProvider[]  prov = providers;

    is.mark( 512 );

    for (int i=0;i<prov.length;i++){
     
      if ( prov[i].getPositionType() == position_type ){
       
        DHTNetworkPositionProvider  provider = prov[i];
       
        try{
          DHTNetworkPosition np = provider.deserialisePosition( is );
         
          CopyOnWriteList<DHTNetworkPositionListener> listeners = position_listeners;
         
          if ( listeners != null ){
           
            Iterator<DHTNetworkPositionListener> it = listeners.iterator();
           
            while( it.hasNext()){
             
              try{
                it.next().positionFound( provider, originator, np );
               
              }catch( Throwable e ){
               
                Debug.printStackTrace(e);
              }
            }
          }
         
          return( np );
         
        }catch( Throwable e ){
         
          Debug.printStackTrace(e);
         
          is.reset();
        }
       
        break;
      }
    }
   
    return( null );
  }
 
  public static void
  addPositionListener(
    DHTNetworkPositionListener    listener )
  {
    synchronized( DHTNetworkPositionManager.class ){
   
      if ( position_listeners == null ){
       
        position_listeners = new CopyOnWriteList<DHTNetworkPositionListener>();
      }
     
      position_listeners.add( listener );
    }
  }
 
  public static void
  removePositionListener(
    DHTNetworkPositionListener    listener )
  {
    synchronized( DHTNetworkPositionManager.class ){
   
      if ( position_listeners != null ){
       
        position_listeners.remove( listener );
       
        if ( position_listeners.size() == 0 ){
         
          position_listeners = null;
        }
      }
    }
  }
 
  public static void
  addProviderListener(
    DHTNetworkPositionProviderListener    listener )
  {
    provider_listeners.add( listener );
  }
 
  public static void
  removeProviderListener(
    DHTNetworkPositionProviderListener    listener )
  {
    provider_listeners.remove( listener );
  }
}
TOP

Related Classes of com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.