Added possibilities to use IEnumerable<T> and ICollection<T> to create an array.

Closes:
thorsten/ExaArray#1
thorsten/ExaArray#3
thorsten/ExaArray#4
This commit is contained in:
Thorsten Sommer 2020-08-01 20:31:11 +02:00
parent d2ae4895c4
commit 0968edab80
3 changed files with 233 additions and 0 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace Exa
{
@ -184,5 +185,81 @@ namespace Exa
} while (leftOverTotal > 0);
return next;
}
/// <summary>
/// Creates a new ExaArray1D from an enumerable sequence of items. The number of items in the sequence is __unknown__.
/// </summary>
/// <remarks>
/// This factory method is slow because the number of items in the sequence is unknown. When you know the
/// number of items, you should use another factory method, where the number of items can be provided.
///
/// Performance: O(n)
/// </remarks>
/// <param name="sequence">The sequence to consume in order to create the array.</param>
/// <param name="strategy">The optional optimization strategy.</param>
/// <returns>The desired instance</returns>
public static ExaArray1D<T> CreateFrom(IEnumerable<T> sequence, Strategy strategy = Strategy.MAX_PERFORMANCE)
{
var inst = new ExaArray1D<T>(strategy);
ulong position = 0;
foreach (var element in sequence)
{
inst.Extend();
inst[position++] = element;
}
return inst;
}
/// <summary>
/// Creates a new ExaArray1D from an enumerable sequence of items. The number of items in the sequence is __known__.
/// </summary>
/// <remarks>
/// Creates an array with <c>length</c> items. When the sequence contains less elements, the remaining values are <c>default(T)</c>.
/// When the sequence contains more elements, these additional elements getting ignored.
///
/// Performance: O(n)
/// </remarks>
/// <param name="sequence">The sequence to consume in order to create the array.</param>
/// <param name="length">The number of elements in the sequence. When the sequence contains more elements, these additional elements are ignored.</param>
/// <param name="strategy">The optional optimization strategy.</param>
/// <returns>The desired instance</returns>
public static ExaArray1D<T> CreateFrom(IEnumerable<T> sequence, ulong length, Strategy strategy = Strategy.MAX_PERFORMANCE)
{
var inst = new ExaArray1D<T>(strategy);
inst.Extend(length);
ulong position = 0;
foreach (var element in sequence)
{
if(position == length)
break;
inst[position++] = element;
}
return inst;
}
/// <summary>
/// Creates a new ExaArray1D from a collection of items.
/// </summary>
/// <remarks>
/// Performance: O(n)
/// </remarks>
/// <param name="collection">The collection to use</param>
/// <param name="strategy">The optional optimization strategy.</param>
/// <returns>The desired instance</returns>
public static ExaArray1D<T> CreateFrom(ICollection<T> collection, Strategy strategy = Strategy.MAX_PERFORMANCE)
{
var inst = new ExaArray1D<T>(strategy);
inst.Extend((ulong) collection.Count);
ulong position = 0;
foreach (var element in collection)
inst[position++] = element;
return inst;
}
}
}

View File

@ -0,0 +1,50 @@
using System.Collections.Generic;
namespace Exa
{
/// <summary>
/// Contains extension methods.
/// </summary>
public static class ExtensionsFramework
{
/// <summary>
/// Creates a new ExaArray1D from this collection of items.
/// </summary>
/// <remarks>
/// Performance: O(n)
/// </remarks>
/// <param name="collection">The collection to use</param>
/// <param name="strategy">The optional optimization strategy.</param>
/// <returns>The desired instance</returns>
public static ExaArray1D<T> AsExaArray<T>(this ICollection<T> collection, Strategy strategy = Strategy.MAX_PERFORMANCE) => ExaArray1D<T>.CreateFrom(collection, strategy);
/// <summary>
/// Creates a new ExaArray1D from this enumerable sequence of items. The number of items in the sequence is __known__.
/// </summary>
/// <remarks>
/// Creates an array with <c>length</c> items. When this sequence contains less elements, the remaining values are <c>default(T)</c>.
/// When the sequence contains more elements, these additional elements getting ignored.
///
/// Performance: O(n)
/// </remarks>
/// <param name="sequence">The sequence to consume in order to create the array.</param>
/// <param name="length">The number of elements in the sequence. When the sequence contains more elements, these additional elements are ignored.</param>
/// <param name="strategy">The optional optimization strategy.</param>
/// <returns>The desired instance</returns>
public static ExaArray1D<T> AsExaArray<T>(this IEnumerable<T> sequence, ulong length, Strategy strategy = Strategy.MAX_PERFORMANCE) => ExaArray1D<T>.CreateFrom(sequence, length, strategy);
/// <summary>
/// Creates a new ExaArray1D from this enumerable sequence of items. The number of items in the sequence is __unknown__.
/// </summary>
/// <remarks>
/// This method is slow because the number of items in this sequence is unknown. When you know the
/// number of items, you should use another factory method, where the number of items can be provided.
///
/// Performance: O(n)
/// </remarks>
/// <param name="sequence">The sequence to consume in order to create the array.</param>
/// <param name="strategy">The optional optimization strategy.</param>
/// <returns>The desired instance</returns>
public static ExaArray1D<T> AsExaArray<T>(this IEnumerable<T> sequence, Strategy strategy = Strategy.MAX_PERFORMANCE) => ExaArray1D<T>.CreateFrom(sequence, strategy);
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@ -550,6 +551,111 @@ namespace ExaArrayTests
Assert.That(next4.Length, Is.EqualTo(exPerf.Length));
}
[Test]
[Category("normal")]
[Category("cover")]
public void CreateFromSequence001()
{
var list = new List<int>
{
5,
7,
8,
10,
16,
};
var exPerf1 = list.AsExaArray();
Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE));
Assert.That(exPerf1.Length, Is.EqualTo(list.Count));
Assert.That(exPerf1.Items(), Is.EquivalentTo(list));
var exPerf2 = list.AsExaArray(Strategy.MAX_ELEMENTS);
Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS));
Assert.That(exPerf2.Length, Is.EqualTo(list.Count));
Assert.That(exPerf2.Items(), Is.EquivalentTo(list));
}
[Test]
[Category("normal")]
[Category("cover")]
public void CreateFromSequence002()
{
var array = new int[]
{
5,
7,
8,
10,
16,
};
var exPerf1 = array.AsExaArray();
Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE));
Assert.That(exPerf1.Length, Is.EqualTo(array.Length));
Assert.That(exPerf1.Items(), Is.EquivalentTo(array));
var exPerf2 = array.AsExaArray(Strategy.MAX_ELEMENTS);
Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS));
Assert.That(exPerf2.Length, Is.EqualTo(array.Length));
Assert.That(exPerf2.Items(), Is.EquivalentTo(array));
}
[Test]
[Category("normal")]
[Category("cover")]
public void CreateFromSequence003()
{
var list = new List<int>
{
5,
7,
8,
10,
16,
};
var exPerf1 = list.AsEnumerable().AsExaArray();
Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE));
Assert.That(exPerf1.Length, Is.EqualTo(list.Count));
Assert.That(exPerf1.Items(), Is.EquivalentTo(list));
var exPerf2 = list.AsEnumerable().AsExaArray(Strategy.MAX_ELEMENTS);
Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS));
Assert.That(exPerf2.Length, Is.EqualTo(list.Count));
Assert.That(exPerf2.Items(), Is.EquivalentTo(list));
}
[Test]
[Category("normal")]
[Category("cover")]
public void CreateFromSequence004()
{
var list = new List<int>
{
5,
7,
8,
10,
16,
};
var exPerf1 = list.AsEnumerable().AsExaArray((ulong) list.Count);
Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE));
Assert.That(exPerf1.Length, Is.EqualTo(list.Count));
Assert.That(exPerf1.Items(), Is.EquivalentTo(list));
var exPerf2 = list.AsEnumerable().AsExaArray((ulong) list.Count, Strategy.MAX_ELEMENTS);
Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS));
Assert.That(exPerf2.Length, Is.EqualTo(list.Count));
Assert.That(exPerf2.Items(), Is.EquivalentTo(list));
var exPerf3 = list.AsEnumerable().AsExaArray(3);
Assert.That(exPerf3.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE));
Assert.That(exPerf3.Length, Is.EqualTo(3));
Assert.That(exPerf3.Items(), Is.EquivalentTo(new int[] {5,7,8}));
}
[Test]
[Category("intensive")]
public void Adding5Billion01()