Project

General

Profile

Download (6.24 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.draw2d.graph;
12

    
13
import java.util.Collection;
14

    
15
/**
16
 * A group of nodes which are interlocked and cannot be separately placed.
17
 * 
18
 * @since 3.1
19
 */
20
class NodeCluster extends NodeList {
21

    
22
	int hashCode = new Object().hashCode();
23

    
24
	boolean isSetMember;
25
	boolean isDirty;
26
	boolean leftDirty;
27
	boolean rightDirty;
28

    
29
	int leftFreedom;
30
	int rightFreedom;
31
	int leftNonzero;
32
	int rightNonzero;
33
	int leftCount = 0;
34
	int rightCount = 0;
35

    
36
	CollapsedEdges leftLinks[] = new CollapsedEdges[10];
37
	CollapsedEdges rightLinks[] = new CollapsedEdges[10];
38
	NodeCluster leftNeighbors[] = new NodeCluster[10];
39
	NodeCluster rightNeighbors[] = new NodeCluster[10];
40

    
41
	int effectivePull;
42
	int weightedTotal;
43
	int weightedDivisor;
44
	int unweightedTotal;
45
	int unweightedDivisor;
46

    
47
	void addLeftNeighbor(NodeCluster neighbor, CollapsedEdges link) {
48
		// Need to grow array in the following case
49
		if (leftNeighbors.length == leftCount) {
50
			int newSize = leftNeighbors.length * 2;
51

    
52
			NodeCluster newNeighbors[] = new NodeCluster[newSize];
53
			CollapsedEdges newLinks[] = new CollapsedEdges[newSize];
54

    
55
			System.arraycopy(leftNeighbors, 0, newNeighbors, 0,
56
					leftNeighbors.length);
57
			System.arraycopy(leftLinks, 0, newLinks, 0, leftLinks.length);
58

    
59
			leftNeighbors = newNeighbors;
60
			leftLinks = newLinks;
61
		}
62
		leftNeighbors[leftCount] = neighbor;
63
		leftLinks[leftCount++] = link;
64
	}
65

    
66
	void addRightNeighbor(NodeCluster neighbor, CollapsedEdges link) {
67
		if (rightNeighbors.length == rightCount) {
68
			int newSize = rightNeighbors.length * 2;
69

    
70
			NodeCluster newNeighbors[] = new NodeCluster[newSize];
71
			CollapsedEdges newLinks[] = new CollapsedEdges[newSize];
72

    
73
			System.arraycopy(rightNeighbors, 0, newNeighbors, 0,
74
					rightNeighbors.length);
75
			System.arraycopy(rightLinks, 0, newLinks, 0, rightLinks.length);
76

    
77
			rightNeighbors = newNeighbors;
78
			rightLinks = newLinks;
79
		}
80
		rightNeighbors[rightCount] = neighbor;
81
		rightLinks[rightCount++] = link;
82
	}
83

    
84
	public void adjustRank(int delta, Collection affected) {
85
		adjustRank(delta);
86
		NodeCluster neighbor;
87
		CollapsedEdges edges;
88
		for (int i = 0; i < leftCount; i++) {
89
			neighbor = leftNeighbors[i];
90
			if (neighbor.isSetMember)
91
				continue;
92
			edges = leftLinks[i];
93

    
94
			neighbor.weightedTotal += delta * edges.collapsedWeight;
95
			neighbor.unweightedTotal += delta * edges.collapsedCount;
96

    
97
			weightedTotal -= delta * edges.collapsedWeight;
98
			unweightedTotal -= delta * edges.collapsedCount;
99

    
100
			neighbor.rightDirty = leftDirty = true;
101
			if (!neighbor.isDirty) {
102
				neighbor.isDirty = true;
103
				affected.add(neighbor);
104
			}
105
		}
106
		for (int i = 0; i < rightCount; i++) {
107
			neighbor = rightNeighbors[i];
108
			if (neighbor.isSetMember)
109
				continue;
110
			edges = rightLinks[i];
111

    
112
			neighbor.weightedTotal += delta * edges.collapsedWeight;
113
			neighbor.unweightedTotal += delta * edges.collapsedCount;
114

    
115
			weightedTotal -= delta * edges.collapsedWeight;
116
			unweightedTotal -= delta * edges.collapsedCount;
117

    
118
			neighbor.leftDirty = rightDirty = true;
119
			if (!neighbor.isDirty) {
120
				neighbor.isDirty = true;
121
				affected.add(neighbor);
122
			}
123
		}
124
		isDirty = true;
125
		affected.add(this);
126
	}
127

    
128
	public boolean equals(Object o) {
129
		return o == this;
130
	}
131

    
132
	CollapsedEdges getLeftNeighbor(NodeCluster neighbor) {
133
		for (int i = 0; i < leftCount; i++) {
134
			if (leftNeighbors[i] == neighbor)
135
				return leftLinks[i];
136
		}
137
		return null;
138
	}
139

    
140
	int getPull() {
141
		return effectivePull;
142
	}
143

    
144
	CollapsedEdges getRightNeighbor(NodeCluster neighbor) {
145
		for (int i = 0; i < rightCount; i++) {
146
			if (rightNeighbors[i] == neighbor)
147
				return rightLinks[i];
148
		}
149
		return null;
150
	}
151

    
152
	public int hashCode() {
153
		return hashCode;
154
	}
155

    
156
	/**
157
	 * Initializes pull and freedom values.
158
	 */
159
	void initValues() {
160
		weightedTotal = 0;
161
		weightedDivisor = 0;
162
		unweightedTotal = 0;
163
		int slack;
164

    
165
		leftNonzero = rightNonzero = leftFreedom = rightFreedom = Integer.MAX_VALUE;
166
		for (int i = 0; i < leftCount; i++) {
167
			CollapsedEdges edges = leftLinks[i];
168
			weightedTotal -= edges.getWeightedPull();
169
			unweightedTotal -= edges.tightestEdge.getSlack();
170
			unweightedDivisor += edges.collapsedCount;
171
			weightedDivisor += edges.collapsedWeight;
172
			slack = edges.tightestEdge.getSlack();
173
			leftFreedom = Math.min(slack, leftFreedom);
174
			if (slack > 0)
175
				leftNonzero = Math.min(slack, leftNonzero);
176
		}
177
		for (int i = 0; i < rightCount; i++) {
178
			CollapsedEdges edges = rightLinks[i];
179
			weightedTotal += edges.getWeightedPull();
180
			unweightedDivisor += edges.collapsedCount;
181
			unweightedTotal += edges.tightestEdge.getSlack();
182
			weightedDivisor += edges.collapsedWeight;
183
			slack = edges.tightestEdge.getSlack();
184
			rightFreedom = Math.min(slack, rightFreedom);
185
			if (slack > 0)
186
				rightNonzero = Math.min(slack, rightNonzero);
187
		}
188
		updateEffectivePull();
189
	}
190

    
191
	/**
192
	 * Refreshes the left and right freedom.
193
	 */
194
	void refreshValues() {
195
		int slack;
196
		isDirty = false;
197
		if (leftDirty) {
198
			leftDirty = false;
199
			leftNonzero = leftFreedom = Integer.MAX_VALUE;
200
			for (int i = 0; i < leftCount; i++) {
201
				CollapsedEdges edges = leftLinks[i];
202
				slack = edges.tightestEdge.getSlack();
203
				leftFreedom = Math.min(slack, leftFreedom);
204
				if (slack > 0)
205
					leftNonzero = Math.min(slack, leftNonzero);
206
			}
207
		}
208
		if (rightDirty) {
209
			rightDirty = false;
210
			rightNonzero = rightFreedom = Integer.MAX_VALUE;
211
			for (int i = 0; i < rightCount; i++) {
212
				CollapsedEdges edges = rightLinks[i];
213
				slack = edges.tightestEdge.getSlack();
214
				rightFreedom = Math.min(slack, rightFreedom);
215
				if (slack > 0)
216
					rightNonzero = Math.min(slack, rightNonzero);
217
			}
218
		}
219
		updateEffectivePull();
220
	}
221

    
222
	private void updateEffectivePull() {
223
		if (weightedDivisor != 0)
224
			effectivePull = weightedTotal / weightedDivisor;
225
		else if (unweightedDivisor != 0)
226
			effectivePull = unweightedTotal / unweightedDivisor;
227
		else
228
			effectivePull = 0;
229
	}
230

    
231
}
(25-25/49)