1+ namespace Hexa . NET . Utilities . Tests
2+ {
3+ using System . Diagnostics ;
4+
5+ [ TestFixture ]
6+ public class UnsafeDictionaryTests
7+ {
8+ [ Test ]
9+ public void TestInitialAdd ( )
10+ {
11+ UnsafeDictionary < uint , int > dict = default ;
12+
13+ dict . Clear ( ) ;
14+ dict [ 1 ] = 2 ;
15+ Assert . That ( dict [ 1 ] , Is . EqualTo ( 2 ) ) ;
16+
17+ foreach ( var item in dict )
18+ {
19+ Console . WriteLine ( item . Key + " " + item . Value ) ;
20+ }
21+
22+ dict . Release ( ) ;
23+ }
24+
25+ [ Test ]
26+ public void TestAddNewKey ( )
27+ {
28+ UnsafeDictionary < uint , int > dict = default ;
29+ dict [ 1 ] = 2 ;
30+ dict [ 2 ] = 3 ;
31+
32+ Assert . That ( dict [ 1 ] , Is . EqualTo ( 2 ) ) ;
33+ Assert . That ( dict [ 2 ] , Is . EqualTo ( 3 ) ) ;
34+
35+ foreach ( var item in dict )
36+ {
37+ Console . WriteLine ( item . Key + " " + item . Value ) ;
38+ }
39+ dict . Release ( ) ;
40+ }
41+
42+ [ Test ]
43+ public void TestUpdateExistingKey ( )
44+ {
45+ UnsafeDictionary < uint , int > dict = default ;
46+ dict [ 1 ] = 2 ;
47+ dict [ 1 ] = 4 ;
48+
49+ Assert . That ( dict [ 1 ] , Is . EqualTo ( 4 ) ) ;
50+
51+ foreach ( var item in dict )
52+ {
53+ Console . WriteLine ( item . Key + " " + item . Value ) ;
54+ }
55+ dict . Release ( ) ;
56+ }
57+
58+ [ Test ]
59+ public void TestRemoveKey ( )
60+ {
61+ UnsafeDictionary < uint , int > dict = default ;
62+ dict [ 1 ] = 2 ;
63+ dict [ 2 ] = 3 ;
64+
65+ dict . Remove ( 1 ) ;
66+
67+ Assert . IsFalse ( dict . ContainsKey ( 1 ) ) ;
68+ Assert . That ( dict [ 2 ] , Is . EqualTo ( 3 ) ) ;
69+
70+ foreach ( var item in dict )
71+ {
72+ Console . WriteLine ( item . Key + " " + item . Value ) ;
73+ }
74+ dict . Release ( ) ;
75+ }
76+
77+ [ Test ]
78+ public void TestRemoveNonExistentKey ( )
79+ {
80+ UnsafeDictionary < uint , int > dict = default ;
81+ dict [ 1 ] = 2 ;
82+
83+ Assert . DoesNotThrow ( ( ) => dict . Remove ( 2 ) ) ;
84+
85+ Assert . That ( dict [ 1 ] , Is . EqualTo ( 2 ) ) ;
86+ Assert . IsFalse ( dict . ContainsKey ( 2 ) ) ;
87+
88+ foreach ( var item in dict )
89+ {
90+ Console . WriteLine ( item . Key + " " + item . Value ) ;
91+ }
92+ dict . Release ( ) ;
93+ }
94+
95+ [ Test ]
96+ public void TestEmptyDictionary ( )
97+ {
98+ UnsafeDictionary < uint , int > dict = default ;
99+ Assert . IsEmpty ( dict ) ;
100+
101+ foreach ( var item in dict )
102+ {
103+ Console . WriteLine ( item . Key + " " + item . Value ) ;
104+ }
105+ dict . Release ( ) ;
106+ }
107+
108+ [ Test ]
109+ public void TestReleaseResources ( )
110+ {
111+ UnsafeDictionary < uint , int > dict = default ;
112+ dict [ 1 ] = 2 ;
113+ dict . Release ( ) ;
114+
115+ // Verify that capacity and size are reset to zero
116+ Assert . That ( dict . Capacity , Is . EqualTo ( 0 ) ) ;
117+ Assert . That ( dict . Size , Is . EqualTo ( 0 ) ) ;
118+
119+ // Access the dictionary after release, expecting it to be reallocated
120+ dict [ 2 ] = 3 ;
121+
122+ // Since dictionary is reallocated, previous values should not exist
123+ Assert . IsFalse ( dict . ContainsKey ( 1 ) ) ;
124+ Assert . That ( dict [ 2 ] , Is . EqualTo ( 3 ) ) ;
125+
126+ foreach ( var item in dict )
127+ {
128+ Console . WriteLine ( item . Key + " " + item . Value ) ;
129+ }
130+
131+ // Verify that the dictionary's capacity and size have been updated correctly
132+ Assert . Greater ( dict . Capacity , 0 ) ;
133+ Assert . That ( dict . Size , Is . EqualTo ( 1 ) ) ;
134+
135+ // Release the dictionary again
136+ dict . Release ( ) ;
137+
138+ // Verify that capacity and size are reset to zero again
139+ Assert . That ( dict . Capacity , Is . EqualTo ( 0 ) ) ;
140+ Assert . That ( dict . Size , Is . EqualTo ( 0 ) ) ;
141+ }
142+
143+ [ Test ]
144+ public void StressTest ( )
145+ {
146+ const int iterations = 100000 ;
147+ UnsafeDictionary < uint , int > dict = default ;
148+ Random random = new Random ( ) ;
149+ Stopwatch stopwatch = new Stopwatch ( ) ;
150+
151+ const int range = int . MaxValue / iterations ;
152+
153+ List < ( uint , int ) > keyValues = new ( ) ;
154+
155+ StressInsert ( iterations , random , range , keyValues , ref dict ) ; // warmup
156+
157+ keyValues . Clear ( ) ;
158+ dict . Clear ( ) ;
159+
160+ stopwatch . Start ( ) ;
161+ StressInsert ( iterations , random , range , keyValues , ref dict ) ;
162+ stopwatch . Stop ( ) ;
163+
164+ Console . WriteLine ( $ "Insert stress test completed in { stopwatch . Elapsed . TotalMilliseconds } ms") ;
165+
166+ StressLookup ( keyValues , ref dict ) ; // warmup
167+
168+ // Verify that the dictionary contains the expected values
169+ stopwatch . Restart ( ) ;
170+ StressLookup ( keyValues , ref dict ) ;
171+ stopwatch . Stop ( ) ;
172+
173+ Console . WriteLine ( $ "Lookup stress test completed in { stopwatch . Elapsed . TotalMilliseconds } ms") ;
174+
175+ var clone = dict . Clone ( ) ;
176+ StressRemove ( keyValues , ref clone ) ;
177+
178+ Assert . That ( clone . Size , Is . EqualTo ( 0 ) ) ;
179+ clone . Release ( ) ;
180+
181+ stopwatch . Restart ( ) ;
182+ StressRemove ( keyValues , ref dict ) ;
183+ stopwatch . Stop ( ) ;
184+
185+ Console . WriteLine ( $ "Delete stress test completed in { stopwatch . Elapsed . TotalMilliseconds } ms") ;
186+
187+ Assert . That ( dict . Size , Is . EqualTo ( 0 ) ) ;
188+
189+ dict . Release ( ) ;
190+
191+ Assert . Pass ( ) ;
192+ }
193+
194+ private void StressRemove ( List < ( uint , int ) > keyValues , ref UnsafeDictionary < uint , int > dict )
195+ {
196+ for ( int i = 0 ; i < keyValues . Count ; i ++ )
197+ {
198+ var ( key , _) = keyValues [ i ] ;
199+ dict . Remove ( key ) ;
200+ }
201+ int siu = dict . Size ;
202+ }
203+
204+ private void StressLookup ( List < ( uint , int ) > keyValues , ref UnsafeDictionary < uint , int > dict )
205+ {
206+ for ( int i = 0 ; i < keyValues . Count ; i ++ )
207+ {
208+ var ( key , value ) = keyValues [ i ] ;
209+ if ( dict [ key ] != value )
210+ {
211+ Assert . Fail ( ) ;
212+ }
213+ }
214+ }
215+
216+ private void StressInsert ( int iterations , Random random , int range , List < ( uint , int ) > keyValues , ref UnsafeDictionary < uint , int > dict )
217+ {
218+ for ( int i = 0 ; i < iterations ; i ++ )
219+ {
220+ uint key = ( uint ) random . Next ( range * i , range * ( i + 1 ) ) ;
221+
222+ int value = random . Next ( ) ;
223+ dict [ key ] = value ;
224+ keyValues . Add ( ( key , value ) ) ;
225+ }
226+ }
227+ }
228+ }
0 commit comments