timer_deque_rs/deque_timeout/timer_signal.rs
1/*-
2 * timer-deque-rs - a Rust crate which provides timer and timer queues based on target OS
3 * functionality.
4 *
5 * Copyright (C) 2025 Aleksandr Morozov alex@nixd.org
6 * 4neko.org alex@4neko.org
7 *
8 * The timer-rs crate can be redistributed and/or modified
9 * under the terms of either of the following licenses:
10 *
11 * 1. the Mozilla Public License Version 2.0 (the “MPL”) OR
12 *
13 * 2. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
14 */
15
16use std::fmt;
17
18use crate::
19{
20 common,
21 deque_timeout::{OrderdTimerDequeOnce, OrderdTimerDequePeriodic, OrderedTimerDequeMode},
22 error::{TimerErrorType, TimerResult},
23 map_timer_err,
24 timer_err,
25 timer_portable::timer::{AbsoluteTime, RelativeTime},
26 TimerReadRes
27};
28
29use super::{OrderedTimerDeque, OrderedTimerDequeIntrf};
30
31/// A trait which should be implemented on the struct which will be provided
32/// to timer dequeue. The trait implements the uniqid and signalling. There
33/// are two realizations: `sig_timeout` for sync and `a_sig_timeout` for
34/// async. Both functions must use any methods to send signal but it must
35/// never block the thread!
36pub trait TimerDequeueSignal: fmt::Debug + fmt::Display + Eq + PartialEq
37{
38 /// A uniq id type. It is used to identify the instance.
39 type TimerQueueID: Eq + PartialEq + fmt::Display + fmt::Debug;
40
41 /// Error type returned by the signal functions.
42 type TimeoutErr: fmt::Display + fmt::Debug;
43
44 /// This function should return the uniq id of the instance.
45 fn get_id(&self) -> Self::TimerQueueID;
46
47 /// This function should notify i.e send signal or whatever. The
48 /// important condition is not to block the thread.
49 fn sig_timeout(&mut self) -> Result<(), Self::TimeoutErr>
50 where Self: Sized
51 {
52 return Ok(());
53 }
54
55 /// This function should notify i.e send signal or whatever. The
56 /// important condition is not to block the thread.
57 async fn a_sig_timeout(&mut self) -> Result<(), Self::TimeoutErr>
58 where Self: Sized
59 {
60 return Ok(());
61 }
62}
63
64/// Defines the type of the dequeue. This type of the dequeue is sending notification when
65/// the timeout event happens. The signal will be sent using `SIG`.
66///
67/// # Arguments
68///
69/// `SIG` - is an instance which provides the signaling and ID. It must implement:
70/// [TimerDequeueSignal], [fmt::Debug], [fmt::Display], [Eq], [PartialEq].
71///
72/// `MODE` - a [OrderedTimerDequeMode] which defines the deque behaviour. There are
73/// two types of the operation:
74///
75/// * [OrderdTimerDequeOnce] - after timeout the element is removed from the queue.
76///
77/// * [OrderdTimerDequePeriodic] - after timeout the element timeout is extended
78/// until the item is not removed from the queue manually.
79///
80/// # Example
81///
82/// ```ignore
83/// let mut time_list =
84/// OrderedTimerDeque
85/// ::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequeOnce>>
86/// ::new("test_label".into(), 4, false).unwrap();
87/// ```
88/// or
89/// ```ignore
90/// let mut time_list =
91/// OrderedTimerDeque
92/// ::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequePeriodic>>
93/// ::new("test_label".into(), 4, false).unwrap();
94/// ```
95#[derive(Debug)]
96pub struct TimerDequeueSignalTicket<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode>
97{
98 /// A notification and id instance.
99 signal: SIG,
100
101 /// A timeout depending on the mode of the operation
102 timeout_mode: MODE
103}
104
105
106/// implemetation for the [OrderdTimerDequeOnce]
107impl<SIG> TimerDequeueSignalTicket<SIG, OrderdTimerDequeOnce>
108where SIG: TimerDequeueSignal
109{
110 pub
111 fn new(sig_hnd: SIG, abs_time: AbsoluteTime) -> TimerResult<Self>
112 {
113 let cur = AbsoluteTime::now();
114
115 if cur > abs_time
116 {
117 timer_err!(TimerErrorType::Expired, "time already expired");
118 }
119
120
121 return Ok(
122 Self
123 {
124 signal:
125 sig_hnd,
126 timeout_mode:
127 OrderdTimerDequeOnce::new(abs_time)
128 }
129 );
130 }
131}
132
133/// implemetation for the [OrderdTimerDequePeriodic]
134impl<SIG> TimerDequeueSignalTicket<SIG, OrderdTimerDequePeriodic>
135where SIG: TimerDequeueSignal
136{
137 pub
138 fn new(sig_hnd: SIG, rel_time: RelativeTime) -> TimerResult<Self>
139 {
140 return Ok(
141 Self
142 {
143 signal:
144 sig_hnd,
145 timeout_mode:
146 OrderdTimerDequePeriodic::new(rel_time)
147 }
148 );
149 }
150}
151
152impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> TimerDequeueSignalTicket<SIG, MODE>
153{
154 fn send_sig_timeout(&mut self) -> TimerResult<()>
155 {
156 return
157 self
158 .signal
159 .sig_timeout()
160 .map_err(|e|
161 map_timer_err!(TimerErrorType::ExternalError, "cannot send signal, error: {}", e)
162 );
163 }
164
165 async
166 fn async_send_sig_timeout(&mut self) -> TimerResult<()>
167 {
168 return
169 self
170 .signal
171 .a_sig_timeout()
172 .await
173 .map_err(|e|
174 map_timer_err!(TimerErrorType::ExternalError, "cannot send signal, error: {}", e)
175 );
176 }
177}
178
179impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> fmt::Display for TimerDequeueSignalTicket<SIG, MODE>
180{
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>
182 {
183 write!(f, "{} until: {}", self.signal.get_id(), self.timeout_mode)
184 }
185}
186
187impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> Eq for TimerDequeueSignalTicket<SIG, MODE> {}
188
189impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> PartialEq for TimerDequeueSignalTicket<SIG, MODE>
190{
191 fn eq(&self, other: &Self) -> bool
192 {
193 return self.signal == other.signal;
194 }
195}
196
197
198impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> Ord for TimerDequeueSignalTicket<SIG, MODE>
199{
200 fn cmp(&self, other: &Self) -> std::cmp::Ordering
201 {
202 return self.timeout_mode.cmp(&other.timeout_mode);
203 }
204}
205
206impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> PartialOrd for TimerDequeueSignalTicket<SIG, MODE>
207{
208 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering>
209 {
210 return Some(self.cmp(other));
211 }
212}
213
214impl<SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode> OrderedTimerDequeIntrf
215for TimerDequeueSignalTicket<SIG, MODE>
216{
217 type Target = SIG;
218 type Ticket = common::NoTicket;
219
220 #[inline]
221 fn get_timeout_absolute(&self) -> AbsoluteTime
222 {
223 return self.timeout_mode.get_absolut_timeout();
224 }
225}
226
227impl<SIG> OrderedTimerDeque<TimerDequeueSignalTicket<SIG, OrderdTimerDequeOnce>>
228where SIG: TimerDequeueSignal
229{
230 /// Adds the new `absolute` (`relative`) timeout to the timer dequeue.
231 ///
232 /// # Arguemnts
233 ///
234 /// `sig_hnd` - a `SIG` generic instance which would identify the instance and
235 /// provide identification.
236 ///
237 /// `abs_time` - a [AbsoluteTime] absolute time in future when the timeout
238 /// should happen.
239 ///
240 /// # Returns
241 ///
242 /// A [Result] as alias [TimerResult] is returned with:
243 ///
244 /// * [Result::Ok] with the [TimerDequeueTicket] ticket.
245 ///
246 /// * [Result::Err] with error description.
247 #[inline]
248 pub
249 fn add_to_timer(&mut self, sig_hnd: SIG, abs_time: AbsoluteTime) -> TimerResult<common::NoTicket>
250 {
251 let inst =
252 TimerDequeueSignalTicket::<SIG, OrderdTimerDequeOnce>::new(sig_hnd, abs_time)?;
253
254 return self.add_to_timer_local(inst).map(|_| common::NoTicket);
255 }
256
257 /// Handles the event which was `read` from the timer. The functions [Self::wait_for_event]
258 /// or [Self::poll] can be used to obtain the event.
259 ///
260 /// # Arguments
261 ///
262 /// `res` - [TimerReadRes] an event from the timer to handle.
263 ///
264 /// `timeout_items` - a vector of tickets which were not dropped and timeout.
265 ///
266 /// A [Result] as alias [TimerResult] is returned with:
267 ///
268 /// * [Result::Ok] witout any innder data.
269 ///
270 /// * [Result::Err] with error description.
271 pub
272 fn timeout_event_handler(&mut self, res: TimerReadRes<u64>) -> TimerResult<()>
273 {
274 // ignore wouldblock
275 if let TimerReadRes::WouldBlock = res
276 {
277 return Ok(());
278 }
279
280 let cur_timestamp = AbsoluteTime::now();
281
282 loop
283 {
284 // get from front of the queue
285 let Some(front_entity) =
286 self.deque_timeout_list.front()
287 else
288 {
289 break;
290 };
291
292 let time_until = front_entity.get_timeout_absolute();
293
294 if time_until <= cur_timestamp
295 {
296 let mut front_entity = self.deque_timeout_list.pop_front().unwrap();
297
298 // send signal
299 front_entity.send_sig_timeout()?;
300 }
301 else
302 {
303 break;
304 }
305 } // loop
306
307 // call timer reschedule
308 self.reschedule_timer()?;
309
310 return Ok(());
311 }
312
313 /// An async version of the event handler.
314 ///
315 /// Handles the event which was `read` from the timer. The functions [Self::wait_for_event]
316 /// or [Self::poll] can be used to obtain the event.
317 ///
318 /// # Arguments
319 ///
320 /// `res` - [TimerReadRes] an event from the timer to handle.
321 ///
322 /// `timeout_items` - a vector of tickets which were not dropped and timeout.
323 ///
324 /// A [Result] as alias [TimerResult] is returned with:
325 ///
326 /// * [Result::Ok] witout any innder data.
327 ///
328 /// * [Result::Err] with error description.
329 pub async
330 fn async_timeout_event_handler(&mut self, res: TimerReadRes<u64>) -> TimerResult<()>
331 {
332 // ignore wouldblock
333 if let TimerReadRes::WouldBlock = res
334 {
335 return Ok(());
336 }
337
338 let cur_timestamp = AbsoluteTime::now();
339
340 loop
341 {
342 // get from front of the queue
343 let Some(front_entity) =
344 self.deque_timeout_list.front()
345 else
346 {
347 break;
348 };
349
350 let time_until = front_entity.get_timeout_absolute();
351
352 if time_until <= cur_timestamp
353 {
354 let mut front_entity = self.deque_timeout_list.pop_front().unwrap();
355
356 // send signal
357 front_entity.async_send_sig_timeout().await?;
358 }
359 else
360 {
361 break;
362 }
363 } // loop
364
365 // call timer reschedule
366 self.reschedule_timer()?;
367
368 return Ok(());
369 }
370}
371
372
373impl<SIG> OrderedTimerDeque<TimerDequeueSignalTicket<SIG, OrderdTimerDequePeriodic>>
374where SIG: TimerDequeueSignal
375{
376 /// Adds the new `periodic` timeout to the timer dequeue.
377 ///
378 /// # Arguemnts
379 ///
380 /// `sig_hnd` - a `SIG` generic instance which would identify the instance and
381 /// provide identification.
382 ///
383 /// `rel_time` - a [RelativeTime] which will be used to extend the further
384 /// timeouts.
385 ///
386 /// # Returns
387 ///
388 /// A [Result] as alias [TimerResult] is returned with:
389 ///
390 /// * [Result::Ok] with the [TimerDequeueTicket] ticket.
391 ///
392 /// * [Result::Err] with error description.
393 #[inline]
394 pub
395 fn add_to_timer(&mut self, sig_hnd: SIG, rel_time: RelativeTime) -> TimerResult<common::NoTicket>
396 {
397 let inst =
398 TimerDequeueSignalTicket::<SIG, OrderdTimerDequePeriodic>::new(sig_hnd, rel_time)?;
399
400 return self.add_to_timer_local(inst).map(|_| common::NoTicket);
401 }
402
403 /// Handles the event which was `read` from the timer. The functions [Self::wait_for_event]
404 /// or [Self::poll] can be used to obtain the event.
405 ///
406 /// # Arguments
407 ///
408 /// `res` - [TimerReadRes] an event from the timer to handle.
409 ///
410 /// `timeout_items` - a vector of tickets which were not dropped and timeout.
411 ///
412 /// A [Result] as alias [TimerResult] is returned with:
413 ///
414 /// * [Result::Ok] witout any innder data.
415 ///
416 /// * [Result::Err] with error description.
417 pub
418 fn timeout_event_handler(&mut self, res: TimerReadRes<u64>) -> TimerResult<()>
419 {
420 // ignore wouldblock
421 if let TimerReadRes::WouldBlock = res
422 {
423 return Ok(());
424 }
425
426 let cur_timestamp = AbsoluteTime::now();
427
428 loop
429 {
430 // get from front of the queue
431 let Some(front_entity) =
432 self.deque_timeout_list.front()
433 else
434 {
435 break;
436 };
437
438 let time_until = front_entity.get_timeout_absolute();
439
440 if time_until <= cur_timestamp
441 {
442 let mut deq = self.deque_timeout_list.pop_front().unwrap();
443
444 // send signal
445 deq.send_sig_timeout()?;
446
447 // advance timer
448 deq.timeout_mode.advance_timeout();
449
450 // return back to deque with new timeout
451 self.add_to_timer_local(deq)?;
452 }
453 else
454 {
455 break;
456 }
457 } // loop
458
459 // call timer reschedule
460 self.reschedule_timer()?;
461
462 return Ok(());
463 }
464
465 /// An async version of the event handler.
466 ///
467 /// Handles the event which was `read` from the timer. The functions [Self::wait_for_event]
468 /// or [Self::poll] can be used to obtain the event.
469 ///
470 /// # Arguments
471 ///
472 /// `res` - [TimerReadRes] an event from the timer to handle.
473 ///
474 /// `timeout_items` - a vector of tickets which were not dropped and timeout.
475 ///
476 /// A [Result] as alias [TimerResult] is returned with:
477 ///
478 /// * [Result::Ok] witout any innder data.
479 ///
480 /// * [Result::Err] with error description.
481 pub async
482 fn async_timeout_event_handler(&mut self, res: TimerReadRes<u64>) -> TimerResult<()>
483 {
484 // ignore wouldblock
485 if let TimerReadRes::WouldBlock = res
486 {
487 return Ok(());
488 }
489
490 let cur_timestamp = AbsoluteTime::now();
491
492 loop
493 {
494 // get from front of the queue
495 let Some(front_entity) =
496 self.deque_timeout_list.front_mut()
497 else
498 {
499 break;
500 };
501
502 let time_until = front_entity.get_timeout_absolute();
503
504 if time_until <= cur_timestamp
505 {
506 let mut deq = self.deque_timeout_list.pop_front().unwrap();
507
508 // send signal
509 deq.async_send_sig_timeout().await?;
510
511 // advance timeout
512 deq.timeout_mode.advance_timeout();
513
514 // return back to deque with new timeout
515 self.add_to_timer_local(deq)?;
516 }
517 else
518 {
519 break;
520 }
521 } // loop
522
523 // call timer reschedule
524 self.reschedule_timer()?;
525
526 return Ok(());
527 }
528}
529
530impl<SIG, MODE> OrderedTimerDeque<TimerDequeueSignalTicket<SIG, MODE>>
531where SIG: TimerDequeueSignal, MODE: OrderedTimerDequeMode
532{
533
534
535 /// Removes the instance from the queue by the `SIG::TimerQueueID` ID.
536 ///
537 /// # Arguments
538 ///
539 /// `arg_uniq_id` - a reference to instance's ID `SIG::TimerQueueID`.
540 ///
541 /// # Returns
542 ///
543 /// A [Result] as alias [TimerResult] is returned with:
544 ///
545 /// * [Result::Ok] witout any innder data.
546 ///
547 /// * [Result::Err] with error description.
548 pub
549 fn remove_from_sched_queue(&mut self, arg_uniq_id: &SIG::TimerQueueID) -> TimerResult<Option<()>>
550 {
551 if self.deque_timeout_list.len() == 0
552 {
553 timer_err!(TimerErrorType::QueueEmpty, "queue list is empty!");
554 }
555 else
556 {
557 // search for the item in list
558 if self.deque_timeout_list.len() == 1
559 {
560 // just pop the from the front
561 let _ = self.deque_timeout_list.pop_front().unwrap();
562
563 // stop timer
564 self.stop_timer()?;
565
566 return Ok(Some(()));
567 }
568 else
569 {
570 // in theory the `ticket` is a reference to ARC, so the weak should be upgraded
571 // succesfully for temoved instance.
572
573 for (pos, q_item)
574 in self.deque_timeout_list.iter().enumerate()
575 {
576 if &q_item.signal.get_id() == arg_uniq_id
577 {
578 // remove by the index
579 let _ =
580 self.deque_timeout_list.remove(pos);
581
582 // call timer reset if index is 0 (front)
583 if pos == 0
584 {
585 self.reschedule_timer()?;
586 }
587
588 return Ok(Some(()));
589 }
590 }
591
592 return Ok(None);
593 }
594 }
595 }
596}
597
598
599#[cfg(test)]
600mod tests
601{
602 use std::{cmp::Ordering, collections::VecDeque, fmt, sync::mpsc::{self, SendError, Sender}, time::{Duration, Instant}};
603
604 use crate::{common, deque_timeout::{OrderdTimerDequeOnce, OrderdTimerDequePeriodic}, timer_portable::timer::{AbsoluteTime, RelativeTime, TimerReadRes}, OrderedTimerDeque, TimerDequeueSignal, TimerDequeueSignalTicket};
605
606#[derive(Debug)]
607 struct TestSigStruct
608 {
609 uniq_id: u64,
610 mpsc_sender: Sender<u64>,
611 }
612
613 impl Eq for TestSigStruct{}
614
615 impl PartialEq for TestSigStruct
616 {
617 fn eq(&self, other: &Self) -> bool
618 {
619 return self.uniq_id == other.uniq_id;
620 }
621 }
622
623 impl fmt::Display for TestSigStruct
624 {
625 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
626 {
627 write!(f, "sig handler timer id: {}", self.uniq_id)
628 }
629 }
630
631 impl TimerDequeueSignal for TestSigStruct
632 {
633 type TimerQueueID = u64;
634
635 type TimeoutErr = SendError<Self::TimerQueueID>;
636
637 fn get_id(&self) -> Self::TimerQueueID
638 {
639 return self.uniq_id;
640 }
641
642 fn sig_timeout(&mut self) -> Result<(), Self::TimeoutErr>
643 {
644 return self.mpsc_sender.send(self.uniq_id);
645 }
646 }
647
648 #[test]
649 fn test_timer_test()
650 {
651
652
653 let mut time_list =
654 OrderedTimerDeque
655 ::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequeOnce>>
656 ::new("test_label".into(), 4, false).unwrap();
657
658
659 let s = Instant::now();
660 let ts = common::get_current_timestamp();
661
662 let tss_set =
663 AbsoluteTime
664 ::new_time(ts.timestamp()+2, ts.timestamp_subsec_nanos() as i64)
665 .unwrap();
666
667 let (snd, rcv) = mpsc::channel::<u64>();
668
669 let sig_tm = TestSigStruct{ uniq_id: 456, mpsc_sender: snd };
670
671 println!("signal handler: {}", sig_tm);
672
673 let _ = time_list.add_to_timer(sig_tm, tss_set.clone()).unwrap();
674
675 for _ in 0..3
676 {
677 let event = time_list.wait_for_event().unwrap();
678 if let TimerReadRes::WouldBlock = event
679 {
680 std::thread::sleep(Duration::from_millis(1001));
681
682 continue;
683 }
684
685 assert_eq!(event, TimerReadRes::Ok(1));
686
687 let e = s.elapsed();
688 let ts = AbsoluteTime::now();
689
690 assert_eq!(ts.seconds_cmp(&tss_set) == Ordering::Equal, true);
691 println!("ev: {}, instant: {:?} ts: {}, timerset: {}", event, e, ts, tss_set);
692
693 time_list.timeout_event_handler(event).unwrap();
694
695 let timer_id = rcv.recv_timeout(Duration::from_secs(1)).unwrap();
696
697 assert_eq!(timer_id, 456);
698
699 return;
700 }
701
702 panic!("timeout befor timer!");
703 }
704
705 #[test]
706 fn test_timer_period_test()
707 {
708
709
710 let mut time_list =
711 OrderedTimerDeque
712 ::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequePeriodic>>
713 ::new("test_label".into(), 4, false).unwrap();
714
715 let (snd, rcv) = mpsc::channel::<u64>();
716
717 let sig_tm = TestSigStruct{ uniq_id: 456, mpsc_sender: snd.clone() };
718 let tss_set = RelativeTime::from(Duration::from_secs(2));
719
720 let sig_tm2 = TestSigStruct{ uniq_id: 457, mpsc_sender: snd };
721 let tss_set2 = RelativeTime::from(Duration::from_secs(2));
722
723 println!("signal handler: {}", sig_tm);
724
725 let _ = time_list.add_to_timer(sig_tm, tss_set).unwrap();
726 let _ = time_list.add_to_timer(sig_tm2, tss_set2).unwrap();
727
728 for _ in 0..3
729 {
730 let abs_time_before = AbsoluteTime::now();
731 let s = Instant::now();
732 std::thread::sleep(Duration::from_millis(2001));
733
734 let event = time_list.wait_for_event().unwrap();
735 let TimerReadRes::Ok(cnt) = event
736 else
737 {
738 panic!("incorrect event res: {}", event);
739 };
740
741 assert_eq!(cnt, 1);
742
743 let e = s.elapsed();
744 let ts = AbsoluteTime::now() - abs_time_before;
745
746 println!("ev: {}, instant: {:?} ts: {}, timerset: {}", event, e, ts, tss_set);
747
748 assert_eq!(ts.seconds_cmp(&AbsoluteTime::new_time(2, 0).unwrap()) == Ordering::Equal, true);
749
750 time_list.timeout_event_handler(event).unwrap();
751
752 while let Ok(timer_id) = rcv.recv_timeout(Duration::from_millis(1))
753 {
754 println!("received timer item ID: {}", timer_id);
755 assert_eq!(timer_id == 456 || timer_id == 457, true);
756 }
757
758
759 }
760
761 time_list.remove_from_sched_queue(&456).unwrap();
762
763 return;
764 }
765 /*
766 #[test]
767 fn test_pop()
768 {
769 let mut ve = VecDeque::<[u8; 32]>::with_capacity(5);
770
771 ve.push_back([0_u8; 32]);
772 ve.push_back([1_u8; 32]);
773 ve.push_back([2_u8; 32]);
774 ve.push_back([3_u8; 32]);
775
776 let mut small: Option<Duration> = None;
777 let mut large: Option<Duration> = None;
778 let mut some_cnt: u32 = 0;
779 let mut mean: u128 = 0;
780
781 for _ in 0..5000
782 {
783 let s = Instant::now();
784
785 let v = ve.pop_front().unwrap();
786
787 if v.len() == 32
788 {
789 some_cnt += 1;
790 }
791
792 ve.push_front(v);
793
794 let e = s.elapsed();
795
796 if small.is_none() == true
797 {
798 small = Some(e);
799 }
800 else if small.as_ref().unwrap() > &e
801 {
802 small = Some(e);
803 }
804
805 if large.is_none() == true
806 {
807 large = Some(e);
808 }
809 else if large.as_ref().unwrap() < &e
810 {
811 large = Some(e);
812 }
813
814 mean += e.as_nanos();
815 }
816
817 println!("s: {:?}, e: {:?}, mean: {} some_cnt: {}", small.unwrap(), large.unwrap(), mean/100, some_cnt);
818 }
819
820 #[test]
821 fn test_pop2()
822 {
823 let mut ve = VecDeque::<[u8; 32]>::with_capacity(5);
824
825 ve.push_back([0_u8; 32]);
826 ve.push_back([1_u8; 32]);
827 ve.push_back([2_u8; 32]);
828 ve.push_back([3_u8; 32]);
829
830 let mut small: Option<Duration> = None;
831 let mut large: Option<Duration> = None;
832 let mut some_cnt: u32 = 0;
833 let mut mean: u128 = 0;
834
835 for _ in 0..5000
836 {
837 let s = Instant::now();
838
839 let v = ve.front().unwrap();
840
841 if v.len() == 32
842 {
843 some_cnt += 1;
844 }
845
846 let v = ve.pop_front().unwrap();
847
848
849 let e = s.elapsed();
850 ve.push_front(v);
851
852 if small.is_none() == true
853 {
854 small = Some(e);
855 }
856 else if small.as_ref().unwrap() > &e
857 {
858 small = Some(e);
859 }
860
861 if large.is_none() == true
862 {
863 large = Some(e);
864 }
865 else if large.as_ref().unwrap() < &e
866 {
867 large = Some(e);
868 }
869
870 mean += e.as_nanos();
871 }
872
873 println!("s: {:?}, e: {:?}, mean: {} some_cnt: {}", small.unwrap(), large.unwrap(), mean/100, some_cnt);
874 }*/
875}