📄 can.java
字号:
Iterator iterator = neighborhood.iterator(); while (iterator.hasNext()) { InetSocketAddress neighbor = (InetSocketAddress) iterator.next(); if ( !neighbor.equals(update.getSource())) { sendRelayUpdate(neighbor, update); } } } /** This method sends a relay of a deep UPDATE message to a neighbor node, containing a copy of the UPDATE. This is shallow by default. */ private void sendRelayUpdate(InetSocketAddress neighbor, Update deepUpdate) { Update update = Update.allocate(deepUpdate.getID(), deepUpdate.getSource(), deepUpdate.getZone(), deepUpdate.getVersion(), deepUpdate.getDepth() - 1); // decrement the StatCollector.addSample(StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_UPDATE, SerializationManager.getPayloadSize(update)); LocalNode.myUDPMessenger.send(mySocketAddress, neighbor, update); } /** Update all neighbors in the given neighborhood with my current state */ private void updateNeighbors(Neighborhood neighborhood) { Iterator iterator = neighborhood.iterator(); // only make it deep if we've reached the DEEP_UPDATE_COUNT value int depth = 0; if (updateCount == 0) { depth = DEPTH; } while (iterator.hasNext()) { InetSocketAddress neighbor = (InetSocketAddress) iterator.next(); sendUpdate(neighbor, depth); } updateCount = (updateCount + 1) % DEEP_UPDATE_COUNT; } /** This method sends an UPDATE message to a neighbor node, containing my current zone, zone version number and depth. When depth is greater than 0, the UPDATE message is marked so as to be relayed further out by my neighbors to their neighbors. */ private void sendUpdate(InetSocketAddress neighbor, int depth) { Update update = Update.allocate(messageID++, mySocketAddress, zone, version, depth); StatCollector.addSample(StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_UPDATE, SerializationManager.getPayloadSize(update)); LocalNode.myUDPMessenger.send(mySocketAddress, neighbor, update); } /** Leave a collective in an orderly manner. A completion message is delivered asynchronously. */ public void leave() { if (active == false) { return; } if ((leaveID != -1) || (joinID != -1)) { retryLeave(); return; } InetSocketAddress suitableNeighbor = neighborhood.getMergeableNeighbor(zone); if (suitableNeighbor == null) { retryLeave(); return; } leaveID = messageID++; Leave leave = Leave.allocate(leaveID, mySocketAddress, zone, neighborhood); StatCollector.addSample(StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_LEAVE, SerializationManager.getPayloadSize(leave)); LocalNode.myUDPMessenger.send(mySocketAddress, suitableNeighbor, leave); } /** Leave */ private void processLeave(Leave leave) { // check no other nodes trying to merge with me, I'm not in middle of joins elsewhere if ((leaveID == -1) && (joinID == -1)) { // set pending zone - augment my neighbourhood leaveID = leave.getID(); int neighborDimension = zone.neighbors(leave.getZone()); // merge the two zones if (neighborDimension != -1) { double[][] currentIntervals = zone.getIntervals(); double[][] arrivalIntervals = leave.getZone().getIntervals(); double[][] newIntervals = new double[DIM][2]; for (int k = 0; k < DIM; k++) { for (int j = 0; j < 2; j++) { if (k == neighborDimension) { newIntervals[k][0] = Math.min(currentIntervals[k][0], arrivalIntervals[k][0]); newIntervals[k][1] = Math.max(currentIntervals[k][1], arrivalIntervals[k][1]); } else { newIntervals[k][0] = currentIntervals[k][0]; newIntervals[k][1] = currentIntervals[k][1]; } } } myPendingZone = new Zone(newIntervals); AcceptLeave acceptLeave = AcceptLeave.allocate(leave.getID(), mySocketAddress); StatCollector.addSample( StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_ACCEPTLEAVE, SerializationManager.getPayloadSize(acceptLeave)); LocalNode.myUDPMessenger.send(mySocketAddress, leave.getSource(), acceptLeave); } else { sendRefuseLeave(leave); } } else { sendRefuseLeave(leave); } } /** Accept leave request */ private void processAcceptLeave(AcceptLeave acceptLeave) { if ((leaveID != -1) && (leaveID == acceptLeave.getID())) { active = false; leaveID = -1; // tell my neighbors to take me off their list Iterator iterator = neighborhood.iterator(); while (iterator.hasNext()) { LeaveUpdate lu = LeaveUpdate.allocate(messageID++, mySocketAddress); InetSocketAddress neighbor = (InetSocketAddress) iterator.next(); StatCollector.addSample( StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_LEAVEUPDATE, SerializationManager.getPayloadSize(lu)); LocalNode.myUDPMessenger.send(mySocketAddress, neighbor, lu); } // after graceful leave call all global clients that leave has occured Iterator clientIterator = localClients.iterator(); while (clientIterator.hasNext()) { LocationServiceClient client = (LocationServiceClient) clientIterator.next(); client.locationMapChange(); } // sends completeleave message LeaveComplete leaveComplete = LeaveComplete.allocate(acceptLeave.getID(), mySocketAddress); StatCollector.addSample( StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_LEAVECOMPLETE, SerializationManager.getPayloadSize(leaveComplete)); LocalNode.myUDPMessenger.send(mySocketAddress, acceptLeave.getSource(), leaveComplete); LocalNode.myUDPMessenger.release(portNumber); } } /** Leave update */ private void processLeaveUpdate(LeaveUpdate lu) { neighborhood.remove(lu.getSource()); } /** complete leave !! */ private void processLeaveComplete(LeaveComplete cl) { if ((leaveID != -1) && (cl.getID() == leaveID)) { // send new zone, inform neighbors, set data zone = myPendingZone; version++; leaveID = -1; updateNeighbors(neighborhood); } } private void sendRefuseLeave(Leave leave) { RefuseLeave refuseLeave = RefuseLeave.allocate(leave.getID(), mySocketAddress); StatCollector.addSample( StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_REFUSELEAVE, SerializationManager.getPayloadSize(refuseLeave)); LocalNode.myUDPMessenger.send(mySocketAddress, leave.getSource(), refuseLeave); } /** Refuse leave message. Happens when the node opposite busy or whatever. */ private void processRefuseLeave(RefuseLeave refuseLeave) { if ((leaveID != -1) && (leaveID == refuseLeave.getID())) { retryLeave(); } } private void retryLeave() { leaveID = -1; double sleepyTime = LocalNode.myRandom.nextDouble() * (MAX_RETRY - MIN_RETRY) + MIN_RETRY; LocalNode.myTimer.schedule(sleepyTime, RETRY_SIGNAL_LEAVE, this); } /** This method forwards a copy of a ROUTE message to a neighbor */ private void sendForward(Route route, InetSocketAddress neighbor) { if (Output.debuggingEnabled) { logger.debug(new LogMessage(new Object[]{ "Sending ROUTE message to ", neighbor})); } StatCollector.addSample(StatVars.NETWORK_OUT, StatVars.LOCATION_SERVICE, StatVars.CAN_ROUTE, SerializationManager.getPayloadSize(route)); LocalNode.myUDPMessenger.send(mySocketAddress, neighbor, route); } /** Process a Lookup reply and informs client */ private void processLookupResponse(LookupResponse lo, boolean local) { Integer messageID = new Integer(lo.getID()); LocationServiceClient client = (LocationServiceClient) lookupResponseClient.remove(messageID); Object requestID = lookupResponseIdentifier.remove(messageID); if (TIMEOUT > 0) { timeoutManager.removeTimeout(messageID); } // Callback the client if (client != null) { client.lookupResult(lo.getAnswer(), requestID, local); } } private BitID getBitID(double[] coordinates) { BitID id = new BitID(); int curPower = 1; int curDim = 0; double curValue = 1 / (Math.pow(2, curPower)); double[] workingCoordinates = new double[DIM]; for (int i = 0; i < DIM; i++) { workingCoordinates[i] = coordinates[i]; } for (int i = idLength - 1; i > 0; i--) { if (workingCoordinates[curDim] >= curValue) { id.set(i); workingCoordinates[curDim] -= curValue; } curDim++; if (curDim == DIM) { curDim = 0; curPower++; curValue = 1 / (Math.pow(2, curPower)); } } return id; } /** * Convert a sequence of bits to CAN coordinates * @param identifier the array of bits * @return CAN routeable coordinates */ private double[] getCoordinates(BitID identifier) { int curCoord = 0; double[] coordinates = new double[DIM]; long[] maxVal = new long[DIM]; long[] curVal = new long[DIM]; for (int i = idLength - 1; i > 0; i--) { curVal[curCoord] <<= 1; if (identifier.get(i)) { curVal[curCoord] += 1; } maxVal[curCoord] = ((maxVal[curCoord] << 1) + 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -