private static int Balance(SortedInt32KeyNode <TValue> tree) { Requires.NotNull(tree, "tree"); Debug_.Assert(!tree.IsEmpty); return(tree._right._height - tree._left._height); }
// Returns size of hashtable to grow to. public static int ExpandPrime(int oldSize) { int newSize = 2 * oldSize; // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow. // Note that this check works even when _items.Length overflowed thanks to the (uint) cast if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) { Debug_.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength"); return(MaxPrimeArrayLength); } return(GetPrime(newSize)); }
/// <summary> /// Initializes a new instance of the <see cref="SortedInt32KeyNode{TValue}"/> class that is not yet frozen. /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> /// <param name="left">The left.</param> /// <param name="right">The right.</param> /// <param name="frozen">Whether this node is prefrozen.</param> private SortedInt32KeyNode(int key, TValue value, SortedInt32KeyNode <TValue> left, SortedInt32KeyNode <TValue> right, bool frozen = false) { Requires.NotNull(left, "left"); Requires.NotNull(right, "right"); Debug_.Assert(!frozen || (left._frozen && right._frozen)); _key = key; _value = value; _left = left; _right = right; _frozen = frozen; _height = checked ((byte)(1 + Math.Max(left._height, right._height))); }
/// <summary> /// AVL rotate double-right operation. /// </summary> /// <param name="tree">The tree.</param> /// <returns>The rotated tree.</returns> private static SortedInt32KeyNode <TValue> DoubleRight(SortedInt32KeyNode <TValue> tree) { Requires.NotNull(tree, "tree"); Debug_.Assert(!tree.IsEmpty); if (tree._left.IsEmpty) { return(tree); } SortedInt32KeyNode <TValue> rotatedLeftChild = tree.Mutate(left: RotateLeft(tree._left)); return(RotateRight(rotatedLeftChild)); }
/// <summary> /// AVL rotate right operation. /// </summary> /// <param name="tree">The tree.</param> /// <returns>The rotated tree.</returns> private static SortedInt32KeyNode <TValue> RotateRight(SortedInt32KeyNode <TValue> tree) { Requires.NotNull(tree, "tree"); Debug_.Assert(!tree.IsEmpty); if (tree._left.IsEmpty) { return(tree); } var left = tree._left; return(left.Mutate(right: tree.Mutate(left: left._right))); }
/// <summary> /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct. /// </summary> /// <param name="items">The array from which to copy.</param> internal static ImmutableArray <T> CreateDefensiveCopy <T>(T[] items) { Debug_.Assert(items != null); if (items.Length == 0) { return(ImmutableArray <T> .Empty); // use just a shared empty array, allowing the input array to be potentially GC'd } // defensive copy var tmp = new T[items.Length]; Array.Copy(items, 0, tmp, 0, items.Length); return(new ImmutableArray <T>(tmp)); }
private static SortedInt32KeyNode <TValue> MakeBalanced(SortedInt32KeyNode <TValue> tree) { Requires.NotNull(tree, "tree"); Debug_.Assert(!tree.IsEmpty); if (IsRightHeavy(tree)) { return(Balance(tree._right) < 0 ? DoubleLeft(tree) : RotateLeft(tree)); } if (IsLeftHeavy(tree)) { return(Balance(tree._left) > 0 ? DoubleRight(tree) : RotateRight(tree)); } return(tree); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static MutationResult Add(T item, MutationInput origin) { Requires.NotNullAllowStructs(item, "item"); OperationResult result; int hashCode = origin.EqualityComparer.GetHashCode(item); HashBucket bucket = origin.Root.GetValueOrDefault(hashCode); var newBucket = bucket.Add(item, origin.EqualityComparer, out result); if (result == OperationResult.NoChangeRequired) { return(new MutationResult(origin.Root, 0)); } var newRoot = UpdateRoot(origin.Root, hashCode, newBucket); Debug_.Assert(result == OperationResult.SizeChanged); return(new MutationResult(newRoot, 1 /*result == OperationResult.SizeChanged ? 1 : 0*/)); }
private static bool IsLeftHeavy(SortedInt32KeyNode <TValue> tree) { Requires.NotNull(tree, "tree"); Debug_.Assert(!tree.IsEmpty); return(Balance(tree) <= -2); }