/// <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*/)); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static MutationResult Intersect(IEnumerable <T> other, MutationInput origin) { Requires.NotNull(other, nameof(other)); var newSet = SortedInt32KeyNode <HashBucket> .EmptyNode; int count = 0; foreach (var item in other.GetEnumerableDisposable <T, Enumerator>()) { if (Contains(item, origin)) { var result = Add(item, new MutationInput(newSet, origin.EqualityComparer, origin.HashBucketEqualityComparer, count)); newSet = result.Root; count += result.Count; } } return(new MutationResult(newSet, count, CountType.FinalValue)); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static bool Overlaps(IEnumerable <T> other, MutationInput origin) { Requires.NotNull(other, nameof(other)); if (origin.Root.IsEmpty) { return(false); } foreach (T item in other.GetEnumerableDisposable <T, Enumerator>()) { if (Contains(item, origin)) { return(true); } } return(false); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static MutationResult Intersect(IEnumerable <T> other, MutationInput origin) { Requires.NotNull(other, "other"); var newSet = ImmutableSortedDictionary <int, HashBucket> .Node.EmptyNode; int count = 0; foreach (var item in other) { if (Contains(item, origin)) { var result = Add(item, new MutationInput(newSet, origin.EqualityComparer, count)); newSet = result.Root; count += result.Count; } } return(new MutationResult(newSet, count, CountType.FinalValue)); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static bool SetEquals(IEnumerable <T> other, MutationInput origin) { Requires.NotNull(other, nameof(other)); var otherSet = new HashSet <T>(other, origin.EqualityComparer); if (origin.Count != otherSet.Count) { return(false); } foreach (T item in otherSet) { if (!Contains(item, origin)) { return(false); } } return(true); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static MutationResult Remove(T item, MutationInput origin) { var result = OperationResult.NoChangeRequired; int hashCode = origin.EqualityComparer.GetHashCode(item); HashBucket bucket; var newRoot = origin.Root; if (origin.Root.TryGetValue(hashCode, out bucket)) { var newBucket = bucket.Remove(item, origin.EqualityComparer, out result); if (result == OperationResult.NoChangeRequired) { return(new MutationResult(origin.Root, 0)); } newRoot = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket); } return(new MutationResult(newRoot, result == OperationResult.SizeChanged ? -1 : 0)); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static bool IsProperSupersetOf(IEnumerable <T> other, MutationInput origin) { Requires.NotNull(other, "other"); if (origin.Root.IsEmpty) { return(false); } int matchCount = 0; foreach (T item in other.GetEnumerableDisposable <T, Enumerator>()) { matchCount++; if (!Contains(item, origin)) { return(false); } } return(origin.Count > matchCount); }
/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static MutationResult Union(IEnumerable <T> other, MutationInput origin) { Requires.NotNull(other, "other"); int count = 0; var newRoot = origin.Root; foreach (var item in other.GetEnumerableDisposable <T, Enumerator>()) { int hashCode = origin.EqualityComparer.GetHashCode(item); HashBucket bucket = newRoot.GetValueOrDefault(hashCode); OperationResult result; var newBucket = bucket.Add(item, origin.EqualityComparer, out result); if (result == OperationResult.SizeChanged) { newRoot = UpdateRoot(newRoot, hashCode, newBucket); count++; } } return(new MutationResult(newRoot, count)); }
/// <summary> /// Performs the operation on a given data structure. /// </summary> private static MutationResult AddRange(IEnumerable <KeyValuePair <TKey, TValue> > items, MutationInput origin, KeyCollisionBehavior collisionBehavior = KeyCollisionBehavior.ThrowIfValueDifferent) { Requires.NotNull(items, nameof(items)); int countAdjustment = 0; var newRoot = origin.Root; foreach (var pair in items) { int hashCode = origin.KeyComparer.GetHashCode(pair.Key); HashBucket bucket = newRoot.GetValueOrDefault(hashCode); OperationResult result; var newBucket = bucket.Add(pair.Key, pair.Value, origin.KeyOnlyComparer, origin.ValueComparer, collisionBehavior, out result); newRoot = UpdateRoot(newRoot, hashCode, newBucket, origin.HashBucketComparer); if (result == OperationResult.SizeChanged) { countAdjustment++; } } return(new MutationResult(newRoot, countAdjustment)); }
/// <summary> /// Performs the operation on a given data structure. /// </summary> private static MutationResult Add(TKey key, TValue value, KeyCollisionBehavior behavior, MutationInput origin) { Requires.NotNullAllowStructs(key, nameof(key)); OperationResult result; int hashCode = origin.KeyComparer.GetHashCode(key); HashBucket bucket = origin.Root.GetValueOrDefault(hashCode); var newBucket = bucket.Add(key, value, origin.KeyOnlyComparer, origin.ValueComparer, behavior, out result); if (result == OperationResult.NoChangeRequired) { return(new MutationResult(origin)); } var newRoot = UpdateRoot(origin.Root, hashCode, newBucket, origin.HashBucketComparer); return(new MutationResult(newRoot, result == OperationResult.SizeChanged ? +1 : 0)); }
/// <summary> /// Initializes a new instance of the <see cref="ImmutableDictionary{TKey, TValue}.MutationResult"/> struct. /// </summary> /// <param name="unchangedInput">The unchanged input.</param> internal MutationResult(MutationInput unchangedInput) { _root = unchangedInput.Root; _countAdjustment = 0; }