view src/main/java/alice/topology/fix/FixTopology.java @ 523:145c425db88d dispose

add CompressedLDSM
author Nozomi Teruya <e125769@ie.u-ryukyu.ac.jp>
date Thu, 09 Apr 2015 18:36:26 +0900
parents 80e461aa10e9
children 15eeb439830c 767d93626b88
line wrap: on
line source

package alice.topology.fix;

import java.util.HashMap;
import java.util.LinkedList;

import alice.codesegment.CodeSegment;
import alice.daemon.ConnectionInfo;
import alice.datasegment.CommandType;
import alice.datasegment.Receiver;
import alice.topology.HostMessage;
import alice.topology.manager.Parent;
import alice.topology.manager.ParentManager;

public class FixTopology extends CodeSegment {

    private Receiver info = ids.create(CommandType.TAKE); // disconnection nodeInfo
    private Receiver info1 = ids.create(CommandType.TAKE); // all connection Info
    private Receiver info3 = ids.create(CommandType.TAKE); // IP Table
    private Receiver info4 = ids.create(CommandType.TAKE); // parentManager

    public FixTopology() {
        info.setKey("_DISCONNECTNODE");
        info1.setKey("topology");
        info3.setKey("nameTable");
        info4.setKey("parentManager");
    }

    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        ConnectionInfo lost = info.asClass(ConnectionInfo.class);
        System.out.println(lost.port+" "+lost.nodeName);
        HashMap<String, HostMessage> nameTable = info3.asClass(HashMap.class);
        ParentManager manager = info4.asClass(ParentManager.class);
        HashMap<String, LinkedList<HostMessage>> topology = info1.asClass(HashMap.class);
        HostMessage lostNode = null;
        String lostNodeName = null;
        for (String name : nameTable.keySet()) {
            lostNode = nameTable.get(name);
            if ((lostNode.name.equals(lost.addr)||lostNode.name.equals(lost.hostname))
                    && lostNode.port == lost.port) {
                lostNodeName = name;
                break;
            }
            lostNode = null;
        }

        if (lostNode!=null && lostNode.isAlive()) {
            // change state not Alive
            lostNode.alive = false;
            // get lastJoinedNode
            String lastJoinNodeName = manager.getLastNode().getName();
            LinkedList<HostMessage> connectionList = topology.get(lastJoinNodeName);
            // lastJoinedNode has one connection
            HostMessage parentNode = connectionList.poll();

            connectionList = topology.get(parentNode.absName);
            for (HostMessage node1 : connectionList) {
                if (node1.absName.equals(lastJoinNodeName)) {
                    connectionList.remove(node1);
                    break;
                }
            }

            if (!lastJoinNodeName.equals(lostNodeName)) {
                if (!lostNodeName.equals(parentNode.remoteAbsName)) {
                    // send close message to lastJoinedNode
                    ods.put(lastJoinNodeName, "_CLOSEMESSEAGE", parentNode.connectionName);
                    // send close message to lastJoinedNode's parent
                    ods.put(parentNode.absName, "_CLOSEMESSEAGE", parentNode.reverseName);
                }

                HostMessage lastJoinNode = nameTable.get(lastJoinNodeName);
                connectionList = topology.get(lastJoinNodeName);
                LinkedList<HostMessage> disconnectionList = topology.get(lostNodeName);
                // remove NodeInformation from disconnection node's children and parent
                for (HostMessage node :disconnectionList) {
                    LinkedList<HostMessage> list = topology.get(node.absName);
                    if (!node.absName.equals(lastJoinNodeName)) {
                        for (HostMessage node1 : list) {
                            if (node1.absName.equals(lostNodeName)) {
                                node1.name = lastJoinNode.name;
                                node1.port = lastJoinNode.port;
                                node1.absName = lastJoinNodeName;
                                ods.put(node1.remoteAbsName, node1);
                                break;
                            }
                        }
                        node.remoteAbsName = lastJoinNodeName;
                        ods.put(node.remoteAbsName, node);
                        connectionList.add(node);
                    } else {
                        for (HostMessage node1 :disconnectionList) {
                            if ("parent".equals(node1.connectionName)) {
                                node1.reverseName = lastJoinNodeName;
                                list.add(node1);
                                ods.put(node1.remoteAbsName, node1);
                                break;
                            }
                        }

                    }
                }
                disconnectionList.clear();
                manager.replaceAndRemove(lostNodeName, lastJoinNodeName);
            } else {
                // disconnection node is lastJoinedNode
                manager.remove(lostNodeName);
            }

            for (Parent p1 : manager.getList()) {
                LinkedList<HostMessage> list = topology.get(p1.getName());
                int child = 0;
                for (HostMessage h : list) {
                    if (!"parent".equals(h.connectionName)) {
                        child++;
                    }
                }
                p1.setChildren(child);
            }

            // need debug option
            for (LinkedList<HostMessage> list :topology.values()){
                if (list.size() !=0) {
                    System.out.print(list.get(0).remoteAbsName+" : ");
                    for (HostMessage host : list){
                        System.out.print("[ "+host.absName+" "+host.name+" "+host.port+" "+host.connectionName+" "+host.reverseName+" "+host.remoteAbsName+" ]");
                    }
                    System.out.println();
                }
            }

            manager.show();
        } else {
            // disconnect message already received.
        }

        ods.put(info1.key, topology);
        ods.put(info3.key, nameTable);
        ods.put(info4.key, manager);
    }
}