public void UpdateSystem() { var stcons = ConnectionTable.GetConnections(ConnectionType.Structured); var lfcons = ConnectionTable.GetConnections(ConnectionType.Leaf); _ahstate = new AHHandler.AHState(Address, stcons, lfcons); }
/** Greedy routing. gen_arg is the Address of the destination */ public override void GenerateTree(Channel q, MapReduceArgs mr_args) { object gen_arg = mr_args.GenArg; Log("{0}: {1}, greedy generator called, arg: {2}.", this.TaskName, _node.Address, gen_arg); string address = gen_arg as string; AHAddress a = (AHAddress)AddressParser.Parse(address); ArrayList retval = new ArrayList(); ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); Connection next_closest = structs.GetNearestTo((AHAddress)_node.Address, a); if (next_closest != null) { //arguments do not change at all MapReduceInfo mr_info = new MapReduceInfo(next_closest.Edge, mr_args); retval.Add(mr_info); } Log("{0}: {1}, greedy generator returning: {2} senders.", this.TaskName, _node.Address, retval.Count); //Send the result: q.Enqueue(retval.ToArray(typeof(MapReduceInfo))); }
/** * Generates tree for bounded broadcast. Algorithm works as follows: * The goal is to broadcast to all nodes in range (start, end). * Given a range (a, b), determine all connections that belong to this range. * Let the left connections be l_1, l_2, ..... l_n. * Let the right connections be r_1, r_2, ... , r_n. * To left connection l_i assign the range [b_{i-1}, b_i). * To right connection r_i assign the range [r_i, r_{i-1}] * To the connection ln assign range [l_{n-1}, end) * To the connection rn assign range (start, r_{n-1}] */ public override void GenerateTree(Channel q, MapReduceArgs mr_args) { ArrayList gen_list = mr_args.GenArg as ArrayList; string start_range = gen_list[0] as string; AHAddress start_addr = (AHAddress)AddressParser.Parse(start_range); AHAddress end_addr; string end_range; /// If users do not specify an end range, this method understands /// that users intend to broadcasting the whole range. /// Thus, the address of end range is set to (start_address - 2), /// the farthest address from the start_addr. if (gen_list.Count < 2) { BigInteger start_int = start_addr.ToBigInteger(); BigInteger end_int = start_int - 2; end_addr = new AHAddress(end_int); end_range = end_addr.ToString(); } else { end_range = gen_list[1] as string; end_addr = (AHAddress)AddressParser.Parse(end_range); } Log("generating child tree, range start: {0}, range end: {1}.", start_range, end_range); //we are at the start node, here we go: ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); List <MapReduceInfo> retval = new List <MapReduceInfo>(); if (InRange(_this_addr, start_addr, end_addr)) { if (structs.Count > 0) { //make connection list in the range. //left connection list is a list of neighbors which are in the range (this node, end of range) //right connection list is a list of neighbors which are in the range (start of range, this node) Brunet.Collections.Pair <List <Connection>, List <Connection> > cons = GetConnectionInfo(_this_addr, start_addr, end_addr, structs); List <Connection> left_cons = cons.First as List <Connection>; List <Connection> right_cons = cons.Second as List <Connection>; //PrintConnectionList(left_cons); //PrintConnectionList(right_cons); retval = GenerateTreeInRange(start_addr, end_addr, left_cons, true, mr_args); List <MapReduceInfo> ret_right = GenerateTreeInRange(start_addr, end_addr, right_cons, false, mr_args); retval.AddRange(ret_right); } else //this node is a leaf node. //MapReduceInfo mr_info = null; //retval.Add(mr_info); //Console.WriteLine("no connection in the range: return null info"); { } } else // _node is out of range. Just pass it to the closest to the middle of range. { retval = GenerateTreeOutRange(start_addr, end_addr, mr_args); } q.Enqueue(retval.ToArray()); }
/// Determine if there are any unuseful STRUC_SHORT that we can trim protected void TrimConnections() { if (_shortcuts <= 2 * DesiredShortcuts) { return; } lock ( _sync ) { TimeSpan elapsed = DateTime.UtcNow - _last_connection_time; if (elapsed.TotalSeconds < TRIM_DELAY) { return; } } ArrayList trim_candidates = new ArrayList(); ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); foreach (Connection c in structs) { if (!c.ConType.Equals(STRUC_SHORT)) { continue; } int left_pos = structs.LeftInclusiveCount(_node.Address, c.Address); int right_pos = structs.RightInclusiveCount(_node.Address, c.Address); // Verify that this shortcut is not close if (left_pos >= DESIRED_NEIGHBORS && right_pos >= DESIRED_NEIGHBORS) { trim_candidates.Add(c); } } /* * The maximum number of shortcuts we allow is log N, * but we only want 1. This gives some flexibility to * prevent too much edge churning */ if (trim_candidates.Count <= 2 * DesiredShortcuts) { return; } /** * @todo use a better algorithm here, such as Nima's * algorithm for biasing towards more distant nodes: */ //Delete a random trim candidate: int idx = _rand.Next(trim_candidates.Count); Connection to_trim = (Connection)trim_candidates[idx]; #if POB_DEBUG Console.Error.WriteLine("Attempt to trim Shortcut: {0}", to_trim); #endif _node.GracefullyClose(to_trim.Edge, "SCO, shortcut connection trim"); }
/** * Recursive function to compute the latency of an Rpc call * by accumulating measured latencies of individual hops. * @param target address of the target */ public void ComputePathLatencyTo(AHAddress a, object req_state) { /* * First find the Connection pointing to the node closest to dest, if * there is one closer than us */ ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); Connection next_closest = structs.GetNearestTo((AHAddress)_node.Address, a); //Okay, we have the next closest: ListDictionary my_entry = new ListDictionary(); my_entry["node"] = _node.Address.ToString(); if (next_closest != null) { my_entry["next_latency"] = GetMeasuredLatency(next_closest.Address); my_entry["next_contype"] = next_closest.ConType; Channel result = new Channel(); //We only want one result, so close the queue after we get the first result.CloseAfterEnqueue(); result.CloseEvent += delegate(object o, EventArgs args) { Channel q = (Channel)o; if (q.Count > 0) { try { RpcResult rres = (RpcResult)q.Dequeue(); IList l = (IList)rres.Result; ArrayList results = new ArrayList(l.Count + 1); results.Add(my_entry); results.AddRange(l); _rpc.SendResult(req_state, results); } catch (Exception x) { string m = String.Format("<node>{0}</node> trying <connection>{1}</connection> got <exception>{2}</exception>", _node.Address, next_closest, x); Exception nx = new Exception(m); _rpc.SendResult(req_state, nx); } } else { //We got no results. IList l = new ArrayList(1); l.Add(my_entry); _rpc.SendResult(req_state, l); } }; _rpc.Invoke(next_closest.Edge, result, "ncserver.ComputePathLatencyTo", a.ToString()); } else { //We are the end of the line, send the result: ArrayList l = new ArrayList(); l.Add(my_entry); _rpc.SendResult(req_state, l); } }
/// Determine if there are any unuseful STRUC_NEAR that we can trim protected void TrimConnections() { ConnectionTable tab = _node.ConnectionTable; ConnectionList cons = tab.GetConnections(ConnectionType.Structured); ArrayList trim_candidates = new ArrayList(); foreach (Connection c in cons) { if (!c.ConType.Equals(STRUC_NEAR)) { continue; } int left_pos = cons.LeftInclusiveCount(_node.Address, c.Address); int right_pos = cons.RightInclusiveCount(_node.Address, c.Address); if (right_pos >= 2 * DESIRED_NEIGHBORS && left_pos >= 2 * DESIRED_NEIGHBORS) { //These are near neighbors that are not so near trim_candidates.Add(c); } } if (trim_candidates.Count == 0) { return; } //Delete a farthest trim candidate: BigInteger biggest_distance = new BigInteger(0); BigInteger tmp_distance = new BigInteger(0); Connection to_trim = null; foreach (Connection tc in trim_candidates) { AHAddress t_ah_add = (AHAddress)tc.Address; tmp_distance = t_ah_add.DistanceTo((AHAddress)_node.Address).abs(); if (tmp_distance > biggest_distance) { biggest_distance = tmp_distance; //Console.Error.WriteLine("...finding far distance for trim: {0}",biggest_distance.ToString() ); to_trim = tc; } } #if POB_DEBUG Console.Error.WriteLine("Attempt to trim Near: {0}", to_trim); #endif _node.GracefullyClose(to_trim.Edge, "SCO, near connection trim"); }
protected Connection NextGreedyClosest(AHAddress dest) { /* * First find the Connection pointing to the node closest * from local to dest, * if there is one closer than us */ ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); AHAddress local = (AHAddress)_node.Address; Connection next_closest = structs.GetNearestTo(local, dest); return(next_closest); }
/** * return a status message for this node. * Currently this provides neighbor list exchange * but may be used for other features in the future * such as network size estimate sharing. * @param con_type_string string representation of the desired type. * @param addr address of the new node we just connected to. */ virtual public StatusMessage GetStatus(string con_type_string, Address addr) { ArrayList neighbors = new ArrayList(); //Get the neighbors of this type: /* * Send the list of all neighbors of this type. * @todo make sure we are not sending more than * will fit in a single packet. */ ConnectionType ct = Connection.StringToMainType(con_type_string); foreach (Connection c in _connection_table.GetConnections(ct)) { neighbors.Add(NodeInfo.CreateInstance(c.Address)); } return(new StatusMessage(con_type_string, neighbors)); }
public void Test() { ITunnelOverlap _ito = new SimpleTunnelOverlap(); Address addr_x = new AHAddress(new RNGCryptoServiceProvider()); byte[] addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (Address.Full / 2)); Address.SetClass(addrbuff, AHAddress._class); Address addr_y = new AHAddress(addrbuff); ArrayList addresses = new ArrayList(); ConnectionTable ct_x = new ConnectionTable(); ConnectionTable ct_y = new ConnectionTable(); ConnectionTable ct_empty = new ConnectionTable(); for (int i = 1; i <= 10; i++) { addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (i * Address.Full / 16)); Address.SetClass(addrbuff, AHAddress._class); addresses.Add(new AHAddress(addrbuff)); TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://158.7.0.1:5000"); Edge fe = new FakeEdge(ta, ta, TransportAddress.TAType.Tcp); ct_x.Add(new Connection(fe, addresses[i - 1] as AHAddress, "structured", null, null)); if (i == 10) { ct_y.Add(new Connection(fe, addresses[i - 1] as AHAddress, "structured", null, null)); } } ConnectionType con_type = ConnectionType.Structured; IDictionary id = _ito.GetSyncMessage(null, addr_x, ct_x.GetConnections(con_type)); Assert.AreEqual(_ito.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0].Address, addresses[9], "Have an overlap!"); Assert.AreEqual(_ito.EvaluateOverlap(ct_empty.GetConnections(con_type), id).Count, 0, "No overlap!"); Assert.AreEqual(addresses.Contains(_ito.EvaluatePotentialOverlap(id)), true, "EvaluatePotentialOverlap returns valid!"); }
public void Test() { Address addr_x = new AHAddress(new RNGCryptoServiceProvider()); byte[] addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (Address.Full / 2)); Address.SetClass(addrbuff, AHAddress._class); Address addr_y = new AHAddress(addrbuff); List<Connection> connections = new List<Connection>(); ConnectionTable ct_x = new ConnectionTable(); ConnectionTable ct_y = new ConnectionTable(); ConnectionTable ct_empty = new ConnectionTable(); NCService ncservice = new NCService(); Connection fast_con = null; for(int i = 1; i <= 11; i++) { addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (i * Address.Full / 16)); Address.SetClass(addrbuff, AHAddress._class); Address addr = new AHAddress(addrbuff); Connection con = null; TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://158.7.0.1:5000"); Edge fe = new FakeEdge(ta, ta, TransportAddress.TAType.Tcp); if(i <= 10) { con = new Connection(fe, addr, "structured", null, null); ct_x.Add(con); if(i % 2 == 0) { ncservice.ProcessSample(DateTime.UtcNow, String.Empty, addr, new Point(new double[] {0, 0}, 0), 0, i*10); } } else { fast_con = new Connection(fe, addr, "structured", null, null); ncservice.ProcessSample(DateTime.UtcNow, String.Empty, addr, new Point(new double[] {0, 0}, 0), 0, 5); } if(i == 10) { ct_y.Add(con); } connections.Add(con); } ITunnelOverlap sto = new SimpleTunnelOverlap(); ITunnelOverlap nto = new NCTunnelOverlap(ncservice); ConnectionType con_type = ConnectionType.Structured; List<Connection> pre_cons = new List<Connection>(); pre_cons.Add(connections[9]); IDictionary id = nto.GetSyncMessage(pre_cons, addr_x, ct_x.GetConnections(con_type)); // We do have some pre-existing overlap Assert.AreEqual(nto.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0], connections[9], "NC: Have an overlap!"); Assert.AreEqual(sto.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0], connections[9], "Simple: Have an overlap!"); // We have no overlap with an empty connection table Assert.AreEqual(nto.EvaluateOverlap(ct_empty.GetConnections(con_type), id).Count, 0, "No overlap!"); Assert.AreEqual(sto.EvaluateOverlap(ct_empty.GetConnections(con_type), id).Count, 0, "No overlap!"); // latency[0] == -1 Assert.AreEqual(connections[1].Address.Equals(nto.EvaluatePotentialOverlap(id)), true, "NC: EvaluatePotentialOverlap returns expected!"); Assert.AreEqual(ct_x.Contains(con_type, sto.EvaluatePotentialOverlap(id)), true, "Simple: EvaluatePotentialOverlap returns valid!"); ct_y.Add(fast_con); ct_x.Add(fast_con); id = nto.GetSyncMessage(pre_cons, addr_x, ct_x.GetConnections(con_type)); Assert.AreEqual(fast_con.Address.Equals(nto.EvaluatePotentialOverlap(id)), true, "NC: EvaluatePotentialOverlap returns expected!"); Assert.AreEqual(nto.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0], fast_con, "NC: Have better overlap!"); }
/** * This is a recursive function over the network * It helps do a link-reliable procedure call on the * on the overlay network. */ protected void RecursiveCall(IList margs, object req_state) { //first argument is the target node. AHAddress a = (AHAddress)AddressParser.Parse((string)margs[0]); /* * First find the Connection pointing to the node closest to dest, if * there is one closer than us */ ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); Connection next_closest = structs.GetNearestTo((AHAddress)_node.Address, a); //Okay, we have the next closest: if (next_closest != null) { Channel result = new Channel(); //We only want one result, so close the queue after we get the first result.CloseAfterEnqueue(); result.CloseEvent += delegate(object o, EventArgs args) { Channel q = (Channel)o; if (q.Count > 0) { try { RpcResult rres = (RpcResult)q.Dequeue(); _rpc.SendResult(req_state, rres.Result); } catch (Exception x) { string m = String.Format("<node>{0}</node> trying <connection>{1}</connection> got <exception>{2}</exception>", _node.Address, next_closest, x); Exception nx = new Exception(m); _rpc.SendResult(req_state, nx); } } else { //We got no results. _rpc.SendResult(req_state, null); } }; object [] new_args = new object[margs.Count]; margs.CopyTo(new_args, 0); _rpc.Invoke(next_closest.State.Edge, result, "trace.RecursiveCall", new_args); } else { //We are the end of the line, send the result: //Console.Error.WriteLine("Doing a local invocation"); Channel result = new Channel(); result.CloseAfterEnqueue(); result.CloseEvent += delegate(object o, EventArgs args) { Channel q = (Channel)o; if (q.Count > 0) { try { //Console.Error.WriteLine("Got result."); RpcResult rres = (RpcResult)q.Dequeue(); _rpc.SendResult(req_state, rres.Result); } catch (Exception x) { string m = String.Format("<node>{0}</node> local invocation got <exception>{1}</exception>", _node.Address, x); Exception nx = new Exception(m); _rpc.SendResult(req_state, nx); } } else { //We got no results. _rpc.SendResult(req_state, null); } }; string method_name = (string)margs[1]; object [] new_args = new object[margs.Count - 2]; margs.RemoveAt(0); //extract destination address margs.RemoveAt(0); //extract method name margs.CopyTo(new_args, 0); //Console.Error.WriteLine("Calling method: {0}, args_count: {1}", method_name, new_args.Length); //for (int i = 0; i < new_args.Length; i++) { //Console.Error.WriteLine(new_args[i]); //} _rpc.Invoke(_node, result, method_name, new_args); } }
public void Test() { IRelayOverlap _ito = new SimpleRelayOverlap(); Address addr_x = new AHAddress(new RNGCryptoServiceProvider()); byte[] addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (Address.Full / 2)); Address.SetClass(addrbuff, AHAddress._class); Address addr_y = new AHAddress(addrbuff); ArrayList addresses = new ArrayList(); ConnectionTable ct_x = new ConnectionTable(); ConnectionTable ct_y = new ConnectionTable(); ConnectionTable ct_empty = new ConnectionTable(); for(int i = 1; i <= 10; i++) { addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (i * Address.Full / 16)); Address.SetClass(addrbuff, AHAddress._class); addresses.Add(new AHAddress(addrbuff)); TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://158.7.0.1:5000"); Edge fe = new FakeEdge(ta, ta, TransportAddress.TAType.Tcp); ct_x.Add(new Connection(fe, addresses[i - 1] as AHAddress, "structured", null, null)); if(i == 10) { ct_y.Add(new Connection(fe, addresses[i - 1] as AHAddress, "structured", null, null)); } } ConnectionType con_type = ConnectionType.Structured; IDictionary id = _ito.GetSyncMessage(null, addr_x, ct_x.GetConnections(con_type)); Assert.AreEqual(_ito.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0].Address, addresses[9], "Have an overlap!"); Assert.AreEqual(_ito.EvaluateOverlap(ct_empty.GetConnections(con_type), id).Count, 0, "No overlap!"); Assert.AreEqual(addresses.Contains(_ito.EvaluatePotentialOverlap(id)), true, "EvaluatePotentialOverlap returns valid!"); }
/** * Generates tree for bounded broadcast. Algorithm works as follows: * The goal is to broadcast to all nodes in range [local_address, end). * Given a range [local_address, b), determine all connections that belong to this range. * Let the connections be b_1, b_2, ..... b_n. * To connection bi assign the range [b_i, b_{i+1}). * To the connection bn assign range [b_n, end).] */ public override void GenerateTree(Channel q, MapReduceArgs mr_args) { object gen_arg = mr_args.GenArg; string end_range = gen_arg as string; Log("generating child tree, range end: {0}.", end_range); AHAddress end_addr = (AHAddress)AddressParser.Parse(end_range); AHAddress start_addr = _node.Address as AHAddress; //we are at the start node, here we go: ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); ArrayList retval = new ArrayList(); if (structs.Count > 0) { Connection curr_con = structs.GetLeftNeighborOf(_node.Address); int curr_idx = structs.IndexOf(curr_con.Address); //keep going until we leave the range int count = 0; ArrayList con_list = new ArrayList(); while (count++ < structs.Count && ((AHAddress)curr_con.Address).IsBetweenFromLeft(start_addr, end_addr)) { con_list.Add(curr_con); //Log("adding connection: {0} to list.", curr_con.Address); curr_idx = (curr_idx + 1) % structs.Count; curr_con = structs[curr_idx]; } Log("{0}: {1}, number of child connections: {2}", this.TaskName, _node.Address, con_list.Count); for (int i = 0; i < con_list.Count; i++) { MapReduceInfo mr_info = null; ISender sender = null; Connection con = (Connection)con_list[i]; sender = (ISender)con.Edge; //check if last connection if (i == con_list.Count - 1) { mr_info = new MapReduceInfo((ISender)sender, new MapReduceArgs(this.TaskName, mr_args.MapArg, //map argument end_range, //generate argument mr_args.ReduceArg //reduce argument )); Log("{0}: {1}, adding address: {2} to sender list, range end: {3}", this.TaskName, _node.Address, con.Address, end_range); retval.Add(mr_info); } else { string child_end = ((Connection)con_list[i + 1]).Address.ToString(); mr_info = new MapReduceInfo(sender, new MapReduceArgs(this.TaskName, mr_args.MapArg, child_end, mr_args.ReduceArg)); Log("{0}: {1}, adding address: {2} to sender list, range end: {3}", this.TaskName, _node.Address, con.Address, child_end); retval.Add(mr_info); } } } q.Enqueue(retval.ToArray(typeof(MapReduceInfo))); }
///////////////// Methods ////////////////////// /** * Starts the Overlord if we are active * * This method is called by the CheckState method * IF we have not seen any connections in a while * AND we still need some connections * */ public override void Activate() { #if POB_DEBUG Console.Error.WriteLine("In Activate: {0}", _node.Address); #endif if (IsActive == false) { return; } DateTime now = DateTime.UtcNow; lock ( _sync ) { if (now - _last_retry_time < _current_retry_interval) { //Not time yet... return; } _last_retry_time = now; //Double the length of time we wait (resets to default on connections) _current_retry_interval += _current_retry_interval; _current_retry_interval = (_MAX_RETRY_INTERVAL < _current_retry_interval) ? _MAX_RETRY_INTERVAL : _current_retry_interval; } ConnectionTable tab = _node.ConnectionTable; //If we are going to connect to someone, this is how we //know who to use Address target = null; string contype = String.Empty; ISender sender = null; int desired_ctms = 1; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); if (structs.Count < 2) { ConnectionList leafs = tab.GetConnections(ConnectionType.Leaf); if (leafs.Count == 0) { /* * We first need to get a Leaf connection */ return; } //We don't have enough connections to guarantee a connected //graph. Use a leaf connection to get another connection Connection leaf = null; //Make sure the following loop can't go on forever int attempts = 2 * leafs.Count; do { leaf = leafs[_rand.Next(leafs.Count)]; attempts--; }while(leafs.Count > 1 && structs.Contains(leaf.Address) && attempts > 0); //Now we have a random leaf that is not a //structured neighbor to try to get a new neighbor with: if (leaf != null) { target = GetSelfTarget(); /* * This is the case of trying to find the nodes nearest * to ourselves, use the Annealing routing to get connected * more quickly */ sender = new ForwardingSender(_node, leaf.Address, target); //We are trying to connect to the two nearest nodes in one //one attempt, so wait for two distinct responses: desired_ctms = 2; //This is a near neighbor connection contype = STRUC_NEAR; } } if (structs.Count > 0 && sender == null) { /** * We need left or right neighbors we send * a ConnectToMessage in the directons we * need. */ if (NeedLeftNeighbor) { #if POB_DEBUG Console.Error.WriteLine("NeedLeftNeighbor: {0}", _node.Address); #endif target = new DirectionalAddress(DirectionalAddress.Direction.Left); short ttl = (short)DESIRED_NEIGHBORS; sender = new AHSender(_node, target, ttl, AHHeader.Options.Last); contype = STRUC_NEAR; } else if (NeedRightNeighbor) { #if POB_DEBUG Console.Error.WriteLine("NeedRightNeighbor: {0}", _node.Address); #endif target = new DirectionalAddress(DirectionalAddress.Direction.Right); short ttl = (short)DESIRED_NEIGHBORS; sender = new AHSender(_node, target, ttl, AHHeader.Options.Last); contype = STRUC_NEAR; } } if (sender != null) { ConnectTo(sender, target, contype, desired_ctms); } }
public void Test() { Address addr_x = new AHAddress(new RNGCryptoServiceProvider()); byte[] addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (Address.Full / 2)); Address.SetClass(addrbuff, AHAddress._class); Address addr_y = new AHAddress(addrbuff); List <Connection> connections = new List <Connection>(); ConnectionTable ct_x = new ConnectionTable(); ConnectionTable ct_y = new ConnectionTable(); ConnectionTable ct_empty = new ConnectionTable(); NCService ncservice = new NCService(); Connection fast_con = null; for (int i = 1; i <= 11; i++) { addrbuff = Address.ConvertToAddressBuffer(addr_x.ToBigInteger() + (i * Address.Full / 16)); Address.SetClass(addrbuff, AHAddress._class); Address addr = new AHAddress(addrbuff); Connection con = null; TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://158.7.0.1:5000"); Edge fe = new FakeEdge(ta, ta, TransportAddress.TAType.Tcp); if (i <= 10) { con = new Connection(fe, addr, "structured", null, null); ct_x.Add(con); if (i % 2 == 0) { ncservice.ProcessSample(DateTime.UtcNow, String.Empty, addr, new Point(new double[] { 0, 0 }, 0), 0, i * 10); } } else { fast_con = new Connection(fe, addr, "structured", null, null); ncservice.ProcessSample(DateTime.UtcNow, String.Empty, addr, new Point(new double[] { 0, 0 }, 0), 0, 5); } if (i == 10) { ct_y.Add(con); } connections.Add(con); } IRelayOverlap sto = new SimpleRelayOverlap(); IRelayOverlap nto = new NCRelayOverlap(ncservice); ConnectionType con_type = ConnectionType.Structured; List <Connection> pre_cons = new List <Connection>(); pre_cons.Add(connections[9]); IDictionary id = nto.GetSyncMessage(pre_cons, addr_x, ct_x.GetConnections(con_type)); // We do have some pre-existing overlap Assert.AreEqual(nto.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0], connections[9], "NC: Have an overlap!"); Assert.AreEqual(sto.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0], connections[9], "Simple: Have an overlap!"); // We have no overlap with an empty connection table Assert.AreEqual(nto.EvaluateOverlap(ct_empty.GetConnections(con_type), id).Count, 0, "No overlap!"); Assert.AreEqual(sto.EvaluateOverlap(ct_empty.GetConnections(con_type), id).Count, 0, "No overlap!"); // latency[0] == -1 Assert.AreEqual(connections[1].Address.Equals(nto.EvaluatePotentialOverlap(id)), true, "NC: EvaluatePotentialOverlap returns expected!"); Assert.AreEqual(ct_x.Contains(con_type, sto.EvaluatePotentialOverlap(id)), true, "Simple: EvaluatePotentialOverlap returns valid!"); ct_y.Add(fast_con); ct_x.Add(fast_con); id = nto.GetSyncMessage(pre_cons, addr_x, ct_x.GetConnections(con_type)); Assert.AreEqual(fast_con.Address.Equals(nto.EvaluatePotentialOverlap(id)), true, "NC: EvaluatePotentialOverlap returns expected!"); Assert.AreEqual(nto.EvaluateOverlap(ct_y.GetConnections(con_type), id)[0], fast_con, "NC: Have better overlap!"); }