99
1010namespace BitFaster . Caching . UnitTests . Lru
1111{
12- public class ClassicLruTests
13- {
14- private const int capacity = 3 ;
12+ public class ClassicLruTests
13+ {
14+ private const int capacity = 3 ;
1515
16- private ClassicLru < int , string > lru = new ClassicLru < int , string > ( 1 , capacity , EqualityComparer < int > . Default ) ;
17- ValueFactory valueFactory = new ValueFactory ( ) ;
16+ private ClassicLru < int , string > lru = new ClassicLru < int , string > ( 1 , capacity , EqualityComparer < int > . Default ) ;
17+ ValueFactory valueFactory = new ValueFactory ( ) ;
1818
1919 [ Fact ]
2020 public void WhenConcurrencyIsLessThan1CtorThrows ( )
@@ -49,137 +49,137 @@ public void ConstructAddAndRetrieveWithDefaultCtorReturnsValue()
4949 }
5050
5151 [ Fact ]
52- public void WhenItemIsAddedCountIsCorrect ( )
53- {
54- lru . Count . Should ( ) . Be ( 0 ) ;
55- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
56- lru . Count . Should ( ) . Be ( 1 ) ;
57- }
58-
59- [ Fact ]
60- public void WhenItemExistsTryGetReturnsValueAndTrue ( )
61- {
62- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
63- bool result = lru . TryGet ( 1 , out var value ) ;
64-
65- result . Should ( ) . Be ( true ) ;
66- value . Should ( ) . Be ( "1" ) ;
67- }
68-
69- [ Fact ]
70- public void WhenItemDoesNotExistTryGetReturnsNullAndFalse ( )
71- {
72- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
73- bool result = lru . TryGet ( 2 , out var value ) ;
74-
75- result . Should ( ) . Be ( false ) ;
76- value . Should ( ) . BeNull ( ) ;
77- }
78-
79- [ Fact ]
80- public void WhenItemIsAddedThenRetrievedHitRatioIsHalf ( )
81- {
82- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
83- bool result = lru . TryGet ( 1 , out var value ) ;
84-
85- lru . HitRatio . Should ( ) . Be ( 0.5 ) ;
86- }
87-
88- [ Fact ]
89- public void WhenKeyIsRequestedItIsCreatedAndCached ( )
90- {
91- var result1 = lru . GetOrAdd ( 1 , valueFactory . Create ) ;
92- var result2 = lru . GetOrAdd ( 1 , valueFactory . Create ) ;
93-
94- valueFactory . timesCalled . Should ( ) . Be ( 1 ) ;
95- result1 . Should ( ) . Be ( result2 ) ;
96- }
97-
98- [ Fact ]
99- public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync ( )
100- {
101- var result1 = await lru . GetOrAddAsync ( 1 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
102- var result2 = await lru . GetOrAddAsync ( 1 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
103-
104- valueFactory . timesCalled . Should ( ) . Be ( 1 ) ;
105- result1 . Should ( ) . Be ( result2 ) ;
106- }
107-
108- [ Fact ]
109- public void WhenDifferentKeysAreRequestedValueIsCreatedForEach ( )
110- {
111- var result1 = lru . GetOrAdd ( 1 , valueFactory . Create ) ;
112- var result2 = lru . GetOrAdd ( 2 , valueFactory . Create ) ;
113-
114- valueFactory . timesCalled . Should ( ) . Be ( 2 ) ;
115-
116- result1 . Should ( ) . Be ( "1" ) ;
117- result2 . Should ( ) . Be ( "2" ) ;
118- }
119-
120- [ Fact ]
121- public async Task WhenDifferentKeysAreRequesteValueIsCreatedForEachAsync ( )
122- {
123- var result1 = await lru . GetOrAddAsync ( 1 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
124- var result2 = await lru . GetOrAddAsync ( 2 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
125-
126- valueFactory . timesCalled . Should ( ) . Be ( 2 ) ;
127-
128- result1 . Should ( ) . Be ( "1" ) ;
129- result2 . Should ( ) . Be ( "2" ) ;
130- }
131-
132- [ Fact ]
133- public void WhenMoreKeysRequestedThanCapacityCountDoesNotIncrease ( )
134- {
135- for ( int i = 0 ; i < capacity + 1 ; i ++ )
136- {
137- lru . GetOrAdd ( i , valueFactory . Create ) ;
138- }
139-
140- lru . Count . Should ( ) . Be ( capacity ) ;
141- valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
142- }
143-
144- [ Fact ]
145- public async Task WhenMoreKeysRequestedThanCapacityCountDoesNotIncreaseAsync ( )
146- {
147- for ( int i = 0 ; i < capacity + 1 ; i ++ )
148- {
149- await lru . GetOrAddAsync ( i , valueFactory . CreateAsync ) ;
150- }
151-
152- lru . Count . Should ( ) . Be ( capacity ) ;
153- valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
154- }
155-
156- [ Fact ]
157- public void WhenMoreKeysRequestedThanCapacityOldestItemIsEvicted ( )
158- {
159- // request 10 items, LRU is now full
160- for ( int i = 0 ; i < capacity ; i ++ )
161- {
162- lru . GetOrAdd ( i , valueFactory . Create ) ;
163- }
164-
165- valueFactory . timesCalled . Should ( ) . Be ( capacity ) ;
166-
167- // request 0, now item 1 is to be evicted
168- lru . GetOrAdd ( 0 , valueFactory . Create ) ;
169- valueFactory . timesCalled . Should ( ) . Be ( capacity ) ;
170-
171- // request next item after last, verify value factory was called
172- lru . GetOrAdd ( capacity , valueFactory . Create ) ;
173- valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
174-
175- // request 0, verify value factory not called
176- lru . GetOrAdd ( 0 , valueFactory . Create ) ;
177- valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
178-
179- // request 1, verify value factory is called (and it was therefore not cached)
180- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
181- valueFactory . timesCalled . Should ( ) . Be ( capacity + 2 ) ;
182- }
52+ public void WhenItemIsAddedCountIsCorrect ( )
53+ {
54+ lru . Count . Should ( ) . Be ( 0 ) ;
55+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
56+ lru . Count . Should ( ) . Be ( 1 ) ;
57+ }
58+
59+ [ Fact ]
60+ public void WhenItemExistsTryGetReturnsValueAndTrue ( )
61+ {
62+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
63+ bool result = lru . TryGet ( 1 , out var value ) ;
64+
65+ result . Should ( ) . Be ( true ) ;
66+ value . Should ( ) . Be ( "1" ) ;
67+ }
68+
69+ [ Fact ]
70+ public void WhenItemDoesNotExistTryGetReturnsNullAndFalse ( )
71+ {
72+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
73+ bool result = lru . TryGet ( 2 , out var value ) ;
74+
75+ result . Should ( ) . Be ( false ) ;
76+ value . Should ( ) . BeNull ( ) ;
77+ }
78+
79+ [ Fact ]
80+ public void WhenItemIsAddedThenRetrievedHitRatioIsHalf ( )
81+ {
82+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
83+ bool result = lru . TryGet ( 1 , out var value ) ;
84+
85+ lru . HitRatio . Should ( ) . Be ( 0.5 ) ;
86+ }
87+
88+ [ Fact ]
89+ public void WhenKeyIsRequestedItIsCreatedAndCached ( )
90+ {
91+ var result1 = lru . GetOrAdd ( 1 , valueFactory . Create ) ;
92+ var result2 = lru . GetOrAdd ( 1 , valueFactory . Create ) ;
93+
94+ valueFactory . timesCalled . Should ( ) . Be ( 1 ) ;
95+ result1 . Should ( ) . Be ( result2 ) ;
96+ }
97+
98+ [ Fact ]
99+ public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync ( )
100+ {
101+ var result1 = await lru . GetOrAddAsync ( 1 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
102+ var result2 = await lru . GetOrAddAsync ( 1 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
103+
104+ valueFactory . timesCalled . Should ( ) . Be ( 1 ) ;
105+ result1 . Should ( ) . Be ( result2 ) ;
106+ }
107+
108+ [ Fact ]
109+ public void WhenDifferentKeysAreRequestedValueIsCreatedForEach ( )
110+ {
111+ var result1 = lru . GetOrAdd ( 1 , valueFactory . Create ) ;
112+ var result2 = lru . GetOrAdd ( 2 , valueFactory . Create ) ;
113+
114+ valueFactory . timesCalled . Should ( ) . Be ( 2 ) ;
115+
116+ result1 . Should ( ) . Be ( "1" ) ;
117+ result2 . Should ( ) . Be ( "2" ) ;
118+ }
119+
120+ [ Fact ]
121+ public async Task WhenDifferentKeysAreRequesteValueIsCreatedForEachAsync ( )
122+ {
123+ var result1 = await lru . GetOrAddAsync ( 1 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
124+ var result2 = await lru . GetOrAddAsync ( 2 , valueFactory . CreateAsync ) . ConfigureAwait ( false ) ;
125+
126+ valueFactory . timesCalled . Should ( ) . Be ( 2 ) ;
127+
128+ result1 . Should ( ) . Be ( "1" ) ;
129+ result2 . Should ( ) . Be ( "2" ) ;
130+ }
131+
132+ [ Fact ]
133+ public void WhenMoreKeysRequestedThanCapacityCountDoesNotIncrease ( )
134+ {
135+ for ( int i = 0 ; i < capacity + 1 ; i ++ )
136+ {
137+ lru . GetOrAdd ( i , valueFactory . Create ) ;
138+ }
139+
140+ lru . Count . Should ( ) . Be ( capacity ) ;
141+ valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
142+ }
143+
144+ [ Fact ]
145+ public async Task WhenMoreKeysRequestedThanCapacityCountDoesNotIncreaseAsync ( )
146+ {
147+ for ( int i = 0 ; i < capacity + 1 ; i ++ )
148+ {
149+ await lru . GetOrAddAsync ( i , valueFactory . CreateAsync ) ;
150+ }
151+
152+ lru . Count . Should ( ) . Be ( capacity ) ;
153+ valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
154+ }
155+
156+ [ Fact ]
157+ public void WhenMoreKeysRequestedThanCapacityOldestItemIsEvicted ( )
158+ {
159+ // request 10 items, LRU is now full
160+ for ( int i = 0 ; i < capacity ; i ++ )
161+ {
162+ lru . GetOrAdd ( i , valueFactory . Create ) ;
163+ }
164+
165+ valueFactory . timesCalled . Should ( ) . Be ( capacity ) ;
166+
167+ // request 0, now item 1 is to be evicted
168+ lru . GetOrAdd ( 0 , valueFactory . Create ) ;
169+ valueFactory . timesCalled . Should ( ) . Be ( capacity ) ;
170+
171+ // request next item after last, verify value factory was called
172+ lru . GetOrAdd ( capacity , valueFactory . Create ) ;
173+ valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
174+
175+ // request 0, verify value factory not called
176+ lru . GetOrAdd ( 0 , valueFactory . Create ) ;
177+ valueFactory . timesCalled . Should ( ) . Be ( capacity + 1 ) ;
178+
179+ // request 1, verify value factory is called (and it was therefore not cached)
180+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
181+ valueFactory . timesCalled . Should ( ) . Be ( capacity + 2 ) ;
182+ }
183183
184184 [ Fact ]
185185 public void WhenValueExpiresItIsDisposed ( )
@@ -212,31 +212,31 @@ public async Task WhenValueExpiresAsyncItIsDisposed()
212212 }
213213
214214 [ Fact ]
215- public void WhenKeyDoesNotExistTryGetReturnsFalse ( )
216- {
217- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
215+ public void WhenKeyDoesNotExistTryGetReturnsFalse ( )
216+ {
217+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
218218
219- lru . TryGet ( 2 , out var result ) . Should ( ) . Be ( false ) ;
220- }
219+ lru . TryGet ( 2 , out var result ) . Should ( ) . Be ( false ) ;
220+ }
221221
222- [ Fact ]
223- public void WhenKeyExistsTryGetReturnsTrueAndOutValueIsCorrect ( )
224- {
225- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
222+ [ Fact ]
223+ public void WhenKeyExistsTryGetReturnsTrueAndOutValueIsCorrect ( )
224+ {
225+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
226226
227- bool result = lru . TryGet ( 1 , out var value ) ;
228- result . Should ( ) . Be ( true ) ;
229- value . Should ( ) . Be ( "1" ) ;
230- }
227+ bool result = lru . TryGet ( 1 , out var value ) ;
228+ result . Should ( ) . Be ( true ) ;
229+ value . Should ( ) . Be ( "1" ) ;
230+ }
231231
232- [ Fact ]
233- public void WhenKeyExistsTryRemoveRemovesItemAndReturnsTrue ( )
232+ [ Fact ]
233+ public void WhenKeyExistsTryRemoveRemovesItemAndReturnsTrue ( )
234234 {
235- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
235+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
236236
237- lru . TryRemove ( 1 ) . Should ( ) . BeTrue ( ) ;
238- lru . TryGet ( 1 , out var value ) . Should ( ) . BeFalse ( ) ;
239- }
237+ lru . TryRemove ( 1 ) . Should ( ) . BeTrue ( ) ;
238+ lru . TryGet ( 1 , out var value ) . Should ( ) . BeFalse ( ) ;
239+ }
240240
241241 [ Fact ]
242242 public void WhenItemIsRemovedItIsDisposed ( )
@@ -251,11 +251,11 @@ public void WhenItemIsRemovedItIsDisposed()
251251 }
252252
253253 [ Fact ]
254- public void WhenKeyDoesNotExistTryRemoveReturnsFalse ( )
255- {
256- lru . GetOrAdd ( 1 , valueFactory . Create ) ;
254+ public void WhenKeyDoesNotExistTryRemoveReturnsFalse ( )
255+ {
256+ lru . GetOrAdd ( 1 , valueFactory . Create ) ;
257257
258- lru . TryRemove ( 2 ) . Should ( ) . BeFalse ( ) ;
259- }
260- }
258+ lru . TryRemove ( 2 ) . Should ( ) . BeFalse ( ) ;
259+ }
260+ }
261261}
0 commit comments