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)); } }
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())); }
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())); }
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)); } }
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)); }
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()); }