timer_deque_rs/deque_timeout/
timer_signal.rs

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