Exemplo n.º 1
0
        public ITwoThree <T> Insert(T item, IComparer <T> comparer, out ITwoThree <T> splitLeft, out ITwoThree <T> splitRight, out T splitValue)
        {
            splitLeft  = splitRight = Instance;
            splitValue = item;

            return(null);
        }
Exemplo n.º 2
0
        // Constructors

        public TwoNode(T value, ITwoThree <T> left, ITwoThree <T> right)
        {
            Value = value;

            Left  = left;
            Right = right;
        }
Exemplo n.º 3
0
        public ITwoThree <T> Insert(T item, IComparer <T> comparer, out ITwoThree <T> splitLeft, out ITwoThree <T> splitRight, out T splitValue)
        {
            var side = GetSide(item, comparer);

            if (side == Side.Same)
            {
                splitLeft  = null;
                splitRight = null;
                splitValue = default(T);

                return(this);
            }

            var child = GetChild(side);
            var node  = child.Insert(item, comparer, out splitLeft, out splitRight, out splitValue);

            if (node == null)
            {
                // Child node split.
                return(side == Side.Left
                    ? new ThreeNode <T>(splitValue, Value, splitLeft, splitRight, Right)
                    : new ThreeNode <T>(Value, splitValue, Left, splitLeft, splitRight));
            }

            // Single node was splitValue.

            if (node == child)
            {
                return(this);
            }

            return(side == Side.Left
                ? new TwoNode <T>(Value, node, Right)
                : new TwoNode <T>(Value, Left, node));
        }
Exemplo n.º 4
0
        public static ITwoThree <T> Remove <T>(this ITwoThree <T> root, T item, IComparer <T> comparer = null)
        {
            comparer = comparer ?? Comparer <T> .Default;

            bool removed;

            return(root.Remove(item, comparer, out removed));
        }
Exemplo n.º 5
0
        private void AssertValid <T>(ITwoThree <T> tree)
        {
            var values = tree.GetValues().ToArray();

            Assert.True(tree.IsBalanced());
            CollectionAssert.IsOrdered(values);
            CollectionAssert.AllItemsAreUnique(values);
        }
Exemplo n.º 6
0
        public static ITwoThree <T> Insert <T>(this ITwoThree <T> root, T item, IComparer <T> comparer = null)
        {
            comparer = comparer ?? Comparer <T> .Default;

            T             propagated;
            ITwoThree <T> left, right;
            var           node = root.Insert(item, comparer, out left, out right, out propagated);

            return(node ?? new TwoNode <T>(propagated, left, right));
        }
        public ImmutableSortedDictionary(IComparer <TKey> keyComparer)
        {
            if (keyComparer == null)
            {
                throw new ArgumentNullException(nameof(keyComparer));
            }

            _root     = EmptyTwoThree <KeyValuePair <TKey, TValue> > .Instance;
            _comparer = new KeyComparer <TKey, TValue>(keyComparer);
        }
Exemplo n.º 8
0
        // Constructors

        public ThreeNode(T first, T second, ITwoThree <T> left, ITwoThree <T> middle, ITwoThree <T> right)
        {
            First  = first;
            Second = second;

            Left   = left;
            Middle = middle;
            Right  = right;

            Debug.Assert(left.IsNullOrEmpty() && middle.IsNullOrEmpty() && right.IsNullOrEmpty() ||
                         !left.IsNullOrEmpty() && !middle.IsNullOrEmpty() && !right.IsNullOrEmpty());
        }
Exemplo n.º 9
0
        public ITwoThree <T> Insert(T item, IComparer <T> comparer, out ITwoThree <T> splitLeft, out ITwoThree <T> splitRight, out T splitValue)
        {
            // Default split values.
            splitLeft  = splitRight = null;
            splitValue = default(T);

            // Get side to insert node.
            var side = GetSide(item, comparer);

            // Values are equal, no need to change tree.
            if (IsSame(side))
            {
                return(this);
            }

            // Insert value into proper node.
            T             pv;
            ITwoThree <T> pl, pr;
            var           child = GetChild(side);
            var           node  = child.Insert(item, comparer, out pl, out pr, out pv);

            // Insert propagated single node.
            if (node != null)
            {
                return(node == child ? this : NewChangedNode(node, side));
            }

            // Insert propagated two nodes and value, meaning it split.
            // Sinde this is 3-node, we are at full capacity and need to split too.
            switch (side)
            {
            case Side.Left:
                splitLeft  = new TwoNode <T>(pv, pl, pr);
                splitRight = new TwoNode <T>(Second, Middle, Right);
                splitValue = First;
                break;

            case Side.Middle:
                splitLeft  = new TwoNode <T>(First, Left, pl);
                splitRight = new TwoNode <T>(Second, pr, Right);
                splitValue = pv;
                break;

            case Side.Right:
                splitLeft  = new TwoNode <T>(First, Left, Middle);
                splitRight = new TwoNode <T>(pv, pl, pr);
                splitValue = Second;
                break;
            }

            return(null);
        }
Exemplo n.º 10
0
        private ITwoThree <T> RedistributeCons(T value, ITwoThree <T> changed, Side side, out bool removed)
        {
            switch (side)
            {
            case Side.SameFirst:
                return(Redistribute(value, Second, Left, changed, Right, Side.Middle, out removed));

            case Side.SameSecond:
                return(Redistribute(First, value, Left, Middle, changed, Side.Right, out removed));

            default:
                throw new ArgumentOutOfRangeException(nameof(side));
            }
        }
Exemplo n.º 11
0
        private ITwoThree <T> NewChangedWithConsequent(T value, ITwoThree <T> node, Side side)
        {
            switch (side)
            {
            case Side.SameFirst:
                return(new ThreeNode <T>(value, Second, Left, node, Right));

            case Side.SameSecond:
                return(new ThreeNode <T>(First, value, Left, Middle, node));

            default:
                throw new ArgumentOutOfRangeException(nameof(side));
            }
        }
Exemplo n.º 12
0
        private ITwoThree <T> RedistributeOrMerge(T value, ITwoThree <T> left, ITwoThree <T> right, Side removedSide, out bool removed)
        {
            removed = false;

            if (removedSide == Side.Right)
            {
                if (left is ThreeNode <T> )
                {
                    // Right redistribute case.

                    var red = (ThreeNode <T>)left;
                    var l   = new TwoNode <T>(red.First, red.Left, red.Middle);
                    var r   = new TwoNode <T>(value, red.Right, right);

                    return(new TwoNode <T>(red.Second, l, r));
                }

                // Right merge case.

                var m = (TwoNode <T>)left;

                removed = true;
                return(new ThreeNode <T>(m.Value, value, m.Left, m.Right, right));
            }

            if (removedSide == Side.Left)
            {
                if (right is ThreeNode <T> )
                {
                    // Left redistribute case.

                    var led = (ThreeNode <T>)right;
                    var l   = new TwoNode <T>(value, left, led.Left);
                    var r   = new TwoNode <T>(led.Second, led.Middle, led.Right);

                    return(new TwoNode <T>(led.First, l, r));
                }

                // Left merge case.

                var m = (TwoNode <T>)right;

                removed = true;
                return(new ThreeNode <T>(value, m.Value, left, m.Left, m.Right));
            }

            throw new InvalidOperationException();
        }
Exemplo n.º 13
0
        private ITwoThree <T> RedistributeFrom(ITwoThree <T> changed, Side side, out bool removed)
        {
            switch (side)
            {
            case Side.Left:
                return(Redistribute(First, Second, changed, Middle, Right, side, out removed));

            case Side.Middle:
                return(Redistribute(First, Second, Left, changed, Right, side, out removed));

            case Side.Right:
                return(Redistribute(First, Second, Left, Middle, changed, side, out removed));

            default:
                throw new ArgumentOutOfRangeException(nameof(side));
            }
        }
Exemplo n.º 14
0
        private ITwoThree <T> NewChangedNode(ITwoThree <T> node, Side side)
        {
            switch (side)
            {
            case Side.Left:
                return(new ThreeNode <T>(First, Second, node, Middle, Right));

            case Side.Middle:
                return(new ThreeNode <T>(First, Second, Left, node, Right));

            case Side.Right:
                return(new ThreeNode <T>(First, Second, Left, Middle, node));

            default:
                throw new InvalidOperationException();
            }
        }
Exemplo n.º 15
0
        private static ITwoThree <T> RedistributeRight(T first, T second, ITwoThree <T> left, ITwoThree <T> middle, ITwoThree <T> right)
        {
            // Case A
            if (left is TwoNode <T> && middle is TwoNode <T> )
            {
                var sm = (TwoNode <T>)middle;

                var l = left;
                var r = new ThreeNode <T>(sm.Value, second, sm.Left, sm.Right, right);

                return(new TwoNode <T>(first, l, r));
            }

            // Case B
            if (middle is ThreeNode <T> )
            {
                var sm = (ThreeNode <T>)middle;

                var l = left;
                var m = new TwoNode <T>(sm.First, sm.Left, sm.Middle);
                var r = new TwoNode <T>(second, sm.Right, right);

                return(new ThreeNode <T>(first, sm.Second, l, m, r));
            }

            // Case C
            if (left is ThreeNode <T> && middle is TwoNode <T> )
            {
                var sl = (ThreeNode <T>)left;
                var sm = (TwoNode <T>)middle;

                var l = new TwoNode <T>(sl.First, sl.Left, sl.Middle);
                var m = new TwoNode <T>(first, sl.Right, sm.Left);
                var r = new TwoNode <T>(second, sm.Right, right);

                return(new ThreeNode <T>(sl.Second, sm.Value, l, m, r));
            }

            throw new InvalidOperationException();
        }
Exemplo n.º 16
0
        private static ITwoThree <T> RedistributeMiddle(T first, T second, ITwoThree <T> left, ITwoThree <T> middle, ITwoThree <T> right)
        {
            // Case A
            if (left is TwoNode <T> && right is TwoNode <T> )
            {
                var sl = (TwoNode <T>)left;

                var l = new ThreeNode <T>(sl.Value, first, sl.Left, sl.Right, middle);
                var r = right;

                return(new TwoNode <T>(second, l, r));
            }

            // Case B
            if (right is ThreeNode <T> )
            {
                var sr = (ThreeNode <T>)right;

                var l = left;
                var m = new TwoNode <T>(second, middle, sr.Left);
                var r = new TwoNode <T>(sr.Second, sr.Middle, sr.Right);

                return(new ThreeNode <T>(first, sr.First, l, m, r));
            }

            // Case C
            if (left is ThreeNode <T> && right is TwoNode <T> )
            {
                var sl = (ThreeNode <T>)left;

                var l = new TwoNode <T>(sl.First, sl.Left, sl.Middle);
                var m = new TwoNode <T>(first, sl.Right, middle);
                var r = right;

                return(new ThreeNode <T>(sl.Second, second, l, m, r));
            }

            throw new InvalidOperationException();
        }
Exemplo n.º 17
0
        private static ITwoThree <T> Redistribute(T first, T second, ITwoThree <T> left,
                                                  ITwoThree <T> middle, ITwoThree <T> right, Side side, out bool removed)
        {
            removed = false;

            if (side == Side.Left)
            {
                return(RedistributeLeft(first, second, left, middle, right));
            }

            if (side == Side.Middle)
            {
                return(RedistributeMiddle(first, second, left, middle, right));
            }

            if (side == Side.Right)
            {
                return(RedistributeRight(first, second, left, middle, right));
            }

            throw new ArgumentOutOfRangeException(nameof(side));
        }
 public static bool IsNullOrEmpty <T>(this ITwoThree <T> node)
 {
     return(node == null || node is EmptyTwoThree <T>);
 }
        // Constructors

        public ImmutableSortedDictionary()
        {
            _root     = EmptyTwoThree <KeyValuePair <TKey, TValue> > .Instance;
            _comparer = new KeyComparer <TKey, TValue>();
        }
 private ImmutableSortedDictionary(ITwoThree <KeyValuePair <TKey, TValue> > root, KeyComparer <TKey, TValue> comparer)
 {
     _root     = root;
     _comparer = comparer;
 }
        // Constructors

        public ImmutableSortedSet()
        {
            _root     = EmptyTwoThree <T> .Instance;
            _comparer = Comparer <T> .Default;
        }
        public static bool IsBalanced <T>(this ITwoThree <T> node)
        {
            int depth;

            return(node.IsBalanced(out depth));
        }
 private ImmutableSortedSet(ITwoThree <T> root, IComparer <T> comparer)
 {
     _root     = root;
     _comparer = comparer;
 }