Mercurial > hg > Applications > TreeVNC
view src/main/java/jp/ac/u_ryukyu/treevnc/TreeManagement.java @ 470:f7210f834403
add unique node id
author | mir3636 |
---|---|
date | Wed, 03 Aug 2016 19:09:11 +0900 |
parents | a817fa255673 |
children | 89f1f7e41838 |
line wrap: on
line source
package jp.ac.u_ryukyu.treevnc; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.LinkedList; public class TreeManagement { private final int treeId; public LinkedList<TreeVNCNode> nodeList = new LinkedList<TreeVNCNode>(); public LinkedList<NetworkAddress> treeAddresses = new LinkedList<NetworkAddress>(); private final int treebranch = 2; private boolean showTreeNode = false; // node id // ttttnnnnnnnnnnnn // tttt 4bit tree number // nnnnnnnnnnnn 12bit node number public final int MAX_TREE = 15; public final int MAX_TREE_NODE = (1<<12)-1; public TreeManagement(String hostName, int vncport, boolean showTree, int id) { treeId = id; TreeVNCNode me = new TreeVNCNode(hostName, vncport,"localhost"); showTreeNode = showTree; me.setTreeNum(0); nodeList.add(me); } private class NetworkAddress { InetAddress inetaddress; byte [] address; byte [] netmask; public NetworkAddress(InetAddress ipaddress, byte[] netaddress, byte[] netmask) { inetaddress = ipaddress; address = netaddress; this.netmask = netmask; } } public int getTreeId() { return treeId; } /** * a parent is lost, remove from the list and move last one into here * @param nodeNum * parent value */ public void moveLastNodeToLostNodePosition(int nodeNum) { nodeList.remove(nodeNum); if (nodeNum != nodeList.size()) { TreeVNCNode node = nodeList.removeLast(); node.setTreeNum(nodeNum); nodeList.add(nodeNum, node); } } private void checkParameter(int parent, int counter, int leaderflag2) { System.out.print("number p =" + parent); System.out.print(" number i =" + counter); System.out.println(" leaderflag=" + leaderflag2 + "\n"); } private TreeVNCNode getParentNode(int nodeNum) { int parentnum = (nodeNum - 1) / treebranch; return nodeList.get(parentnum); } public TreeVNCNode getChildNode(TreeVNCNode newparent, int i) { int child = newparent.getTreeNum() * treebranch + i + 1; if (child >= nodeList.size()) { return(null); } else { return(nodeList.get(child)); } } /** * A parent is lost, move last node which has no child to the position * @param hostname * @param port * @param myHostName */ public void fixLostParent(String hostname, int port, String myHostName) { TreeVNCNode lostParentNode = lookup(nodeList,hostname,port); if (lostParentNode == null ) return; // something wrong int treeNumber = lostParentNode.getTreeNum(); TreeVNCNode deadParent = getParentNode(treeNumber); TreeVNCNode me = nodeList.getFirst(); me.setHostName(myHostName); if (deadParent.getTreeNum() == 0) { // if dead root, connect me. try { connectTo(me, lostParentNode); } catch (IOException e) { e.printStackTrace(); } return; } if (getChildNode(deadParent, 0) == null) return; moveLastNodeToLostNodePosition(deadParent.getTreeNum()); lostNodeConnection(deadParent); // if lostParentNode is the last one, we don't need reconnection // Thread.sleep(intv_time); } public void fixLostChild(String hostname, int port, String myHostName, int clientId) { TreeVNCNode lostChildNode = lookup(nodeList, hostname, port); if (lostChildNode == null) return; int lostChildNodeNum; // if isTreeManager if (lostChildNode.getTreeNum() == 0) { lostChildNodeNum = clientId + 1; } else { lostChildNodeNum = (lostChildNode.getTreeNum() * treebranch) + clientId + 1; } TreeVNCNode deadChild; fixLostChild1(lostChildNodeNum); } public void fixLostChild1(int nodeNum) { TreeVNCNode deadNode; try { deadNode = nodeList.get(nodeNum); } catch (IndexOutOfBoundsException e) { // this node became new node instead of deathChild. deadNode = null; } if (deadNode != null) { moveLastNodeToLostNodePosition(deadNode.getTreeNum()); lostNodeConnection(deadNode); } if (showTreeNode) { showTreeNode(); } } /** * send reconnect to all children * @param deadNode */ public void lostNodeConnection(TreeVNCNode deadNode) { if (nodeList.size() < deadNode.getTreeNum()+1) { return; } TreeVNCNode newNode = nodeList.get(deadNode.getTreeNum()); TreeVNCNode parentNode = getParentNode(newNode.getTreeNum()); // new node connect to parent node. try { connectTo(parentNode, newNode); } catch (IOException e) { e.printStackTrace(); } // if children node exist, children connect to new node. for(int i=0; i < treebranch; i++) { TreeVNCNode child = getChildNode(newNode, i); if (child != null) { try { connectTo(newNode, child); } catch (IOException e) { e.printStackTrace(); } } } } public void connectTo(TreeVNCNode newparent, TreeVNCNode n) throws IOException { TreeVncProtocol vc1 = new TreeVncProtocol(n.getHostname(),n.getPort()); short nodeId = (short) n.getId(); vc1.connectTo(newparent.getHostname(), newparent.getPort(), isLeader(n), nodeId); } private int isLeader(TreeVNCNode n) { return ( n.getTreeNum() % treebranch == 1) ? 1 : 0; } private TreeVNCNode lookup(LinkedList<TreeVNCNode> list, String hostname, int port) { for (TreeVNCNode r : list) { if (r.getHostname().equals(hostname) && r.getPort() == port ) return r; } return null; } /** * Determine tree topology and send CONNECT_TO command * @param hostname * @param port * @param id */ public void decideWhereToConnect(String hostname, int port, String localhostname, int id) { TreeVNCNode node = new TreeVNCNode(hostname, port, localhostname); node.setTreeNum(nodeList.size()); node.setId(id); InetAddress ipAddress = null; try { ipAddress = InetAddress.getByName(hostname); } catch (UnknownHostException e) { System.out.println("root : whereToConnect : cannot get ipAddress" + hostname); return; } if (onTheSameNetwork(ipAddress)) nodeList.add(node); if (nodeList.size() >= treebranch + 1) { TreeVNCNode parent = getParentNode(node.getTreeNum()); checkParameter(parent.getTreeNum(), nodeList.size(), isLeader(node)); try { connectTo(parent, node); } catch (IOException e) { nodeList.remove(node); System.out.println("root : whereToConnect : Connection Faild" + hostname); return; } } else { // connect to me TreeVNCNode me = nodeList.getFirst(); me.setHostName(localhostname); try { connectTo(me, node); } catch (IOException e) { nodeList.remove(node); System.out.println("root : whereToConnect : Connection Faild" + hostname); return; } } if (showTreeNode) { showTreeNode(); } } /** * show Tree Node. */ public void showTreeNode() { int nl = 0, pow = 2; for (int i=0; i<nodeList.size(); i++) { TreeVNCNode treeNode = nodeList.get(i); System.out.print(treeNode.getTreeNum() + ":" + treeNode.getPort() + ":" + treeNode.getHostname()); if (i==nl) { System.out.println(); nl = nl + pow; pow = pow * pow; } else { System.out.print(" "); } } System.out.println(); } public LinkedList<TreeVNCNode> getList() { return nodeList; } public void setList(LinkedList<TreeVNCNode> _ls) { nodeList = _ls; } public int getTreeBranch() { return treebranch; } public void setNetMask(byte[] netmask, byte[] netaddress, InetAddress ipaddress) { treeAddresses.add(new NetworkAddress(ipaddress,netaddress,netmask) ); } public boolean onTheSameNetwork(InetAddress adr) { byte [] byteadr = adr.getAddress(); for (NetworkAddress n : treeAddresses) { byte [] netmask = n.netmask; byte [] netaddress = n.address; if (byteadr.length != netmask.length) continue; int i; for (i = 0; i < netmask.length; i++) { if ((netmask[i] & byteadr[i]) != netaddress[i]) break; } if (i < netmask.length) continue; return true; } return false; } }