annotate dwtx/jface/viewers/deferred/LazySortedCollection.d @ 104:04b47443bb01

Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections. These new wrappers now use the tango.util.containers instead of the tango.util.collections.
author Frank Benoit <benoit@tionex.de>
date Thu, 07 Aug 2008 15:01:33 +0200
parents b6c35faf97c8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1 /*******************************************************************************
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
2 * Copyright (c) 2004, 2006 IBM Corporation and others.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
3 * All rights reserved. This program and the accompanying materials
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
4 * are made available under the terms of the Eclipse Public License v1.0
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
5 * which accompanies this distribution, and is available at
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
6 * http://www.eclipse.org/legal/epl-v10.html
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
7 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
8 * Contributors:
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
9 * IBM Corporation - initial API and implementation
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
10 * Port to the D programming language:
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
11 * Frank Benoit <benoit@tionex.de>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
12 *******************************************************************************/
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
13 module dwtx.jface.viewers.deferred.LazySortedCollection;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
14
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
15 import dwtx.jface.viewers.deferred.IntHashMap;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
16 import dwtx.jface.viewers.deferred.FastProgressReporter;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
17 // import java.util.Collection;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
18 // import java.util.Comparator;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
19 // import java.util.Iterator;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
20
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
21 import dwtx.core.runtime.Assert;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
22
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
23 import dwt.dwthelper.utils;
104
04b47443bb01 Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents: 10
diff changeset
24 import dwtx.dwtxhelper.Collection;
10
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
25
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
26 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
27 * This object maintains a collection of elements, sorted by a comparator
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
28 * given in the constructor. The collection is lazily sorted, allowing
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
29 * more efficient runtimes for most methods. There are several methods on this
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
30 * object that allow objects to be queried by their position in the sorted
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
31 * collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
32 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
33 * <p>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
34 * This is a modified binary search tree. Each subtree has a value, a left and right subtree,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
35 * a count of the number of children, and a set of unsorted children.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
36 * Insertion happens lazily. When a new node N is inserted into a subtree T, it is initially
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
37 * added to the set of unsorted children for T without actually comparing it with the value for T.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
38 * </p>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
39 * <p>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
40 * The unsorted children will remain in the unsorted set until some subsequent operation requires
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
41 * us to know the exact set of elements in one of the subtrees. At that time, we partition
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
42 * T by comparing all of its unsorted children with T's value and moving them into the left
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
43 * or right subtrees.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
44 * </p>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
45 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
46 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
47 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
48 public class LazySortedCollection {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
49 private const int MIN_CAPACITY = 8;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
50 private Object[] contents;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
51 private int[] leftSubTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
52 private int[] rightSubTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
53 private int[] nextUnsorted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
54 private int[] treeSize;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
55 private int[] parentTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
56 private int root = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
57 private int lastNode = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
58 private int firstUnusedNode = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
59
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
60 private static const float loadFactor = 0.75f;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
61
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
62 private IntHashMap objectIndices;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
63 private Comparator comparator;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
64 private static int counter = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
65
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
66 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
67 * Disables randomization and enables additional runtime error checking.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
68 * Severely degrades performance if set to true. Intended for use in test
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
69 * suites only.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
70 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
71 public bool enableDebug = false;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
72
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
73 // This object is inserted as the value into any node scheduled for lazy removal
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
74 private Object lazyRemovalFlag;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
75
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
76 private void init_instance(){
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
77 contents = new Object[MIN_CAPACITY];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
78 leftSubTree = new int[MIN_CAPACITY];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
79 rightSubTree = new int[MIN_CAPACITY];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
80 nextUnsorted = new int[MIN_CAPACITY];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
81 treeSize = new int[MIN_CAPACITY];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
82 parentTree = new int[MIN_CAPACITY];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
83 lazyRemovalFlag = new class Object {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
84 public String toString() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
85 return "Lazy removal flag"; //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
86 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
87 };
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
88 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
89
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
90 private const static int DIR_LEFT = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
91 private const static int DIR_RIGHT = 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
92 private const static int DIR_UNSORTED = 2;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
93
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
94 // Direction constants indicating root nodes
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
95 private const static int DIR_ROOT = 3;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
96 private const static int DIR_UNUSED = 4;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
97
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
98 private final class Edge {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
99 private int startNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
100 private int direction;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
101
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
102 private this() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
103 startNode = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
104 direction = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
105 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
106
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
107 private this(int node, int dir) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
108 startNode = node;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
109 direction = dir;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
110 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
111
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
112 private int getStart() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
113 return startNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
114 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
115
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
116 private int getTarget() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
117 if (startNode is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
118 if (direction is DIR_UNSORTED) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
119 return firstUnusedNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
120 } else if (direction is DIR_ROOT) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
121 return root;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
122 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
123 return -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
124 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
125
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
126 if (direction is DIR_LEFT) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
127 return leftSubTree[startNode];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
128 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
129 if (direction is DIR_RIGHT) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
130 return rightSubTree[startNode];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
131 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
132 return nextUnsorted[startNode];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
133 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
134
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
135 private bool isNull() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
136 return getTarget() is -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
137 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
138
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
139 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
140 * Redirects this edge to a new node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
141 * @param newNode
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
142 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
143 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
144 private void setTarget(int newNode) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
145 if (direction is DIR_LEFT) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
146 leftSubTree[startNode] = newNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
147 } else if (direction is DIR_RIGHT) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
148 rightSubTree[startNode] = newNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
149 } else if (direction is DIR_UNSORTED) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
150 nextUnsorted[startNode] = newNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
151 } else if (direction is DIR_ROOT) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
152 root = newNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
153 } else if (direction is DIR_UNUSED) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
154 firstUnusedNode = newNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
155 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
156
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
157 if (newNode !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
158 parentTree[newNode] = startNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
159 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
160 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
161
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
162 private void advance(int direction) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
163 startNode = getTarget();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
164 this.direction = direction;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
165 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
166 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
167
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
168 private void setRootNode(int node) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
169 root = node;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
170 if (node !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
171 parentTree[node] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
172 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
173 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
174
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
175 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
176 * Creates a new sorted collection using the given comparator to determine
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
177 * sort order.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
178 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
179 * @param c comparator that determines the sort order
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
180 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
181 public this(Comparator c) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
182 this.comparator = c;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
183 init_instance();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
184 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
185
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
186 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
187 * Tests if this object's internal state is valid. Throws a runtime
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
188 * exception if the state is invalid, indicating a programming error
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
189 * in this class. This method is intended for use in test
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
190 * suites and should not be called by clients.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
191 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
192 public void testInvariants() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
193 if (!enableDebug) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
194 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
195 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
196
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
197 testInvariants(root);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
198 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
199
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
200 private void testInvariants(int node) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
201 if (node is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
202 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
203 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
204
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
205 // Get the current tree size (we will later force the tree size
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
206 // to be recomputed from scratch -- if everything works properly, then
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
207 // there should be no change.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
208 int treeSize = getSubtreeSize(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
209
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
210 int left = leftSubTree[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
211 int right = rightSubTree[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
212 int unsorted = nextUnsorted[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
213
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
214 if (isUnsorted(node)) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
215 Assert.isTrue(left is -1, "unsorted nodes shouldn't have a left subtree"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
216 Assert.isTrue(right is -1, "unsorted nodes shouldn't have a right subtree"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
217 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
218
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
219 if (left !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
220 testInvariants(left);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
221 Assert.isTrue(parentTree[left] is node, "left node has invalid parent pointer"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
222 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
223 if (right !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
224 testInvariants(right);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
225 Assert.isTrue(parentTree[right] is node, "right node has invalid parent pointer"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
226 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
227
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
228 int previous = node;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
229 while (unsorted !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
230 int oldTreeSize = this.treeSize[unsorted];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
231 recomputeTreeSize(unsorted);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
232
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
233 Assert.isTrue(this.treeSize[unsorted] is oldTreeSize,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
234 "Invalid node size for unsorted node"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
235 Assert.isTrue(leftSubTree[unsorted] is -1, "unsorted nodes shouldn't have left subtrees"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
236 Assert.isTrue(rightSubTree[unsorted] is -1, "unsorted nodes shouldn't have right subtrees"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
237 Assert.isTrue(parentTree[unsorted] is previous, "unsorted node has invalid parent pointer"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
238 Assert.isTrue(contents[unsorted] !is lazyRemovalFlag, "unsorted nodes should not be lazily removed"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
239 previous = unsorted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
240 unsorted = nextUnsorted[unsorted];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
241 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
242
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
243 // Note that we've already tested that the child sizes are correct... if our size is
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
244 // correct, then recomputing it now should not cause any change.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
245 recomputeTreeSize(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
246
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
247 Assert.isTrue(treeSize is getSubtreeSize(node), "invalid tree size"); //$NON-NLS-1$
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
248 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
249
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
250 private bool isUnsorted(int node) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
251 int parent = parentTree[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
252
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
253 if (parent !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
254 return nextUnsorted[parent] is node;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
255 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
256
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
257 return false;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
258 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
259
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
260 private final bool isLess(int element1, int element2) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
261 return comparator.compare(contents[element1], contents[element2]) < 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
262 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
263
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
264 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
265 * Adds the given element to the given subtree. Returns the new
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
266 * root of the subtree.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
267 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
268 * @param subTree index of the subtree to insert elementToAdd into. If -1,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
269 * then a new subtree will be created for elementToAdd
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
270 * @param elementToAdd index of the element to add to the subtree. If -1, this method
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
271 * is a NOP.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
272 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
273 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
274 private final int addUnsorted(int subTree, int elementToAdd) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
275 if (elementToAdd is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
276 return subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
277 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
278
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
279 if (subTree is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
280 nextUnsorted[elementToAdd] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
281 treeSize[elementToAdd] = 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
282 return elementToAdd;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
283 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
284
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
285 // If the subTree is empty (ie: it only contains nodes flagged for lazy removal),
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
286 // chop it off.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
287 if (treeSize[subTree] is 0) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
288 removeSubTree(subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
289 nextUnsorted[elementToAdd] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
290 treeSize[elementToAdd] = 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
291 return elementToAdd;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
292 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
293
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
294 // If neither subtree has any children, add a pseudorandom chance of the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
295 // newly added element becoming the new pivot for this node. Note: instead
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
296 // of a real pseudorandom generator, we simply use a counter here.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
297 if (!enableDebug && leftSubTree[subTree] is -1 && rightSubTree[subTree] is -1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
298 && leftSubTree[elementToAdd] is -1 && rightSubTree[elementToAdd] is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
299 counter--;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
300
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
301 if (counter % treeSize[subTree] is 0) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
302 // Make the new node into the new pivot
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
303 nextUnsorted[elementToAdd] = subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
304 parentTree[elementToAdd] = parentTree[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
305 parentTree[subTree] = elementToAdd;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
306 treeSize[elementToAdd] = treeSize[subTree] + 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
307 return elementToAdd;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
308 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
309 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
310
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
311 int oldNextUnsorted = nextUnsorted[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
312 nextUnsorted[elementToAdd] = oldNextUnsorted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
313
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
314 if (oldNextUnsorted is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
315 treeSize[elementToAdd] = 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
316 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
317 treeSize[elementToAdd] = treeSize[oldNextUnsorted] + 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
318 parentTree[oldNextUnsorted] = elementToAdd;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
319 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
320
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
321 parentTree[elementToAdd] = subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
322
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
323 nextUnsorted[subTree] = elementToAdd;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
324 treeSize[subTree]++;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
325 return subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
326 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
327
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
328 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
329 * Returns the number of elements in the collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
330 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
331 * @return the number of elements in the collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
332 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
333 public int size() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
334 int result = getSubtreeSize(root);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
335
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
336 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
337
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
338 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
339 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
340
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
341 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
342 * Given a tree and one of its unsorted children, this sorts the child by moving
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
343 * it into the left or right subtrees. Returns the next unsorted child or -1 if none
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
344 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
345 * @param subTree parent tree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
346 * @param toMove child (unsorted) subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
347 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
348 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
349 private final int partition(int subTree, int toMove) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
350 int result = nextUnsorted[toMove];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
351
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
352 if (isLess(toMove, subTree)) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
353 int nextLeft = addUnsorted(leftSubTree[subTree], toMove);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
354 leftSubTree[subTree] = nextLeft;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
355 parentTree[nextLeft] = subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
356 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
357 int nextRight = addUnsorted(rightSubTree[subTree], toMove);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
358 rightSubTree[subTree] = nextRight;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
359 parentTree[nextRight] = subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
360 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
361
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
362 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
363 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
364
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
365 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
366 * Partitions the given subtree. Moves all unsorted elements at the given node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
367 * to either the left or right subtrees. If the node itself was scheduled for
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
368 * lazy removal, this will force the node to be removed immediately. Returns
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
369 * the new subTree.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
370 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
371 * @param subTree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
372 * @return the replacement node (this may be different from subTree if the subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
373 * was replaced during the removal)
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
374 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
375 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
376 private final int partition(int subTree, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
377 if (subTree is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
378 return -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
379 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
380
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
381 if (contents[subTree] is lazyRemovalFlag) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
382 subTree = removeNode(subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
383 if (subTree is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
384 return -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
385 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
386 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
387
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
388 for (int idx = nextUnsorted[subTree]; idx !is -1;) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
389 idx = partition(subTree, idx);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
390 nextUnsorted[subTree] = idx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
391 if (idx !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
392 parentTree[idx] = subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
393 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
394
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
395 if (mon.isCanceled()) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
396 throw new InterruptedException();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
397 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
398 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
399
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
400 // At this point, there are no remaining unsorted nodes in this subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
401 nextUnsorted[subTree] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
402
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
403 return subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
404 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
405
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
406 private final int getSubtreeSize(int subTree) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
407 if (subTree is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
408 return 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
409 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
410 return treeSize[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
411 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
412
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
413 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
414 * Increases the capacity of this collection, if necessary, so that it can hold the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
415 * given number of elements. This can be used prior to a sequence of additions to
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
416 * avoid memory reallocation. This cannot be used to reduce the amount
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
417 * of memory used by the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
418 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
419 * @param newSize capacity for this collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
420 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
421 public final void setCapacity(int newSize) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
422 if (newSize > contents.length) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
423 setArraySize(newSize);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
424 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
425 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
426
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
427 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
428 * Adjusts the capacity of the array.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
429 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
430 * @param newCapacity
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
431 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
432 private final void setArraySize(int newCapacity) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
433 Object[] newContents = new Object[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
434 System.arraycopy(contents, 0, newContents, 0, lastNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
435 contents = newContents;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
436
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
437 int[] newLeftSubTree = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
438 System.arraycopy(leftSubTree, 0, newLeftSubTree, 0, lastNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
439 leftSubTree = newLeftSubTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
440
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
441 int[] newRightSubTree = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
442 System.arraycopy(rightSubTree, 0, newRightSubTree, 0, lastNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
443 rightSubTree = newRightSubTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
444
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
445 int[] newNextUnsorted = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
446 System.arraycopy(nextUnsorted, 0, newNextUnsorted, 0, lastNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
447 nextUnsorted = newNextUnsorted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
448
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
449 int[] newTreeSize = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
450 System.arraycopy(treeSize, 0, newTreeSize, 0, lastNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
451 treeSize = newTreeSize;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
452
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
453 int[] newParentTree = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
454 System.arraycopy(parentTree, 0, newParentTree, 0, lastNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
455 parentTree = newParentTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
456 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
457
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
458 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
459 * Creates a new node with the given value. Returns the index of the newly
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
460 * created node.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
461 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
462 * @param value
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
463 * @return the index of the newly created node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
464 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
465 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
466 private final int createNode(Object value) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
467 int result = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
468
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
469 if (firstUnusedNode is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
470 // If there are no unused nodes from prior removals, then
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
471 // we add a node at the end
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
472 result = lastNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
473
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
474 // If this would cause the array to overflow, reallocate the array
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
475 if (contents.length <= lastNode) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
476 setCapacity(lastNode * 2);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
477 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
478
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
479 lastNode++;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
480 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
481 // Reuse a node from a prior removal
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
482 result = firstUnusedNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
483 firstUnusedNode = nextUnsorted[result];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
484 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
485
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
486 contents[result] = value;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
487 treeSize[result] = 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
488
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
489 // Clear pointers
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
490 leftSubTree[result] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
491 rightSubTree[result] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
492 nextUnsorted[result] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
493
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
494 // As long as we have a hash table of values onto tree indices, incrementally
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
495 // update the hash table. Note: the table is only constructed as needed, and it
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
496 // is destroyed whenever the arrays are reallocated instead of reallocating it.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
497 if (objectIndices !is null) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
498 objectIndices.put(value, result);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
499 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
500
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
501 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
502 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
503
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
504 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
505 * Returns the current tree index for the given object.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
506 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
507 * @param value
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
508 * @return the current tree index
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
509 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
510 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
511 private int getObjectIndex(Object value) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
512 // If we don't have a map of values onto tree indices, build the map now.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
513 if (objectIndices is null) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
514 int result = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
515
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
516 objectIndices = new IntHashMap(cast(int)(contents.length / loadFactor) + 1, loadFactor);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
517
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
518 for (int i = 0; i < lastNode; i++) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
519 Object element = contents[i];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
520
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
521 if (element !is null && element !is lazyRemovalFlag) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
522 objectIndices.put(element, i);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
523
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
524 if (value is element) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
525 result = i;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
526 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
527 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
528 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
529
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
530 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
531 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
532
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
533 // If we have a map of values onto tree indices, return the result by looking it up in
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
534 // the map
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
535 return objectIndices.get(value, -1);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
536 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
537
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
538 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
539 * Redirects any pointers from the original to the replacement. If the replacement
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
540 * causes a change in the number of elements in the parent tree, the changes are
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
541 * propogated toward the root.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
542 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
543 * @param nodeToReplace
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
544 * @param replacementNode
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
545 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
546 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
547 private void replaceNode(int nodeToReplace, int replacementNode) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
548 int parent = parentTree[nodeToReplace];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
549
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
550 if (parent is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
551 if (root is nodeToReplace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
552 setRootNode(replacementNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
553 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
554 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
555 if (leftSubTree[parent] is nodeToReplace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
556 leftSubTree[parent] = replacementNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
557 } else if (rightSubTree[parent] is nodeToReplace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
558 rightSubTree[parent] = replacementNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
559 } else if (nextUnsorted[parent] is nodeToReplace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
560 nextUnsorted[parent] = replacementNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
561 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
562 if (replacementNode !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
563 parentTree[replacementNode] = parent;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
564 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
565 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
566 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
567
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
568 private void recomputeAncestorTreeSizes(int node) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
569 while (node !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
570 int oldSize = treeSize[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
571
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
572 recomputeTreeSize(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
573
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
574 if (treeSize[node] is oldSize) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
575 break;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
576 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
577
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
578 node = parentTree[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
579 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
580 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
581
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
582 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
583 * Recomputes the tree size for the given node.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
584 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
585 * @param node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
586 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
587 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
588 private void recomputeTreeSize(int node) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
589 if (node is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
590 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
591 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
592 treeSize[node] = getSubtreeSize(leftSubTree[node])
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
593 + getSubtreeSize(rightSubTree[node])
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
594 + getSubtreeSize(nextUnsorted[node])
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
595 + (contents[node] is lazyRemovalFlag ? 0 : 1);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
596 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
597
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
598 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
599 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
600 * @param toRecompute
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
601 * @param whereToStop
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
602 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
603 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
604 private void forceRecomputeTreeSize(int toRecompute, int whereToStop) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
605 while (toRecompute !is -1 && toRecompute !is whereToStop) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
606 recomputeTreeSize(toRecompute);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
607
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
608 toRecompute = parentTree[toRecompute];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
609 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
610 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
611
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
612 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
613 * Destroy the node at the given index in the tree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
614 * @param nodeToDestroy
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
615 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
616 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
617 private void destroyNode(int nodeToDestroy) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
618 // If we're maintaining a map of values onto tree indices, remove this entry from
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
619 // the map
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
620 if (objectIndices !is null) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
621 Object oldContents = contents[nodeToDestroy];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
622 if (oldContents !is lazyRemovalFlag) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
623 objectIndices.remove(oldContents);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
624 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
625 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
626
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
627 contents[nodeToDestroy] = null;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
628 leftSubTree[nodeToDestroy] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
629 rightSubTree[nodeToDestroy] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
630
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
631 if (firstUnusedNode is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
632 treeSize[nodeToDestroy] = 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
633 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
634 treeSize[nodeToDestroy] = treeSize[firstUnusedNode] + 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
635 parentTree[firstUnusedNode] = nodeToDestroy;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
636 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
637
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
638 nextUnsorted[nodeToDestroy] = firstUnusedNode;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
639
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
640 firstUnusedNode = nodeToDestroy;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
641 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
642
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
643 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
644 * Frees up memory by clearing the list of nodes that have been freed up through removals.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
645 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
646 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
647 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
648 private final void pack() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
649
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
650 // If there are no unused nodes, then there is nothing to do
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
651 if (firstUnusedNode is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
652 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
653 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
654
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
655 int reusableNodes = getSubtreeSize(firstUnusedNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
656 int nonPackableNodes = lastNode - reusableNodes;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
657
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
658 // Only pack the array if we're utilizing less than 1/4 of the array (note:
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
659 // this check is important, or it will change the time bounds for removals)
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
660 if (contents.length < MIN_CAPACITY || nonPackableNodes > contents.length / 4) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
661 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
662 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
663
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
664 // Rather than update the entire map, just null it out. If it is needed,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
665 // it will be recreated lazily later. This will save some memory if the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
666 // map isn't needed, and it takes a similar amount of time to recreate the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
667 // map as to update all the indices.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
668 objectIndices = null;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
669
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
670 // Maps old index -> new index
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
671 int[] mapNewIdxOntoOld = new int[contents.length];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
672 int[] mapOldIdxOntoNew = new int[contents.length];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
673
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
674 int nextNewIdx = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
675 // Compute the mapping. Determine the new index for each element
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
676 for (int oldIdx = 0; oldIdx < lastNode; oldIdx++) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
677 if (contents[oldIdx] !is null) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
678 mapOldIdxOntoNew[oldIdx] = nextNewIdx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
679 mapNewIdxOntoOld[nextNewIdx] = oldIdx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
680 nextNewIdx++;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
681 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
682 mapOldIdxOntoNew[oldIdx] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
683 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
684 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
685
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
686 // Make the actual array size double the number of nodes to allow
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
687 // for expansion.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
688 int newNodes = nextNewIdx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
689 int newCapacity = Math.max(newNodes * 2, MIN_CAPACITY);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
690
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
691 // Allocate new arrays
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
692 Object[] newContents = new Object[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
693 int[] newTreeSize = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
694 int[] newNextUnsorted = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
695 int[] newLeftSubTree = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
696 int[] newRightSubTree = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
697 int[] newParentTree = new int[newCapacity];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
698
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
699 for (int newIdx = 0; newIdx < newNodes; newIdx++) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
700 int oldIdx = mapNewIdxOntoOld[newIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
701 newContents[newIdx] = contents[oldIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
702 newTreeSize[newIdx] = treeSize[oldIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
703
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
704 int left = leftSubTree[oldIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
705 if (left is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
706 newLeftSubTree[newIdx] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
707 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
708 newLeftSubTree[newIdx] = mapOldIdxOntoNew[left];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
709 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
710
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
711 int right = rightSubTree[oldIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
712 if (right is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
713 newRightSubTree[newIdx] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
714 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
715 newRightSubTree[newIdx] = mapOldIdxOntoNew[right];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
716 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
717
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
718 int unsorted = nextUnsorted[oldIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
719 if (unsorted is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
720 newNextUnsorted[newIdx] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
721 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
722 newNextUnsorted[newIdx] = mapOldIdxOntoNew[unsorted];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
723 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
724
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
725 int parent = parentTree[oldIdx];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
726 if (parent is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
727 newParentTree[newIdx] = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
728 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
729 newParentTree[newIdx] = mapOldIdxOntoNew[parent];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
730 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
731 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
732
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
733 contents = newContents;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
734 nextUnsorted = newNextUnsorted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
735 treeSize = newTreeSize;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
736 leftSubTree = newLeftSubTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
737 rightSubTree = newRightSubTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
738 parentTree = newParentTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
739
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
740 if (root !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
741 root = mapOldIdxOntoNew[root];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
742 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
743
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
744 // All unused nodes have been removed
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
745 firstUnusedNode = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
746 lastNode = newNodes;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
747 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
748
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
749 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
750 * Adds the given object to the collection. Runs in O(1) amortized time.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
751 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
752 * @param toAdd object to add
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
753 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
754 public final void add(Object toAdd) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
755 Assert.isNotNull(toAdd);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
756 // Create the new node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
757 int newIdx = createNode(toAdd);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
758
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
759 // Insert the new node into the root tree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
760 setRootNode(addUnsorted(root, newIdx));
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
761
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
762 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
763 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
764
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
765 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
766 * Adds all items from the given collection to this collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
767 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
768 * @param toAdd objects to add
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
769 */
104
04b47443bb01 Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents: 10
diff changeset
770 public final void addAll( Collection toAdd) {
10
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
771 Assert.isNotNull(cast(Object)toAdd);
104
04b47443bb01 Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents: 10
diff changeset
772 Iterator iter = toAdd.iterator();
04b47443bb01 Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents: 10
diff changeset
773 while (iter.hasNext()) {
04b47443bb01 Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents: 10
diff changeset
774 add(iter.next());
10
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
775 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
776
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
777 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
778 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
779
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
780 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
781 * Adds all items from the given array to the collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
782 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
783 * @param toAdd objects to add
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
784 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
785 public final void addAll(Object[] toAdd) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
786 // Assert.isNotNull(toAdd);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
787 for (int i = 0; i < toAdd.length; i++) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
788 Object object = toAdd[i];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
789
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
790 add(object);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
791 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
792
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
793 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
794 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
795
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
796 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
797 * Returns true iff the collection is empty
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
798 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
799 * @return true iff the collection contains no elements
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
800 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
801 public final bool isEmpty() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
802 bool result = (root is -1);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
803
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
804 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
805
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
806 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
807 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
808
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
809 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
810 * Removes the given object from the collection. Has no effect if
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
811 * the element does not exist in this collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
812 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
813 * @param toRemove element to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
814 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
815 public final void remove(Object toRemove) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
816 internalRemove(toRemove);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
817
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
818 pack();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
819
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
820 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
821 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
822
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
823 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
824 * Internal implementation of remove. Removes the given element but does not
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
825 * pack the container after the removal.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
826 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
827 * @param toRemove element to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
828 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
829 private void internalRemove(Object toRemove) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
830 int objectIndex = getObjectIndex(toRemove);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
831
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
832 if (objectIndex !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
833 int parent = parentTree[objectIndex];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
834 lazyRemoveNode(objectIndex);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
835 //Edge parentEdge = getEdgeTo(objectIndex);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
836 //parentEdge.setTarget(lazyRemoveNode(objectIndex));
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
837 recomputeAncestorTreeSizes(parent);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
838 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
839
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
840 //testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
841 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
842
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
843 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
844 * Removes all elements in the given array from this collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
845 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
846 * @param toRemove elements to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
847 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
848 public final void removeAll(Object[] toRemove) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
849 // Assert.isNotNull(toRemove);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
850
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
851 for (int i = 0; i < toRemove.length; i++) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
852 Object object = toRemove[i];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
853
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
854 internalRemove(object);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
855 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
856 pack();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
857 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
858
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
859 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
860 * Retains the n smallest items in the collection, removing the rest. When
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
861 * this method returns, the size of the collection will be n. Note that
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
862 * this is a no-op if n > the current size of the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
863 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
864 * Temporarily package visibility until the implementation of FastProgressReporter
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
865 * is finished.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
866 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
867 * @param n number of items to retain
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
868 * @param mon progress monitor
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
869 * @throws InterruptedException if the progress monitor is cancelled in another thread
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
870 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
871 /* package */ final void retainFirst(int n, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
872 int sz = size();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
873
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
874 if (n >= sz) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
875 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
876 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
877
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
878 removeRange(n, sz - n, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
879
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
880 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
881 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
882
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
883 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
884 * Retains the n smallest items in the collection, removing the rest. When
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
885 * this method returns, the size of the collection will be n. Note that
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
886 * this is a no-op if n > the current size of the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
887 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
888 * @param n number of items to retain
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
889 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
890 public final void retainFirst(int n) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
891 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
892 retainFirst(n, new FastProgressReporter());
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
893 } catch (InterruptedException e) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
894 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
895
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
896 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
897 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
898
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
899 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
900 * Removes all elements in the given range from this collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
901 * For example, removeRange(10, 3) would remove the 11th through 13th
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
902 * smallest items from the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
903 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
904 * @param first 0-based index of the smallest item to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
905 * @param length number of items to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
906 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
907 public final void removeRange(int first, int length) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
908 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
909 removeRange(first, length, new FastProgressReporter());
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
910 } catch (InterruptedException e) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
911 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
912
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
913 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
914 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
915
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
916 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
917 * Removes all elements in the given range from this collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
918 * For example, removeRange(10, 3) would remove the 11th through 13th
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
919 * smallest items from the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
920 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
921 * Temporarily package visiblity until the implementation of FastProgressReporter is
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
922 * finished.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
923 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
924 * @param first 0-based index of the smallest item to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
925 * @param length number of items to remove
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
926 * @param mon progress monitor
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
927 * @throws InterruptedException if the progress monitor is cancelled in another thread
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
928 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
929 /* package */ final void removeRange(int first, int length, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
930 removeRange(root, first, length, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
931
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
932 pack();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
933
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
934 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
935 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
936
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
937 private final void removeRange(int node, int rangeStart, int rangeLength, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
938 if (rangeLength is 0) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
939 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
940 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
941
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
942 int size = getSubtreeSize(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
943
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
944 if (size <= rangeStart) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
945 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
946 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
947
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
948 // If we can chop off this entire subtree without any sorting, do so.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
949 if (rangeStart is 0 && rangeLength >= size) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
950 removeSubTree(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
951 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
952 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
953 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
954 // Partition any unsorted nodes
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
955 node = partition(node, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
956
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
957 int left = leftSubTree[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
958 int leftSize = getSubtreeSize(left);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
959
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
960 int toRemoveFromLeft = Math.min(leftSize - rangeStart, rangeLength);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
961
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
962 // If we're removing anything from the left node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
963 if (toRemoveFromLeft >= 0) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
964 removeRange(leftSubTree[node], rangeStart, toRemoveFromLeft, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
965
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
966 // Check if we're removing from both sides
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
967 int toRemoveFromRight = rangeStart + rangeLength - leftSize - 1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
968
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
969 if (toRemoveFromRight >= 0) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
970 // Remove from right subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
971 removeRange(rightSubTree[node], 0, toRemoveFromRight, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
972
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
973 // ... removing from both sides means we need to remove the node itself too
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
974 removeNode(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
975 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
976 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
977 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
978 // If removing from the right side only
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
979 removeRange(rightSubTree[node], rangeStart - leftSize - 1, rangeLength, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
980 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
981 } finally {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
982 recomputeTreeSize(node);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
983 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
984 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
985
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
986 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
987 * Prunes the given subtree (and all child nodes, sorted or unsorted).
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
988 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
989 * @param subTree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
990 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
991 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
992 private final void removeSubTree(int subTree) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
993 if (subTree is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
994 return;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
995 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
996
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
997 // Destroy all unsorted nodes
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
998 for (int next = nextUnsorted[subTree]; next !is -1;) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
999 int current = next;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1000 next = nextUnsorted[next];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1001
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1002 // Destroy this unsorted node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1003 destroyNode(current);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1004 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1005
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1006 // Destroy left subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1007 removeSubTree(leftSubTree[subTree]);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1008
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1009 // Destroy right subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1010 removeSubTree(rightSubTree[subTree]);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1011
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1012 replaceNode(subTree, -1);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1013 // Destroy pivot node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1014 destroyNode(subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1015 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1016
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1017 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1018 * Schedules the node for removal. If the node can be removed in constant time,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1019 * it is removed immediately.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1020 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1021 * @param subTree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1022 * @return the replacement node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1023 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1024 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1025 private final int lazyRemoveNode(int subTree) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1026 int left = leftSubTree[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1027 int right = rightSubTree[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1028
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1029 // If this is a leaf node, remove it immediately
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1030 if (left is -1 && right is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1031 int result = nextUnsorted[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1032 replaceNode(subTree, result);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1033 destroyNode(subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1034 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1035 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1036
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1037 // Otherwise, flag it for future removal
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1038 Object value = contents[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1039 contents[subTree] = lazyRemovalFlag;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1040 treeSize[subTree]--;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1041 if (objectIndices !is null) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1042 objectIndices.remove(value);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1043 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1044
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1045 return subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1046 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1047
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1048 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1049 * Removes the given subtree, replacing it with one of its children.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1050 * Returns the new root of the subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1051 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1052 * @param subTree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1053 * @return the index of the new root
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1054 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1055 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1056 private final int removeNode(int subTree) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1057 int left = leftSubTree[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1058 int right = rightSubTree[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1059
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1060 if (left is -1 || right is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1061 int result = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1062
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1063 if (left is -1 && right is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1064 // If this is a leaf node, replace it with its first unsorted child
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1065 result = nextUnsorted[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1066 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1067 // Either the left or right child is missing -- replace with the remaining child
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1068 if (left is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1069 result = right;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1070 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1071 result = left;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1072 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1073
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1074 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1075 result = partition(result, new FastProgressReporter());
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1076 } catch (InterruptedException e) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1077
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1078 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1079 if (result is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1080 result = nextUnsorted[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1081 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1082 int unsorted = nextUnsorted[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1083 nextUnsorted[result] = unsorted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1084 int additionalNodes = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1085 if (unsorted !is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1086 parentTree[unsorted] = result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1087 additionalNodes = treeSize[unsorted];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1088 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1089 treeSize[result] += additionalNodes;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1090 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1091 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1092
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1093 replaceNode(subTree, result);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1094 destroyNode(subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1095 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1096 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1097
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1098 // Find the edges that lead to the next-smallest and
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1099 // next-largest nodes
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1100 Edge nextSmallest = new Edge(subTree, DIR_LEFT);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1101 while (!nextSmallest.isNull()) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1102 nextSmallest.advance(DIR_RIGHT);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1103 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1104
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1105 Edge nextLargest = new Edge(subTree, DIR_RIGHT);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1106 while (!nextLargest.isNull()) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1107 nextLargest.advance(DIR_LEFT);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1108 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1109
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1110 // Index of the replacement node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1111 int replacementNode = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1112
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1113 // Count of number of nodes moved to the right
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1114
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1115 int leftSize = getSubtreeSize(left);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1116 int rightSize = getSubtreeSize(right);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1117
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1118 // Swap with a child from the larger subtree
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1119 if (leftSize > rightSize) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1120 replacementNode = nextSmallest.getStart();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1121
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1122 // Move any unsorted nodes that are larger than the replacement node into
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1123 // the left subtree of the next-largest node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1124 Edge unsorted = new Edge(replacementNode, DIR_UNSORTED);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1125 while (!unsorted.isNull()) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1126 int target = unsorted.getTarget();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1127
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1128 if (!isLess(target, replacementNode)) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1129 unsorted.setTarget(nextUnsorted[target]);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1130 nextLargest.setTarget(addUnsorted(nextLargest.getTarget(), target));
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1131 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1132 unsorted.advance(DIR_UNSORTED);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1133 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1134 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1135
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1136 forceRecomputeTreeSize(unsorted.getStart(), replacementNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1137 forceRecomputeTreeSize(nextLargest.getStart(), subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1138 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1139 replacementNode = nextLargest.getStart();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1140
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1141 // Move any unsorted nodes that are smaller than the replacement node into
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1142 // the right subtree of the next-smallest node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1143 Edge unsorted = new Edge(replacementNode, DIR_UNSORTED);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1144 while (!unsorted.isNull()) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1145 int target = unsorted.getTarget();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1146
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1147 if (isLess(target, replacementNode)) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1148 unsorted.setTarget(nextUnsorted[target]);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1149 nextSmallest.setTarget(addUnsorted(nextSmallest.getTarget(), target));
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1150 } else {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1151 unsorted.advance(DIR_UNSORTED);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1152 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1153 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1154
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1155 forceRecomputeTreeSize(unsorted.getStart(), replacementNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1156 forceRecomputeTreeSize(nextSmallest.getStart(), subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1157 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1158
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1159 // Now all the affected treeSize[...] elements should be updated to reflect the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1160 // unsorted nodes that moved. Swap nodes.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1161 Object replacementContent = contents[replacementNode];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1162 contents[replacementNode] = contents[subTree];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1163 contents[subTree] = replacementContent;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1164
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1165 if (objectIndices !is null) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1166 objectIndices.put(replacementContent, subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1167 // Note: currently we don't bother updating the index of the replacement
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1168 // node since we're going to remove it immediately afterwards and there's
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1169 // no good reason to search for the index in a method that was given the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1170 // index as a parameter...
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1171
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1172 // objectIndices.put(contents[replacementNode], replacementNode)
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1173 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1174
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1175 int replacementParent = parentTree[replacementNode];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1176
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1177 replaceNode(replacementNode, removeNode(replacementNode));
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1178 //Edge parentEdge = getEdgeTo(replacementNode);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1179 //parentEdge.setTarget(removeNode(replacementNode));
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1180
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1181 forceRecomputeTreeSize(replacementParent, subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1182 recomputeTreeSize(subTree);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1183
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1184 //testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1185
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1186 return subTree;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1187 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1188
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1189 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1190 * Removes all elements from the collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1191 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1192 public final void clear() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1193 lastNode = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1194 setArraySize(MIN_CAPACITY);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1195 root = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1196 firstUnusedNode = -1;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1197 objectIndices = null;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1198
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1199 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1200 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1201
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1202 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1203 * Returns the comparator that is determining the sort order for this collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1204 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1205 * @return comparator for this collection
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1206 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1207 public Comparator getComparator() {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1208 return comparator;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1209 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1210
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1211 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1212 * Fills in an array of size n with the n smallest elements from the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1213 * Can compute the result in sorted or unsorted order.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1214 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1215 * Currently package visible until the implementation of FastProgressReporter is finished.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1216 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1217 * @param result array to be filled
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1218 * @param sorted if true, the result array will be sorted. If false, the result array
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1219 * may be unsorted. This does not affect which elements appear in the result, only their
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1220 * order.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1221 * @param mon monitor used to report progress and check for cancellation
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1222 * @return the number of items inserted into the result array. This will be equal to the minimum
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1223 * of result.length and container.size()
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1224 * @throws InterruptedException if the progress monitor is cancelled
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1225 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1226 /* package */ final int getFirst(Object[] result, bool sorted, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1227 int returnValue = getRange(result, 0, sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1228
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1229 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1230
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1231 return returnValue;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1232 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1233
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1234 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1235 * Fills in an array of size n with the n smallest elements from the collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1236 * Can compute the result in sorted or unsorted order.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1237 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1238 * @param result array to be filled
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1239 * @param sorted if true, the result array will be sorted. If false, the result array
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1240 * may be unsorted. This does not affect which elements appear in the result. It only
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1241 * affects their order. Computing an unsorted result is asymptotically faster.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1242 * @return the number of items inserted into the result array. This will be equal to the minimum
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1243 * of result.length and container.size()
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1244 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1245 public final int getFirst(Object[] result, bool sorted) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1246 int returnValue = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1247
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1248 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1249 returnValue = getFirst(result, sorted, new FastProgressReporter());
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1250 } catch (InterruptedException e) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1251 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1252
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1253 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1254
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1255 return returnValue;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1256 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1257
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1258 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1259 * Given a position defined by k and an array of size n, this fills in the array with
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1260 * the kth smallest element through to the (k+n)th smallest element. For example,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1261 * getRange(myArray, 10, false) would fill in myArray starting with the 10th smallest item
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1262 * in the collection. The result can be computed in sorted or unsorted order. Computing the
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1263 * result in unsorted order is more efficient.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1264 * <p>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1265 * Temporarily set to package visibility until the implementation of FastProgressReporter
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1266 * is finished.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1267 * </p>
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1268 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1269 * @param result array to be filled in
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1270 * @param rangeStart index of the smallest element to appear in the result
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1271 * @param sorted true iff the result array should be sorted
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1272 * @param mon progress monitor used to cancel the operation
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1273 * @throws InterruptedException if the progress monitor was cancelled in another thread
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1274 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1275 /* package */ final int getRange(Object[] result, int rangeStart, bool sorted, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1276 return getRange(result, 0, rangeStart, root, sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1277 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1278
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1279 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1280 * Computes the n through n+k items in this collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1281 * Computing the result in unsorted order is more efficient. Sorting the result will
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1282 * not change which elements actually show up in the result. That is, even if the result is
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1283 * unsorted, it will still contain the same elements as would have been at that range in
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1284 * a fully sorted collection.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1285 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1286 * @param result array containing the result
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1287 * @param rangeStart index of the first element to be inserted into the result array
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1288 * @param sorted true iff the result will be computed in sorted order
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1289 * @return the number of items actually inserted into the result array (will be the minimum
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1290 * of result.length and this.size())
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1291 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1292 public final int getRange(Object[] result, int rangeStart, bool sorted) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1293 int returnValue = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1294
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1295 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1296 returnValue = getRange(result, rangeStart, sorted, new FastProgressReporter());
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1297 } catch (InterruptedException e) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1298 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1299
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1300 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1301
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1302 return returnValue;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1303 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1304
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1305 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1306 * Returns the item at the given index. Indexes are based on sorted order.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1307 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1308 * @param index index to test
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1309 * @return the item at the given index
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1310 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1311 public final Object getItem(int index) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1312 Object[] result = new Object[1];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1313 try {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1314 getRange(result, index, false, new FastProgressReporter());
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1315 } catch (InterruptedException e) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1316 // shouldn't happen
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1317 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1318 Object returnValue = result[0];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1319
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1320 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1321
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1322 return returnValue;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1323 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1324
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1325 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1326 * Returns the contents of this collection as a sorted or unsorted
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1327 * array. Computing an unsorted array is more efficient.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1328 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1329 * @param sorted if true, the result will be in sorted order. If false,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1330 * the result may be in unsorted order.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1331 * @return the contents of this collection as an array.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1332 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1333 public final Object[] getItems(bool sorted) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1334 Object[] result = new Object[size()];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1335
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1336 getRange(result, 0, sorted);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1337
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1338 return result;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1339 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1340
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1341 private final int getRange(Object[] result, int resultIdx, int rangeStart, int node, bool sorted, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1342 if (node is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1343 return 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1344 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1345
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1346 int availableSpace = result.length - resultIdx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1347
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1348 // If we're asking for all children of the current node, simply call getChildren
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1349 if (rangeStart is 0) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1350 if (treeSize[node] <= availableSpace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1351 return getChildren(result, resultIdx, node, sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1352 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1353 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1354
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1355 node = partition(node, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1356 if (node is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1357 return 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1358 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1359
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1360 int inserted = 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1361
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1362 int numberLessThanNode = getSubtreeSize(leftSubTree[node]);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1363
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1364 if (rangeStart < numberLessThanNode) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1365 if (inserted < availableSpace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1366 inserted += getRange(result, resultIdx, rangeStart, leftSubTree[node], sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1367 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1368 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1369
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1370 if (rangeStart <= numberLessThanNode) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1371 if (inserted < availableSpace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1372 result[resultIdx + inserted] = contents[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1373 inserted++;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1374 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1375 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1376
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1377 if (inserted < availableSpace) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1378 inserted += getRange(result, resultIdx + inserted,
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1379 Math.max(rangeStart - numberLessThanNode - 1, 0), rightSubTree[node], sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1380 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1381
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1382 return inserted;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1383 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1384
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1385 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1386 * Fills in the available space in the given array with all children of the given node.
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1387 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1388 * @param result
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1389 * @param resultIdx index in the result array where we will begin filling in children
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1390 * @param node
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1391 * @return the number of children added to the array
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1392 * @since 3.1
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1393 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1394 private final int getChildren(Object[] result, int resultIdx, int node, bool sorted, FastProgressReporter mon) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1395 if (node is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1396 return 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1397 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1398
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1399 int tempIdx = resultIdx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1400
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1401 if (sorted) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1402 node = partition(node, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1403 if (node is -1) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1404 return 0;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1405 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1406 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1407
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1408 // Add child nodes smaller than this one
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1409 if (tempIdx < result.length) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1410 tempIdx += getChildren(result, tempIdx, leftSubTree[node], sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1411 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1412
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1413 // Add the pivot
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1414 if (tempIdx < result.length) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1415 Object value = contents[node];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1416 if (value !is lazyRemovalFlag) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1417 result[tempIdx++] = value;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1418 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1419 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1420
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1421 // Add child nodes larger than this one
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1422 if (tempIdx < result.length) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1423 tempIdx += getChildren(result, tempIdx, rightSubTree[node], sorted, mon);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1424 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1425
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1426 // Add unsorted children (should be empty if the sorted flag was true)
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1427 for (int unsortedNode = nextUnsorted[node]; unsortedNode !is -1 && tempIdx < result.length;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1428 unsortedNode = nextUnsorted[unsortedNode]) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1429
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1430 result[tempIdx++] = contents[unsortedNode];
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1431 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1432
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1433 return tempIdx - resultIdx;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1434 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1435
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1436 /**
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1437 * Returns true iff this collection contains the given item
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1438 *
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1439 * @param item item to test
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1440 * @return true iff this collection contains the given item
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1441 */
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1442 public bool contains(Object item) {
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1443 Assert.isNotNull(item);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1444 bool returnValue = (getObjectIndex(item) !is -1);
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1445
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1446 testInvariants();
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1447
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1448 return returnValue;
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1449 }
b6c35faf97c8 Viewers
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1450 }