Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(837)

Side by Side Diff: sdk/lib/collection/splay_tree.dart

Issue 12304016: Restructure SplayTreeMap to be reusable (e.g., for a SplayTreeSet). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/corelib/map_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.collection; 5 part of dart.collection;
6 6
7 /** 7 /**
8 * A node in a splay tree. It holds the key, the value and the left 8 * A node in a splay tree. It holds the sorting key and the left
9 * and right children in the tree. 9 * and right children in the tree.
10 */ 10 */
11 class SplayTreeNode<K, V> { 11 class _SplayTreeNode<K> {
12 final K key; 12 final K key;
13 V value; 13 _SplayTreeNode<K> left;
14 SplayTreeNode<K, V> left; 14 _SplayTreeNode<K> right;
15 SplayTreeNode<K, V> right;
16 15
17 SplayTreeNode(K this.key, V this.value); 16 _SplayTreeNode(K this.key);
18 } 17 }
19 18
20 /** 19 /**
21 * A splay tree is a self-balancing binary 20 * A node in a splay tree based map.
22 * search tree with the additional property that recently accessed
23 * elements are quick to access again. It performs basic operations
24 * such as insertion, look-up and removal in O(log(n)) amortized time.
25 * 21 *
26 * This implementation is a Dart version of the JavaScript 22 * A [_SplayTreeNode] that also contains a value
27 * implementation in the V8 project.
28 */ 23 */
29 class SplayTreeMap<K extends Comparable<K>, V> implements Map<K, V> { 24 class _SplayTreeMapNode<K, V> extends _SplayTreeNode<K> {
25 V value;
26 _SplayTreeMapNode(K key, V this.value) : super(key);
27 }
30 28
29 /**
30 * A splay tree is a self-balancing binary search tree.
31 *
32 * It has the additional property that recently accessed elements
33 * are quick to access again.
34 * It performs basic operations such as insertion, look-up and
35 * removal, in O(log(n)) amortized time.
36 */
37 abstract class _SplayTree<K> {
31 // The root node of the splay tree. It will contain either the last 38 // The root node of the splay tree. It will contain either the last
32 // element inserted, or the last element looked up. 39 // element inserted, or the last element looked up.
33 SplayTreeNode<K, V> _root; 40 _SplayTreeNode<K> _root;
34 41
35 // The dummy node used when performing a splay on the tree. It is a 42 // The dummy node used when performing a splay on the tree. It is a
36 // local field of the class to avoid allocating a node each time a 43 // local field of the class to avoid allocating a node each time a
37 // splay is performed. 44 // splay is performed.
38 SplayTreeNode<K, V> _dummy; 45 // TODO(lrn); Should it be a getter backed by a static instead?
46 _SplayTreeNode<K> _dummy = new _SplayTreeNode<K>(null);
39 47
40 // Number of elements in the splay tree. 48 // Number of elements in the splay tree.
41 int _count; 49 int _count = 0;
42 50
43 /** 51 /**
44 * Counter incremented whenever the keys in the map changes. 52 * Counter incremented whenever the keys in the map changes.
45 * 53 *
46 * Used to detect concurrent modifications. 54 * Used to detect concurrent modifications.
47 */ 55 */
48 int _modificationCount = 0; 56 int _modificationCount = 0;
57
49 /** 58 /**
50 * Counter incremented whenever the tree structure changes. 59 * Counter incremented whenever the tree structure changes.
51 * 60 *
52 * Used to detect that an in-place traversal cannot use 61 * Used to detect that an in-place traversal cannot use
53 * cached information that relies on the tree structure. 62 * cached information that relies on the tree structure.
54 */ 63 */
55 int _splayCount = 0; 64 int _splayCount = 0;
56 65
57 SplayTreeMap() : 66 /** Comparison used to compare keys. */
58 _dummy = new SplayTreeNode<K, V>(null, null), 67 int _compare(K key1, K key2);
59 _count = 0;
60 68
61 /** 69 /**
62 * Perform the splay operation for the given key. Moves the node with 70 * Perform the splay operation for the given key. Moves the node with
63 * the given key to the top of the tree. If no node has the given 71 * the given key to the top of the tree. If no node has the given
64 * key, the last node on the search path is moved to the top of the 72 * key, the last node on the search path is moved to the top of the
65 * tree. This is the simplified top-down splaying algorithm from: 73 * tree. This is the simplified top-down splaying algorithm from:
66 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. 74 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan.
67 * 75 *
68 * Returns the result of comparing the new root of the tree to [key]. 76 * Returns the result of comparing the new root of the tree to [key].
69 * Returns -1 if the table is empty. 77 * Returns -1 if the table is empty.
70 */ 78 */
71 int _splay(K key) { 79 int _splay(K key) {
72 if (_root == null) return -1; 80 if (_root == null) return -1;
73 81
74 // The right child of the dummy node will hold 82 // The right child of the dummy node will hold
75 // the L tree of the algorithm. The left child of the dummy node 83 // the L tree of the algorithm. The left child of the dummy node
76 // will hold the R tree of the algorithm. Using a dummy node, left 84 // will hold the R tree of the algorithm. Using a dummy node, left
77 // and right will always be nodes and we avoid special cases. 85 // and right will always be nodes and we avoid special cases.
78 SplayTreeNode<K, V> left = _dummy; 86 _SplayTreeNode<K> left = _dummy;
79 SplayTreeNode<K, V> right = _dummy; 87 _SplayTreeNode<K> right = _dummy;
80 SplayTreeNode<K, V> current = _root; 88 _SplayTreeNode<K> current = _root;
81 int comp; 89 int comp;
82 while (true) { 90 while (true) {
83 comp = current.key.compareTo(key); 91 comp = current.key.compareTo(key);
84 if (comp > 0) { 92 if (comp > 0) {
85 if (current.left == null) break; 93 if (current.left == null) break;
86 comp = current.left.key.compareTo(key); 94 comp = current.left.key.compareTo(key);
87 if (comp > 0) { 95 if (comp > 0) {
88 // Rotate right. 96 // Rotate right.
89 SplayTreeNode<K, V> tmp = current.left; 97 _SplayTreeNode<K> tmp = current.left;
90 current.left = tmp.right; 98 current.left = tmp.right;
91 tmp.right = current; 99 tmp.right = current;
92 current = tmp; 100 current = tmp;
93 if (current.left == null) break; 101 if (current.left == null) break;
94 } 102 }
95 // Link right. 103 // Link right.
96 right.left = current; 104 right.left = current;
97 right = current; 105 right = current;
98 current = current.left; 106 current = current.left;
99 } else if (comp < 0) { 107 } else if (comp < 0) {
100 if (current.right == null) break; 108 if (current.right == null) break;
101 comp = current.right.key.compareTo(key); 109 comp = current.right.key.compareTo(key);
102 if (comp < 0) { 110 if (comp < 0) {
103 // Rotate left. 111 // Rotate left.
104 SplayTreeNode<K, V> tmp = current.right; 112 _SplayTreeNode<K> tmp = current.right;
105 current.right = tmp.left; 113 current.right = tmp.left;
106 tmp.left = current; 114 tmp.left = current;
107 current = tmp; 115 current = tmp;
108 if (current.right == null) break; 116 if (current.right == null) break;
109 } 117 }
110 // Link left. 118 // Link left.
111 left.right = current; 119 left.right = current;
112 left = current; 120 left = current;
113 current = current.right; 121 current = current.right;
114 } else { 122 } else {
115 break; 123 break;
116 } 124 }
117 } 125 }
118 // Assemble. 126 // Assemble.
119 left.right = current.left; 127 left.right = current.left;
120 right.left = current.right; 128 right.left = current.right;
121 current.left = _dummy.right; 129 current.left = _dummy.right;
122 current.right = _dummy.left; 130 current.right = _dummy.left;
123 _root = current; 131 _root = current;
124 132
125 _dummy.right = null; 133 _dummy.right = null;
126 _dummy.left = null; 134 _dummy.left = null;
127 _splayCount++; 135 _splayCount++;
128 return comp; 136 return comp;
129 } 137 }
130 138
131 V operator [](K key) { 139 _SplayTreeNode _remove(K key) {
132 if (_root != null) {
133 int comp = _splay(key);
134 if (comp == 0) return _root.value;
135 }
136 return null;
137 }
138
139 V remove(K key) {
140 if (_root == null) return null; 140 if (_root == null) return null;
141 int comp = _splay(key); 141 int comp = _splay(key);
142 if (comp != 0) return null; 142 if (comp != 0) return null;
143 V value = _root.value; 143 _SplayTreeNode result = _root;
144
145 _count--; 144 _count--;
146 // assert(_count >= 0); 145 // assert(_count >= 0);
147 if (_root.left == null) { 146 if (_root.left == null) {
148 _root = _root.right; 147 _root = _root.right;
149 } else { 148 } else {
150 SplayTreeNode<K, V> right = _root.right; 149 _SplayTreeNode<K> right = _root.right;
151 _root = _root.left; 150 _root = _root.left;
152 // Splay to make sure that the new root has an empty right child. 151 // Splay to make sure that the new root has an empty right child.
153 _splay(key); 152 _splay(key);
154 // Insert the original right child as the right child of the new 153 // Insert the original right child as the right child of the new
155 // root. 154 // root.
156 _root.right = right; 155 _root.right = right;
157 } 156 }
158 _modificationCount++; 157 _modificationCount++;
159 return value; 158 return result;
160 }
161
162 void operator []=(K key, V value) {
163 if (_root == null) {
164 _count++;
165 _root = new SplayTreeNode(key, value);
166 _modificationCount++;
167 return;
168 }
169 // Splay on the key to move the last node on the search path for
170 // the key to the root of the tree.
171 int comp = _splay(key);
172 if (comp == 0) {
173 _root.value = value;
174 return;
175 }
176 _addNewRoot(key, value, comp);
177 } 159 }
178 160
179 /** 161 /**
180 * Adds a new root node with the given [key] or [value]. 162 * Adds a new root node with the given [key] or [value].
181 * 163 *
182 * The [comp] value is the result of comparing the existing root's key 164 * The [comp] value is the result of comparing the existing root's key
183 * with key. 165 * with key.
184 */ 166 */
185 void _addNewRoot(K key, V value, int comp) { 167 void _addNewRoot(_SplayTreeNode<K> node, int comp) {
186 SplayTreeNode<K, V> node = new SplayTreeNode(key, value); 168 _count++;
169 _modificationCount++;
170 if (_root == null) {
171 _root = node;
172 return;
173 }
187 // assert(_count >= 0); 174 // assert(_count >= 0);
188 _count++;
189 if (comp < 0) { 175 if (comp < 0) {
190 node.left = _root; 176 node.left = _root;
191 node.right = _root.right; 177 node.right = _root.right;
192 _root.right = null; 178 _root.right = null;
193 } else { 179 } else {
194 node.right = _root; 180 node.right = _root;
195 node.left = _root.left; 181 node.left = _root.left;
196 _root.left = null; 182 _root.left = null;
197 } 183 }
198 _root = node; 184 _root = node;
185 }
186
187 _SplayTreeNode get _first {
188 if (_root == null) return null;
189 _SplayTreeNode<K> node = _root;
190 while (node.left != null) {
191 node = node.left;
192 }
193 // Maybe implement a splay-method that can splay the minimum without
194 // performing comparisons.
195 _splay(node.key);
196 return node;
197 }
198
199 _SplayTreeNode get _last {
200 if (_root == null) return null;
201 _SplayTreeNode<K> node = _root;
202 while (node.right != null) {
203 node = node.right;
204 }
205 // Maybe implement a splay-method that can splay the minimum without
206 // performing comparisons.
207 _splay(node.key);
208 return node;
209 }
210
211 void _clear() {
212 _root = null;
213 _count = 0;
199 _modificationCount++; 214 _modificationCount++;
200 } 215 }
216 }
217
218 /*
219 * A [Map] of objects that can be ordered relative to each other.
220 *
221 * The map is based on a self-balancing binary tree. It allows most operations
222 * in amortized logarithmic time.
223 *
224 * Keys of the map are compared using the `compare` function passed in
225 * the constructor. If that is omitted, the objects are assumed to be
226 * [Comparable], and are compared using their [Comparable.compareTo]
227 * method.
228 */
229 class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> {
230 Comparator<K> _comparator;
231
232 SplayTreeMap([int compare(K key1, K key2)])
233 : _comparator = (compare == null) ? Comparable.compare : compare;
234
235 int _compare(K key1, K key2) => _comparator(key1, key2);
236
237 SplayTreeMap._internal();
238
239 V operator [](K key) {
240 if (_root != null) {
241 int comp = _splay(key);
242 if (comp == 0) return _root.value;
243 }
244 return null;
245 }
246
247 V remove(K key) {
248 _SplayTreeMapNode root = _remove(key);
249 if (root != null) return root.value;
250 return null;
251 }
252
253 void operator []=(K key, V value) {
254 // Splay on the key to move the last node on the search path for
255 // the key to the root of the tree.
256 int comp = _splay(key);
257 if (comp == 0) {
258 _root.value = value;
259 return;
260 }
261 _addNewRoot(new _SplayTreeMapNode(key, value), comp);
262 }
263
201 264
202 V putIfAbsent(K key, V ifAbsent()) { 265 V putIfAbsent(K key, V ifAbsent()) {
203 if (_root == null) {
204 V value = ifAbsent();
205 if (_root != null) {
206 throw new ConcurrentModificationError(this);
207 }
208 _root = new SplayTreeNode(key, value);
209 _count++;
210 _modificationCount++;
211 return value;
212 }
213 int comp = _splay(key); 266 int comp = _splay(key);
214 if (comp == 0) return _root.value; 267 if (comp == 0) return _root.value;
215 int modificationCount = _modificationCount; 268 int modificationCount = _modificationCount;
216 int splayCount = _splayCount; 269 int splayCount = _splayCount;
217 V value = ifAbsent(); 270 V value = ifAbsent();
218 if (modificationCount != _modificationCount) { 271 if (modificationCount != _modificationCount) {
219 throw new ConcurrentModificationError(this); 272 throw new ConcurrentModificationError(this);
220 } 273 }
221 if (splayCount != _splayCount) { 274 if (splayCount != _splayCount) {
222 comp = _splay(key); 275 comp = _splay(key);
223 // Key is still not there, otherwise _modificationCount would be changed. 276 // Key is still not there, otherwise _modificationCount would be changed.
224 assert(comp != 0); 277 assert(comp != 0);
225 } 278 }
226 _addNewRoot(key, value, comp); 279 _addNewRoot(new _SplayTreeMapNode(key, value), comp);
227 return value; 280 return value;
228 } 281 }
229 282
230 bool get isEmpty { 283 bool get isEmpty {
231 // assert(!((_root == null) && (_count != 0))); 284 // assert(!((_root == null) && (_count != 0)));
232 // assert(!((_count == 0) && (_root != null))); 285 // assert(!((_count == 0) && (_root != null)));
233 return (_root == null); 286 return (_root == null);
234 } 287 }
235 288
236 void forEach(void f(K key, V value)) { 289 void forEach(void f(K key, V value)) {
237 Iterator<SplayTreeNode<K, V>> nodes = 290 Iterator<_SplayTreeNode<K>> nodes =
238 new _SplayTreeNodeIterator<K, V>(this); 291 new _SplayTreeNodeIterator<K>(this);
239 while (nodes.moveNext()) { 292 while (nodes.moveNext()) {
240 SplayTreeNode<K, V> node = nodes.current; 293 _SplayTreeMapNode<K, V> node = nodes.current;
241 f(node.key, node.value); 294 f(node.key, node.value);
242 } 295 }
243 } 296 }
244 297
245 int get length { 298 int get length {
246 return _count; 299 return _count;
247 } 300 }
248 301
249 void clear() { 302 void clear() {
250 _root = null; 303 _clear();
251 _count = 0;
252 } 304 }
253 305
254 bool containsKey(K key) { 306 bool containsKey(K key) {
255 return _splay(key) == 0; 307 return _splay(key) == 0;
256 } 308 }
257 309
258 bool containsValue(V value) { 310 bool containsValue(V value) {
259 bool found = false; 311 bool found = false;
260 bool visit(SplayTreeNode node) { 312 bool visit(_SplayTreeNode node) {
261 if (node == null) return false; 313 if (node == null) return false;
262 if (node.value == value) return true; 314 if (node.value == value) return true;
263 // TODO(lrn): Do we want to handle the case where node.value.operator== 315 // TODO(lrn): Do we want to handle the case where node.value.operator==
264 // modifies the map? 316 // modifies the map?
265 return visit(node.left) || visit(node.right); 317 return visit(node.left) || visit(node.right);
266 } 318 }
267 return visit(_root); 319 return visit(_root);
268 } 320 }
269 321
270 Iterable<K> get keys => new _SplayTreeKeyIterable(this); 322 Iterable<K> get keys => new _SplayTreeKeyIterable<K>(this);
271 323
272 Iterable<V> get values => new _SplayTreeValueIterable(this); 324 Iterable<V> get values => new _SplayTreeValueIterable<K, V>(this);
273 325
274 String toString() { 326 String toString() {
275 return Maps.mapToString(this); 327 return Maps.mapToString(this);
276 } 328 }
277 329
278 /** 330 /**
279 * Get the first key in the map. Returns [null] if the map is empty. 331 * Get the first key in the map. Returns [null] if the map is empty.
280 */ 332 */
281 K firstKey() { 333 K firstKey() {
282 if (_root == null) return null; 334 _SplayTreeNode node = _first;
283 SplayTreeNode<K, V> node = _root; 335 return (node == null) ? null : node.key;
284 while (node.left != null) {
285 node = node.left;
286 }
287 // Maybe implement a splay-method that can splay the minimum without
288 // performing comparisons.
289 _splay(node.key);
290 return node.key;
291 } 336 }
292 337
293 /** 338 /**
294 * Get the last key in the map. Returns [null] if the map is empty. 339 * Get the last key in the map. Returns [null] if the map is empty.
295 */ 340 */
296 K lastKey() { 341 K lastKey() {
297 if (_root == null) return null; 342 _SplayTreeNode node = _last;
298 SplayTreeNode<K, V> node = _root; 343 return (node == null) ? null : node.key;
299 while (node.right != null) {
300 node = node.right;
301 }
302 // Maybe implement a splay-method that can splay the maximum without
303 // performing comparisons.
304 _splay(node.key);
305 return node.key;
306 } 344 }
307 345
308 /** 346 /**
309 * Get the last key in the map that is strictly smaller than [key]. Returns 347 * Get the last key in the map that is strictly smaller than [key]. Returns
310 * [null] if no key was not found. 348 * [null] if no key was not found.
311 */ 349 */
312 K lastKeyBefore(K key) { 350 K lastKeyBefore(K key) {
313 if (_root == null) return null; 351 if (_root == null) return null;
314 int comp = _splay(key); 352 int comp = _splay(key);
315 if (comp < 0) return _root.key; 353 if (comp < 0) return _root.key;
316 SplayTreeNode<K, V> node = _root.left; 354 _SplayTreeNode<K> node = _root.left;
317 if (node == null) return null; 355 if (node == null) return null;
318 while (node.right != null) { 356 while (node.right != null) {
319 node = node.right; 357 node = node.right;
320 } 358 }
321 return node.key; 359 return node.key;
322 } 360 }
323 361
324 /** 362 /**
325 * Get the first key in the map that is strictly larger than [key]. Returns 363 * Get the first key in the map that is strictly larger than [key]. Returns
326 * [null] if no key was not found. 364 * [null] if no key was not found.
327 */ 365 */
328 K firstKeyAfter(K key) { 366 K firstKeyAfter(K key) {
329 if (_root == null) return null; 367 if (_root == null) return null;
330 int comp = _splay(key); 368 int comp = _splay(key);
331 if (comp > 0) return _root.key; 369 if (comp > 0) return _root.key;
332 SplayTreeNode<K, V> node = _root.right; 370 _SplayTreeNode<K> node = _root.right;
333 if (node == null) return null; 371 if (node == null) return null;
334 while (node.left != null) { 372 while (node.left != null) {
335 node = node.left; 373 node = node.left;
336 } 374 }
337 return node.key; 375 return node.key;
338 } 376 }
339 } 377 }
340 378
341 abstract class _SplayTreeIterator<T> implements Iterator<T> { 379 abstract class _SplayTreeIterator<T> implements Iterator<T> {
342 final SplayTreeMap _map; 380 final _SplayTree _tree;
343 /** 381 /**
344 * Worklist of nodes to visit. 382 * Worklist of nodes to visit.
345 * 383 *
346 * These nodes have been passed over on the way down in a 384 * These nodes have been passed over on the way down in a
347 * depth-first left-to-right traversal. Visiting each node, 385 * depth-first left-to-right traversal. Visiting each node,
348 * and their right subtrees will visit the remainder of 386 * and their right subtrees will visit the remainder of
349 * the nodes of a full traversal. 387 * the nodes of a full traversal.
350 * 388 *
351 * Only valid as long as the original tree map isn't reordered. 389 * Only valid as long as the original tree isn't reordered.
352 */ 390 */
353 final List<SplayTreeNode> _workList = <SplayTreeNode>[]; 391 final List<_SplayTreeNode> _workList = <_SplayTreeNode>[];
354 392
355 /** 393 /**
356 * Original modification counter of [_map]. 394 * Original modification counter of [_tree].
357 * 395 *
358 * Incremented on [_map] when a key is added or removed. 396 * Incremented on [_tree] when a key is added or removed.
359 * If it changes, iteration is aborted. 397 * If it changes, iteration is aborted.
360 */ 398 */
361 final int _modificationCount; 399 final int _modificationCount;
362 400
363 /** 401 /**
364 * Count of splay operations on [_map] when [_workList] was built. 402 * Count of splay operations on [_tree] when [_workList] was built.
365 * 403 *
366 * If the splay count on [_map] increases, [_workList] becomes invalid. 404 * If the splay count on [_tree] increases, [_workList] becomes invalid.
367 */ 405 */
368 int _splayCount; 406 int _splayCount;
369 407
370 /** Current node. */ 408 /** Current node. */
371 SplayTreeNode _currentNode; 409 _SplayTreeNode _currentNode;
372 410
373 _SplayTreeIterator(SplayTreeMap map) 411 _SplayTreeIterator(_SplayTree tree)
374 : _map = map, 412 : _tree = tree,
375 _modificationCount = map._modificationCount, 413 _modificationCount = tree._modificationCount,
376 _splayCount = map._splayCount { 414 _splayCount = tree._splayCount {
377 _findLeftMostDescendent(map._root); 415 _findLeftMostDescendent(tree._root);
378 } 416 }
379 417
380 T get current { 418 T get current {
381 if (_currentNode == null) return null; 419 if (_currentNode == null) return null;
382 return _getValue(_currentNode); 420 return _getValue(_currentNode);
383 } 421 }
384 422
385 void _findLeftMostDescendent(SplayTreeNode node) { 423 void _findLeftMostDescendent(_SplayTreeNode node) {
386 while (node != null) { 424 while (node != null) {
387 _workList.add(node); 425 _workList.add(node);
388 node = node.left; 426 node = node.left;
389 } 427 }
390 } 428 }
391 429
392 /** 430 /**
393 * Called when the tree structure of the map has changed. 431 * Called when the tree structure of the tree has changed.
394 * 432 *
395 * This can be caused by a splay operation. 433 * This can be caused by a splay operation.
396 * If the key-set changes, iteration is aborted before getting 434 * If the key-set changes, iteration is aborted before getting
397 * here, so we know that the keys are the same as before, it's 435 * here, so we know that the keys are the same as before, it's
398 * only the tree that has been reordered. 436 * only the tree that has been reordered.
399 */ 437 */
400 void _rebuildWorkList(SplayTreeNode currentNode) { 438 void _rebuildWorkList(_SplayTreeNode currentNode) {
401 assert(!_workList.isEmpty); 439 assert(!_workList.isEmpty);
402 _workList.clear(); 440 _workList.clear();
403 if (currentNode == null) { 441 if (currentNode == null) {
404 _findLeftMostDescendent(_map._root); 442 _findLeftMostDescendent(_tree._root);
405 } else { 443 } else {
406 _map._splay(currentNode.key); 444 _tree._splay(currentNode.key);
407 _findLeftMostDescendent(_map._root.right); 445 _findLeftMostDescendent(_tree._root.right);
408 assert(!_workList.isEmpty); 446 assert(!_workList.isEmpty);
409 } 447 }
410 } 448 }
411 449
412 bool moveNext() { 450 bool moveNext() {
413 if (_modificationCount != _map._modificationCount) { 451 if (_modificationCount != _tree._modificationCount) {
414 throw new ConcurrentModificationError(_map); 452 throw new ConcurrentModificationError(_tree);
415 } 453 }
416 // Picks the next element in the worklist as current. 454 // Picks the next element in the worklist as current.
417 // Updates the worklist with the left-most path of the current node's 455 // Updates the worklist with the left-most path of the current node's
418 // right-hand child. 456 // right-hand child.
419 // If the worklist is no longer valid (after a splay), it is rebuild 457 // If the worklist is no longer valid (after a splay), it is rebuild
420 // from scratch. 458 // from scratch.
421 if (_workList.isEmpty) { 459 if (_workList.isEmpty) {
422 _currentNode = null; 460 _currentNode = null;
423 return false; 461 return false;
424 } 462 }
425 if (_map._splayCount != _splayCount) { 463 if (_tree._splayCount != _splayCount) {
426 _rebuildWorkList(_currentNode); 464 _rebuildWorkList(_currentNode);
427 } 465 }
428 _currentNode = _workList.removeLast(); 466 _currentNode = _workList.removeLast();
429 _findLeftMostDescendent(_currentNode.right); 467 _findLeftMostDescendent(_currentNode.right);
430 return true; 468 return true;
431 } 469 }
432 470
433 T _getValue(SplayTreeNode node); 471 T _getValue(_SplayTreeNode node);
434 } 472 }
435 473
436 474 class _SplayTreeKeyIterable<K> extends Iterable<K> {
437 class _SplayTreeKeyIterable<K, V> extends Iterable<K> { 475 _SplayTree<K> _tree;
438 SplayTreeMap<K, V> _map; 476 _SplayTreeKeyIterable(this._tree);
439 _SplayTreeKeyIterable(this._map); 477 Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree);
440 Iterator<K> get iterator => new _SplayTreeKeyIterator<K, V>(_map);
441 } 478 }
442 479
443 class _SplayTreeValueIterable<K, V> extends Iterable<V> { 480 class _SplayTreeValueIterable<K, V> extends Iterable<V> {
444 SplayTreeMap<K, V> _map; 481 SplayTreeMap<K, V> _map;
445 _SplayTreeValueIterable(this._map) ; 482 _SplayTreeValueIterable(this._map);
446 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map); 483 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map);
447 } 484 }
448 485
449 class _SplayTreeKeyIterator<K, V> extends _SplayTreeIterator<K> { 486 class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K> {
450 _SplayTreeKeyIterator(SplayTreeMap<K, V> map): super(map); 487 _SplayTreeKeyIterator(_SplayTree<K> map): super(map);
451 K _getValue(SplayTreeNode node) => node.key; 488 K _getValue(_SplayTreeNode node) => node.key;
452 } 489 }
453 490
454 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { 491 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> {
455 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); 492 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map);
456 V _getValue(SplayTreeNode node) => node.value; 493 V _getValue(_SplayTreeMapNode node) => node.value;
457 } 494 }
458 495
459 class _SplayTreeNodeIterator<K, V> 496 class _SplayTreeNodeIterator<K>
460 extends _SplayTreeIterator<SplayTreeNode<K, V>> { 497 extends _SplayTreeIterator<_SplayTreeNode<K>> {
461 _SplayTreeNodeIterator(SplayTreeMap<K, V> map): super(map); 498 _SplayTreeNodeIterator(_SplayTree<K> map): super(map);
462 SplayTreeNode<K, V> _getValue(SplayTreeNode node) => node; 499 _SplayTreeNode<K> _getValue(_SplayTreeNode node) => node;
463 } 500 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/map_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698