private ImHashMap(Data data, ImHashMap <K, V> left, ImHashMap <K, V> right, int height) { _data = data; Left = left; Right = right; Height = height; }
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); }
private ImHashMap(Data data) { _data = data; Left = Empty; Right = Empty; Height = 1; }
/// <summary> /// Scan a single assembly /// </summary> /// <param name="assembly"></param> /// <returns></returns> public static Task <AssemblyTypes> ForAssembly(Assembly assembly) { if (_assemblies.TryFind(assembly, out var types)) { return(types); } types = Task.Factory.StartNew(() => new AssemblyTypes(assembly)); _assemblies = _assemblies.AddOrUpdate(assembly, types); return(types); }
/// <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; } } }
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()); }
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)); }
public static void ClearAll() { _assemblies = ImHashMap <Assembly, Task <AssemblyTypes> > .Empty; }