You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2025/10/01 06:13:56 UTC

(lucenenet) 03/09: Lucene.Net.Support.Arrays::Copy(): Added overloads to cover ReadOnlySpan and Span combinations with arrays so we don't have to change the syntax to differ from Lucene

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 da04c6f456a3e7165e2693a1766fdd6257c4db89
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Sep 28 22:13:53 2025 +0700

    Lucene.Net.Support.Arrays::Copy(): Added overloads to cover ReadOnlySpan<T> and Span<T> combinations with arrays so we don't have to change the syntax to differ from Lucene
---
 src/Lucene.Net.Tests/Support/TestArrays.cs | 223 +++++++++++++++++++++++++++++
 src/Lucene.Net/Support/Arrays.Span.cs      | 114 +++++++++++++++
 src/Lucene.Net/Support/Arrays.cs           |   6 +-
 3 files changed, 340 insertions(+), 3 deletions(-)

diff --git a/src/Lucene.Net.Tests/Support/TestArrays.cs b/src/Lucene.Net.Tests/Support/TestArrays.cs
index b0ccc1383..4b4d04a5e 100644
--- a/src/Lucene.Net.Tests/Support/TestArrays.cs
+++ b/src/Lucene.Net.Tests/Support/TestArrays.cs
@@ -833,6 +833,229 @@ public void Copy_ObjectArray_WithIndices()
             Assert.AreEqual(4L, dest[4]);
         }
 
+        #region Copy (Array-Span overloads)
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Int32Array_Span()
+        {
+            int[] source = { 1, 2, 3, 4, 5 };
+            Span<int> dest = new int[5];
+            Arrays.Copy(source, dest, source.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2, dest[1]);
+            Assert.AreEqual(3, dest[2]);
+            Assert.AreEqual(4, dest[3]);
+            Assert.AreEqual(5, dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ObjectArray_Span()
+        {
+            object[] source = { 1, 2f, 3d, 4L, new object() };
+            Span<object> dest = new object[5];
+            Arrays.Copy(source, dest, source.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2f, dest[1]);
+            Assert.AreEqual(3d, dest[2]);
+            Assert.AreEqual(4L, dest[3]);
+            Assert.IsNotNull(dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Int32Array_Span_Partial()
+        {
+            int[] source = { 1, 2, 3, 4, 5 };
+            Span<int> dest = new int[3];
+            Arrays.Copy(source, dest, dest.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2, dest[1]);
+            Assert.AreEqual(3, dest[2]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ObjectArray_Span_Partial()
+        {
+            object[] source = { 1, 2f, 3d, 4L, new object() };
+            Span<object> dest = new object[3];
+            Arrays.Copy(source, dest, dest.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2f, dest[1]);
+            Assert.AreEqual(3d, dest[2]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Int32Array_Span_WithIndices()
+        {
+            int[] source = { 1, 2, 3, 4, 5 };
+            Span<int> dest = new int[5];
+            Arrays.Copy(source, 1, dest, 2, 3);
+            Assert.AreEqual(2, dest[2]);
+            Assert.AreEqual(3, dest[3]);
+            Assert.AreEqual(4, dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ObjectArray_Span_WithIndices()
+        {
+            object[] source = { 1, 2f, 3d, 4L, new object() };
+            Span<object> dest = new object[5];
+            Arrays.Copy(source, 1, dest, 2, 3);
+            Assert.AreEqual(2f, dest[2]);
+            Assert.AreEqual(3d, dest[3]);
+            Assert.AreEqual(4L, dest[4]);
+        }
+
+        #endregion Copy (Array-Span overloads)
+
+        #region Copy (ReadOnlySpan-Array overloads)
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ReadOnlySpan_Int32Array()
+        {
+            ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
+            int[] dest = new int[5];
+            Arrays.Copy(source, dest, source.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2, dest[1]);
+            Assert.AreEqual(3, dest[2]);
+            Assert.AreEqual(4, dest[3]);
+            Assert.AreEqual(5, dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ReadOnlySpan_ObjectArray()
+        {
+            ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
+            object[] dest = new object[5];
+            Arrays.Copy(source, dest, source.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2f, dest[1]);
+            Assert.AreEqual(3d, dest[2]);
+            Assert.AreEqual(4L, dest[3]);
+            Assert.IsNotNull(dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ReadOnlySpan_Int32Array_Partial()
+        {
+            ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
+            int[] dest = new int[3];
+            Arrays.Copy(source, dest, dest.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2, dest[1]);
+            Assert.AreEqual(3, dest[2]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ReadOnlySpan_ObjectArray_Partial()
+        {
+            ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
+            object[] dest = new object[3];
+            Arrays.Copy(source, dest, dest.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2f, dest[1]);
+            Assert.AreEqual(3d, dest[2]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ReadOnlySpan_Int32Array_WithIndices()
+        {
+            ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
+            int[] dest = new int[5];
+            Arrays.Copy(source, 1, dest, 2, 3);
+            Assert.AreEqual(2, dest[2]);
+            Assert.AreEqual(3, dest[3]);
+            Assert.AreEqual(4, dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_ReadOnlySpan_ObjectArray_WithIndices()
+        {
+            ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
+            object[] dest = new object[5];
+            Arrays.Copy(source, 1, dest, 2, 3);
+            Assert.AreEqual(2f, dest[2]);
+            Assert.AreEqual(3d, dest[3]);
+            Assert.AreEqual(4L, dest[4]);
+        }
+
+        #endregion Copy (ReadOnlySpan-Array overloads)
+
+        #region Copy (ReadOnlySpan-Span overloads)
+
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Int32_ReadOnlySpan_Span()
+        {
+            ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
+            Span<int> dest = stackalloc int[5];
+            Arrays.Copy(source, dest, source.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2, dest[1]);
+            Assert.AreEqual(3, dest[2]);
+            Assert.AreEqual(4, dest[3]);
+            Assert.AreEqual(5, dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Object_ReadOnlySpan_Span()
+        {
+            ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
+            Span<object> dest = new object[5];
+            Arrays.Copy(source, dest, source.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2f, dest[1]);
+            Assert.AreEqual(3d, dest[2]);
+            Assert.AreEqual(4L, dest[3]);
+            Assert.IsNotNull(dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Int32_ReadOnlySpan_Span_Partial()
+        {
+            ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
+            Span<int> dest = stackalloc int[3];
+            Arrays.Copy(source, dest, dest.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2, dest[1]);
+            Assert.AreEqual(3, dest[2]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Object_ReadOnlySpan_Span_Partial()
+        {
+            ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
+            Span<object> dest = new object[3];
+            Arrays.Copy(source, dest, dest.Length);
+            Assert.AreEqual(1, dest[0]);
+            Assert.AreEqual(2f, dest[1]);
+            Assert.AreEqual(3d, dest[2]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Int32_ReadOnlySpan_Span_WithIndices()
+        {
+            ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
+            Span<int> dest = stackalloc int[5];
+            Arrays.Copy(source, 1, dest, 2, 3);
+            Assert.AreEqual(2, dest[2]);
+            Assert.AreEqual(3, dest[3]);
+            Assert.AreEqual(4, dest[4]);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void Copy_Object_ReadOnlySpan_Span_WithIndices()
+        {
+            ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
+            Span<object> dest = new object[5];
+            Arrays.Copy(source, 1, dest, 2, 3);
+            Assert.AreEqual(2f, dest[2]);
+            Assert.AreEqual(3d, dest[3]);
+            Assert.AreEqual(4L, dest[4]);
+        }
+
+        #endregion Copy (ReadOnlySpan-Span overloads)
+
         [Test, LuceneNetSpecific]
         public void CopyOf_Int32Array()
         {
diff --git a/src/Lucene.Net/Support/Arrays.Span.cs b/src/Lucene.Net/Support/Arrays.Span.cs
new file mode 100644
index 000000000..a7aaed943
--- /dev/null
+++ b/src/Lucene.Net/Support/Arrays.Span.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.Support
+{
+    internal static partial class Arrays
+    {
+        // Span overloads of array methods to make usage syntax similar to Lucene.
+
+        /// <summary>
+        /// Copies a range of elements from an Array starting at the first element and pastes them
+        /// into a Span starting at the first element. The length is specified as a 32-bit integer.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="sourceArray">The Array that contains the data to copy.</param>
+        /// <param name="destinationArray">The Span that receives the data.</param>
+        /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Copy<T>(T[] sourceArray, Span<T> destinationArray, int length)
+        {
+            sourceArray.AsSpan(0, length).CopyTo(destinationArray);
+        }
+
+        /// <summary>
+        /// Copies a range of elements from a Span starting at the first element and pastes them
+        /// into an Array starting at the first element. The length is specified as a 32-bit integer.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="sourceArray">The Span that contains the data to copy.</param>
+        /// <param name="destinationArray">The Array that receives the data.</param>
+        /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Copy<T>(ReadOnlySpan<T> sourceArray, T[] destinationArray, int length)
+        {
+            sourceArray.Slice(0, length).CopyTo(destinationArray);
+        }
+
+        /// <summary>
+        /// Copies a range of elements from a Span starting at the first element and pastes them
+        /// into another Span starting at the first element. The length is specified as a 32-bit integer.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="sourceArray">The Span that contains the data to copy.</param>
+        /// <param name="destinationArray">The Span that receives the data.</param>
+        /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Copy<T>(ReadOnlySpan<T> sourceArray, Span<T> destinationArray, int length)
+        {
+            sourceArray.Slice(0, length).CopyTo(destinationArray);
+        }
+
+        /// <summary>
+        /// Copies a range of elements from an Array starting at the specified source index and pastes them
+        /// to a Span starting at the specified destination index. The length and the indexes are
+        /// specified as 32-bit integers.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="sourceArray">The Array that contains the data to copy.</param>
+        /// <param name="sourceIndex">A 32-bit integer that represents the index in the
+        /// <paramref name="sourceArray"/> at which copying begins.</param>
+        /// <param name="destinationArray">The Span that receives the data.</param>
+        /// <param name="destinationIndex">A 32-bit integer that represents the index in the
+        /// <paramref name="destinationArray"/> at which storing begins.</param>
+        /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Copy<T>(T[] sourceArray, int sourceIndex, Span<T> destinationArray, int destinationIndex, int length)
+        {
+            sourceArray.AsSpan(sourceIndex, length).CopyTo(destinationArray.Slice(destinationIndex));
+        }
+
+        /// <summary>
+        /// Copies a range of elements from a Span starting at the specified source index and pastes them
+        /// to an Array starting at the specified destination index. The length and the indexes are
+        /// specified as 32-bit integers.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="sourceArray">The Span that contains the data to copy.</param>
+        /// <param name="sourceIndex">A 32-bit integer that represents the index in the
+        /// <paramref name="sourceArray"/> at which copying begins.</param>
+        /// <param name="destinationArray">The Array that receives the data.</param>
+        /// <param name="destinationIndex">A 32-bit integer that represents the index in the
+        /// <paramref name="destinationArray"/> at which storing begins.</param>
+        /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Copy<T>(ReadOnlySpan<T> sourceArray, int sourceIndex, T[] destinationArray, int destinationIndex, int length)
+        {
+            sourceArray.Slice(sourceIndex, length).CopyTo(destinationArray.AsSpan(destinationIndex));
+        }
+
+        /// <summary>
+        /// Copies a range of elements from a Span starting at the specified source index and pastes them
+        /// to another Span starting at the specified destination index. The length and the indexes are
+        /// specified as 32-bit integers.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="sourceArray">The Span that contains the data to copy.</param>
+        /// <param name="sourceIndex">A 32-bit integer that represents the index in the
+        /// <paramref name="sourceArray"/> at which copying begins.</param>
+        /// <param name="destinationArray">The Span that receives the data.</param>
+        /// <param name="destinationIndex">A 32-bit integer that represents the index in the
+        /// <paramref name="destinationArray"/> at which storing begins.</param>
+        /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Copy<T>(ReadOnlySpan<T> sourceArray, int sourceIndex, Span<T> destinationArray, int destinationIndex, int length)
+        {
+            sourceArray.Slice(sourceIndex, length).CopyTo(destinationArray.Slice(destinationIndex));
+        }
+    }
+}
diff --git a/src/Lucene.Net/Support/Arrays.cs b/src/Lucene.Net/Support/Arrays.cs
index e2699da55..2665ddcc3 100644
--- a/src/Lucene.Net/Support/Arrays.cs
+++ b/src/Lucene.Net/Support/Arrays.cs
@@ -29,7 +29,7 @@ namespace Lucene.Net.Support
      * limitations under the License.
      */
 
-    internal static class Arrays
+    internal static partial class Arrays
     {
         /// <summary>
         /// Compares the entire members of one array with the other one.
@@ -167,7 +167,7 @@ public void Fill(T[] array, T value, int startIndex, int count)
         /// <b>Usage Note:</b> This implementation uses the most efficient (known) method for copying the
         /// array based on the data type and platform.
         /// </summary>
-        /// <typeparam name="T">The array type.</typeparam>
+        /// <typeparam name="T">The array element type.</typeparam>
         /// <param name="sourceArray">The Array that contains the data to copy.</param>
         /// <param name="destinationArray">The Array that receives the data.</param>
         /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
@@ -195,7 +195,7 @@ public static void Copy<T>(T[] sourceArray, T[] destinationArray, int length)
         /// <b>Usage Note:</b> This implementation uses the most efficient (known) method for copying the
         /// array based on the data type and platform.
         /// </summary>
-        /// <typeparam name="T">The array type.</typeparam>
+        /// <typeparam name="T">The array element type.</typeparam>
         /// <param name="sourceArray">The Array that contains the data to copy.</param>
         /// <param name="sourceIndex">A 32-bit integer that represents the index in the
         /// <paramref name="sourceArray"/> at which copying begins.</param>