Esempio n. 1
0
        /// <summary>
        /// Removes the specified key. Callers are expected to validate arguments.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="mutated">Receives a value indicating whether this node tree has mutated because of this operation.</param>
        /// <returns>The new AVL tree.</returns>
        private SortedInt32KeyNode <TValue> RemoveRecursive(int key, out bool mutated)
        {
            if (this.IsEmpty)
            {
                mutated = false;
                return(this);
            }
            else
            {
                SortedInt32KeyNode <TValue> result = this;
                if (key == _key)
                {
                    // We have a match.
                    mutated = true;

                    // If this is a leaf, just remove it
                    // by returning Empty.  If we have only one child,
                    // replace the node with the child.
                    if (_right.IsEmpty && _left.IsEmpty)
                    {
                        result = EmptyNode;
                    }
                    else if (_right.IsEmpty && !_left.IsEmpty)
                    {
                        result = _left;
                    }
                    else if (!_right.IsEmpty && _left.IsEmpty)
                    {
                        result = _right;
                    }
                    else
                    {
                        // We have two children. Remove the next-highest node and replace
                        // this node with it.
                        var successor = _right;
                        while (!successor._left.IsEmpty)
                        {
                            successor = successor._left;
                        }

                        bool dummyMutated;
                        var  newRight = _right.Remove(successor._key, out dummyMutated);
                        result = successor.Mutate(left: _left, right: newRight);
                    }
                }
                else if (key < _key)
                {
                    var newLeft = _left.Remove(key, out mutated);
                    if (mutated)
                    {
                        result = this.Mutate(left: newLeft);
                    }
                }
                else
                {
                    var newRight = _right.Remove(key, out mutated);
                    if (mutated)
                    {
                        result = this.Mutate(right: newRight);
                    }
                }

                return(result.IsEmpty ? result : MakeBalanced(result));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a node mutation, either by mutating this node (if not yet frozen) or by creating a clone of this node
        /// with the described changes.
        /// </summary>
        /// <param name="left">The left branch of the mutated node.</param>
        /// <param name="right">The right branch of the mutated node.</param>
        /// <returns>The mutated (or created) node.</returns>
        private SortedInt32KeyNode <TValue> Mutate(SortedInt32KeyNode <TValue> left = null, SortedInt32KeyNode <TValue> right = null)
        {
            if (_frozen)
            {
                return(new SortedInt32KeyNode <TValue>(_key, _value, left ?? _left, right ?? _right));
            }
            else
            {
                if (left != null)
                {
                    _left = left;
                }

                if (right != null)
                {
                    _right = right;
                }

                _height = checked ((byte)(1 + Math.Max(_left._height, _right._height)));
                return(this);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Performs the set operation on a given data structure.
        /// </summary>
        private static MutationResult Except(IEnumerable <T> other, IEqualityComparer <T> equalityComparer, IEqualityComparer <HashBucket> hashBucketEqualityComparer, SortedInt32KeyNode <HashBucket> root)
        {
            Requires.NotNull(other, nameof(other));
            Requires.NotNull(equalityComparer, nameof(equalityComparer));
            Requires.NotNull(root, nameof(root));

            int count   = 0;
            var newRoot = root;

            foreach (var item in other.GetEnumerableDisposable <T, Enumerator>())
            {
                int hashCode = item != null?equalityComparer.GetHashCode(item) : 0;

                HashBucket bucket;
                if (newRoot.TryGetValue(hashCode, out bucket))
                {
                    OperationResult result;
                    HashBucket      newBucket = bucket.Remove(item, equalityComparer, out result);
                    if (result == OperationResult.SizeChanged)
                    {
                        count--;
                        newRoot = UpdateRoot(newRoot, hashCode, hashBucketEqualityComparer, newBucket);
                    }
                }
            }

            return(new MutationResult(newRoot, count));
        }
Esempio n. 4
0
 private static bool IsLeftHeavy(SortedInt32KeyNode <TValue> tree)
 {
     Requires.NotNull(tree, nameof(tree));
     Debug.Assert(!tree.IsEmpty);
     return(Balance(tree) <= -2);
 }
Esempio n. 5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableDictionary&lt;TKey, TValue&gt;.MutationInput"/> struct.
 /// </summary>
 /// <param name="map">The map.</param>
 internal MutationInput(ImmutableDictionary <TKey, TValue> map)
 {
     this.root      = map.root;
     this.comparers = map.comparers;
     this.count     = map.count;
 }
Esempio n. 6
0
 /// <summary>
 /// Wraps the specified data structure with an immutable collection wrapper.
 /// </summary>
 /// <param name="root">The root of the data structure.</param>
 /// <param name="adjustedCountIfDifferentRoot">The adjusted count if the root has changed.</param>
 /// <returns>The immutable collection.</returns>
 private ImmutableHashSet <T> Wrap(SortedInt32KeyNode <HashBucket> root, int adjustedCountIfDifferentRoot)
 {
     return((root != _root) ? new ImmutableHashSet <T>(root, _equalityComparer, adjustedCountIfDifferentRoot) : this);
 }
 /// <summary>
 /// Removes all items from the <see cref="ICollection{T}"/>.
 /// </summary>
 /// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only. </exception>
 public void Clear()
 {
     this.Root = SortedInt32KeyNode <HashBucket> .EmptyNode;
     _count    = 0;
 }
 /// <summary>
 /// Applies the result of some mutation operation to this instance.
 /// </summary>
 /// <param name="result">The result.</param>
 private bool Apply(MutationResult result)
 {
     this.Root = result.Root;
     _count   += result.CountAdjustment;
     return(result.CountAdjustment != 0);
 }
Esempio n. 9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableHashSet{T}.NodeEnumerable"/> struct.
 /// </summary>
 /// <param name="root">The root.</param>
 internal NodeEnumerable(SortedInt32KeyNode <HashBucket> root)
 {
     Requires.NotNull(root, nameof(root));
     _root = root;
 }
Esempio n. 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SortedInt32KeyNode{TValue}"/> class that is not yet frozen.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <param name="frozen">Whether this node is prefrozen.</param>
        private SortedInt32KeyNode(int key, TValue value, SortedInt32KeyNode <TValue> left, SortedInt32KeyNode <TValue> right, bool frozen = false)
        {
            Requires.NotNull(left, nameof(left));
            Requires.NotNull(right, nameof(right));
            Debug.Assert(!frozen || (left._frozen && right._frozen));

            _key    = key;
            _value  = value;
            _left   = left;
            _right  = right;
            _frozen = frozen;

            _height = checked ((byte)(1 + Math.Max(left._height, right._height)));
        }
Esempio n. 11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableDictionary{TKey, TValue}"/> class.
 /// </summary>
 /// <param name="comparers">The comparers.</param>
 private ImmutableDictionary(Comparers comparers = null)
 {
     _comparers = comparers ?? Comparers.Get(EqualityComparer <TKey> .Default, EqualityComparer <TValue> .Default);
     _root      = SortedInt32KeyNode <HashBucket> .EmptyNode;
 }
Esempio n. 12
0
 private static bool IsRightHeavy(SortedInt32KeyNode <TValue> tree)
 {
     Requires.NotNull(tree, "tree");
     Debug.Assert(!tree.IsEmpty);
     return(Balance(tree) >= 2);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableDictionary{TKey, TValue}.MutationInput"/> struct.
 /// </summary>
 /// <param name="map">The map.</param>
 internal MutationInput(ImmutableDictionary <TKey, TValue> map)
 {
     _root      = map._root;
     _comparers = map._comparers;
 }
Esempio n. 14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableDictionary&lt;TKey, TValue&gt;.MutationResult"/> struct.
 /// </summary>
 /// <param name="root">The root.</param>
 /// <param name="countAdjustment">The count adjustment.</param>
 internal MutationResult(SortedInt32KeyNode <HashBucket> root, int countAdjustment)
 {
     Requires.NotNull(root, "root");
     _root            = root;
     _countAdjustment = countAdjustment;
 }
Esempio n. 15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableDictionary&lt;TKey, TValue&gt;.MutationResult"/> struct.
 /// </summary>
 /// <param name="unchangedInput">The unchanged input.</param>
 internal MutationResult(MutationInput unchangedInput)
 {
     _root            = unchangedInput.Root;
     _countAdjustment = 0;
 }