Skip to content

Commit 7579a83

Browse files
author
LoneWandererProductions
committed
Cleanup and comment all the new stuff
Add headers and improve Dispose Patterns.
1 parent ce87f55 commit 7579a83

5 files changed

Lines changed: 204 additions & 51 deletions

File tree

CommonExtendedObjectsTests/SortedKvStoreTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
using System;
1+
/*
2+
* COPYRIGHT: See COPYING in the top level directory
3+
* PROJECT: CommonExtendedObjectsTests
4+
* FILE: CommonExtendedObjectsTests/SortedKvStoreTests.cs
5+
* PURPOSE: A generic test for my SortedKvStore
6+
* PROGRAMMER: Peter Geinitz (Wayfarer)
7+
*/
8+
29
using System.Diagnostics;
310
using ExtendedSystemObjects;
411
using Microsoft.VisualStudio.TestTools.UnitTesting;

ExtendedSystemObjects/IUnmanagedArray.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,33 @@ namespace ExtendedSystemObjects
1818
/// <seealso cref="T:System.IDisposable" />
1919
public interface IUnmanagedArray<T> : IDisposable
2020
{
21+
/// <summary>
22+
/// Gets the length.
23+
/// </summary>
24+
/// <value>
25+
/// The length.
26+
/// </value>
2127
int Length { get; }
28+
29+
/// <summary>
30+
/// Gets or sets the <see cref="T"/> at the specified index.
31+
/// </summary>
32+
/// <value>
33+
/// The <see cref="T"/>.
34+
/// </value>
35+
/// <param name="index">The index.</param>
36+
/// <returns></returns>
2237
T this[int index] { get; set; }
38+
39+
/// <summary>
40+
/// Resizes the specified new size.
41+
/// </summary>
42+
/// <param name="newSize">The new size.</param>
2343
void Resize(int newSize);
44+
45+
/// <summary>
46+
/// Clears this instance.
47+
/// </summary>
2448
void Clear();
2549
}
2650
}

ExtendedSystemObjects/IntArray.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ public IntArray(int size)
6262
/// </summary>
6363
public int Length { get; private set; }
6464

65+
/// <summary>
66+
/// Gets or sets the <see cref="T" /> at the specified index.
67+
/// </summary>
68+
/// <value>
69+
/// The <see cref="T" />.
70+
/// </value>
71+
/// <param name="i">The i.</param>
72+
/// <returns></returns>
73+
/// <exception cref="System.IndexOutOfRangeException"></exception>
6574
public int this[int i]
6675
{
6776
[MethodImpl(MethodImplOptions.AggressiveInlining)]

ExtendedSystemObjects/IntList.cs

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public sealed unsafe class IntList : IDisposable
4040
/// </summary>
4141
private int* _ptr;
4242

43+
/// <summary>
44+
/// The disposed
45+
/// </summary>
46+
private bool _disposed;
47+
4348
/// <summary>
4449
/// Initializes a new instance of the <see cref="IntList" /> class with the specified initial capacity.
4550
/// </summary>
@@ -86,23 +91,6 @@ public int this[int i]
8691
}
8792
}
8893

89-
/// <inheritdoc />
90-
/// <summary>
91-
/// Frees unmanaged resources used by the <see cref="T:ExtendedSystemObjects.IntList" />.
92-
/// After calling this method, the instance should not be used.
93-
/// </summary>
94-
public void Dispose()
95-
{
96-
if (_buffer != IntPtr.Zero)
97-
{
98-
Marshal.FreeHGlobal(_buffer);
99-
_buffer = IntPtr.Zero;
100-
}
101-
102-
Count = 0;
103-
_capacity = 0;
104-
}
105-
10694
/// <summary>
10795
/// Pushes the specified value.
10896
/// </summary>
@@ -152,29 +140,6 @@ public int Peek()
152140
return _ptr[Count - 1];
153141
}
154142

155-
/// <summary>
156-
/// Ensures the capacity of the internal buffer is at least the specified minimum size.
157-
/// Resizes the buffer if necessary by doubling its capacity or setting it to the minimum required size.
158-
/// </summary>
159-
/// <param name="min">The minimum capacity required.</param>
160-
private void EnsureCapacity(int min)
161-
{
162-
if (min <= _capacity)
163-
{
164-
return;
165-
}
166-
167-
var newCapacity = _capacity * 2;
168-
if (newCapacity < min)
169-
{
170-
newCapacity = min;
171-
}
172-
173-
_buffer = Marshal.ReAllocHGlobal(_buffer, (IntPtr)(newCapacity * sizeof(int)));
174-
_ptr = (int*)_buffer;
175-
_capacity = newCapacity;
176-
}
177-
178143
/// <summary>
179144
/// Removes all elements from the list. The capacity remains unchanged.
180145
/// </summary>
@@ -193,12 +158,74 @@ public Span<int> AsSpan()
193158
return new Span<int>((void*)_buffer, Count);
194159
}
195160

161+
/// <inheritdoc />
162+
/// <summary>
163+
/// Frees unmanaged resources used by the <see cref="T:ExtendedSystemObjects.IntList" />.
164+
/// After calling this method, the instance should not be used.
165+
/// </summary>
166+
public void Dispose()
167+
{
168+
Dispose(true);
169+
GC.SuppressFinalize(this);
170+
}
171+
196172
/// <summary>
197173
/// Finalizes an instance of the <see cref="IntList" /> class, releasing unmanaged resources.
198174
/// </summary>
199175
~IntList()
200176
{
201-
Dispose();
177+
Dispose(false);
178+
}
179+
180+
/// <summary>
181+
/// Releases unmanaged and - optionally - managed resources.
182+
/// </summary>
183+
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
184+
private void Dispose(bool disposing)
185+
{
186+
if (_disposed)
187+
return;
188+
189+
// Free unmanaged resources
190+
if (_buffer != IntPtr.Zero)
191+
{
192+
Marshal.FreeHGlobal(_buffer);
193+
_buffer = IntPtr.Zero;
194+
_ptr = null;
195+
_capacity = 0;
196+
Count = 0;
197+
}
198+
199+
// If you had managed disposable members and disposing is true,
200+
// dispose them here. None exist for now.
201+
202+
_disposed = true; // Always set to true after dispose
203+
204+
// Suppress unused parameter warning
205+
_ = disposing;
206+
}
207+
208+
/// <summary>
209+
/// Ensures the capacity of the internal buffer is at least the specified minimum size.
210+
/// Resizes the buffer if necessary by doubling its capacity or setting it to the minimum required size.
211+
/// </summary>
212+
/// <param name="min">The minimum capacity required.</param>
213+
private void EnsureCapacity(int min)
214+
{
215+
if (min <= _capacity)
216+
{
217+
return;
218+
}
219+
220+
var newCapacity = _capacity * 2;
221+
if (newCapacity < min)
222+
{
223+
newCapacity = min;
224+
}
225+
226+
_buffer = Marshal.ReAllocHGlobal(_buffer, (IntPtr)(newCapacity * sizeof(int)));
227+
_ptr = (int*)_buffer;
228+
_capacity = newCapacity;
202229
}
203230
}
204231
}

ExtendedSystemObjects/UnmanagedArray.cs

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
// ReSharper disable MemberCanBeInternal
1+
/*
2+
* COPYRIGHT: See COPYING in the top level directory
3+
* PROJECT: ExtendedSystemObjects
4+
* FILE: ExtendedSystemObjects/IUnmanagedArray.cs
5+
* PURPOSE: A high-performance array implementation with reduced features. Limited to unmanaged Types, very similiar to IntArray.
6+
* PROGRAMMER: Peter Geinitz (Wayfarer)
7+
*/
8+
9+
// ReSharper disable MemberCanBeInternal
210

311
using System;
412
using System.Runtime.InteropServices;
@@ -13,22 +21,48 @@ namespace ExtendedSystemObjects
1321
/// <seealso cref="T:System.IDisposable" />
1422
public sealed unsafe class UnmanagedArray<T> : IUnmanagedArray<T> where T : unmanaged
1523
{
24+
/// <summary>
25+
/// The buffer
26+
/// </summary>
1627
private IntPtr _buffer;
28+
29+
/// <summary>
30+
/// The pointer
31+
/// </summary>
1732
private T* _ptr;
1833

34+
/// <summary>
35+
/// The capacity
36+
/// </summary>
37+
private int _capacity;
38+
39+
40+
/// <summary>
41+
/// The disposed
42+
/// </summary>
43+
private bool _disposed;
44+
45+
/// <summary>
46+
/// Gets the length.
47+
/// </summary>
48+
/// <value>
49+
/// The length.
50+
/// </value>
51+
public int Length { get; private set; }
52+
1953
/// <summary>
2054
/// Initializes a new instance of the <see cref="UnmanagedArray{T}" /> class.
2155
/// </summary>
2256
/// <param name="size">The size.</param>
2357
public UnmanagedArray(int size)
2458
{
59+
_capacity = size;
2560
Length = size;
2661
_buffer = Marshal.AllocHGlobal(size * sizeof(T));
2762
_ptr = (T*)_buffer;
63+
Clear();
2864
}
2965

30-
public int Length { get; private set; }
31-
3266
/// <summary>
3367
/// Gets or sets the <see cref="T" /> at the specified index.
3468
/// </summary>
@@ -62,7 +96,6 @@ public T this[int index]
6296
}
6397
}
6498

65-
6699
/// <summary>
67100
/// Resizes the internal array to the specified new size.
68101
/// Contents will be preserved up to the minimum of old and new size.
@@ -72,7 +105,9 @@ public void Resize(int newSize)
72105
{
73106
_buffer = Marshal.ReAllocHGlobal(_buffer, (IntPtr)(newSize * sizeof(T)));
74107
_ptr = (T*)_buffer;
75-
Length = newSize;
108+
_capacity = newSize;
109+
if (Length > newSize)
110+
Length = newSize;
76111
}
77112

78113
/// <summary>
@@ -84,20 +119,71 @@ public void Clear()
84119
AsSpan().Clear();
85120
}
86121

122+
/// <summary>
123+
/// Ensures the capacity.
124+
/// </summary>
125+
/// <param name="minCapacity">The minimum capacity.</param>
126+
public void EnsureCapacity(int minCapacity)
127+
{
128+
if (minCapacity <= _capacity)
129+
return;
130+
131+
int newCapacity = _capacity == 0 ? 4 : _capacity;
132+
while (newCapacity < minCapacity)
133+
newCapacity *= 2;
134+
135+
Resize(newCapacity);
136+
}
137+
138+
/// <summary>
139+
/// Ases the span.
140+
/// </summary>
141+
/// <returns>Return all Values as Span</returns>
142+
public Span<T> AsSpan()
143+
{
144+
return new(_ptr, Length);
145+
}
146+
147+
/// <summary>
148+
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
149+
/// </summary>
87150
public void Dispose()
88151
{
152+
Dispose(true);
153+
GC.SuppressFinalize(this);
154+
}
155+
156+
/// <summary>
157+
/// Finalizes an instance of the <see cref="UnmanagedArray{T}"/> class.
158+
/// </summary>
159+
~UnmanagedArray()
160+
{
161+
Dispose(false);
162+
}
163+
164+
/// <summary>
165+
/// Releases unmanaged and - optionally - managed resources.
166+
/// </summary>
167+
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
168+
private void Dispose(bool disposing)
169+
{
170+
if (_disposed)
171+
return;
172+
173+
// Only unmanaged cleanup here.
89174
if (_buffer != IntPtr.Zero)
90175
{
91176
Marshal.FreeHGlobal(_buffer);
92177
_buffer = IntPtr.Zero;
93178
_ptr = null;
94179
Length = 0;
180+
_capacity = 0;
95181
}
96-
}
97182

98-
public Span<T> AsSpan()
99-
{
100-
return new(_ptr, Length);
183+
_disposed = true;
184+
185+
// 'disposing' parameter unused but required by pattern.
186+
_ = disposing;
101187
}
102188
}
103189
}

0 commit comments

Comments
 (0)