/** * Copyright (c) 2009, iPlant Collaborative, Texas Advanced Computing Center * This software is licensed under the CC-GNU GPL version 2.0 or later. * License: http://creativecommons.org/licenses/GPL/2.0/ */ package org.iplantc.phyloviewer.shared.model; import java.util.Comparator; import java.util.HashMap; import java.util.Map; public class Ladderizer { private Map<INode, Integer> subtreeSizes = new HashMap<INode, Integer>(); private LadderizeComparator comparator = new LadderizeComparator(); private Direction direction; public Ladderizer(Direction direction) { this.direction = direction; } /** * Ladderizes the children of a node * @return the number of nodes in this subtree */ public int ladderize(INode node) { int size = 1; for (int i = 0; i < node.getNumberOfChildren(); i++) { INode child = node.getChild(i); int subtreeSize = ladderize(child); subtreeSizes.put(child, subtreeSize); size += subtreeSize; } node.sortChildrenBy(comparator); return size; } public enum Direction { UP(1), DOWN(-1); private int value; private Direction(int value) { this.value = value; } } private class LadderizeComparator implements Comparator<INode> { @Override public int compare(INode node0, INode node1) { if (!subtreeSizes.containsKey(node0) || !subtreeSizes.containsKey(node1)) { throw new NullPointerException("subtreeSizes does not contain both nodes " + node0 + " and " + node1 + ". The child subtree sized must be calculated before they can be reordered."); } return direction.value * (subtreeSizes.get(node0) - subtreeSizes.get(node1)); } } }