@@ -55,6 +55,68 @@ public void WhenItemsAddedExceedsCapacityItemsAreDiscarded()
5555 cache . Count . Should ( ) . Be ( 20 ) ;
5656 }
5757
58+ // protected 15
59+ // probation 4
60+ // window 1
61+ [ Fact ]
62+ public void WhenNewItemsAreAddedTheyArePromotedBasedOnFrequency ( )
63+ {
64+ for ( int i = 0 ; i < 20 ; i ++ )
65+ {
66+ cache . GetOrAdd ( i , k => k ) ;
67+ }
68+
69+ // W [19] Protected [] Probation [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
70+ cache . PendingMaintenance ( ) ;
71+ LogLru ( ) ;
72+
73+ for ( int i = 0 ; i < 15 ; i ++ )
74+ {
75+ cache . GetOrAdd ( i , k => k ) ;
76+ }
77+
78+ // W [19] Protected [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14] Probation [15,16,17,18]
79+ cache . PendingMaintenance ( ) ;
80+ LogLru ( ) ;
81+
82+ for ( int k = 0 ; k < 2 ; k ++ )
83+ {
84+ for ( int j = 0 ; j < 6 ; j ++ )
85+ {
86+ for ( int i = 0 ; i < 15 ; i ++ )
87+ {
88+ cache . GetOrAdd ( j + 20 , k => k ) ;
89+ }
90+ cache . PendingMaintenance ( ) ;
91+ LogLru ( ) ;
92+ }
93+ }
94+
95+ // Values promoted to probation then protected:
96+ // W[21] Protected[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Probation[16, 17, 18, 20]
97+ // W[22] Protected[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Probation[17, 18, 20, 21]
98+ // W[23] Protected[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Probation[18, 20, 21, 22]
99+ // W[24] Protected[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Probation[20, 21, 22, 23]
100+ // W[25] Protected[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Probation[20, 21, 22, 23]
101+ // W[25] Protected[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20] Probation[21, 22, 23, 0]
102+ // W[25] Protected[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 21] Probation[22, 23, 0, 1]
103+ // W[25] Protected[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 21, 22] Probation[23, 0, 1, 2]
104+ // W[25] Protected[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 21, 22, 23] Probation[0, 1, 2, 3]
105+ // W[24] Protected[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 21, 22, 23] Probation[1, 2, 3, 25]
106+ // W[24] Protected[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 21, 22, 23, 25] Probation[1, 2, 3, 4]
107+
108+ cache . Count . Should ( ) . Be ( 20 ) ;
109+
110+ // W [24] Protected [5,6,7,8,9,10,11,12,13,14,20,21,22,23,25] Probation []
111+ cache . Trim ( 4 ) ;
112+ cache . PendingMaintenance ( ) ;
113+ LogLru ( ) ;
114+
115+ cache . TryGet ( 1 , out var value1 ) . Should ( ) . BeFalse ( ) ;
116+ cache . TryGet ( 2 , out var value2 ) . Should ( ) . BeFalse ( ) ;
117+ cache . Count . Should ( ) . Be ( 16 ) ;
118+ }
119+
58120 [ Fact ]
59121 public void ReadPromotesProbation ( )
60122 {
@@ -68,7 +130,7 @@ public void ReadPromotesProbation()
68130 cache . GetOrAdd ( i , k => k ) ;
69131 }
70132
71- // W [24] Protected [1,2,0,3,4,5,6,7,8,9,10,11,12,13,14] Probation [ 15,16,17,18]
133+ // W [24] Protected [] Probation [ 1,2,0,3,4,5,6,7,8,9,10,11,12,13,14, 15,16,17,18]
72134 cache . PendingMaintenance ( ) ;
73135 LogLru ( ) ;
74136
@@ -80,13 +142,13 @@ public void ReadPromotesProbation()
80142 cache . GetOrAdd ( i , k => k ) ;
81143 }
82144
83- // W [49] Protected [2,0,3,4,5,6,7,8,9,10,11,12,13,14,16] Probation [1,25,26,27 ]
145+ // W [49] Protected [16] Probation [1, 2,0,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18 ]
84146 cache . PendingMaintenance ( ) ;
85147 LogLru ( ) ;
86148
87- cache . Trim ( 5 ) ;
149+ cache . Trim ( 18 ) ;
88150
89- // W [49] Protected [0,3,4,5,6,7,8,9,10,11,12,13,14, 16] Probation []
151+ // W [49] Protected [16] Probation []
90152 cache . PendingMaintenance ( ) ;
91153 LogLru ( ) ;
92154
@@ -107,7 +169,7 @@ public void WritePromotesProbation()
107169 cache . GetOrAdd ( i , k => k ) ;
108170 }
109171
110- // W [24] Protected [1,2,0,3,4,5,6,7,8,9,10,11,12,13,14] Probation [ 15,16,17,18]
172+ // W [24] Protected [] Probation [ 1,2,0,3,4,5,6,7,8,9,10,11,12,13,14, 15,16,17,18]
111173 cache . PendingMaintenance ( ) ;
112174 LogLru ( ) ;
113175
@@ -119,39 +181,85 @@ public void WritePromotesProbation()
119181 cache . GetOrAdd ( i , k => k ) ;
120182 }
121183
122- // W [49] Protected [2,0,3,4,5,6,7,8,9,10,11,12,13,14,16] Probation [1,25,26,27 ]
184+ // [49] Protected [16] Probation [1, 2,0,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18 ]
123185 cache . PendingMaintenance ( ) ;
124186 LogLru ( ) ;
125187
126- cache . Trim ( 5 ) ;
188+ cache . Trim ( 18 ) ;
127189
128- // W [49] Protected [0,3,4,5,6,7,8,9,10,11,12,13,14, 16] Probation []
190+ // W [49] Protected [16] Probation []
129191 cache . PendingMaintenance ( ) ;
130192 LogLru ( ) ;
131193
132194 cache . TryGet ( 16 , out var value1 ) . Should ( ) . BeTrue ( ) ;
133195 }
134196
135197 [ Fact ]
136- public void WriteUpdateProtectedLruOrder ( )
198+ public void ReadUpdatesProtectedLruOrder ( )
137199 {
138- // W [19], Protected [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], Probation [ 15, 16, 17, 18]
200+ // W [19] Protected [] Probation [0,1,2,3,4,5,6,7,8,9, 10,11,12,13,14, 15,16,17,18]
139201 for ( int i = 0 ; i < 20 ; i ++ )
140202 {
141203 cache . GetOrAdd ( i , k => k ) ;
142204 }
143205
144206 cache . PendingMaintenance ( ) ;
207+ LogLru ( ) ;
208+
209+ cache . GetOrAdd ( 7 , k => k ) ;
210+ cache . GetOrAdd ( 8 , k => k ) ;
211+ cache . GetOrAdd ( 9 , k => k ) ;
145212
146- // W [19], Protected [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 7], Probation [15, 16, 17, 18]
213+ // W [19] Protected [7,8,9] Probation [0,1,2,3,4,5,6,10,11,12,13,14,15,16,17,18]
214+ cache . PendingMaintenance ( ) ;
215+ LogLru ( ) ;
216+
217+ // W [19] Protected [8,9,7] Probation [0,1,2,3,4,5,6,10,11,12,13,14,15,16,17,18]
218+ // element 7 now moved to back of LRU
219+ cache . GetOrAdd ( 7 , k => k ) ;
220+ cache . PendingMaintenance ( ) ;
221+ LogLru ( ) ;
222+
223+ // Trim is LRU order
224+ //W [19] Protected [7] Probation []
225+ cache . Trim ( 18 ) ;
226+ cache . PendingMaintenance ( ) ;
227+ LogLru ( ) ;
228+
229+ cache . TryGet ( 7 , out var _ ) . Should ( ) . BeTrue ( ) ;
230+ }
231+
232+ [ Fact ]
233+ public void WriteUpdatesProtectedLruOrder ( )
234+ {
235+ // W [19] Protected [] Probation [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
236+ for ( int i = 0 ; i < 20 ; i ++ )
237+ {
238+ cache . GetOrAdd ( i , k => k ) ;
239+ }
240+
241+ cache . PendingMaintenance ( ) ;
242+ LogLru ( ) ;
243+
244+ cache . GetOrAdd ( 7 , k => k ) ;
245+ cache . GetOrAdd ( 8 , k => k ) ;
246+ cache . GetOrAdd ( 9 , k => k ) ;
247+
248+ // W [19] Protected [7,8,9] Probation [0,1,2,3,4,5,6,10,11,12,13,14,15,16,17,18]
249+ cache . PendingMaintenance ( ) ;
250+ LogLru ( ) ;
251+
252+ // W [19] Protected [8,9,7] Probation [0,1,2,3,4,5,6,10,11,12,13,14,15,16,17,18]
147253 // element 7 now moved to back of LRU
148254 cache . TryUpdate ( 7 , - 7 ) . Should ( ) . BeTrue ( ) ;
149255 cache . PendingMaintenance ( ) ;
256+ LogLru ( ) ;
150257
151258 // Trim is LRU order
152- // W [19], Protected [9, 10, 11, 12, 14, 7], Probation []
153- cache . Trim ( 12 ) ;
259+ //W [19] Protected [7] Probation []
260+ cache . Trim ( 18 ) ;
154261 cache . PendingMaintenance ( ) ;
262+ LogLru ( ) ;
155263
156264 cache . TryGet ( 7 , out var _ ) . Should ( ) . BeTrue ( ) ;
157265 }
0 commit comments