Skip to content

Commit ce87f55

Browse files
author
LoneWandererProductions
committed
add some needed stuff
1 parent b4f115e commit ce87f55

7 files changed

Lines changed: 379 additions & 31 deletions

File tree

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
using System;
2+
using System.Diagnostics;
3+
using ExtendedSystemObjects;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
6+
namespace CommonExtendedObjectsTests
7+
{
8+
/// <summary>
9+
/// Test my Key Value class
10+
/// </summary>
11+
[TestClass]
12+
public class SortedKvStoreTests
13+
{
14+
/// <summary>
15+
/// The item count
16+
/// </summary>
17+
private const int ItemCount = 100_000;
18+
19+
/// <summary>
20+
/// Adds the and try get works.
21+
/// </summary>
22+
[TestMethod]
23+
public void AddAndTryGetWorks()
24+
{
25+
var store = new SortedKvStore();
26+
store.Add(10, 100);
27+
store.Add(5, 50);
28+
store.Add(15, 150);
29+
30+
Assert.IsTrue(store.TryGet(10, out var val10));
31+
Assert.AreEqual(100, val10);
32+
33+
Assert.IsTrue(store.TryGet(5, out var val5));
34+
Assert.AreEqual(50, val5);
35+
36+
Assert.IsTrue(store.TryGet(15, out var val15));
37+
Assert.AreEqual(150, val15);
38+
39+
Assert.IsFalse(store.TryGet(99, out _));
40+
}
41+
42+
/// <summary>
43+
/// Tries the remove removes existing.
44+
/// </summary>
45+
[TestMethod]
46+
public void TryRemoveRemovesExisting()
47+
{
48+
var store = new SortedKvStore();
49+
store.Add(1, 10);
50+
store.Add(2, 20);
51+
52+
Assert.IsTrue(store.TryRemove(1, out var idx));
53+
Assert.IsFalse(store.TryGet(1, out _));
54+
Assert.IsTrue(idx >= 0);
55+
}
56+
57+
/// <summary>
58+
/// Removes the many works.
59+
/// </summary>
60+
[TestMethod]
61+
public void RemoveManyWorks()
62+
{
63+
var store = new SortedKvStore();
64+
for (var i = 0; i < 10; i++)
65+
store.Add(i, i * 10);
66+
67+
store.RemoveMany(new int[] { 2, 4, 6 });
68+
69+
Assert.IsFalse(store.TryGet(2, out _));
70+
Assert.IsFalse(store.TryGet(4, out _));
71+
Assert.IsFalse(store.TryGet(6, out _));
72+
73+
Assert.IsTrue(store.TryGet(3, out _));
74+
}
75+
76+
/// <summary>
77+
/// Compacts the removes unoccupied.
78+
/// </summary>
79+
[TestMethod]
80+
public void CompactRemovesUnoccupied()
81+
{
82+
var store = new SortedKvStore();
83+
for (var i = 0; i < 10; i++)
84+
store.Add(i, i * 10);
85+
86+
store.Remove(1);
87+
store.Remove(3);
88+
store.Compact();
89+
90+
Assert.AreEqual(8, store.Count);
91+
Assert.IsFalse(store.TryGet(1, out _));
92+
}
93+
94+
/// <summary>
95+
/// Indexers the works.
96+
/// </summary>
97+
[TestMethod]
98+
public void IndexerWorks()
99+
{
100+
var store = new SortedKvStore();
101+
store[42] = 123;
102+
Assert.AreEqual(123, store[42]);
103+
104+
store[42] = 456;
105+
Assert.AreEqual(456, store[42]);
106+
}
107+
108+
/// <summary>
109+
/// Adds the and try get should return expected values.
110+
/// </summary>
111+
[TestMethod]
112+
public void AddAndTryGetShouldReturnExpectedValues()
113+
{
114+
var store = new SortedKvStore();
115+
116+
for (int i = 0; i < 1000; i++)
117+
store.Add(i, i * 10);
118+
119+
for (int i = 0; i < 1000; i++)
120+
{
121+
Assert.IsTrue(store.TryGet(i, out var value));
122+
Assert.AreEqual(i * 10, value);
123+
}
124+
125+
Assert.IsFalse(store.TryGet(1001, out _));
126+
}
127+
128+
/// <summary>
129+
/// Performances the add and try get.
130+
/// </summary>
131+
[TestMethod]
132+
public void PerformanceAddAndTryGet()
133+
{
134+
var store = new SortedKvStore(ItemCount);
135+
136+
var sw = Stopwatch.StartNew();
137+
138+
for (int i = 0; i < ItemCount; i++)
139+
store.Add(i, i * 2);
140+
141+
sw.Stop();
142+
Trace.WriteLine($"Add {ItemCount} items: {sw.ElapsedMilliseconds} ms");
143+
144+
sw.Restart();
145+
146+
int hits = 0;
147+
for (int i = 0; i < ItemCount; i++)
148+
{
149+
if (store.TryGet(i, out var value) && value == i * 2)
150+
hits++;
151+
}
152+
153+
sw.Stop();
154+
Trace.WriteLine($"TryGet {ItemCount} items: {sw.ElapsedMilliseconds} ms");
155+
156+
Assert.AreEqual(ItemCount, hits);
157+
}
158+
159+
/// <summary>
160+
/// Performances the remove compact.
161+
/// </summary>
162+
[TestMethod]
163+
public void PerformanceRemoveCompact()
164+
{
165+
var store = new SortedKvStore(ItemCount);
166+
167+
for (int i = 0; i < ItemCount; i++)
168+
store.Add(i, i);
169+
170+
// Remove half of them
171+
for (int i = 0; i < ItemCount; i += 2)
172+
store.Remove(i);
173+
174+
var sw = Stopwatch.StartNew();
175+
store.Compact();
176+
sw.Stop();
177+
178+
Trace.WriteLine($"Compact after removing half: {sw.ElapsedMilliseconds} ms");
179+
Assert.AreEqual(ItemCount / 2, store.Count);
180+
}
181+
}
182+
}

CommonExtendedObjectsTests/Utilities.cs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
* PROGRAMER: Peter Geinitz (Wayfarer)
77
*/
88

9+
using System;
910
using System.Collections.Generic;
11+
using System.Diagnostics;
1012
using ExtendedSystemObjects;
1113
using Microsoft.VisualStudio.TestTools.UnitTesting;
1214

@@ -264,5 +266,92 @@ public void FindSequencesShouldReturnCorrectResultWhenListHasMixedSequences()
264266
Assert.AreEqual((8, 9, 6), result[4]);
265267
Assert.AreEqual((10, 10, 7), result[5]);
266268
}
269+
270+
/// <summary>
271+
/// Binaries the search performance and correctness.
272+
/// </summary>
273+
[TestMethod]
274+
public void BinarySearchPerformanceAndCorrectness()
275+
{
276+
const int N = 1_000_000;
277+
int[] sortedKeys = new int[N];
278+
for (int i = 0; i < N; i++)
279+
sortedKeys[i] = i * 2; // even numbers sorted
280+
281+
var keysSpan = sortedKeys.AsSpan();
282+
283+
// Warm-up to avoid JIT bias
284+
for (int i = 0; i < 10_000; i++)
285+
{
286+
Utility.BinarySearch(keysSpan, N, i * 2);
287+
}
288+
289+
var sw = Stopwatch.StartNew();
290+
291+
int foundCount = 0;
292+
for (int i = 0; i < N; i++)
293+
{
294+
int val = i * 2;
295+
int idx = Utility.BinarySearch(keysSpan, N, val);
296+
297+
Assert.IsTrue(idx >= 0, $"Key {val} should be found.");
298+
Assert.AreEqual(val, sortedKeys[idx]);
299+
300+
foundCount++;
301+
}
302+
303+
sw.Stop();
304+
305+
Trace.WriteLine($"BinarySearch found {foundCount} keys out of {N} in {sw.ElapsedMilliseconds} ms");
306+
307+
// Optional: Assert performance threshold (example: must finish under 200ms)
308+
Assert.IsTrue(sw.ElapsedMilliseconds < 1000, $"BinarySearch took too long: {sw.ElapsedMilliseconds} ms");
309+
}
310+
311+
[TestMethod]
312+
public void CompareCustomVsArrayBinarySearch_Performance()
313+
{
314+
const int N = 1_000_000;
315+
int[] sortedKeys = new int[N];
316+
for (int i = 0; i < N; i++)
317+
sortedKeys[i] = i * 2; // even numbers sorted
318+
319+
var keysSpan = sortedKeys.AsSpan();
320+
321+
// Warm-up both methods
322+
for (int i = 0; i < 10_000; i++)
323+
{
324+
Utility.BinarySearch(keysSpan, N, i * 2);
325+
Array.BinarySearch(sortedKeys, i * 2);
326+
}
327+
328+
// Custom BinarySearch benchmark
329+
var swCustom = Stopwatch.StartNew();
330+
for (int i = 0; i < N; i++)
331+
{
332+
int val = i * 2;
333+
int idx = Utility.BinarySearch(keysSpan, N, val);
334+
Assert.IsTrue(idx >= 0);
335+
}
336+
swCustom.Stop();
337+
338+
// Array.BinarySearch benchmark
339+
var swArray = Stopwatch.StartNew();
340+
for (int i = 0; i < N; i++)
341+
{
342+
int val = i * 2;
343+
int idx = Array.BinarySearch(sortedKeys, val);
344+
Assert.IsTrue(idx >= 0);
345+
}
346+
swArray.Stop();
347+
348+
Trace.WriteLine($"Custom BinarySearch: {swCustom.ElapsedMilliseconds} ms");
349+
Trace.WriteLine($"Array.BinarySearch: {swArray.ElapsedMilliseconds} ms");
350+
351+
// Optionally assert your method is within some factor of Array.BinarySearch
352+
Assert.IsTrue(swCustom.ElapsedMilliseconds < swArray.ElapsedMilliseconds * 2,
353+
$"Custom BinarySearch is too slow: {swCustom.ElapsedMilliseconds} ms vs {swArray.ElapsedMilliseconds} ms");
354+
}
355+
267356
}
268357
}
0 Bytes
Loading
0 Bytes
Loading

ExtendedSystemObjects/IntArray.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ namespace ExtendedSystemObjects
2222
/// </summary>
2323
public sealed unsafe class IntArray : IUnmanagedArray<int>
2424
{
25+
/// <summary>
26+
/// The buffer
27+
/// </summary>
2528
private IntPtr _buffer;
2629

30+
/// <summary>
31+
/// The pointer
32+
/// </summary>
2733
private int* _ptr;
2834

2935
/// <summary>
@@ -286,6 +292,9 @@ public void EnsureCapacity(int minCapacity)
286292
Resize(newCapacity);
287293
}
288294

295+
/// <summary>
296+
/// Finalizes an instance of the <see cref="IntArray"/> class.
297+
/// </summary>
289298
~IntArray()
290299
{
291300
Dispose();

0 commit comments

Comments
 (0)