Пример #1
0
    public void TestSample() {
      Sample sample = new Sample();
      Assert.IsTrue(sample.GetSample() < 0.0);
      sample.AddSample(DateTime.UtcNow, (double) 100.0, new Point(), (double) 0.001);
      sample.AddSample(DateTime.UtcNow, (double) 100.0, new Point(), (double) 0.002);
      sample.AddSample(DateTime.UtcNow, (double) 100.0, new Point(), (double) 0.003);
      sample.AddSample(DateTime.UtcNow, (double) 100.0, new Point(), (double) 0.004);
      Assert.IsTrue(sample.GetSample() > 0.0);

    }
Пример #2
0
    /** Processing of a latency sample using Vivaldi network coordinate approach. 
     *  @param o_stamp timestamp
     *  @param o_host name of the host from which we got the sample
     *  @param o_neighbor neighbor node from where sample is received
     *  @param o_position position vector of neighbor
     *  @param o_weightedError at the neighbor
     *  @param o_rawLatency latency of the sample
     */
    public void ProcessSample(DateTime o_stamp, string o_host, Address o_neighbor, Point o_position, 
            double o_weightedError, double o_rawLatency) {
      lock(_sync) {
  Sample sample = null;
  if (_samples.ContainsKey(o_neighbor)) {
    sample = (Sample) _samples[o_neighbor];
  } else {
    sample = new Sample();
    _samples[o_neighbor] = sample;
  }

  sample.AddSample(o_stamp, o_rawLatency, o_position, o_weightedError);
  double o_latency = sample.GetSample();
  if (o_latency < 0.0) {
#if NC_DEBUG
    Console.Error.WriteLine("Too few samples to consider.");
#endif
    return;
  }

#if NC_DEBUG
  Console.Error.WriteLine("Sample at: {0}, from: {1} {2}, position: {3}, error: {4}, raw latency: {5}, smooth latency: {6}", 
        o_stamp, o_host, o_neighbor, o_position, o_weightedError, o_rawLatency, o_latency);
#endif
  double o_distance = _vivaldi_state.Position.GetEucledianDistance(o_position);
  while (o_distance == 0) {
    _vivaldi_state.Position.Bump();
    o_distance = _vivaldi_state.Position.GetEucledianDistance(o_position);
  }

#if NC_DEBUG
  Console.Error.WriteLine("Current position: {0}, distance: {1}", _vivaldi_state.Position, o_distance);
#endif
  double o_relativeError = Math.Abs((o_distance - o_latency)/o_latency);
  //double o_rawRelativeError = Math.Abs((o_distance - o_rawLatency)/o_rawLatency);
  double o_weight = _vivaldi_state.WeightedError/(_vivaldi_state.WeightedError + o_weightedError);
  double o_alphaWeightedError = ERROR_FRACTION * o_weight;
      
#if NC_DEBUG
  Console.Error.WriteLine("o_distance: {0}", o_distance);
  Console.Error.WriteLine("o_latency: {0}", o_latency);
  Console.Error.WriteLine("o_relativeError (epsi): {0}", o_relativeError);
  Console.Error.WriteLine("o_weight (w_s): {0}", o_weight);
  Console.Error.WriteLine("my_weighted_error (preupdate)): {0}", _vivaldi_state.WeightedError);
  Console.Error.WriteLine("alpha: {0}", o_alphaWeightedError);
#endif

  _vivaldi_state.WeightedError = (o_relativeError* o_alphaWeightedError) + 
    _vivaldi_state.WeightedError*(1 - o_alphaWeightedError);

#if NC_DEBUG
  Console.Error.WriteLine("my_weighted_error (postupdate)): {0}", _vivaldi_state.WeightedError);
#endif
  if (_vivaldi_state.WeightedError > 1.0) {
    _vivaldi_state.WeightedError = 1.0;
  } 
  if (_vivaldi_state.WeightedError < 0.0) {
    _vivaldi_state.WeightedError = 0.0;
  }
      
  Point o_force = new Point();
  int measurementsUsed = 0;
  DateTime o_oldestSample = o_stamp;
      
  ArrayList valid_nodes = new ArrayList();
  ArrayList invalid_nodes = new ArrayList();
  //only consider nodes we have heard from in "near" past
  foreach(Address node in _samples.Keys) {
    Sample n_sample = (Sample) _samples[node];
    if ((o_stamp - n_sample.TimeStamp).TotalSeconds > SAMPLE_EXPIRATION) {
      //
      // Invalidate node.
      //
      invalid_nodes.Add(node);
      continue;
    }
    
    if (n_sample.GetSample() < 0) {
      //
      // Neither valid nor invalid.
      //
#if NC_DEBUG
      Console.Error.WriteLine("Neither valid nor invalid.");
#endif
      continue;
    }
    
    //
    // valid sample.
    //
    valid_nodes.Add(node);
    if (o_oldestSample > n_sample.TimeStamp) {
      o_oldestSample = n_sample.TimeStamp;
    }
  }
      
  //get rid of invalid nodes.
  for (int k = 0; k < invalid_nodes.Count; k++) {
    Address node = (Address) invalid_nodes[k];
#if NC_DEBUG
    Console.Error.WriteLine("Removing samples from node: {0}", node);
#endif
    _samples.Remove(node);
  }

#if NC_DEBUG
  Console.Error.WriteLine("Initiating force computation.");
#endif   
      
  double o_sampleWeightSum = 0.0f;
  for (int k = 0; k < valid_nodes.Count; k++) {
    Address node = (Address) valid_nodes[k];
    Sample n_sample = (Sample) _samples[node];  
    o_sampleWeightSum += (double) (n_sample.TimeStamp - o_oldestSample).TotalSeconds;
  }

#if NC_DEBUG
  Console.Error.WriteLine("Oldest sample: {0}", o_oldestSample);
  Console.Error.WriteLine("Sample weight sum: {0}", o_sampleWeightSum);
#endif   

     for (int k = 0; k < valid_nodes.Count; k++) {
    Address node = (Address) valid_nodes[k];
    Sample n_sample = (Sample) _samples[node];
    

    double s_distance = _vivaldi_state.Position.GetEucledianDistance(n_sample.Position);
    while (s_distance == 0) {
      _vivaldi_state.Position.Bump();
      s_distance = _vivaldi_state.Position.GetEucledianDistance(n_sample.Position);    
    }

    Point s_unitVector = _vivaldi_state.Position.GetDirection(n_sample.Position);
    if (s_unitVector == null) {
      s_unitVector = Point.GetRandomUnitVector();
    }

    double s_latency = n_sample.GetSample();
    double s_dampening = _vivaldi_state.WeightedError / (_vivaldi_state.WeightedError + n_sample.WeightedError);
    double s_error = s_distance - s_latency;
    double s_sampleWeight = 1.0f;
    double s_sampleNewness = (double) (n_sample.TimeStamp - o_oldestSample).TotalSeconds;
    if (o_sampleWeightSum > 0.0) {
      s_sampleWeight = s_sampleNewness/o_sampleWeightSum;
    }

#if NC_DEBUG
    Console.Error.WriteLine("Force component: {0}", k);
    Console.Error.WriteLine("Unit vector: {0}", s_unitVector);    
    Console.Error.WriteLine("s_distance: {0}", s_distance);
    Console.Error.WriteLine("s_latency: {0}", s_latency);
    Console.Error.WriteLine("s_error: {0}", s_error);
    Console.Error.WriteLine("s_weighted_error (ws): {0}", n_sample.WeightedError);
    Console.Error.WriteLine("s_dampening (ws): {0}", s_dampening);
    Console.Error.WriteLine("s_sampleNewness: {0}", s_sampleNewness);
    Console.Error.WriteLine("s_sampleWeight: {0}", s_sampleWeight);
#endif

    s_unitVector.Scale(s_error * s_dampening * s_sampleWeight);
#if NC_DEBUG
    Console.Error.WriteLine("s_force: {0}", s_unitVector);
#endif 
    o_force.Add(s_unitVector);
    measurementsUsed++;
  }

#if NC_DEBUG
  Console.Error.WriteLine("force (pre-scaling): {0}", o_force);
#endif
  o_force.Height = -o_force.Height;
  o_force.Scale(DAMPENING_FRACTION);

#if NC_DEBUG
  Console.Error.WriteLine("force (post-scaling): {0}", o_force);
#endif
  _vivaldi_state.Position.Add(o_force);
  _vivaldi_state.Position.CheckHeight();

#if NC_DEBUG
  Console.Error.WriteLine("Updated position: {0}, distance: {1}", 
        _vivaldi_state.Position,  
        _vivaldi_state.Position.GetEucledianDistance(o_position));
#endif
      }//end of lock
    }