lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nightowl...@apache.org
Subject [lucenenet] 02/03: Lucene.Net.Support.CollectionExtensions: Made more efficient RemoveAll() method and added RetainAll() for use in rare circumstances when we want to do set actions on ICollection<T>
Date Sat, 24 Jul 2021 19:04:31 GMT
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 0d9abf64c4eb8d3867254bc7f60c4ef1367b3b90
Author: Shad Storhaug <shad@shadstorhaug.com>
AuthorDate: Fri Jul 23 13:06:43 2021 +0700

    Lucene.Net.Support.CollectionExtensions: Made more efficient RemoveAll() method and added
RetainAll() for use in rare circumstances when we want to do set actions on ICollection<T>
---
 src/Lucene.Net/Support/CollectionExtensions.cs | 84 +++++++++++++++++++++++---
 1 file changed, 76 insertions(+), 8 deletions(-)

diff --git a/src/Lucene.Net/Support/CollectionExtensions.cs b/src/Lucene.Net/Support/CollectionExtensions.cs
index 6eb7ed0..12c9f70 100644
--- a/src/Lucene.Net/Support/CollectionExtensions.cs
+++ b/src/Lucene.Net/Support/CollectionExtensions.cs
@@ -1,7 +1,8 @@
-´╗┐using System;
+´╗┐using J2N.Collections.Generic.Extensions;
+using System;
 using System.Collections.Generic;
 using System.Diagnostics;
-using System.Runtime.CompilerServices;
+using JCG = J2N.Collections.Generic;
 
 namespace Lucene.Net.Support
 {
@@ -29,23 +30,90 @@ namespace Lucene.Net.Support
     {
         /// <summary>
         /// Removes the given collection of elements from the source <see cref="ICollection{T}"/>.
+        /// <para/>
+        /// Usage Note: This is the same operation as <see cref="ISet{T}.ExceptWith(IEnumerable{T})"/>
or
+        /// <see cref="List{T}.RemoveAll(Predicate{T})"/> with a predicate of <c>(value)
=> collection.Contains(value)</c>. It is
+        /// recommended to use these alternatives when possible.
         /// </summary>
         /// <typeparam name="T">The type of the elements of <paramref name="source"/>.</typeparam>
         /// <param name="source">An <see cref="ICollection{T}"/> to remove elements
from.</param>
-        /// <param name="removeList">An <see cref="IEnumerable{T}"/> containing
the items to remove from <paramref name="source"/>.</param>
+        /// <param name="collection">An <see cref="ICollection{T}"/> containing
the items to remove from <paramref name="source"/>.</param>
+        /// <returns><c>true</c> if the collection changed as a result
of the call; otherwise, <c>false</c>.</returns>
         [DebuggerStepThrough]
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static void RemoveAll<T>(this ICollection<T> source, IEnumerable<T>
removeList)
+        public static bool RemoveAll<T>(this ICollection<T> source, ICollection<T>
collection)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
+            if (collection == null)
+                throw new ArgumentNullException(nameof(collection));
 
-            if (source.Count == 0) return;
+            if (source.Count == 0) return false;
 
-            foreach (var elt in removeList)
+            if (source is ISet<T> set)
             {
-                source.Remove(elt);
+                int originalCount = set.Count;
+                set.ExceptWith(collection);
+                return originalCount != set.Count;
             }
+            else if (source is IList<T> list)
+            {
+                int removed = list.RemoveAll((value) => collection.Contains(value));
+                return removed > 0;
+            }
+
+            // Slow path for unknown collection types
+            bool modified = false;
+            foreach (var e in collection)
+            {
+                modified |= source.Remove(e);
+            }
+            return modified;
+        }
+
+        /// <summary>
+        /// Retains only the elements in this list that are contained in the specified collection
(optional operation).
+        /// In other words, removes from this list all of its elements that are not contained
in the specified collection.
+        /// <para/>
+        /// Usage Note: This is the same operation as <see cref="ISet{T}.IntersectWith(IEnumerable{T})"/>
or
+        /// <see cref="List{T}.RemoveAll(Predicate{T})"/> with a predicate of <c>(value)
=> !collection.Contains(value)</c>. It is
+        /// recommended to use these alternatives when possible.
+        /// </summary>
+        /// <typeparam name="T">The type of the elements of <paramref name="source"/>.</typeparam>
+        /// <param name="source">An <see cref="ICollection{T}"/> to remove elements
from.</param>
+        /// <param name="collection">An <see cref="ICollection{T}"/> containing
the items to remove from <paramref name="source"/>.</param>
+        /// <returns><c>true</c> if the collection changed as a result
of the call; otherwise, <c>false</c>.</returns>
+        [DebuggerStepThrough]
+        public static bool RetainAll<T>(this ICollection<T> source, ICollection<T>
collection)
+        {
+            if (source == null)
+                throw new ArgumentNullException(nameof(source));
+            if (collection == null)
+                throw new ArgumentNullException(nameof(collection));
+
+            if (source.Count == 0) return false;
+
+            if (source is ISet<T> set)
+            {
+                int originalCount = set.Count;
+                set.IntersectWith(collection);
+                return originalCount != set.Count;
+            }
+            else if (source is IList<T> list)
+            {
+                int removed = list.RemoveAll((value) => !collection.Contains(value));
+                return removed > 0;
+            }
+
+            // Slow path for unknown collection types
+            var toRemove = new JCG.HashSet<T>();
+            foreach (var e in source)
+            {
+                if (!collection.Contains(e))
+                    toRemove.Add(e);
+            }
+            if (toRemove.Count > 0)
+                return source.RemoveAll(toRemove);
+            return false;
         }
     }
 }

Mime
View raw message