| OLD | NEW |
| 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 } |
| OLD | NEW |