Ejemplo n.º 1
0
        public void UpdateSystem()
        {
            var stcons = ConnectionTable.GetConnections(ConnectionType.Structured);
            var lfcons = ConnectionTable.GetConnections(ConnectionType.Leaf);

            _ahstate = new AHHandler.AHState(Address, stcons, lfcons);
        }
Ejemplo n.º 2
0
        /** 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)));
        }
Ejemplo n.º 3
0
        /**
         * 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");
        }
Ejemplo n.º 5
0
        /**
         * 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");
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        /**
         * 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));
        }
Ejemplo n.º 9
0
        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!");
        }
Ejemplo n.º 10
0
    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!");
    }
Ejemplo n.º 11
0
        /**
         * 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);
            }
        }
Ejemplo n.º 12
0
    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!");
    }
Ejemplo n.º 13
0
        /**
         * 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);
            }
        }
Ejemplo n.º 15
0
        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!");
        }