aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Utils/src/Memory/VnTable.cs42
-rw-r--r--lib/Utils/tests/Memory/VnTableTests.cs71
2 files changed, 53 insertions, 60 deletions
diff --git a/lib/Utils/src/Memory/VnTable.cs b/lib/Utils/src/Memory/VnTable.cs
index ce105f9..43e2c02 100644
--- a/lib/Utils/src/Memory/VnTable.cs
+++ b/lib/Utils/src/Memory/VnTable.cs
@@ -40,7 +40,7 @@ namespace VNLib.Utils.Memory
/// <summary>
/// A value that indicates if the table does not contain any values
/// </summary>
- public bool Empty { get; }
+ public bool Empty => Rows == 0 && Cols == 0;
/// <summary>
/// The number of rows in the table
@@ -74,16 +74,12 @@ namespace VNLib.Utils.Memory
public VnTable(IUnmangedHeap heap, uint rows, uint cols)
{
//empty table
- if (rows == 0 && cols == 0)
- {
- Empty = true;
- }
- else
+ if (rows != 0 || cols != 0)
{
ulong tableSize = checked((ulong)rows * (ulong)cols);
ArgumentNullException.ThrowIfNull(heap);
- ArgumentOutOfRangeException.ThrowIfGreaterThan(tableSize, nuint.MinValue);
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(tableSize, nuint.MaxValue);
ArgumentOutOfRangeException.ThrowIfGreaterThan(MemoryUtil.ByteCount<T>((nuint)tableSize), nuint.MaxValue, nameof(rows));
Rows = rows;
@@ -107,6 +103,8 @@ namespace VNLib.Utils.Memory
{
ValidateArgs(row, col);
+ Debug.Assert(BufferHandle != null, nameof(BufferHandle) + " != null");
+
//Calculate the address in memory for the item
//Calc row offset
ulong address = checked(row * Cols);
@@ -135,6 +133,8 @@ namespace VNLib.Utils.Memory
{
ValidateArgs(row, col);
+ Debug.Assert(BufferHandle != null, nameof(BufferHandle) + " != null");
+
//Calculate the address in memory for the item
//Calc row offset
@@ -153,17 +153,8 @@ namespace VNLib.Utils.Memory
private void ValidateArgs(uint row, uint col)
{
Check();
-
- if (Empty)
- {
- throw new InvalidOperationException("Table is empty");
- }
-
- //If not empty expect a non-null handle
- Debug.Assert(BufferHandle != null, nameof(BufferHandle) + " != null");
-
- ArgumentOutOfRangeException.ThrowIfGreaterThan(row, Rows);
- ArgumentOutOfRangeException.ThrowIfGreaterThan(col, Cols);
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(row, Rows);
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(col, Cols);
}
/// <summary>
@@ -191,16 +182,14 @@ namespace VNLib.Utils.Memory
get
{
Check();
- return !Empty ? *(BufferHandle!.GetOffset(index)) : throw new InvalidOperationException("Cannot index an empty table");
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, (ulong)Rows * (ulong)Cols);
+ return *(BufferHandle!.GetOffset(index));
}
set
{
Check();
- if (Empty)
- {
- throw new InvalidOperationException("Cannot index an empty table");
- }
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, (ulong)Rows * (ulong)Cols);
*(BufferHandle!.GetOffset(index)) = value;
}
}
@@ -208,11 +197,8 @@ namespace VNLib.Utils.Memory
///<inheritdoc/>
protected override void Free()
{
- if (!Empty)
- {
- //Dispose the buffer
- BufferHandle!.Dispose();
- }
+ //Dispose the buffer
+ BufferHandle?.Dispose();
}
}
} \ No newline at end of file
diff --git a/lib/Utils/tests/Memory/VnTableTests.cs b/lib/Utils/tests/Memory/VnTableTests.cs
index cb8ea91..832ef26 100644
--- a/lib/Utils/tests/Memory/VnTableTests.cs
+++ b/lib/Utils/tests/Memory/VnTableTests.cs
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2023 Vaughn Nugent
+* Copyright (c) 2024 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.UtilsTests
@@ -41,6 +41,12 @@ namespace VNLib.Utils.Memory.Tests
//Test 0 rows/cols
Assert.IsTrue(0 == empty.Rows);
Assert.IsTrue(0 == empty.Cols);
+
+ //Test that empty table throws on access
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => _ = empty[0, 0]);
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => _ = empty.Get(0, 0));
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => empty.Set(0, 0, 10));
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => empty[0, 0] = 10);
}
using (VnTable<int> table = new(40000, 10000))
@@ -52,6 +58,16 @@ namespace VNLib.Utils.Memory.Tests
Assert.IsTrue(10000 == table.Cols);
}
+ //Test params
+ Assert.ThrowsException<ArgumentNullException>(() => _ = new VnTable<int>(null!, 1, 1));
+
+ /*
+ * Try-catch is used because underlying heaps
+ * may cause different OOM exceptions to be raised
+ * but still have a base class of OutOfMemoryException.
+ * So catch covers all OOM exceptions.
+ */
+
try
{
using VnTable<int> table = new(uint.MaxValue, 20);
@@ -67,20 +83,6 @@ namespace VNLib.Utils.Memory.Tests
}
[TestMethod()]
- public void VnTableTest1()
- {
- //No throw if empty
- using VnTable<int> table = new(null!,0, 0);
-
- //Throw if table is not empty
- Assert.ThrowsException<ArgumentNullException>(() =>
- {
- using VnTable<int> table = new(null!,1, 1);
- });
-
- }
-
- [TestMethod()]
public void GetSetTest()
{
static void TestIndexAt(VnTable<int> table, uint row, uint col, int value)
@@ -119,28 +121,33 @@ namespace VNLib.Utils.Memory.Tests
Assert.IsTrue(value == table[row, col]);
Assert.IsTrue(value == table.Get(row, col));
}
-
- using (VnTable<int> table = new(11, 11))
- {
- //Test index at 10,10
- TestIndexAt(table, 10, 10, 11);
- //Test same index with different value using the .set() method
- TestSetAt(table, 10, 10, 25);
- //Test direct access
- TestSetDirectAccess(table, 10, 10, 50);
+ using VnTable<int> table = new(11, 11);
+
+ //Test index at 10,10
+ TestIndexAt(table, 10, 10, 11);
+ //Test same index with different value using the .set() method
+ TestSetAt(table, 10, 10, 25);
+
+ //Test direct access
+ TestSetDirectAccess(table, 10, 10, 50);
- TestGetDirectAccess(table, 10, 10, 37);
+ TestGetDirectAccess(table, 10, 10, 37);
- //Test index at 0,0
- TestIndexAt(table, 0, 0, 13);
- TestSetAt(table, 0, 0, 85);
+ //Test index at 0,0
+ TestIndexAt(table, 0, 0, 13);
+ TestSetAt(table, 0, 0, 85);
- //Test at 0,0
- TestSetDirectAccess(table, 0, 0, 100);
- TestGetDirectAccess(table, 0, 0, 86);
- }
+ //Test at 0,0
+ TestSetDirectAccess(table, 0, 0, 100);
+ TestGetDirectAccess(table, 0, 0, 86);
+
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => _ = table[11, 11]);
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => _ = table.Get(11, 11));
+
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => table.Set(11, 11, 10));
+ Assert.ThrowsException<ArgumentOutOfRangeException>(() => table[11, 11] = 10);
}
[TestMethod()]