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

Unified Diff: quiver/lib/src/collection/treeset.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « quiver/lib/src/collection/multimap.dart ('k') | quiver/lib/src/core/hash.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: quiver/lib/src/collection/treeset.dart
diff --git a/quiver/lib/src/collection/treeset.dart b/quiver/lib/src/collection/treeset.dart
deleted file mode 100644
index 200c21fcf1a61df65451a798e40cf3d31b6c0cf6..0000000000000000000000000000000000000000
--- a/quiver/lib/src/collection/treeset.dart
+++ /dev/null
@@ -1,1050 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-part of quiver.collection;
-
-/**
- * A [Set] of items stored in a binary tree according to [comparator].
- * Supports bidirectional iteration.
- */
-abstract class TreeSet<V> extends IterableBase<V> implements Set<V> {
- final Comparator<V> comparator;
-
- int get length;
-
- /**
- * Create a new [TreeSet] with an ordering defined by [comparator] or the
- * default `(a, b) => a.compareTo(b)`.
- */
- factory TreeSet({Comparator<V> comparator}) {
- if (comparator == null) {
- comparator = (a, b) => a.compareTo(b);
- }
- return new AvlTreeSet(comparator: comparator);
- }
-
- TreeSet._(this.comparator);
-
- /**
- * Returns an [BidirectionalIterator] that iterates over this tree.
- */
- BidirectionalIterator<V> get iterator;
-
- /**
- * Returns an [BidirectionalIterator] that iterates over this tree, in reverse.
- */
- BidirectionalIterator<V> get reverseIterator;
-
- /**
- * Returns an [BidirectionalIterator] that starts at [anchor].
- * By default, the iterator includes the anchor with the first movement;
- * set [inclusive] to false if you want to exclude the anchor. Set [reversed]
- * to true to change the direction of of moveNext and movePrevious.
- *
- * Note: This iterator allows you to walk the entire set. It does not present
- * a subview.
- */
- BidirectionalIterator<V> fromIterator(V anchor,
- {bool reversed: false, bool inclusive: true});
-
- /**
- * Search the tree for the matching [object] or the [nearestOption]
- * if missing. See [TreeSearch].
- */
- V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST});
-
- // TODO: toString or not toString, that is the question.
-}
-
-/**
- * Controls the results for [TreeSet.searchNearest]()
- */
-class TreeSearch {
-
- /**
- * If result not found, always chose the smaler element
- */
- static const LESS_THAN = const TreeSearch._(1);
-
- /**
- * If result not found, chose the nearest based on comparison
- */
- static const NEAREST = const TreeSearch._(2);
-
- /**
- * If result not found, always chose the greater element
- */
- static const GREATER_THAN = const TreeSearch._(3);
-
- final int _val;
- const TreeSearch._(this._val);
-}
-
-/**
- * A node in the [TreeSet].
- */
-abstract class _TreeNode<V> {
- _TreeNode<V> get left;
- _TreeNode<V> get right;
-
- //TODO(codefu): Remove need for [parent]; this is just an implementation note
- _TreeNode<V> get parent;
- V object;
-
- /**
- * TreeNodes are always allocated as leafs.
- */
- _TreeNode({this.object});
-
- /**
- * Return the minimum node for the subtree
- */
- _TreeNode<V> get minimumNode {
- var node = this;
- while (node.left != null) {
- node = node.left;
- }
- return node;
- }
-
- /**
- * Return the maximum node for the subtree
- */
- _TreeNode<V> get maximumNode {
- var node = this;
- while (node.right != null) {
- node = node.right;
- }
- return node;
- }
-
- /**
- * Return the next greatest element (or null)
- */
- _TreeNode<V> get successor {
- var node = this;
- if (node.right != null) {
- return node.right.minimumNode;
- }
- while (node.parent != null && node == node.parent.right) {
- node = node.parent;
- }
- return node.parent;
- }
-
- /**
- * Return the next smaller element (or null)
- */
- _TreeNode<V> get predecessor {
- var node = this;
- if (node.left != null) {
- return node.left.maximumNode;
- }
- while (node.parent != null && node.parent._left == node) {
- node = node.parent;
- }
- return node.parent;
- }
-}
-
-/**
- * AVL implementation of a self-balancing binary tree. Optimized for lookup
- * operations.
- *
- * Notes: Adapted from "Introduction to Algorithms", second edition,
- * by Thomas H. Cormen, Charles E. Leiserson,
- * Ronald L. Rivest, Clifford Stein.
- * chapter 13.2
- */
-class AvlTreeSet<V> extends TreeSet<V> {
- int _length = 0;
- AvlNode<V> _root;
- // Modification count to the tree, monotonically increasing
- int _modCount = 0;
-
- int get length => _length;
-
- AvlTreeSet({Comparator<V> comparator}) : super._(comparator);
-
- /**
- * Add the element to the tree.
- */
- bool add(V element) {
- if (_root == null) {
- AvlNode<V> node = new AvlNode<V>(object: element);
- _root = node;
- ++_length;
- ++_modCount;
- return true;
- }
-
- AvlNode<V> x = _root;
- while (true) {
- int compare = comparator(element, x.object);
- if (compare == 0) {
- return false;
- } else if (compare < 0) {
- if (x._left == null) {
- AvlNode<V> node = new AvlNode<V>(object: element).._parent = x;
- x
- .._left = node
- .._balanceFactor -= 1;
- break;
- }
- x = x.left;
- } else {
- if (x._right == null) {
- AvlNode<V> node = new AvlNode<V>(object: element).._parent = x;
- x
- .._right = node
- .._balanceFactor += 1;
- break;
- }
- x = x.right;
- }
- }
-
- ++_modCount;
-
- // AVL balancing act (for height balanced trees)
- // Now that we've inserted, we've unbalanced some trees, we need
- // to follow the tree back up to the _root double checking that the tree
- // is still balanced and _maybe_ perform a single or double rotation.
- // Note: Left additions == -1, Right additions == +1
- // Balanced Node = { -1, 0, 1 }, out of balance = { -2, 2 }
- // Single rotation when Parent & Child share signed balance,
- // Double rotation when sign differs!
- AvlNode<V> node = x;
- while (node._balanceFactor != 0 && node.parent != null) {
- // Find out which side of the parent we're on
- if (node.parent._left == node) {
- node.parent._balanceFactor -= 1;
- } else {
- node.parent._balanceFactor += 1;
- }
-
- node = node.parent;
- if (node._balanceFactor == 2) {
- // Heavy on the right side - Test for which rotation to perform
- if (node.right._balanceFactor == 1) {
- // Single (left) rotation; this will balance everything to zero
- _rotateLeft(node);
- node._balanceFactor = node.parent._balanceFactor = 0;
- node = node.parent;
- } else {
- // Double (Right/Left) rotation
- // node will now be old node.right.left
- _rotateRightLeft(node);
- node = node.parent; // Update to new parent (old grandchild)
- if (node._balanceFactor == 1) {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = -1;
- } else if (node._balanceFactor == 0) {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = 0;
- } else {
- node.right._balanceFactor = 1;
- node.left._balanceFactor = 0;
- }
- node._balanceFactor = 0;
- }
- break; // out of loop, we're balanced
- } else if (node._balanceFactor == -2) {
- // Heavy on the left side - Test for which rotation to perform
- if (node.left._balanceFactor == -1) {
- _rotateRight(node);
- node._balanceFactor = node.parent._balanceFactor = 0;
- node = node.parent;
- } else {
- // Double (Left/Right) rotation
- // node will now be old node.left.right
- _rotateLeftRight(node);
- node = node.parent;
- if (node._balanceFactor == -1) {
- node.right._balanceFactor = 1;
- node.left._balanceFactor = 0;
- } else if (node._balanceFactor == 0) {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = 0;
- } else {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = -1;
- }
- node._balanceFactor = 0;
- }
- break; // out of loop, we're balanced
- }
- } // end of while (balancing)
- _length++;
- return true;
- }
-
- /**
- * Test to see if an element is stored in the tree
- */
- AvlNode<V> _getNode(V element) {
- if (element == null) return null;
- AvlNode<V> x = _root;
- while (x != null) {
- int compare = comparator(element, x.object);
- if (compare == 0) {
- // This only means our node matches; we need to search for the exact
- // element. We could have been glutons and used a hashmap to back.
- return x;
- } else if (compare < 0) {
- x = x.left;
- } else {
- x = x.right;
- }
- }
- return null;
- }
-
- /**
- * This function will right rotate/pivot N with its left child, placing
- * it on the right of its left child.
- *
- * N Y
- * / \ / \
- * Y A Z N
- * / \ ==> / \ / \
- * Z B D CB A
- * / \
- *D C
- *
- * Assertion: must have a left element
- */
- void _rotateRight(AvlNode<V> node) {
- AvlNode<V> y = node.left;
- if (y == null) throw new AssertionError();
-
- // turn Y's right subtree(B) into N's left subtree.
- node._left = y.right;
- if (node.left != null) {
- node.left._parent = node;
- }
- y._parent = node.parent;
- if (y._parent == null) {
- _root = y;
- } else {
- if (node.parent._left == node) {
- node.parent._left = y;
- } else {
- node.parent._right = y;
- }
- }
- y._right = node;
- node._parent = y;
- }
-
- /**
- * This function will left rotate/pivot N with its right child, placing
- * it on the left of its right child.
- *
- * N Y
- * / \ / \
- * A Y N Z
- * / \ ==> / \ / \
- * B Z A BC D
- * / \
- * C D
- *
- * Assertion: must have a right element
- */
- void _rotateLeft(AvlNode<V> node) {
- AvlNode<V> y = node.right;
- if (y == null) throw new AssertionError();
-
- // turn Y's left subtree(B) into N's right subtree.
- node._right = y.left;
- if (node.right != null) {
- node.right._parent = node;
- }
- y._parent = node.parent;
- if (y._parent == null) {
- _root = y;
- } else {
- if (node.parent._left == node) {
- y.parent._left = y;
- } else {
- y.parent._right = y;
- }
- }
- y._left = node;
- node._parent = y;
- }
-
- /**
- * This function will double rotate node with right/left operations.
- * node is S.
- *
- * S G
- * / \ / \
- * A C S C
- * / \ ==> / \ / \
- * G B A DC B
- * / \
- * D C
- */
- void _rotateRightLeft(AvlNode<V> node) {
- _rotateRight(node.right);
- _rotateLeft(node);
- }
-
- /**
- * This function will double rotate node with left/right operations.
- * node is S.
- *
- * S G
- * / \ / \
- * C A C S
- * / \ ==> / \ / \
- *B G B CD A
- * / \
- * C D
- */
- void _rotateLeftRight(AvlNode<V> node) {
- _rotateLeft(node.left);
- _rotateRight(node);
- }
-
- bool addAll(Iterable<V> items) {
- bool modified = false;
- for (V ele in items) {
- modified = add(ele) ? true : modified;
- }
- return modified;
- }
-
- void clear() {
- _length = 0;
- _root = null;
- ++_modCount;
- }
-
- bool containsAll(Iterable<Object> items) {
- for (var ele in items) {
- if (!contains(ele)) return false;
- }
- return true;
- }
-
- bool remove(Object item) {
- AvlNode<V> x = _getNode(item);
- if (x != null) {
- _removeNode(x);
- return true;
- }
- return false;
- }
-
- void _removeNode(AvlNode<V> node) {
- AvlNode<V> y, w;
-
- ++_modCount;
- --_length;
-
- // note: if you read wikipedia, it states remove the node if its a leaf,
- // otherwise, replace it with its predecessor or successor. We're not.
- if (node._right == null || node.right._left == null) {
- // simple solutions
- if (node.right != null) {
- y = node.right;
- y._parent = node.parent;
- y._balanceFactor = node._balanceFactor - 1;
- y._left = node.left;
- if (y.left != null) {
- y.left._parent = y;
- }
- } else if (node.left != null) {
- y = node.left;
- y._parent = node.parent;
- y._balanceFactor = node._balanceFactor + 1;
- } else {
- y = null;
- }
- if (_root == node) {
- _root = y;
- } else if (node.parent._left == node) {
- node.parent._left = y;
- if (y == null) {
- // account for leaf deletions changing the balance
- node.parent._balanceFactor += 1;
- y = node.parent; // start searching from here;
- }
- } else {
- node.parent._right = y;
- if (y == null) {
- node.parent._balanceFactor -= 1;
- y = node.parent;
- }
- }
- w = y;
- } else {
- // This node is not a leaf; we should find the successor node, swap
- //it with this* and then update the balance factors.
- y = node.successor;
- y._left = node.left;
- if (y.left != null) {
- y.left._parent = y;
- }
-
- w = y.parent;
- w._left = y.right;
- if (w.left != null) {
- w.left._parent = w;
- }
- // known: we're removing from the left
- w._balanceFactor += 1;
-
- // known due to test for n->r->l above
- y._right = node.right;
- y.right._parent = y;
- y._balanceFactor = node._balanceFactor;
-
- y._parent = node.parent;
- if (_root == node) {
- _root = y;
- } else if (node.parent._left == node) {
- node.parent._left = y;
- } else {
- node.parent._right = y;
- }
- }
-
- // Safe to kill node now; its free to go.
- node._balanceFactor = 0;
- node._left = node._right = node._parent = null;
- node.object = null;
-
- // Recalculate max values all the way to the top.
- node = w;
- while (node != null) {
- node = node.parent;
- }
-
- // Re-balance to the top, ending early if OK
- node = w;
- while (node != null) {
- if (node._balanceFactor == -1 || node._balanceFactor == 1) {
- // The height of node hasn't changed; done!
- break;
- }
- if (node._balanceFactor == 2) {
- // Heavy on the right side; figure out which rotation to perform
- if (node.right._balanceFactor == -1) {
- _rotateRightLeft(node);
- node = node.parent; // old grand-child!
- if (node._balanceFactor == 1) {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = -1;
- } else if (node._balanceFactor == 0) {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = 0;
- } else {
- node.right._balanceFactor = 1;
- node.left._balanceFactor = 0;
- }
- node._balanceFactor = 0;
- } else {
- // single left-rotation
- _rotateLeft(node);
- if (node.parent._balanceFactor == 0) {
- node.parent._balanceFactor = -1;
- node._balanceFactor = 1;
- break;
- } else {
- node.parent._balanceFactor = 0;
- node._balanceFactor = 0;
- node = node.parent;
- continue;
- }
- }
- } else if (node._balanceFactor == -2) {
- // Heavy on the left
- if (node.left._balanceFactor == 1) {
- _rotateLeftRight(node);
- node = node.parent; // old grand-child!
- if (node._balanceFactor == -1) {
- node.right._balanceFactor = 1;
- node.left._balanceFactor = 0;
- } else if (node._balanceFactor == 0) {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = 0;
- } else {
- node.right._balanceFactor = 0;
- node.left._balanceFactor = -1;
- }
- node._balanceFactor = 0;
- } else {
- _rotateRight(node);
- if (node.parent._balanceFactor == 0) {
- node.parent._balanceFactor = 1;
- node._balanceFactor = -1;
- break;
- } else {
- node.parent._balanceFactor = 0;
- node._balanceFactor = 0;
- node = node.parent;
- continue;
- }
- }
- }
-
- // continue up the tree for testing
- if (node.parent != null) {
- // The concept of balance here is reverse from addition; since
- // we are taking away weight from one side or the other (thus
- // the balance changes in favor of the other side)
- if (node.parent.left == node) {
- node.parent._balanceFactor += 1;
- } else {
- node.parent._balanceFactor -= 1;
- }
- }
- node = node.parent;
- }
- }
-
- /**
- * See [Set.removeAll]
- */
- void removeAll(Iterable items) {
- for (var ele in items) {
- remove(ele);
- }
- }
-
- /**
- * See [Set.retainAll]
- */
- void retainAll(Iterable<Object> elements) {
- List<V> chosen = [];
- for (var target in elements) {
- if (contains(target)) {
- chosen.add(target);
- }
- }
- clear();
- addAll(chosen);
- }
-
- /**
- * See [Set.retainWhere]
- */
- void retainWhere(bool test(V element)) {
- List<V> chosen = [];
- for (var target in this) {
- if (test(target)) {
- chosen.add(target);
- }
- }
- clear();
- addAll(chosen);
- }
-
- /**
- * See [Set.removeWhere]
- */
- void removeWhere(bool test(V element)) {
- List<V> damned = [];
- for (var target in this) {
- if (test(target)) {
- damned.add(target);
- }
- }
- removeAll(damned);
- }
-
- /**
- * See [IterableBase.first]
- */
- V get first {
- if (_root == null) return null;
- AvlNode<V> min = _root.minimumNode;
- return min != null ? min.object : null;
- }
-
- /**
- * See [IterableBase.last]
- */
- V get last {
- if (_root == null) return null;
- AvlNode<V> max = _root.maximumNode;
- return max != null ? max.object : null;
- }
-
- /**
- * See [Set.lookup]
- */
- V lookup(Object element) {
- if (element == null || _root == null) return null;
- AvlNode<V> x = _root;
- int compare = 0;
- while (x != null) {
- compare = comparator(element, x.object);
- if (compare == 0) {
- return x.object;
- } else if (compare < 0) {
- x = x.left;
- } else {
- x = x.right;
- }
- }
- return null;
- }
-
- V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST}) {
- AvlNode<V> found = _searchNearest(object, option: nearestOption);
- return (found != null) ? found.object : null;
- }
-
- /**
- * Search the tree for the matching element, or the 'nearest' node.
- * NOTE: [BinaryTree.comparator] needs to have finer granulatity than -1,0,1
- * in order for this to return something that's meaningful.
- */
- AvlNode<V> _searchNearest(V element,
- {TreeSearch option: TreeSearch.NEAREST}) {
- if (element == null || _root == null) {
- return null;
- }
- AvlNode<V> x = _root;
- AvlNode<V> previous;
- int compare = 0;
- while (x != null) {
- previous = x;
- compare = comparator(element, x.object);
- if (compare == 0) {
- return x;
- } else if (compare < 0) {
- x = x.left;
- } else {
- x = x.right;
- }
- }
-
- if (option == TreeSearch.GREATER_THAN) {
- return (compare < 0) ? previous : previous.successor;
- } else if (option == TreeSearch.LESS_THAN) {
- return (compare < 0) ? previous.predecessor : previous;
- }
- // Default: nearest absolute value
- // Fell off the tree looking for the exact match; now we need
- // to find the nearest element.
- x = (compare < 0) ? previous.predecessor : previous.successor;
- if (x == null) {
- return previous;
- }
- int otherCompare = comparator(element, x.object);
- if (compare < 0) {
- return compare.abs() < otherCompare ? previous : x;
- }
- return otherCompare.abs() < compare ? x : previous;
- }
-
- //
- // [IterableBase]<V> Methods
- //
-
- /**
- * See [IterableBase.iterator]
- */
- BidirectionalIterator<V> get iterator => new _AvlTreeIterator._(this);
-
- /**
- * See [TreeSet.reverseIterator]
- */
- BidirectionalIterator<V> get reverseIterator =>
- new _AvlTreeIterator._(this, reversed: true);
-
- /**
- * See [TreeSet.fromIterator]
- */
- BidirectionalIterator<V> fromIterator(V anchor,
- {bool reversed: false, bool inclusive: true}) =>
- new _AvlTreeIterator<V>._(this,
- anchorObject: anchor, reversed: reversed, inclusive: inclusive);
-
- /**
- * See [IterableBase.contains]
- */
- bool contains(Object object) {
- AvlNode<V> x = _getNode(object as V);
- return x != null;
- }
-
- //
- // [Set] methods
- //
-
- /**
- * See [Set.intersection]
- */
- Set<V> intersection(Set<Object> other) {
- TreeSet<V> set = new TreeSet(comparator: comparator);
-
- // Opitimized for sorted sets
- if (other is TreeSet) {
- var i1 = iterator;
- var i2 = other.iterator;
- var hasMore1 = i1.moveNext();
- var hasMore2 = i2.moveNext();
- while (hasMore1 && hasMore2) {
- var c = comparator(i1.current, i2.current);
- if (c == 0) {
- set.add(i1.current);
- hasMore1 = i1.moveNext();
- hasMore2 = i2.moveNext();
- } else if (c < 0) {
- hasMore1 = i1.moveNext();
- } else {
- hasMore2 = i2.moveNext();
- }
- }
- return set;
- }
-
- // Non-optimized version.
- for (var target in this) {
- if (other.contains(target)) {
- set.add(target);
- }
- }
- return set;
- }
-
- /**
- * See [Set.union]
- */
- Set<V> union(Set<V> other) {
- TreeSet<V> set = new TreeSet(comparator: comparator);
-
- if (other is TreeSet) {
- var i1 = iterator;
- var i2 = other.iterator;
- var hasMore1 = i1.moveNext();
- var hasMore2 = i2.moveNext();
- while (hasMore1 && hasMore2) {
- var c = comparator(i1.current, i2.current);
- if (c == 0) {
- set.add(i1.current);
- hasMore1 = i1.moveNext();
- hasMore2 = i2.moveNext();
- } else if (c < 0) {
- set.add(i1.current);
- hasMore1 = i1.moveNext();
- } else {
- set.add(i2.current);
- hasMore2 = i2.moveNext();
- }
- }
- if (hasMore1 || hasMore2) {
- i1 = hasMore1 ? i1 : i2;
- do {
- set.add(i1.current);
- } while (i1.moveNext());
- }
- return set;
- }
-
- // Non-optimized version.
- return set
- ..addAll(this)
- ..addAll(other);
- }
-
- /**
- * See [Set.difference]
- */
- Set<V> difference(Set<V> other) {
- TreeSet<V> set = new TreeSet(comparator: comparator);
-
- if (other is TreeSet) {
- var i1 = iterator;
- var i2 = other.iterator;
- var hasMore1 = i1.moveNext();
- var hasMore2 = i2.moveNext();
- while (hasMore1 && hasMore2) {
- var c = comparator(i1.current, i2.current);
- if (c == 0) {
- hasMore1 = i1.moveNext();
- hasMore2 = i2.moveNext();
- } else if (c < 0) {
- set.add(i1.current);
- hasMore1 = i1.moveNext();
- } else {
- hasMore2 = i2.moveNext();
- }
- }
- if (hasMore1) {
- do {
- set.add(i1.current);
- } while (i1.moveNext());
- }
- return set;
- }
-
- // Non-optimized version.
- for (var target in this) {
- if (!other.contains(target)) {
- set.add(target);
- }
- }
- return set;
- }
-
- /**
- * Visible for testing only.
- */
- AvlNode<V> getNode(V object) => _getNode(object);
-}
-
-typedef bool _IteratorMove();
-
-/**
- * This iterator either starts at the beginning or end (see [TreeSet.iterator]
- * and [TreeSet.reverseIterator]) or from an anchor point in the set (see
- * [TreeSet.fromIterator]). When using fromIterator, the inital
- * anchor point is included in the first movement (either [moveNext] or
- * [movePrevious]) but can optionally be excluded in the constructor.
- */
-class _AvlTreeIterator<V> implements BidirectionalIterator<V> {
- static const LEFT = -1;
- static const WALK = 0;
- static const RIGHT = 1;
-
- final bool reversed;
- final AvlTreeSet<V> tree;
- final int _modCountGuard;
- final Object anchorObject;
- final bool inclusive;
-
- _IteratorMove _moveNext;
- _IteratorMove _movePrevious;
-
- int state;
- _TreeNode<V> _current;
-
- _AvlTreeIterator._(AvlTreeSet<V> tree,
- {reversed: false, this.inclusive: true, this.anchorObject: null})
- : this.tree = tree,
- this._modCountGuard = tree._modCount,
- this.reversed = reversed {
- if (anchorObject == null || tree.length == 0) {
- // If the anchor is far left or right, we're just a normal iterator.
- state = reversed ? RIGHT : LEFT;
- _moveNext = reversed ? _movePreviousNormal : _moveNextNormal;
- _movePrevious = reversed ? _moveNextNormal : _movePreviousNormal;
- return;
- }
-
- state = WALK;
- // Else we've got an anchor we have to worry about initalizing from.
- // This isn't known till the caller actually performs a previous/next.
- _moveNext = () {
- _current = tree._searchNearest(anchorObject,
- option: reversed ? TreeSearch.LESS_THAN : TreeSearch.GREATER_THAN);
- _moveNext = reversed ? _movePreviousNormal : _moveNextNormal;
- _movePrevious = reversed ? _moveNextNormal : _movePreviousNormal;
- if (_current == null) {
- state = reversed ? LEFT : RIGHT;
- } else if (tree.comparator(_current.object, anchorObject) == 0 &&
- !inclusive) {
- _moveNext();
- }
- return state == WALK;
- };
-
- _movePrevious = () {
- _current = tree._searchNearest(anchorObject,
- option: reversed ? TreeSearch.GREATER_THAN : TreeSearch.LESS_THAN);
- _moveNext = reversed ? _movePreviousNormal : _moveNextNormal;
- _movePrevious = reversed ? _moveNextNormal : _movePreviousNormal;
- if (_current == null) {
- state = reversed ? RIGHT : LEFT;
- } else if (tree.comparator(_current.object, anchorObject) == 0 &&
- !inclusive) {
- _movePrevious();
- }
- return state == WALK;
- };
- }
-
- V get current => (state != WALK || _current == null) ? null : _current.object;
-
- bool moveNext() => _moveNext();
- bool movePrevious() => _movePrevious();
-
- bool _moveNextNormal() {
- if (_modCountGuard != tree._modCount) {
- throw new ConcurrentModificationError(tree);
- }
- if (state == RIGHT || tree.length == 0) return false;
- switch (state) {
- case LEFT:
- _current = tree._root.minimumNode;
- state = WALK;
- return true;
- case WALK:
- default:
- _current = _current.successor;
- if (_current == null) {
- state = RIGHT;
- }
- return state == WALK;
- }
- }
-
- bool _movePreviousNormal() {
- if (_modCountGuard != tree._modCount) {
- throw new ConcurrentModificationError(tree);
- }
- if (state == LEFT || tree.length == 0) return false;
- switch (state) {
- case RIGHT:
- _current = tree._root.maximumNode;
- state = WALK;
- return true;
- case WALK:
- default:
- _current = _current.predecessor;
- if (_current == null) {
- state = LEFT;
- }
- return state == WALK;
- }
- }
-}
-
-/**
- * Private class used to track element insertions in the [TreeSet].
- */
-class AvlNode<V> extends _TreeNode<V> {
- AvlNode<V> _left;
- AvlNode<V> _right;
- //TODO(codefu): Remove need for [parent]; this is just an implementation note
- AvlNode<V> _parent;
- int _balanceFactor = 0;
-
- AvlNode<V> get left => _left;
- AvlNode<V> get right => _right;
- AvlNode<V> get parent => _parent;
- int get balance => _balanceFactor;
-
- AvlNode({V object}) : super(object: object);
-
- String toString() =>
- "(b:$balance o: $object l:${left != null} r:${right != null})";
-}
« no previous file with comments | « quiver/lib/src/collection/multimap.dart ('k') | quiver/lib/src/core/hash.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698