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); }
/** 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 }