@@ -88,26 +88,23 @@ pub struct Timer {
88
88
}
89
89
90
90
impl Timer {
91
- /// Create a new timeout manager.
92
- ///
93
- /// Takes a threshold below which two timeouts cannot overlap.
91
+ /// Create a new timer containing no timeouts.
94
92
pub fn new ( ) -> Self { Self { timeouts : bset ! { } } }
95
93
96
94
/// Return the number of timeouts being tracked.
97
- pub fn len ( & self ) -> usize { self . timeouts . len ( ) }
95
+ pub fn count ( & self ) -> usize { self . timeouts . len ( ) }
98
96
99
97
/// Check whether there are timeouts being tracked.
100
- pub fn is_empty ( & self ) -> bool { self . timeouts . is_empty ( ) }
98
+ pub fn has_timeouts ( & self ) -> bool { ! self . timeouts . is_empty ( ) }
101
99
102
- /// Register a new timeout with an associated key and wake-up time from a
103
- /// UNIX time epoch.
104
- pub fn set_timer ( & mut self , span : Duration , after : Timestamp ) {
105
- let time = after + Timestamp ( span. as_millis ( ) ) ;
100
+ /// Register a new timeout relative to a certain point in time.
101
+ pub fn set_timeout ( & mut self , timeout : Duration , after : Timestamp ) {
102
+ let time = after + Timestamp ( timeout. as_millis ( ) ) ;
106
103
self . timeouts . insert ( time) ;
107
104
}
108
105
109
- /// Get the minimum time duration we should wait for at least one timeout
110
- /// to be reached. Returns `None` if there are no timeouts.
106
+ /// Get the first timeout expiring right at or after certain moment of time.
107
+ /// Returns `None` if there are no timeouts.
111
108
///
112
109
/// ```
113
110
/// # use std::time::{Duration};
@@ -116,30 +113,33 @@ impl Timer {
116
113
/// let mut tm = Timer::new();
117
114
///
118
115
/// let now = Timestamp::now();
119
- /// tm.set_timer (Duration::from_secs(16), now);
120
- /// tm.set_timer (Duration::from_secs(8), now);
121
- /// tm.set_timer (Duration::from_secs(64), now);
116
+ /// tm.set_timeout (Duration::from_secs(16), now);
117
+ /// tm.set_timeout (Duration::from_secs(8), now);
118
+ /// tm.set_timeout (Duration::from_secs(64), now);
122
119
///
123
120
/// let mut now = Timestamp::now();
124
121
/// // We need to wait 8 secs to trigger the next timeout (1).
125
- /// assert!(tm.next (now) <= Some(Duration::from_secs(8)));
122
+ /// assert!(tm.next_expiring_from (now) <= Some(Duration::from_secs(8)));
126
123
///
127
124
/// // ... sleep for a sec ...
128
125
/// now += Duration::from_secs(1);
129
126
///
130
127
/// // Now we don't need to wait as long!
131
- /// assert!(tm.next (now).unwrap() <= Duration::from_secs(7));
128
+ /// assert!(tm.next_expiring_from (now).unwrap() <= Duration::from_secs(7));
132
129
/// ```
133
- pub fn next ( & self , after : impl Into < Timestamp > ) -> Option < Duration > {
134
- let after = after. into ( ) ;
135
- self . timeouts
136
- . iter ( )
137
- . find ( |t| * * t >= after)
138
- . map ( |t| Duration :: from_millis ( ( * t - after) . as_millis ( ) ) )
130
+ pub fn next_expiring_from ( & self , time : impl Into < Timestamp > ) -> Option < Duration > {
131
+ let time = time. into ( ) ;
132
+ let last = * self . timeouts . first ( ) ?;
133
+ Some ( if last >= time {
134
+ Duration :: from_millis ( last. as_millis ( ) - time. as_millis ( ) )
135
+ } else {
136
+ Duration :: from_secs ( 0 )
137
+ } )
139
138
}
140
139
141
- /// Returns vector of timers which has fired before certain time.
142
- pub fn expire ( & mut self , time : Timestamp ) -> usize {
140
+ /// Removes timeouts which expire by a certain moment of time (inclusive),
141
+ /// returning total number of timeouts which were removed.
142
+ pub fn remove_expired_by ( & mut self , time : Timestamp ) -> usize {
143
143
// Since `split_off` returns everything *after* the given key, including the key,
144
144
// if a timer is set for exactly the given time, it would remain in the "after"
145
145
// set of unexpired keys. This isn't what we want, therefore we add `1` to the
@@ -162,34 +162,56 @@ mod tests {
162
162
let mut tm = Timer :: new ( ) ;
163
163
164
164
let now = Timestamp :: now ( ) ;
165
- tm. set_timer ( Duration :: from_secs ( 8 ) , now) ;
166
- tm. set_timer ( Duration :: from_secs ( 9 ) , now) ;
167
- tm. set_timer ( Duration :: from_secs ( 10 ) , now) ;
165
+ tm. set_timeout ( Duration :: from_secs ( 8 ) , now) ;
166
+ tm. set_timeout ( Duration :: from_secs ( 9 ) , now) ;
167
+ tm. set_timeout ( Duration :: from_secs ( 10 ) , now) ;
168
168
169
- assert_eq ! ( tm. expire ( now + Duration :: from_secs( 9 ) ) , 2 ) ;
170
- assert_eq ! ( tm. len ( ) , 1 ) ;
169
+ assert_eq ! ( tm. remove_expired_by ( now + Duration :: from_secs( 9 ) ) , 2 ) ;
170
+ assert_eq ! ( tm. count ( ) , 1 ) ;
171
171
}
172
172
173
173
#[ test]
174
174
fn test_wake ( ) {
175
175
let mut tm = Timer :: new ( ) ;
176
176
177
177
let now = Timestamp :: now ( ) ;
178
- tm. set_timer ( Duration :: from_secs ( 8 ) , now) ;
179
- tm. set_timer ( Duration :: from_secs ( 16 ) , now) ;
180
- tm. set_timer ( Duration :: from_secs ( 64 ) , now) ;
181
- tm. set_timer ( Duration :: from_secs ( 72 ) , now) ;
178
+ tm. set_timeout ( Duration :: from_secs ( 8 ) , now) ;
179
+ tm. set_timeout ( Duration :: from_secs ( 16 ) , now) ;
180
+ tm. set_timeout ( Duration :: from_secs ( 64 ) , now) ;
181
+ tm. set_timeout ( Duration :: from_secs ( 72 ) , now) ;
182
+
183
+ assert_eq ! ( tm. remove_expired_by( now) , 0 ) ;
184
+ assert_eq ! ( tm. count( ) , 4 ) ;
185
+
186
+ assert_eq ! ( tm. remove_expired_by( now + Duration :: from_secs( 9 ) ) , 1 ) ;
187
+ assert_eq ! ( tm. count( ) , 3 , "one timeout has expired" ) ;
188
+
189
+ assert_eq ! ( tm. remove_expired_by( now + Duration :: from_secs( 66 ) ) , 2 ) ;
190
+ assert_eq ! ( tm. count( ) , 1 , "another two timeouts have expired" ) ;
191
+
192
+ assert_eq ! ( tm. remove_expired_by( now + Duration :: from_secs( 96 ) ) , 1 ) ;
193
+ assert ! ( !tm. has_timeouts( ) , "all timeouts have expired" ) ;
194
+ }
195
+
196
+ #[ test]
197
+ fn test_next ( ) {
198
+ let mut tm = Timer :: new ( ) ;
199
+
200
+ let mut now = Timestamp :: now ( ) ;
201
+ tm. set_timeout ( Duration :: from_secs ( 3 ) , now) ;
202
+ assert_eq ! ( tm. next_expiring_from( now) , Some ( Duration :: from_secs( 3 ) ) ) ;
182
203
183
- assert_eq ! ( tm . expire ( now) , 0 ) ;
184
- assert_eq ! ( tm. len ( ) , 4 ) ;
204
+ now += Duration :: from_secs ( 2 ) ;
205
+ assert_eq ! ( tm. next_expiring_from ( now ) , Some ( Duration :: from_secs ( 1 ) ) ) ;
185
206
186
- assert_eq ! ( tm . expire ( now + Duration :: from_secs( 9 ) ) , 1 ) ;
187
- assert_eq ! ( tm. len ( ) , 3 , "one timeout has expired" ) ;
207
+ now += Duration :: from_secs ( 1 ) ;
208
+ assert_eq ! ( tm. next_expiring_from ( now ) , Some ( Duration :: from_secs ( 0 ) ) ) ;
188
209
189
- assert_eq ! ( tm . expire ( now + Duration :: from_secs( 66 ) ) , 2 ) ;
190
- assert_eq ! ( tm. len ( ) , 1 , "another two timeouts have expired" ) ;
210
+ now += Duration :: from_secs ( 1 ) ;
211
+ assert_eq ! ( tm. next_expiring_from ( now ) , Some ( Duration :: from_secs ( 0 ) ) ) ;
191
212
192
- assert_eq ! ( tm. expire( now + Duration :: from_secs( 96 ) ) , 1 ) ;
193
- assert ! ( tm. is_empty( ) , "all timeouts have expired" ) ;
213
+ assert_eq ! ( tm. remove_expired_by( now) , 1 ) ;
214
+ assert_eq ! ( tm. count( ) , 0 ) ;
215
+ assert_eq ! ( tm. next_expiring_from( now) , None ) ;
194
216
}
195
217
}
0 commit comments