blob: 4c07bad8562ca1ebd064500b660cd936ee98d980 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.draw2d.graph;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class NestingTree {
List contents = new ArrayList();
boolean isLeaf = true;
int size;
double sortValue;
Node subgraph;
private static void addToNestingTree(Map map, Node child) {
Subgraph subgraph = child.getParent();
NestingTree parent = (NestingTree)map.get(subgraph);
if (parent == null) {
parent = new NestingTree();
parent.subgraph = subgraph;
map.put(subgraph, parent);
if (subgraph != null)
addToNestingTree(map, parent);
}
parent.contents.add(child);
}
private static void addToNestingTree(Map map, NestingTree branch) {
Subgraph subgraph = branch.subgraph.getParent();
NestingTree parent = (NestingTree)map.get(subgraph);
if (parent == null) {
parent = new NestingTree();
parent.subgraph = subgraph;
map.put(subgraph, parent);
if (subgraph != null)
addToNestingTree(map, parent);
}
parent.contents.add(branch);
}
static NestingTree buildNestingTreeForRank(Rank rank) {
Map nestingMap = new HashMap();
for (int j = 0; j < rank.count(); j++) {
Node node = rank.getNode(j);
addToNestingTree(nestingMap, node);
}
return (NestingTree)nestingMap.get(null);
}
void calculateSortValues() {
int total = 0;
for (int i = 0; i < contents.size(); i++) {
Object o = contents.get(i);
if (o instanceof NestingTree) {
isLeaf = false;
NestingTree e = (NestingTree)o;
e.calculateSortValues();
total += (int)(e.sortValue * e.size);
size += e.size;
} else {
Node n = (Node)o;
n.sortValue = n.index;
total += n.index;
size++;
}
}
sortValue = (double)total / size;
}
void getSortValueFromSubgraph() {
if (subgraph != null)
sortValue = subgraph.sortValue;
for (int i = 0; i < contents.size(); i++) {
Object o = contents.get(i);
if (o instanceof NestingTree)
((NestingTree)o).getSortValueFromSubgraph();
}
}
void recursiveSort(boolean sortLeaves) {
if (isLeaf && !sortLeaves)
return;
boolean change = false;
//Use modified bubble sort for almost-sorted lists.
do {
change = false;
for (int i = 0; i < contents.size() - 1; i++)
change |= swap(i);
if (!change)
break;
change = false;
for (int i = contents.size() - 2; i >= 0; i--)
change |= swap(i);
} while (change);
for (int i = 0; i < contents.size(); i++) {
Object o = contents.get(i);
if (o instanceof NestingTree)
((NestingTree)o).recursiveSort(sortLeaves);
}
}
void repopulateRank(Rank r) {
for (int i = 0; i < contents.size(); i++) {
Object o = contents.get(i);
if (o instanceof Node)
r.add(o);
else
((NestingTree)o).repopulateRank(r);
}
}
boolean swap(int index) {
Object left = contents.get(index);
Object right = contents.get(index + 1);
double iL = (left instanceof Node)
? ((Node)left).sortValue
: ((NestingTree)left).sortValue;
double iR = (right instanceof Node)
? ((Node)right).sortValue
: ((NestingTree)right).sortValue;
if (iL <= iR)
return false;
contents.set(index, right);
contents.set(index + 1, left);
return true;
}
public String toString() {
return "Nesting:" + subgraph; //$NON-NLS-1$
}
}