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 typedef bool _Predicate<T>(T value); | 7 typedef bool _Predicate<T>(T value); |
8 | 8 |
9 /** | 9 /** |
10 * A node in a splay tree. It holds the sorting key and the left | 10 * A node in a splay tree. It holds the sorting key and the left |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 * | 632 * |
633 * The set is based on a self-balancing binary tree. It allows most operations | 633 * The set is based on a self-balancing binary tree. It allows most operations |
634 * in amortized logarithmic time. | 634 * in amortized logarithmic time. |
635 * | 635 * |
636 * Elements of the set are compared using the `compare` function passed in | 636 * Elements of the set are compared using the `compare` function passed in |
637 * the constructor. If that is omitted, the objects are assumed to be | 637 * the constructor. If that is omitted, the objects are assumed to be |
638 * [Comparable], and are compared using their [Comparable.compareTo] | 638 * [Comparable], and are compared using their [Comparable.compareTo] |
639 * method. Non-comparable objects (including `null`) will not work as an element | 639 * method. Non-comparable objects (including `null`) will not work as an element |
640 * in that case. | 640 * in that case. |
641 */ | 641 */ |
642 class SplayTreeSet<E> extends _SplayTree<E> with IterableMixin<E> | 642 class SplayTreeSet<E> extends _SplayTree<E> with IterableMixin<E>, SetMixin<E> { |
643 implements Set<E> { | |
644 Comparator _comparator; | 643 Comparator _comparator; |
645 _Predicate _validKey; | 644 _Predicate _validKey; |
646 | 645 |
647 /** | 646 /** |
648 * Create a new [SplayTreeSet] with the given compare function. | 647 * Create a new [SplayTreeSet] with the given compare function. |
649 * | 648 * |
650 * If the [compare] function is omitted, it defaults to [Comparable.compare], | 649 * If the [compare] function is omitted, it defaults to [Comparable.compare], |
651 * and the elements must be comparable. | 650 * and the elements must be comparable. |
652 * | 651 * |
653 * A provided `compare` function may not work on all objects. It may not even | 652 * A provided `compare` function may not work on all objects. It may not even |
(...skipping 22 matching lines...) Expand all Loading... |
676 | 675 |
677 // From Iterable. | 676 // From Iterable. |
678 | 677 |
679 Iterator<E> get iterator => new _SplayTreeKeyIterator<E>(this); | 678 Iterator<E> get iterator => new _SplayTreeKeyIterator<E>(this); |
680 | 679 |
681 int get length => _count; | 680 int get length => _count; |
682 bool get isEmpty => _root == null; | 681 bool get isEmpty => _root == null; |
683 bool get isNotEmpty => _root != null; | 682 bool get isNotEmpty => _root != null; |
684 | 683 |
685 E get first { | 684 E get first { |
686 if (_count == 0) throw new StateError("no such element"); | 685 if (_count == 0) throw IterableElementError.noElement(); |
687 return _first.key; | 686 return _first.key; |
688 } | 687 } |
689 | 688 |
690 E get last { | 689 E get last { |
691 if (_count == 0) throw new StateError("no such element"); | 690 if (_count == 0) throw IterableElementError.noElement(); |
692 return _last.key; | 691 return _last.key; |
693 } | 692 } |
694 | 693 |
695 E get single { | 694 E get single { |
696 if (_count == 0) throw new StateError("no such element"); | 695 if (_count == 0) throw IterableElementError.noElement(); |
697 if (_count > 1) throw new StateError("too many elements"); | 696 if (_count > 1) throw IterableElementError.tooMany(); |
698 return _root.key; | 697 return _root.key; |
699 } | 698 } |
700 | 699 |
701 // From Set. | 700 // From Set. |
702 bool contains(Object object) { | 701 bool contains(Object object) { |
703 return _validKey(object) && _splay(object) == 0; | 702 return _validKey(object) && _splay(object) == 0; |
704 } | 703 } |
705 | 704 |
706 bool add(E element) { | 705 bool add(E element) { |
707 int compare = _splay(element); | 706 int compare = _splay(element); |
(...skipping 15 matching lines...) Expand all Loading... |
723 } | 722 } |
724 } | 723 } |
725 } | 724 } |
726 | 725 |
727 void removeAll(Iterable<Object> elements) { | 726 void removeAll(Iterable<Object> elements) { |
728 for (Object element in elements) { | 727 for (Object element in elements) { |
729 if (_validKey(element)) _remove(element); | 728 if (_validKey(element)) _remove(element); |
730 } | 729 } |
731 } | 730 } |
732 | 731 |
733 /** | |
734 * Removes all elements not in [elements]. | |
735 */ | |
736 void retainAll(Iterable<Object> elements) { | 732 void retainAll(Iterable<Object> elements) { |
737 // Build a set with the same sense of equality as this set. | 733 // Build a set with the same sense of equality as this set. |
738 SplayTreeSet<E> retainSet = new SplayTreeSet<E>(_comparator, _validKey); | 734 SplayTreeSet<E> retainSet = new SplayTreeSet<E>(_comparator, _validKey); |
739 int modificationCount = _modificationCount; | 735 int modificationCount = _modificationCount; |
740 for (Object object in elements) { | 736 for (Object object in elements) { |
741 if (modificationCount != _modificationCount) { | 737 if (modificationCount != _modificationCount) { |
742 // The iterator should not have side effects. | 738 // The iterator should not have side effects. |
743 throw new ConcurrentModificationError(this); | 739 throw new ConcurrentModificationError(this); |
744 } | 740 } |
745 // Equivalent to this.contains(object). | 741 // Equivalent to this.contains(object). |
746 if (_validKey(object) && _splay(object) == 0) retainSet.add(_root.key); | 742 if (_validKey(object) && _splay(object) == 0) retainSet.add(_root.key); |
747 } | 743 } |
748 // Take over the elements from the retained set, if it differs. | 744 // Take over the elements from the retained set, if it differs. |
749 if (retainSet._count != _count) { | 745 if (retainSet._count != _count) { |
750 _root = retainSet._root; | 746 _root = retainSet._root; |
751 _count = retainSet._count; | 747 _count = retainSet._count; |
752 _modificationCount++; | 748 _modificationCount++; |
753 } | 749 } |
754 } | 750 } |
755 | 751 |
756 void _filterWhere(bool test(E element), bool removeMatching) { | |
757 _SplayTreeNodeIterator it = new _SplayTreeNodeIterator(this); | |
758 while (it.moveNext()) { | |
759 _SplayTreeNode node = it.current; | |
760 int modificationCount = _modificationCount; | |
761 bool matches = test(node.key); | |
762 if (modificationCount != _modificationCount) { | |
763 throw new ConcurrentModificationError(this); | |
764 } | |
765 if (matches == removeMatching) { | |
766 _remove(node.key); | |
767 it = new _SplayTreeNodeIterator.startAt(this, node.key); | |
768 } | |
769 } | |
770 } | |
771 | |
772 void removeWhere(bool test(E element)) { | |
773 _filterWhere(test, true); | |
774 } | |
775 | |
776 void retainWhere(bool test(E element)) { | |
777 _filterWhere(test, false); | |
778 } | |
779 | |
780 E lookup(Object object) { | 752 E lookup(Object object) { |
781 if (!_validKey(object)) return null; | 753 if (!_validKey(object)) return null; |
782 int comp = _splay(object); | 754 int comp = _splay(object); |
783 if (comp != 0) return null; | 755 if (comp != 0) return null; |
784 return _root.key; | 756 return _root.key; |
785 } | 757 } |
786 | 758 |
787 Set<E> intersection(Set<E> other) { | |
788 Set<E> result = new SplayTreeSet<E>(_compare, _validKey); | |
789 for (E element in this) { | |
790 if (other.contains(element)) result.add(element); | |
791 } | |
792 return result; | |
793 } | |
794 | |
795 Set<E> difference(Set<E> other) { | |
796 Set<E> result = new SplayTreeSet<E>(_compare, _validKey); | |
797 for (E element in this) { | |
798 if (!other.contains(element)) result.add(element); | |
799 } | |
800 return result; | |
801 } | |
802 | |
803 Set<E> union(Set<E> other) { | |
804 return _clone()..addAll(other); | |
805 } | |
806 | |
807 SplayTreeSet<E> _clone() { | 759 SplayTreeSet<E> _clone() { |
808 var set = new SplayTreeSet<E>(_compare, _validKey); | 760 var set = new SplayTreeSet<E>(_comparator, _validKey); |
809 set._count = _count; | 761 set._count = _count; |
810 set._root = _cloneNode(_root); | 762 set._root = _cloneNode(_root); |
811 return set; | 763 return set; |
812 } | 764 } |
813 | 765 |
814 _SplayTreeNode<E> _cloneNode(_SplayTreeNode<E> node) { | 766 _SplayTreeNode<E> _cloneNode(_SplayTreeNode<E> node) { |
815 if (node == null) return null; | 767 if (node == null) return null; |
816 return new _SplayTreeNode<E>(node.key)..left = _cloneNode(node.left) | 768 return new _SplayTreeNode<E>(node.key)..left = _cloneNode(node.left) |
817 ..right = _cloneNode(node.right); | 769 ..right = _cloneNode(node.right); |
818 } | 770 } |
819 | 771 |
820 bool containsAll(Iterable<Object> other) { | 772 void clear() { _clear(); } |
821 for (var element in other) { | |
822 if (!this.contains(element)) return false; | |
823 } | |
824 return true; | |
825 } | |
826 | 773 |
827 void clear() { _clear(); } | 774 Set<E> toSet() => _clone(); |
828 } | 775 } |
OLD | NEW |