cfx_rpc/helpers/
poll_manager.rs1#![allow(dead_code)]
2use cfx_types::H128;
21use transient_hashmap::{StandardTimer, Timer, TransientHashMap};
22
23pub type PollId = H128;
24
25pub struct PollManager<F, T = StandardTimer>
29where T: Timer
30{
31 polls: TransientHashMap<PollId, F, T>,
32}
33
34impl<F> PollManager<F, StandardTimer> {
35 pub fn new(lifetime: u32) -> Self {
37 PollManager::new_with_timer(Default::default(), lifetime)
38 }
39}
40
41impl<F, T> PollManager<F, T>
42where T: Timer
43{
44 pub fn new_with_timer(timer: T, lifetime: u32) -> Self {
45 PollManager {
46 polls: TransientHashMap::new_with_timer(lifetime, timer),
47 }
48 }
49
50 pub fn create_poll(&mut self, filter: F) -> PollId {
54 self.polls.prune();
55
56 let id = loop {
57 let id = PollId::random();
58 if self.polls.contains_key(&id) {
59 continue;
60 }
61
62 break id;
63 };
64
65 self.polls.insert(id, filter);
66
67 id
68 }
69
70 pub fn poll(&mut self, id: &PollId) -> Option<&F> {
73 self.polls.prune();
74 self.polls.get(id)
75 }
76
77 pub fn poll_mut(&mut self, id: &PollId) -> Option<&mut F> {
79 self.polls.prune();
80 self.polls.get_mut(id)
81 }
82
83 pub fn remove_poll(&mut self, id: &PollId) -> bool {
85 self.polls.remove(id).is_some()
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::PollManager;
92 use std::cell::Cell;
93 use transient_hashmap::Timer;
94
95 struct TestTimer<'a> {
96 time: &'a Cell<i64>,
97 }
98
99 impl<'a> Timer for TestTimer<'a> {
100 fn get_time(&self) -> i64 { self.time.get() }
101 }
102
103 #[test]
104 fn test_poll_indexer() {
105 let time = Cell::new(0);
106 let timer = TestTimer { time: &time };
107
108 let mut indexer = PollManager::new_with_timer(timer, 60);
109 let id1 = indexer.create_poll(20);
110 let id2 = indexer.create_poll(20);
111 assert_ne!(id1, id2);
112
113 time.set(10);
114 *indexer.poll_mut(&id1).unwrap() = 21;
115 assert_eq!(*indexer.poll(&id1).unwrap(), 21);
116 assert_eq!(*indexer.poll(&id2).unwrap(), 20);
117
118 time.set(30);
119 *indexer.poll_mut(&id2).unwrap() = 23;
120 assert_eq!(*indexer.poll(&id2).unwrap(), 23);
121
122 time.set(75);
123 assert!(indexer.poll(&id1).is_none());
124 assert_eq!(*indexer.poll(&id2).unwrap(), 23);
125
126 indexer.remove_poll(&id2);
127 assert!(indexer.poll(&id2).is_none());
128 }
129}