Beispiel #1
0
 private ImHashMap(Data data, ImHashMap <K, V> left, ImHashMap <K, V> right, int height)
 {
     _data  = data;
     Left   = left;
     Right  = right;
     Height = height;
 }
Beispiel #2
0
 private ImHashMap(Data data, ImHashMap <K, V> left, ImHashMap <K, V> right)
 {
     _data  = data;
     Left   = left;
     Right  = right;
     Height = 1 + (left.Height > right.Height ? left.Height : right.Height);
 }
Beispiel #3
0
 private ImHashMap(Data data)
 {
     _data  = data;
     Left   = Empty;
     Right  = Empty;
     Height = 1;
 }
Beispiel #4
0
        /// <summary>Depth-first in-order traversal as described in http://en.wikipedia.org/wiki/Tree_traversal
        /// The only difference is using fixed size array instead of stack for speed-up (~20% faster than stack).</summary>
        /// <returns>Sequence of enumerated key value pairs.</returns>
        public IEnumerable <KV <K, V> > Enumerate()
        {
            if (Height == 0)
            {
                yield break;
            }

            var parents = new ImHashMap <K, V> [Height];

            var node        = this;
            var parentCount = -1;

            while (node.Height != 0 || parentCount != -1)
            {
                if (node.Height != 0)
                {
                    parents[++parentCount] = node;
                    node = node.Left;
                }
                else
                {
                    node = parents[parentCount--];
                    yield return(new KV <K, V>(node.Key, node.Value));

                    if (node.Conflicts != null)
                    {
                        for (var i = 0; i < node.Conflicts.Length; i++)
                        {
                            yield return(node.Conflicts[i]);
                        }
                    }

                    node = node.Right;
                }
            }
        }
Beispiel #5
0
        internal ImHashMap <K, V> Remove(int hash, K key, bool ignoreKey = false)
        {
            if (Height == 0)
            {
                return(this);
            }

            ImHashMap <K, V> result;

            if (hash == Hash) // found node
            {
                if (ignoreKey || Equals(Key, key))
                {
                    if (!ignoreKey && Conflicts != null)
                    {
                        return(ReplaceRemovedWithConflicted());
                    }

                    if (Height == 1) // remove node
                    {
                        return(Empty);
                    }

                    if (Right.IsEmpty)
                    {
                        result = Left;
                    }
                    else if (Left.IsEmpty)
                    {
                        result = Right;
                    }
                    else
                    {
                        // we have two children, so remove the next highest node and replace this node with it.
                        var successor = Right;
                        while (!successor.Left.IsEmpty)
                        {
                            successor = successor.Left;
                        }
                        result = new ImHashMap <K, V>(successor._data,
                                                      Left, Right.Remove(successor.Hash, default(K), ignoreKey: true));
                    }
                }
                else if (Conflicts != null)
                {
                    return(TryRemoveConflicted(key));
                }
                else
                {
                    return(this); // if key is not matching and no conflicts to lookup - just return
                }
            }
            else if (hash < Hash)
            {
                result = new ImHashMap <K, V>(_data, Left.Remove(hash, key, ignoreKey), Right);
            }
            else
            {
                result = new ImHashMap <K, V>(_data, Left, Right.Remove(hash, key, ignoreKey));
            }

            if (result.Height == 1)
            {
                return(result);
            }

            return(result.KeepBalance());
        }
Beispiel #6
0
 private ImHashMap <K, V> With(ImHashMap <K, V> left, ImHashMap <K, V> right)
 {
     return(left == Left && right == Right ? this : new ImHashMap <K, V>(_data, left, right));
 }