Skip to content

Commit daac623

Browse files
committed
Fixed Enumerator bugs.
1 parent 1595890 commit daac623

File tree

5 files changed

+125
-25
lines changed

5 files changed

+125
-25
lines changed

Hexa.NET.Utilities.Tests/UnsafeDictionaryTests.cs

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,73 @@
55
[TestFixture]
66
public class UnsafeDictionaryTests
77
{
8+
[Test]
9+
public void TestEnumerator()
10+
{
11+
UnsafeDictionary<uint, int> dict = default;
12+
dict[1] = 10;
13+
dict[2] = 20;
14+
dict[3] = 30;
15+
16+
IEnumerator<KeyValuePair<uint, int>> enumerator = dict.GetEnumerator();
17+
18+
// Act
19+
var result = new List<KeyValuePair<uint, int>>();
20+
while (enumerator.MoveNext())
21+
{
22+
result.Add(enumerator.Current);
23+
}
24+
25+
// Assert
26+
var expected = new List<KeyValuePair<uint, int>>
27+
{
28+
new KeyValuePair<uint, int>(1, 10),
29+
new KeyValuePair<uint, int>(2, 20),
30+
new KeyValuePair<uint, int>(3, 30)
31+
};
32+
33+
Assert.That(result, Is.EquivalentTo(expected));
34+
35+
dict.Release();
36+
}
37+
38+
[Test]
39+
public void TestKeyValueEnumerator()
40+
{
41+
// Arrange
42+
UnsafeDictionary<uint, int> dict = new UnsafeDictionary<uint, int>();
43+
44+
// Populate the dictionary with data
45+
dict[1] = 10;
46+
dict[2] = 20;
47+
dict[3] = 30;
48+
49+
// Act & Assert for Key Enumerator
50+
IEnumerator<uint> keyEnumerator = dict.Keys.GetEnumerator();
51+
var keyResult = new List<uint>();
52+
while (keyEnumerator.MoveNext())
53+
{
54+
keyResult.Add(keyEnumerator.Current);
55+
}
56+
57+
var expectedKeys = new List<uint> { 1, 2, 3 };
58+
Assert.That(keyResult, Is.EquivalentTo(expectedKeys));
59+
60+
// Act & Assert for Value Enumerator
61+
IEnumerator<int> valueEnumerator = dict.Values.GetEnumerator();
62+
var valueResult = new List<int>();
63+
while (valueEnumerator.MoveNext())
64+
{
65+
valueResult.Add(valueEnumerator.Current);
66+
}
67+
68+
var expectedValues = new List<int> { 10, 20, 30 };
69+
Assert.That(valueResult, Is.EquivalentTo(expectedValues));
70+
71+
// Clean up
72+
dict.Release();
73+
}
74+
875
[Test]
976
public void TestInitialAdd()
1077
{
@@ -64,7 +131,7 @@ public void TestRemoveKey()
64131

65132
dict.Remove(1);
66133

67-
Assert.IsFalse(dict.ContainsKey(1));
134+
Assert.That(dict.ContainsKey(1), Is.False);
68135
Assert.That(dict[2], Is.EqualTo(3));
69136

70137
foreach (var item in dict)
@@ -83,7 +150,7 @@ public void TestRemoveNonExistentKey()
83150
Assert.DoesNotThrow(() => dict.Remove(2));
84151

85152
Assert.That(dict[1], Is.EqualTo(2));
86-
Assert.IsFalse(dict.ContainsKey(2));
153+
Assert.That(dict.ContainsKey(2), Is.False);
87154

88155
foreach (var item in dict)
89156
{
@@ -96,7 +163,7 @@ public void TestRemoveNonExistentKey()
96163
public void TestEmptyDictionary()
97164
{
98165
UnsafeDictionary<uint, int> dict = default;
99-
Assert.IsEmpty(dict);
166+
Assert.That(dict, Is.Empty);
100167

101168
foreach (var item in dict)
102169
{
@@ -120,7 +187,7 @@ public void TestReleaseResources()
120187
dict[2] = 3;
121188

122189
// Since dictionary is reallocated, previous values should not exist
123-
Assert.IsFalse(dict.ContainsKey(1));
190+
Assert.That(dict.ContainsKey(1), Is.False);
124191
Assert.That(dict[2], Is.EqualTo(3));
125192

126193
foreach (var item in dict)
@@ -129,7 +196,7 @@ public void TestReleaseResources()
129196
}
130197

131198
// Verify that the dictionary's capacity and size have been updated correctly
132-
Assert.Greater(dict.Capacity, 0);
199+
Assert.That(dict.Capacity, Is.EqualTo(3));
133200
Assert.That(dict.Size, Is.EqualTo(1));
134201

135202
// Release the dictionary again

Hexa.NET.Utilities.Tests/UnsafeHashSetTests.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,36 @@
55
[TestFixture]
66
public class UnsafeHashSetTests
77
{
8+
[Test]
9+
public void TestEnumerator()
10+
{
11+
UnsafeHashSet<int> dict = default;
12+
dict.Add(10);
13+
dict.Add(20);
14+
dict.Add(30);
15+
16+
IEnumerator<int> enumerator = dict.GetEnumerator();
17+
18+
// Act
19+
var result = new List<int>();
20+
while (enumerator.MoveNext())
21+
{
22+
result.Add(enumerator.Current);
23+
}
24+
25+
// Assert
26+
var expected = new List<int>
27+
{
28+
10,
29+
20,
30+
30
31+
};
32+
33+
Assert.That(result, Is.EquivalentTo(expected));
34+
35+
dict.Release();
36+
}
37+
838
[Test]
939
public void TestAdd()
1040
{
@@ -205,7 +235,7 @@ public void Contains_ShouldReturnTrueIfItemExists()
205235
bool contains = list.Contains(42);
206236

207237
// Assert
208-
Assert.IsTrue(contains);
238+
Assert.That(contains, Is.True);
209239

210240
list.Release();
211241
}
@@ -239,7 +269,7 @@ public void Remove_ShouldRemoveItemIfExists()
239269
bool removed = list.Remove(42);
240270

241271
// Assert
242-
Assert.IsTrue(removed);
272+
Assert.That(removed, Is.True);
243273
Assert.That(list.Count, Is.EqualTo(1));
244274
Assert.That(list[0], Is.EqualTo(24));
245275

Hexa.NET.Utilities/Hexa.NET.Utilities.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<PropertyGroup>
2020
<PackageId>Hexa.NET.Utilities</PackageId>
2121
<AssemblyVersion>1.0.0</AssemblyVersion>
22-
<PackageVersion>2.1.13</PackageVersion>
22+
<PackageVersion>2.1.14</PackageVersion>
2323
<Authors>Juna</Authors>
2424
<AssemblyName>Hexa.NET.Utilities</AssemblyName>
2525
<PackageProjectUrl>https://github.com/HexaEngine/Hexa.NET.Utilities</PackageProjectUrl>

Hexa.NET.Utilities/UnsafeDictionary.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ public unsafe struct UnsafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
1313

1414
private const float loadFactor = 0.75f;
1515

16-
internal enum EntryFlags : byte
16+
public enum EntryFlags : byte
1717
{
1818
Empty = 0,
1919
Tombstone = 1,
2020
Filled = 2
2121
}
2222

23-
internal struct Entry
23+
public struct Entry
2424
{
2525
public uint HashCode;
2626
public TKey Key;
@@ -118,6 +118,14 @@ public UnsafeDictionary(IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs, d
118118
TrimExcess();
119119
}
120120

121+
public UnsafeDictionary(Entry* buckets, int capacity, int size, delegate*<TKey, TKey, bool>* comparer)
122+
{
123+
this.buckets = buckets;
124+
this.capacity = capacity;
125+
this.size = size;
126+
this.comparer = comparer;
127+
}
128+
121129
public void Release()
122130
{
123131
if (buckets != null)
@@ -470,7 +478,7 @@ public readonly void Dispose()
470478

471479
public bool MoveNext()
472480
{
473-
if (itemIndex >= dictionary.size - 1)
481+
if (itemIndex >= dictionary.size)
474482
{
475483
return false;
476484
}
@@ -544,7 +552,7 @@ readonly IEnumerator IEnumerable.GetEnumerator()
544552

545553
public bool MoveNext()
546554
{
547-
if (itemIndex >= dictionary.size - 1)
555+
if (itemIndex >= dictionary.size)
548556
{
549557
return false;
550558
}
@@ -618,7 +626,7 @@ readonly IEnumerator IEnumerable.GetEnumerator()
618626

619627
public bool MoveNext()
620628
{
621-
if (itemIndex >= dictionary.size - 1)
629+
if (itemIndex >= dictionary.size)
622630
{
623631
return false;
624632
}

Hexa.NET.Utilities/UnsafeHashSet.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,12 @@ public void CopyTo(T[] array, int arrayIndex, int count)
369369

370370
public readonly IEnumerator<T> GetEnumerator()
371371
{
372-
return new Enumerator();
372+
return new Enumerator(this);
373373
}
374374

375375
readonly IEnumerator IEnumerable.GetEnumerator()
376376
{
377-
return new Enumerator();
377+
return new Enumerator(this);
378378
}
379379

380380
public void UnionWith(IEnumerable<T> other)
@@ -758,24 +758,19 @@ private struct Enumerator : IEnumerable<T>, IEnumerator<T>
758758
private UnsafeHashSet<T> hashSet;
759759
private int index;
760760
private int itemIndex;
761-
private Entry* current;
761+
private T current;
762762

763763
public Enumerator(UnsafeHashSet<T> hashSet)
764764
{
765765
this.hashSet = hashSet;
766766
index = 0;
767-
current = null;
768767
}
769768

770769
public T Current
771770
{
772771
get
773772
{
774-
if (current == null)
775-
{
776-
throw new InvalidOperationException("The enumerator is positioned before the first element or after the last element.");
777-
}
778-
return current->Value;
773+
return current;
779774
}
780775
}
781776

@@ -810,20 +805,20 @@ public bool MoveNext()
810805
continue;
811806
}
812807

813-
current = entry;
808+
current = entry->Value;
814809
index = i + 1;
815810
itemIndex++;
816811
return true;
817812
}
818-
current = null;
813+
current = default;
819814
return false;
820815
}
821816

822817
public void Reset()
823818
{
824819
index = 0;
825820
itemIndex = 0;
826-
current = null;
821+
current = default;
827822
}
828823
}
829824

0 commit comments

Comments
 (0)