public ImMap <K, V> Update(K key, V value) { var hash = key.GetHashCode(); var treeIndex = hash & HashBitsToTree; var trees = _trees; var tree = trees[treeIndex]; if (tree == null) { return(this); } var newTree = tree.AddOrUpdate(hash, key, value, null, true); if (newTree == tree) { return(this); } var newTrees = new ImTreeMap <K, V> [NumberOfTrees]; Array.Copy(trees, 0, newTrees, 0, NumberOfTrees); newTrees[treeIndex] = newTree; return(new ImMap <K, V>(newTrees, Count)); }
private ImTreeMap(int hash, K key, V value, KV <K, V>[] conficts, ImTreeMap <K, V> left, ImTreeMap <K, V> right) { Hash = hash; Key = key; Value = value; Conflicts = conficts; Left = left; Right = right; Height = 1 + (left.Height > right.Height ? left.Height : right.Height); }
/// <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 ImTreeMap <K, V> [Height]; var tree = this; var parentCount = -1; while (tree.Height != 0 || parentCount != -1) { if (tree.Height != 0) { parents[++parentCount] = tree; tree = tree.Left; } else { tree = parents[parentCount--]; yield return(new KV <K, V>(tree.Key, tree.Value)); if (tree.Conflicts != null) { for (var i = 0; i < tree.Conflicts.Length; i++) { yield return(tree.Conflicts[i]); } } tree = tree.Right; } } }
private ImTreeMap <K, V> With(ImTreeMap <K, V> left, ImTreeMap <K, V> right) { return(left == Left && right == Right ? this : new ImTreeMap <K, V>(Hash, Key, Value, Conflicts, left, right)); }