FileDocCategorySizeDatePackage
VivaldiPositionImpl.javaAPI DocAzureus 3.0.3.46093Wed Jan 03 16:43:18 GMT 2007com.aelitis.azureus.core.dht.netcoords.vivaldi.ver1.impl

VivaldiPositionImpl

public class VivaldiPositionImpl extends Object implements VivaldiPosition
Vivaldi Papers : http://www.sigcomm.org/sigcomm2004/papers/p426-dabek111111.pdf

Fields Summary
private static final float
cc
private static final float
ce
private static final float
initial_error
private HeightCoordinatesImpl
coordinates
private float
error
private int
nbUpdates
Constructors Summary
public VivaldiPositionImpl(HeightCoordinatesImpl coordinates)

  
     
    this.coordinates = coordinates;
    error = initial_error;
  
Methods Summary
public booleanequals(java.lang.Object arg0)

   if(arg0 instanceof VivaldiPositionImpl) {
     VivaldiPositionImpl other = (VivaldiPositionImpl) arg0;
     if(other.error != error) return false;
     if(! other.coordinates.equals(coordinates)) return false;
     return true;
   }
   return false;
  
public floatestimateRTT(Coordinates coordinates)

    return this.coordinates.distance(coordinates);
  
public floatestimateRTT(com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition _other)

	  VivaldiPosition	other = (VivaldiPosition)_other;
	  
	  Coordinates other_coords = other.getCoordinates();
	  
	  if ( coordinates.atOrigin() || other_coords.atOrigin()){
		  
		  return( Float.NaN );
	  }
	
	  return( estimateRTT( other_coords ));
  
public voidfromFloatArray(float[] data)

	  
	  coordinates = new HeightCoordinatesImpl( data[0], data[1], data[2] );
	  
	  error			= data[3];
  
public CoordinatesgetCoordinates()

    return coordinates;
  
public floatgetErrorEstimate()

   return error;
  
public bytegetPositionType()

	  return( DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1 );
  
public intgetSerialisedSize()

	  return( 16 ); 	// 4 floats
  
public booleanisValid()

	  return( (!Float.isNaN( getErrorEstimate())) && getCoordinates().isValid());
  
public voidserialise(java.io.DataOutputStream os)

	float[]	data = toFloatArray();
		
	for (int i=0;i<data.length;i++){
			
	  os.writeFloat( data[i] );
	}  
  
public voidsetErrorEstimate(float error)

    this.error = error;
   
public float[]toFloatArray()

	  return( new float[]{ coordinates.getX(), coordinates.getY(), coordinates.getH(), error });
  
public java.lang.StringtoString()

    return coordinates +  " : " + error;
  
public voidupdate(byte[] _other_id, com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition _other, float rtt)

    VivaldiPositionImpl	other = (VivaldiPositionImpl)_other;
	  
	Coordinates other_coords = other.getCoordinates();

	update( rtt,  other_coords, other.getErrorEstimate());
  
public voidupdate(float rtt, Coordinates cj, float ej)

	  
	  if ( valid(rtt) && valid(ej) && cj.isValid()){
		  
		 // System.out.println( "accepted vivaldi update:" + rtt + "/" + cj + "/" + ej );

	    //Ensure we have valid data in input (clock changes lead to crazy rtt values)
	    if(rtt <= 0 || rtt > 5*60*1000 ) return;
	    if(error + ej == 0) return;
	    
	    //Sample weight balances local and remote error. (1)
	    float w = error / (ej + error);
	    
	    //Real error
	    float re = rtt - coordinates.distance(cj);
	    
	    //Compute relative error of this sample. (2)
	    float es = Math.abs(re) / rtt;
	    
	    //Update weighted moving average of local error. (3)
	    
	    float new_error = es * ce * w + error * (1 - ce * w);
	    
	    	//Update local coordinates. (4)
	    
	    float delta = cc * w;
	    
	    float scale = delta * re;
	    
	    HeightCoordinatesImpl random_error = new HeightCoordinatesImpl((float)Math.random()/10,(float)Math.random()/10,0f);
      
	    HeightCoordinatesImpl new_coordinates = (HeightCoordinatesImpl)coordinates.add(coordinates.sub(cj.add(random_error)).unity().scale(scale));
	    
	    if ( valid( new_error ) && new_coordinates.isValid()){
	    	
	    	coordinates = new_coordinates;
	    	
	    	error		= new_error > ERROR_MIN ? new_error : ERROR_MIN;
	    	
	    }else{
	    	
	    	/* not very interesting and occasionally happen...
	    	Debug.out( "VivaldiPosition: resetting as invalid: " + 
	    				coordinates + "/" + error + " + " + rtt + "," + cj + "," + ej + "->" + new_coordinates + "/" + new_error );
	    	*/
	    	
	    	coordinates = new HeightCoordinatesImpl(0,0,0);
	    	error		= initial_error;
	    }
      
      if(! cj.atOrigin()) {
        nbUpdates++;
      }
      if(nbUpdates > CONVERGE_EVERY) {
        nbUpdates = 0;
        update(10,new HeightCoordinatesImpl(0,0,0),CONVERGE_FACTOR);
      }
      
	  }else{
		 // System.out.println( "rejected vivaldi update:" + rtt + "/" + cj + "/" + ej );
	  }
  
public voidupdate(float rtt, float[] data)

	  
	  update( rtt, new HeightCoordinatesImpl( data[0], data[1], data[2] ), data[3] );
  
private booleanvalid(float f)

	  return( !(Float.isInfinite( f ) || Float.isNaN( f )));