public override INode AddOrUpdate(OneItemLeaf item)
 {
     if (item.Hash < LeftItem.Hash)
     {
         var newLeft = Left.AddOrUpdate(item);
         return(!IsEmerged(newLeft, Left)
             ? new TwoItemsTree(LeftItem, RightItem, newLeft, Middle, Right)
             : (INode) new OneItemTree(LeftItem, newLeft, new OneItemTree(RightItem, Middle, Right)));
     }
     // if (item.Hash == LeftItem.Hash)
     if (item.Hash < RightItem.Hash)
     {
         var newMiddle = Middle.AddOrUpdate(item);
         if (!IsEmerged(newMiddle, Middle))
         {
             return(new TwoItemsTree(LeftItem, RightItem, Left, newMiddle, Right));
         }
         var emergedMiddle = (OneItemTree)newMiddle;
         return(new OneItemTree(emergedMiddle.Item,
                                new OneItemTree(LeftItem, Left, emergedMiddle.Right),
                                new OneItemTree(RightItem, emergedMiddle.Left, Right)));
     }
     // for now skip if (item.Hash == RightItem.Hash)
     // else if (item.Hash > RightItem.Hash)
     {
         var newRight = Right.AddOrUpdate(item);
         return(!IsEmerged(newRight, Right)
             ? new TwoItemsTree(LeftItem, RightItem, Left, Middle, newRight)
             : (INode) new OneItemTree(RightItem, new OneItemTree(LeftItem, Left, Middle), newRight));
     }
 }
Exemple #2
0
 public IntTree <V> AddOrUpdate(int key, V value, Update <V> updateValue = null)
 {
     return(Height == 0 ? new IntTree <V>(key, value, Empty, Empty)
         : (key == Key ? new IntTree <V>(key, updateValue == null ? value : updateValue(Value, value), Left, Right)
         : (key < Key
             ? With(Left.AddOrUpdate(key, value, updateValue), Right)
             : With(Left, Right.AddOrUpdate(key, value, updateValue))).EnsureBalanced()));
 }
 public HashTreeV2 <V> AddOrUpdate(int key, V newValue, UpdateValue update = null)
 {
     return(Height == 0 ? new HashTreeV2 <V>(key, newValue, Empty, Empty)
         : (key == Key ? new HashTreeV2 <V>(key, update == null ? newValue : update(Value, newValue), Left, Right)
             : (key < Key
                 ? With(Left.AddOrUpdate(key, newValue), Right)
                 : With(Left, Right.AddOrUpdate(key, newValue))).EnsureBalanced()));
 }
Exemple #4
0
 private AvlTree <K, V> AddOrUpdate(int hash, K key, V value, UpdateValue updateValue)
 {
     return(Height == 0 ? new AvlTree <K, V>(hash, key, value, null, Empty, Empty)
         : (hash == Hash ? UpdateValueAndResolveConflicts(key, value, updateValue)
         : (hash < Hash
             ? With(Left.AddOrUpdate(hash, key, value, updateValue), Right)
             : With(Left, Right.AddOrUpdate(hash, key, value, updateValue)))
            .KeepBalanced()));
 }
Exemple #5
0
        public IImmutableTree <TKey, TValue> AddOrUpdate(TKey key, TValue value, Func <TKey, TValue, TValue> updateValueFactory)
        {
            ImmutableTree <TKey, TValue> result;
            var comparison = _comparer.Compare(key, _key);

            if (comparison > 0)
            {
                result = new ImmutableTree <TKey, TValue>(_comparer, _keyCloner, _valueCloner, _key, _value, Left,
                                                          Right.AddOrUpdate(key, value, updateValueFactory));
            }
            else if (comparison < 0)
            {
                result = new ImmutableTree <TKey, TValue>(_comparer, _keyCloner, _valueCloner, _key, _value,
                                                          Left.AddOrUpdate(key, value, updateValueFactory), Right);
            }
            else
            {
                result = new ImmutableTree <TKey, TValue>(_comparer, _keyCloner, _valueCloner, key,
                                                          updateValueFactory(key, _value), Left, Right);
            }

            return(BalanceTree(result));
        }
 public INode AddOrUpdate(OneItemLeaf item)
 {
     if (item.Hash < Item.Hash)
     {
         var newLeft = Left.AddOrUpdate(item);
         if (!IsEmerged(newLeft, Left))
         {
             return(new OneItemTree(Item, newLeft, Right));
         }
         var emergedLeft = (OneItemTree)newLeft;
         return(new TwoItemsTree(emergedLeft.Item, Item, emergedLeft.Left, emergedLeft.Right, Right));
         // otherwise just reattach new left
     }
     //else if (item.Hash > LeftItem.Hash)
     {
         var newRight = Right.AddOrUpdate(item);
         if (!IsEmerged(newRight, Right))
         {
             return(new OneItemTree(Item, Left, newRight));
         }
         var emergedRight = (OneItemTree)newRight;
         return(new TwoItemsTree(Item, emergedRight.Item, Left, emergedRight.Left, emergedRight.Right));
     }
 }
Exemple #7
0
        public IBinarySearchTree <TKey, TValue> AddOrUpdate(TKey key, TValue value, Func <TKey, TValue, TValue> updateValueFactory)
        {
            AVLTree <TKey, TValue> result;
            var compare = comparer.Compare(key, theKey);

            if (compare > 0)
            {
                result = new AVLTree <TKey, TValue>(comparer, deepCopyKey, deepCopyValue, theKey, theValue, Left, Right.AddOrUpdate(key, value, updateValueFactory));
            }
            else if (compare < 0)
            {
                result = new AVLTree <TKey, TValue>(comparer, deepCopyKey, deepCopyValue, theKey, theValue, Left.AddOrUpdate(key, value, updateValueFactory), Right);
            }
            else
            {
                var newValue = updateValueFactory(key, theValue);
                result = new AVLTree <TKey, TValue>(comparer, deepCopyKey, deepCopyValue, key, newValue, Left, Right);
            }
            return(MakeBalanced(result));
        }
Exemple #8
0
        private IntNTree <V> AddOrUpdate(DryIoc.Playground.KV <int, V> item, UpdateValue updateValue)
        {
            if (Height == 0)
            {
                return(new IntNTree <V>(new[] { item }, Empty, Empty));
            }

            if (item.Key < LeftKey)
            {
                if (Items.Length < N)
                {
                    var newItems = new DryIoc.Playground.KV <int, V> [Items.Length + 1];
                    newItems[0] = item;
                    Array.Copy(Items, 0, newItems, 1, Items.Length);
                    return(new IntNTree <V>(newItems, Left, Right));
                }

                return(With(Left.AddOrUpdate(item, updateValue), Right).EnsureBalanced());
            }

            if (item.Key > RightKey)
            {
                if (Items.Length < N)
                {
                    var newItems = new DryIoc.Playground.KV <int, V> [Items.Length + 1];
                    Array.Copy(Items, 0, newItems, 0, Items.Length);
                    newItems[Items.Length] = item;
                    return(new IntNTree <V>(newItems, Left, Right));
                }

                return(With(Left, Right.AddOrUpdate(item, updateValue)).EnsureBalanced());
            }

            var i = 0;

            while (item.Key > Items[i].Key)
            {
                i++;
            }

            if (item.Key == Items[i].Key) // Update value
            {
                var newItems = new DryIoc.Playground.KV <int, V> [Items.Length];
                Array.Copy(Items, 0, newItems, 0, Items.Length);
                newItems[i] = updateValue == null ? item : new DryIoc.Playground.KV <int, V>(item.Key, updateValue(Items[i].Value, item.Value));
                return(new IntNTree <V>(newItems, Left, Right));
            }

            if (Items.Length < N) // Insert value into current node
            {
                var newItems = new DryIoc.Playground.KV <int, V> [Items.Length + 1];
                Array.Copy(Items, 0, newItems, 0, i);
                newItems[i] = item;
                Array.Copy(Items, i, newItems, i + 1, Items.Length - i);
                return(new IntNTree <V>(newItems, Left, Right));
            }

            var items = new DryIoc.Playground.KV <int, V> [Items.Length];

            // Drop left item to the left node if it has room for insert, otherwise drop right item to right node.
            if (Left.Height == 0 || Left.Items.Length < N)
            {
                // values: drop 1, 2, insert 3, 4, 6, 9
                // indexes:     0, 1, insert 1, 2, 3, 4
                // i == 2
                Array.Copy(Items, 1, items, 0, i - 1);
                items[i - 1] = item;
                Array.Copy(Items, i, items, i, Items.Length - i);
                return(new IntNTree <V>(items, Left.AddOrUpdate(Items[0], updateValue), Right).EnsureBalanced());
            }

            // values:  copy 1, 2, insert 3, copy 4, 6, drop 9
            // indexes: copy 0, 1, insert 1, copy 2, 3, drop 4
            // i == 2
            Array.Copy(Items, 0, items, 0, i);
            items[i] = item;
            Array.Copy(Items, i, items, i + 1, Items.Length - i - 1);
            return(new IntNTree <V>(items, Left, Right.AddOrUpdate(Items[Items.Length - 1], updateValue)).EnsureBalanced());
        }