@@ -10,9 +10,10 @@ internal interface INodePolicy<K, V, N>
10
10
{
11
11
N Create ( K key , V value ) ;
12
12
bool IsExpired ( N node ) ;
13
- void AdvanceTime ( ) ;
14
13
void OnRead ( N node ) ;
15
14
void OnWrite ( N node ) ;
15
+ void AfterRead ( N node ) ;
16
+ void AfterWrite ( N node ) ;
16
17
void OnEvict ( N node ) ;
17
18
void ExpireEntries < P > ( ref ConcurrentLfuCore < K , V , N , P > cache ) where P : struct , INodePolicy < K , V , N > ;
18
19
}
@@ -33,17 +34,22 @@ public bool IsExpired(AccessOrderNode<K, V> node)
33
34
}
34
35
35
36
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
36
- public void AdvanceTime ( )
37
+ public void OnRead ( AccessOrderNode < K , V > node )
37
38
{
38
39
}
39
40
40
41
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
41
- public void OnRead ( AccessOrderNode < K , V > node )
42
+ public void OnWrite ( AccessOrderNode < K , V > node )
42
43
{
43
44
}
44
45
45
46
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
46
- public void OnWrite ( AccessOrderNode < K , V > node )
47
+ public void AfterRead ( AccessOrderNode < K , V > node )
48
+ {
49
+ }
50
+
51
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
52
+ public void AfterWrite ( AccessOrderNode < K , V > node )
47
53
{
48
54
}
49
55
@@ -84,29 +90,33 @@ public TimeOrderNode<K, V> Create(K key, V value)
84
90
85
91
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
86
92
public bool IsExpired ( TimeOrderNode < K , V > node )
87
- {
88
- return node . TimeToExpire < Duration . SinceEpoch ( ) ;
89
- }
90
-
91
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
92
- public void AdvanceTime ( )
93
93
{
94
94
current = Duration . SinceEpoch ( ) ;
95
+ return node . TimeToExpire < current ;
95
96
}
96
97
97
98
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
98
99
public void OnRead ( TimeOrderNode < K , V > node )
99
100
{
100
- var oldTte = node . TimeToExpire ;
101
+ // we know IsExpired is always called immediate before OnRead, so piggyback on the current time
101
102
node . TimeToExpire = current + expiryCalculator . GetExpireAfterRead ( node . Key , node . Value , node . TimeToExpire - current ) ;
102
- if ( oldTte . raw != node . TimeToExpire . raw )
103
- {
104
- wheel . Reschedule ( node ) ;
105
- }
106
103
}
107
104
108
105
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
109
106
public void OnWrite ( TimeOrderNode < K , V > node )
107
+ {
108
+ var current = Duration . SinceEpoch ( ) ;
109
+ node . TimeToExpire = current + expiryCalculator . GetExpireAfterUpdate ( node . Key , node . Value , node . TimeToExpire - current ) ;
110
+ }
111
+
112
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
113
+ public void AfterRead ( TimeOrderNode < K , V > node )
114
+ {
115
+ wheel . Reschedule ( node ) ;
116
+ }
117
+
118
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
119
+ public void AfterWrite ( TimeOrderNode < K , V > node )
110
120
{
111
121
// if the node is not yet scheduled, it is being created
112
122
// the time is set on create in case it is read before the buffer is processed
@@ -116,12 +126,7 @@ public void OnWrite(TimeOrderNode<K, V> node)
116
126
}
117
127
else
118
128
{
119
- var oldTte = node . TimeToExpire ;
120
- node . TimeToExpire = current + expiryCalculator . GetExpireAfterUpdate ( node . Key , node . Value , node . TimeToExpire - current ) ;
121
- if ( oldTte . raw != node . TimeToExpire . raw )
122
- {
123
- wheel . Reschedule ( node ) ;
124
- }
129
+ wheel . Reschedule ( node ) ;
125
130
}
126
131
}
127
132
@@ -134,7 +139,7 @@ public void OnEvict(TimeOrderNode<K, V> node)
134
139
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
135
140
public void ExpireEntries < P > ( ref ConcurrentLfuCore < K , V , TimeOrderNode < K , V > , P > cache ) where P : struct , INodePolicy < K , V , TimeOrderNode < K , V > >
136
141
{
137
- wheel . Advance ( ref cache , current ) ;
142
+ wheel . Advance ( ref cache , Duration . SinceEpoch ( ) ) ;
138
143
}
139
144
}
140
145
}
0 commit comments