Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/TMG-Framework/Construct/ConstructTimePeriodFromTimes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ namespace TMG.Construct
public sealed class ConstructTimePeriodFromTimes : BaseFunction<TimePeriod>
{
[Parameter(Index = 0, Name = "Start Time", Required = true, Description = "The time to use as the starting point of the time period (Inclusive).")]
public IFunction<Time> StartTime;
public IFunction<Time> StartTime = null!;

[Parameter(Index = 1, Name = "End Time", Required = true, Description = "The time to use as the ending point of the time period (Exclusive).")]
public IFunction<Time> EndTime;
public IFunction<Time> EndTime = null!;

public override TimePeriod Invoke()
{
Expand Down
11 changes: 8 additions & 3 deletions src/TMG-Framework/Data/Categories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ You should have received a copy of the GNU General Public License
using System.Linq;
using static TMG.Utilities.ExceptionHelper;
using System.Collections;
using System.Diagnostics.CodeAnalysis;

namespace TMG
{
Expand All @@ -46,7 +47,9 @@ public sealed class Categories : IEnumerable<int>
/// <param name="elements"></param>
/// <param name="error"></param>
/// <returns></returns>
public static Categories CreateCategories(List<int> elements, ref string error)
public static bool CreateCategories(List<int> elements,
[NotNullWhen(true)] out Categories? categories,
[NotNullWhen(false)] ref string? error)
{
elements = elements?.ToList() ?? throw new ArgumentNullException(nameof(elements));
elements.Sort();
Expand All @@ -55,10 +58,12 @@ public static Categories CreateCategories(List<int> elements, ref string error)
if(elements[i - 1] == elements[i])
{
error = $"Found a duplicate category {elements[i]}!";
return null;
categories = null;
return false;
}
}
return new Categories(elements);
categories = new Categories(elements);
return true;
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/TMG-Framework/Data/CategoryIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public bool Equals(CategoryIndex other)
return _Value == other._Value;
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj is CategoryIndex other)
{
Expand Down
16 changes: 11 additions & 5 deletions src/TMG-Framework/Data/CategoryMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using static TMG.Utilities.ExceptionHelper;
Expand Down Expand Up @@ -46,7 +47,9 @@ public sealed class CategoryMap
private readonly List<(int originFlatIndex, int destinationFlatIndex)> _baseToDestination;

public static bool CreateCategoryMap(Categories baseCategories, Categories destinationCategories,
List<(int originFlatIndex, int destinationFlatIndex)> baseToDestination, out CategoryMap map, ref string error)
List<(int originFlatIndex, int destinationFlatIndex)> baseToDestination,
[NotNullWhen(true) ] out CategoryMap? map,
[NotNullWhen(false)] ref string? error)
{
if (baseCategories == null)
{
Expand Down Expand Up @@ -95,7 +98,7 @@ private CategoryMap(Categories baseCategories, Categories destinationCategories,
_baseToDestination = baseToDestination;
}

private static bool FailWith(ref string error, string message)
private static bool FailWith([NotNullWhen(false)] ref string? error, string message)
{
error = message;
return false;
Expand All @@ -106,7 +109,8 @@ private static bool FailWith(ref string error, string message)
/// </summary>
/// <param name="baseToDestination"></param>
private static bool ValidateMapping(Categories baseCategories, Categories destinationCategories,
List<(int originFlatIndex, int destinationFlatIndex)> baseToDestination, ref string error)
List<(int originFlatIndex, int destinationFlatIndex)> baseToDestination,
[NotNullWhen(false)] ref string? error)
{
if (baseCategories == null)
{
Expand Down Expand Up @@ -138,10 +142,12 @@ private static bool ValidateMapping(Categories baseCategories, Categories destin
/// <param name="ret"></param>
/// <param name="error"></param>
/// <returns></returns>
public bool AggregateToDestination(Vector baseVector, out Vector ret, ref string error)
public bool AggregateToDestination(Vector baseVector,
[NotNullWhen(true)] out Vector? ret,
[NotNullWhen(false)] ref string? error)
{
ret = null;
if (baseVector == null)
if (baseVector is null)
{
return FailWith(ref error, "baseVector was null!");
}
Expand Down
90 changes: 76 additions & 14 deletions src/TMG-Framework/Data/Matrix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ You should have received a copy of the GNU General Public License
along with TMG-Framework for XTMF2. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using static TMG.Utilities.ExceptionHelper;

namespace TMG
{
/// <summary>
/// A 2D representation with categories for rows and columns
/// </summary>
public sealed class Matrix
public sealed class Matrix : IDisposable
{
/// <summary>
/// The categories for the rows.
Expand All @@ -42,56 +45,102 @@ public sealed class Matrix
/// <summary>
/// The backend storage for the matrix
/// </summary>
public float[] Data { get; }
public Span<float> Data => _backingMemory is null ? ThrowAlreadyDisposed() : _backingMemory.Value.Span;

[DoesNotReturn]
private Span<float> ThrowAlreadyDisposed()
{
throw new ObjectDisposedException(nameof(Matrix));
}

private Memory<float>? _backingMemory;

/// <summary>
/// Used as a quick lookup for the number of columns per row.
/// </summary>
private readonly int _rowSpan;

private IMemoryOwner<float>? _allocator;

/// <summary>
/// Create a new matrix with the given row and column categories.
/// </summary>
/// <param name="rowCategories">The categories for the rows.</param>
/// <param name="columnCategories">The categories for the columns.</param>
public Matrix(Categories rowCategories, Categories columnCategories) : this(rowCategories, columnCategories, null) { }

/// <summary>
/// Get the number of columns in this matrix.
/// </summary>
public int NumberOfColumns => ColumnCategories.Count;

/// <summary>
/// Get the number of rows in this matrix.
/// </summary>
public int NumberOfRows => RowCategories.Count;

/// <summary>
/// Create a new matrix with the given row and column categories.
/// </summary>
/// <param name="rowCategories">The categories for the rows.</param>
/// <param name="columnCategories">The categories for the columns.</param>
public Matrix(Categories rowCategories, Categories columnCategories)
/// <param name="allocator">The memory pool to use for the matrix data.</param>
public Matrix(Categories rowCategories, Categories columnCategories, MemoryPool<float>? allocator)
{
RowCategories = rowCategories ?? throw new ArgumentNullException(nameof(rowCategories));
ColumnCategories = columnCategories ?? throw new ArgumentNullException(nameof(columnCategories));
RowCategories = rowCategories ?? ThrowParameterNull<Categories>(nameof(rowCategories));
ColumnCategories = columnCategories ?? ThrowParameterNull<Categories>(nameof(columnCategories));
_rowSpan = ColumnCategories.Count;
Data = new float[RowCategories.Count * ColumnCategories.Count];
var size = RowCategories.Count * ColumnCategories.Count;
_backingMemory = allocator is null ?
new float[size].AsMemory()
: (_allocator = allocator.Rent(size)).Memory[..size];
}

/// <summary>
/// Create a new matrix using the dimensions from the given vector.
/// </summary>
/// <param name="vector">The vector to get the dimensions from.</param>
public Matrix(Vector vector)
public Matrix(Vector vector) : this(vector, null) { }

public Matrix(Vector vector, MemoryPool<float>? allocator)
{
if (vector == null)
if (vector is null)
{
ThrowParameterNull(nameof(vector));
}
ColumnCategories = RowCategories = vector.Categories;
_rowSpan = ColumnCategories.Count;
Data = new float[RowCategories.Count * ColumnCategories.Count];
var size = RowCategories.Count * ColumnCategories.Count;
_backingMemory = allocator is null ?
new float[size].AsMemory() :
(_allocator = allocator.Rent(size)).Memory[..size];
}

/// <summary>
/// Create a new matrix with the dimensions from the provided
/// matrix.
/// </summary>
/// <param name="matrix">The matrix to copy the dimensions from.</param>
public Matrix(Matrix matrix)
public Matrix(Matrix matrix) : this(matrix, null) {}

/// <summary>
/// Create a new matrix with the dimensions from the provided
/// </summary>
/// <param name="matrix">The matrix to copy the dimensions from.</param>
/// <param name="allocator">The memory pool to use for the matrix data.</param>
public Matrix(Matrix matrix, MemoryPool<float>? allocator)
{
if (matrix == null)
if (matrix is null)
{
ThrowParameterNull(nameof(matrix));
}
RowCategories = matrix.RowCategories;
ColumnCategories = matrix.ColumnCategories;
_rowSpan = matrix._rowSpan;
Data = new float[RowCategories.Count * ColumnCategories.Count];
var size = RowCategories.Count * ColumnCategories.Count;
_backingMemory = allocator is null ?
new float[size].AsMemory() :
(_allocator = allocator.Rent(size)).Memory[..size];
}

/// <summary>
Expand Down Expand Up @@ -153,7 +202,7 @@ public Span<float> GetRow(int flatRowIndex)
ThrowOutOfRangeException(nameof(flatRowIndex));
}
flatRowIndex = GetFlatRowIndex(flatRowIndex);
return new Span<float>(Data, flatRowIndex, _rowSpan);
return Data.Slice(flatRowIndex, _rowSpan);
}

[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
Expand All @@ -179,7 +228,7 @@ public ref float GetFromSparseIndexes(int rowIndex, int columnIndex)
public Matrix Clone()
{
var ret = new Matrix(this);
Array.Copy(Data, ret.Data, Data.Length);
Data.CopyTo(ret.Data);
return ret;
}

Expand All @@ -194,5 +243,18 @@ private void InvalidRow(int rowIndex)
{
throw new ArgumentOutOfRangeException($"Invalid row index {rowIndex}!");
}

~Matrix()
{
Dispose();
}

public void Dispose()
{
_backingMemory = null;
Thread.MemoryBarrier();
_allocator?.Dispose();
_allocator = null;
}
}
}
2 changes: 1 addition & 1 deletion src/TMG-Framework/Data/Range.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Range(int start, int stop)
return (first.Start == other.Start) & (first.Stop == other.Stop);
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj is Range other)
{
Expand Down
11 changes: 7 additions & 4 deletions src/TMG-Framework/Data/RangeSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using static System.Char;
using static System.String;
Expand Down Expand Up @@ -72,13 +73,15 @@ public Range this[int index]
set => SetRanges[index] = value;
}

public static bool TryParse(string rangeString, out RangeSet output)
public static bool TryParse(string rangeString, [NotNullWhen(true)] out RangeSet? output)
{
string error = null;
string? error = null;
return TryParse(ref error, rangeString, out output);
}

public static bool TryParse(ref string error, string rangeString, out RangeSet output)
public static bool TryParse([NotNullWhen(false)] ref string? error,
string rangeString,
[NotNullWhen(true)] out RangeSet? output)
{
var tempRange = new List<Range>();
var length = rangeString.Length;
Expand Down Expand Up @@ -232,7 +235,7 @@ public void CopyTo(Range[] array, int arrayIndex)
}
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
var other = obj as RangeSet;
if (other?.Count != Count) return false;
Expand Down
15 changes: 9 additions & 6 deletions src/TMG-Framework/Data/RangeSetSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using static TMG.Utilities.ExceptionHelper;

Expand All @@ -42,13 +43,15 @@ public RangeSet this[int index]
set => RangeSets[index] = value;
}

public static bool TryParse(string rangeString, out RangeSetSet output)
public static bool TryParse(string rangeString, [NotNullWhen(true)] out RangeSetSet? output)
{
string error = null;
string? error = null;
return TryParse(ref error, rangeString, out output);
}

public static bool TryParse(ref string error, string rangeString, out RangeSetSet output)
public static bool TryParse([NotNullWhen(false)] ref string? error,
string rangeString,
[NotNullWhen(true)] out RangeSetSet? output)
{
if (rangeString == null)
{
Expand All @@ -68,7 +71,7 @@ public static bool TryParse(ref string error, string rangeString, out RangeSetSe
{
if (rangeString[endPos] == '}')
{
if (!RangeSet.TryParse(ref error, rangeString.Substring(startPos + 1, endPos - startPos - 1), out RangeSet temp))
if (!RangeSet.TryParse(ref error, rangeString.Substring(startPos + 1, endPos - startPos - 1), out RangeSet? temp))
{
return false;
}
Expand All @@ -88,7 +91,7 @@ public static bool TryParse(ref string error, string rangeString, out RangeSetSe
// in case it is a set of 1 element
if (rangeSets.Count == 0)
{
if (RangeSet.TryParse(ref error, rangeString, out RangeSet temp))
if (!RangeSet.TryParse(ref error, rangeString, out RangeSet? temp))
{
return false;
}
Expand Down Expand Up @@ -128,7 +131,7 @@ public void CopyTo(RangeSet[] array, int arrayIndex)
}
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
var other = obj as RangeSetSet;
if (Count != other?.Count) return false;
Expand Down
Loading
Loading