private void ForwardDataDown(DataDownMessage msg) { // forward the message down based on the destination supernode id // find the appropriate direction (left or right?) based on ddMsg.DestinationSupernode // find the corresponding supernode id // forward the message to all connected nodes in the supernode var nextHops = (from NodeConnection nc in InternalConnections where nc.FromSupernode == msg.NextSupernode && nc.Direction == NodeConnectionDirection.Down select nc).ToArray(); if (nextHops.Length != 2) { throw new Exception("Invalid node connection information: node " + Id); } NodeConnection leftConnection, rightConnection; if (nextHops[0].ToSupernode < nextHops[1].ToSupernode) { leftConnection = nextHops[0]; rightConnection = nextHops[1]; } else { leftConnection = nextHops[1]; rightConnection = nextHops[0]; } NodeConnection nextHop; var dir = (msg.DestinationSupernode % netWidth) >> (netHeight - (msg.NextSupernode / netWidth) - 2); if (dir % 2 == 0) { nextHop = leftConnection; } else { nextHop = rightConnection; } var nextHopDown = nextHop as DownNodeConnection; if (nextHopDown == null) { throw new Exception("Invalid node connection information: node " + Id); } msg.NextSupernode = nextHopDown.ToSupernode; msg.BackPath.Push(new BackConnection() { NodeId = Id, FromSupernode = nextHopDown.ToSupernode }); foreach (var nextHopNodeId in nextHopDown.NodeIds) { Send(nextHopNodeId, msg, 100); } }
public void Search(IDataItem <T> query) { if (SearchStarted != null) { SearchStarted(this); } var bottomSupernodeIndexes = HashBottomSupernodes(query, B); foreach (var topConnection in TopConnections) { foreach (var topNodeId in topConnection.NodeIds) { foreach (var bottomSupernodeIndex in bottomSupernodeIndexes) { // follow the path from topSuperNode to bottomSuperNode var msg = new DataDownMessage( bottomSupernodeIndex, topConnection.ToSupernode, query); msg.BackPath.Push(new BackConnection() { NodeId = Id, FromSupernode = topConnection.ToSupernode }); Send(topNodeId, msg, 100); } } } }