Chromium Code Reviews| 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 /** | 5 /** |
| 6 * A node in a splay tree. It holds the key, the value and the left | 6 * A node in a splay tree. It holds the key, the value and the left |
| 7 * and right children in the tree. | 7 * and right children in the tree. |
| 8 */ | 8 */ |
| 9 class SplayTreeNode<K, V> { | 9 class SplayTreeNode<K, V> { |
| 10 SplayTreeNode(K k, V v) { | 10 SplayTreeNode(K k, V v) { |
|
kasperl
2012/02/27 06:50:03
Use this.key and this.value?
Anders Johnsen
2012/02/27 09:06:51
Done.
| |
| 11 key = k; | 11 key = k; |
| 12 value = v; | 12 value = v; |
| 13 } | 13 } |
| 14 | 14 |
| 15 K key; | 15 K key; |
| 16 V value; | 16 V value; |
| 17 SplayTreeNode<K, V> left; | 17 SplayTreeNode<K, V> left; |
| 18 SplayTreeNode<K, V> right; | 18 SplayTreeNode<K, V> right; |
| 19 } | 19 } |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * A splay tree is a self-balancing binary | 22 * A splay tree is a self-balancing binary |
| 23 * search tree with the additional property that recently accessed | 23 * search tree with the additional property that recently accessed |
| 24 * elements are quick to access again. It performs basic operations | 24 * elements are quick to access again. It performs basic operations |
| 25 * such as insertion, look-up and removal in O(log(n)) amortized time. | 25 * such as insertion, look-up and removal in O(log(n)) amortized time. |
| 26 * | 26 * |
| 27 * This implementation is a Dart version of the JavaScript | 27 * This implementation is a Dart version of the JavaScript |
| 28 * implementation in the V8 project. | 28 * implementation in the V8 project. |
| 29 */ | 29 */ |
| 30 class SplayTree<K extends Comparable, V> implements Map<K, V> { | 30 class SplayTree<K extends Comparable, V> implements Map<K, V> { |
|
kasperl
2012/02/27 06:50:03
Long term, it would be great with both a map and a
Anders Johnsen
2012/02/27 09:06:51
Yep, renamed!
| |
| 31 | 31 |
| 32 // The root node of the splay tree. It will contain either the last | 32 // The root node of the splay tree. It will contain either the last |
| 33 // element inserted, or the last element looked up. | 33 // element inserted, or the last element looked up. |
| 34 SplayTreeNode<K, V> _root; | 34 SplayTreeNode<K, V> _root; |
| 35 | 35 |
| 36 // The dummy node used when performing a splay on the tree. It is a | 36 // The dummy node used when performing a splay on the tree. It is a |
| 37 // local field of the class to avoid allocating a node each time a | 37 // local field of the class to avoid allocating a node each time a |
| 38 // splay is performed. | 38 // splay is performed. |
| 39 SplayTreeNode<K, V> _dummy; | 39 SplayTreeNode<K, V> _dummy; |
| 40 | 40 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 if (_root.key.compareTo(key) == 0) return true; | 212 if (_root.key.compareTo(key) == 0) return true; |
| 213 } | 213 } |
| 214 return false; | 214 return false; |
| 215 } | 215 } |
| 216 | 216 |
| 217 bool containsValue(V value) { | 217 bool containsValue(V value) { |
| 218 bool found = false; | 218 bool found = false; |
| 219 // Note: Worst performance you can get because we don't have | 219 // Note: Worst performance you can get because we don't have |
| 220 // non-local return. | 220 // non-local return. |
| 221 // TODO: optimize this method with a similar code than forEach. | 221 // TODO: optimize this method with a similar code than forEach. |
| 222 forEach((Object k, Object v) { if (value == v) found = true; }); | 222 forEach((Object k, Object v) { if (value == v) found = true; }); |
|
kasperl
2012/02/27 06:50:03
I guess there's no need to do containsValue in ord
Anders Johnsen
2012/02/27 09:06:51
Done.
| |
| 223 return found; | 223 return found; |
| 224 } | 224 } |
| 225 | 225 |
| 226 Collection<K> getKeys() { | 226 Collection<K> getKeys() { |
| 227 List<K> list = new List<K>(); | 227 List<K> list = new List<K>(); |
| 228 forEach((K k, V v) { list.add(k); }); | 228 forEach((K k, V v) { list.add(k); }); |
| 229 return list; | 229 return list; |
| 230 } | 230 } |
| 231 | 231 |
| 232 Collection<V> getValues() { | 232 Collection<V> getValues() { |
| 233 List<V> list = new List<V>(); | 233 List<V> list = new List<V>(); |
| 234 forEach((K k, V v) { list.add(v); }); | 234 forEach((K k, V v) { list.add(v); }); |
| 235 return list; | 235 return list; |
| 236 } | 236 } |
| 237 | 237 |
| 238 String toString() { | 238 String toString() { |
| 239 return Maps.mapToString(this); | 239 return Maps.mapToString(this); |
| 240 } | 240 } |
| 241 | |
| 242 /** | |
| 243 * Get the first key in the map. Returns [ifEmpty] if the map is empty. | |
| 244 */ | |
| 245 K firstKey([K ifEmpty]) { | |
|
kasperl
2012/02/27 06:50:03
Have you considered making ifEmpty a closure inste
Søren Gjesse
2012/02/27 07:53:16
Why not just return null if the splay tree is empt
kasperl
2012/02/27 08:53:17
I think we should go with Søren's proposal for now
Anders Johnsen
2012/02/27 09:06:51
If we return null, then map[] should support null
kasperl
2012/02/27 09:18:45
I actually find it hard to read the line:
var f
Anders Johnsen
2012/02/27 11:49:59
Yeah, I've turned them into a getter. Thank you!
| |
| 246 if (_root === null) return ifEmpty; | |
| 247 SplayTreeNode<K, V> node = _root; | |
| 248 while (node.left !== null) { | |
| 249 node = node.left; | |
| 250 } | |
| 251 splay_(node.key); | |
| 252 return node.key; | |
| 253 } | |
| 254 | |
| 255 /** | |
| 256 * Get the last key in the map. Returns [ifEmpty] if the map is empty. | |
| 257 */ | |
| 258 V lastKey([K ifEmpty]) { | |
| 259 if (_root === null) return ifEmpty; | |
| 260 SplayTreeNode<K, V> node = _root; | |
| 261 while (node.right !== null) { | |
| 262 node = node.right; | |
| 263 } | |
| 264 splay_(node.key); | |
| 265 return node.key; | |
| 266 } | |
| 267 | |
| 268 /** | |
| 269 * Get the last key in the map that is strictly smaller then [key]. Returns | |
|
kasperl
2012/02/27 06:50:03
then -> than
Anders Johnsen
2012/02/27 09:06:51
Done.
| |
| 270 * [ifInvalid] if [key] was not found. | |
| 271 */ | |
| 272 K keyBefore(K key, [K ifInvalid]) { | |
|
kasperl
2012/02/27 06:50:03
lastKeyBefore?
Anders Johnsen
2012/02/27 09:06:51
Hmm, to me this sort of implies I could give any k
kasperl
2012/02/27 09:18:45
To me the term 'keyBefore' is almost the same as '
Anders Johnsen
2012/02/27 11:49:59
I agree, and it makes a lot more sense the more I
| |
| 273 splay_(key); | |
| 274 if (_root === null || key.compareTo(_root.key) != 0) return ifInvalid; | |
| 275 SplayTreeNode<K, V> node = _root; | |
| 276 if (node.left === null) return ifInvalid; | |
| 277 node = node.left; | |
| 278 while (node.right !== null) { | |
| 279 node = node.right; | |
| 280 } | |
| 281 return node.key; | |
| 282 } | |
| 283 | |
| 284 /** | |
| 285 * Get the first key in the map that is strictly larger then [key]. Returns | |
|
kasperl
2012/02/27 06:50:03
then -> than
Anders Johnsen
2012/02/27 09:06:51
Done.
| |
| 286 * [ifInvalid] if [key] was not found. | |
| 287 */ | |
| 288 K keyAfter(K key, [K ifInvalid]) { | |
|
kasperl
2012/02/27 06:50:03
firstKeyAfter?
Anders Johnsen
2012/02/27 09:06:51
Same as above.
| |
| 289 splay_(key); | |
| 290 if (_root === null || key.compareTo(_root.key) != 0) return ifInvalid; | |
| 291 SplayTreeNode<K, V> node = _root; | |
| 292 if (node.right === null) return ifInvalid; | |
| 293 node = node.right; | |
| 294 while (node.left !== null) { | |
| 295 node = node.left; | |
| 296 } | |
| 297 return node.key; | |
| 298 } | |
| 241 } | 299 } |
| OLD | NEW |