1use futures_core::Stream;
2use std::borrow::Borrow;
3use std::collections::HashMap;
4use std::future::poll_fn;
5use std::hash::Hash;
6use std::pin::Pin;
7use std::task::{Context, Poll, ready};
8
9#[derive(Debug, Clone)]
37pub struct StreamMap<K, V> {
38 entries: Vec<(K, V)>,
39 index: HashMap<K, usize>,
41}
42
43impl<K, V> StreamMap<K, V> {
44 pub fn new() -> Self {
53 Self {
54 entries: Vec::new(),
55 index: HashMap::new(),
56 }
57 }
58
59 pub fn with_capacity(capacity: usize) -> Self {
61 Self {
62 entries: Vec::with_capacity(capacity),
63 index: HashMap::with_capacity(capacity),
64 }
65 }
66
67 pub fn iter(&self) -> impl Iterator<Item = &(K, V)> {
69 self.entries.iter()
70 }
71
72 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
76 self.entries.iter_mut().map(|(key, stream)| (&*key, stream))
77 }
78
79 pub fn keys(&self) -> impl Iterator<Item = &K> {
81 self.entries.iter().map(|(k, _)| k)
82 }
83
84 pub fn values(&self) -> impl Iterator<Item = &V> {
86 self.entries.iter().map(|(_, v)| v)
87 }
88
89 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
91 self.entries.iter_mut().map(|(_, v)| v)
92 }
93
94 pub fn capacity(&self) -> usize {
96 self.entries.capacity()
97 }
98
99 pub fn len(&self) -> usize {
101 self.entries.len()
102 }
103
104 pub fn is_empty(&self) -> bool {
106 self.entries.is_empty()
107 }
108
109 pub fn clear(&mut self) {
111 self.entries.clear();
112 self.index.clear();
113 }
114
115 pub fn insert(&mut self, k: K, stream: V) -> Option<V>
119 where
120 K: Hash + Eq + Clone,
121 {
122 if let Some(&pos) = self.index.get(&k) {
123 let slot = &mut self.entries[pos].1;
124 return Some(std::mem::replace(slot, stream));
125 }
126 let pos = self.entries.len();
127 self.index.insert(k.clone(), pos);
128 self.entries.push((k, stream));
129 None
130 }
131
132 pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
134 where
135 K: Borrow<Q> + Hash + Eq + Clone,
136 Q: Hash + Eq + ?Sized,
137 {
138 let idx = *self.index.get(k)?;
139 self.index.remove(k);
140 Some(self.swap_remove_idx(idx).1)
141 }
142
143 pub fn contains_key<Q>(&self, k: &Q) -> bool
145 where
146 K: Borrow<Q> + Hash + Eq,
147 Q: Hash + Eq + ?Sized,
148 {
149 self.index.contains_key(k)
150 }
151
152 pub fn get<Q>(&self, k: &Q) -> Option<&V>
154 where
155 K: Borrow<Q> + Hash + Eq,
156 Q: Hash + Eq + ?Sized,
157 {
158 let &idx = self.index.get(k)?;
159 self.entries.get(idx).map(|(_, v)| v)
160 }
161
162 pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
164 where
165 K: Borrow<Q> + Hash + Eq,
166 Q: Hash + Eq + ?Sized,
167 {
168 let &idx = self.index.get(k)?;
169 self.entries.get_mut(idx).map(|(_, v)| v)
170 }
171}
172
173impl<K, V> StreamMap<K, V>
174where
175 K: Clone,
176{
177 fn swap_remove_idx(&mut self, idx: usize) -> (K, V)
180 where
181 K: Hash + Eq,
182 {
183 let out = self.entries.swap_remove(idx);
184 if idx < self.entries.len() {
185 let moved = self.entries[idx].0.clone();
186 self.index.insert(moved, idx);
187 }
188 out
189 }
190}
191
192impl<K, V> StreamMap<K, V>
193where
194 K: Unpin,
195 V: Stream + Unpin,
196{
197 fn poll_next_entry(&mut self, cx: &mut Context<'_>) -> Poll<Option<(usize, V::Item)>>
198 where
199 K: Hash + Eq + Clone,
200 {
201 if self.entries.is_empty() {
202 return Poll::Ready(None);
203 }
204 let start = crate::rand::thread_rng_n(self.entries.len() as u32) as usize;
205 let mut idx = start;
206
207 for _ in 0..self.entries.len() {
208 let (_, stream) = &mut self.entries[idx];
209 match Pin::new(stream).poll_next(cx) {
210 Poll::Ready(Some(val)) => return Poll::Ready(Some((idx, val))),
211 Poll::Ready(None) => {
212 let key = self.entries[idx].0.clone();
214 self.index.remove(&key);
215 self.swap_remove_idx(idx);
216 if self.entries.is_empty() {
217 return Poll::Ready(None);
218 }
219 if idx == self.entries.len() {
220 idx = 0;
221 } else if idx < start && start <= self.entries.len() {
222 idx = idx.wrapping_add(1) % self.entries.len();
224 }
225 }
226 Poll::Pending => {
227 idx = idx.wrapping_add(1) % self.entries.len();
228 }
229 }
230 }
231
232 if self.entries.is_empty() {
233 Poll::Ready(None)
234 } else {
235 Poll::Pending
236 }
237 }
238}
239
240impl<K, V> Default for StreamMap<K, V> {
241 fn default() -> Self {
242 Self::new()
243 }
244}
245
246impl<K, V> StreamMap<K, V>
247where
248 K: Clone + Unpin,
249 V: Stream + Unpin,
250{
251 pub async fn next_many(&mut self, buffer: &mut Vec<(K, V::Item)>, limit: usize) -> usize
256 where
257 K: Hash + Eq,
258 {
259 poll_fn(|cx| self.poll_next_many(cx, buffer, limit)).await
260 }
261
262 pub fn poll_next_many(
264 &mut self,
265 cx: &mut Context<'_>,
266 buffer: &mut Vec<(K, V::Item)>,
267 limit: usize,
268 ) -> Poll<usize>
269 where
270 K: Hash + Eq,
271 {
272 if limit == 0 || self.entries.is_empty() {
273 return Poll::Ready(0);
274 }
275
276 let mut added = 0;
277 let start = crate::rand::thread_rng_n(self.entries.len() as u32) as usize;
278 let mut idx = start;
279
280 while added < limit {
281 let mut made_progress = false;
282
283 for _ in 0..self.entries.len() {
284 if self.entries.is_empty() {
285 break;
286 }
287 let (_, stream) = &mut self.entries[idx];
288 match Pin::new(stream).poll_next(cx) {
289 Poll::Ready(Some(val)) => {
290 added += 1;
291 buffer.push((self.entries[idx].0.clone(), val));
292 made_progress = true;
293 idx = idx.wrapping_add(1) % self.entries.len();
294 if added == limit {
295 break;
296 }
297 }
298 Poll::Ready(None) => {
299 let key = self.entries[idx].0.clone();
300 self.index.remove(&key);
301 self.swap_remove_idx(idx);
302 if self.entries.is_empty() {
303 break;
304 }
305 if idx == self.entries.len() {
306 idx = 0;
307 } else if idx < start && start <= self.entries.len() {
308 idx = idx.wrapping_add(1) % self.entries.len();
309 }
310 }
311 Poll::Pending => {
312 idx = idx.wrapping_add(1) % self.entries.len();
313 }
314 }
315 }
316
317 if !made_progress {
318 break;
319 }
320 }
321
322 if added > 0 {
323 Poll::Ready(added)
324 } else if self.entries.is_empty() {
325 Poll::Ready(0)
326 } else {
327 Poll::Pending
328 }
329 }
330}
331
332impl<K, V> Stream for StreamMap<K, V>
333where
334 K: Clone + Unpin,
335 V: Stream + Unpin,
336 K: Hash + Eq,
337{
338 type Item = (K, V::Item);
339
340 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
341 if let Some((idx, val)) = ready!(self.poll_next_entry(cx)) {
342 let key = self.entries[idx].0.clone();
343 Poll::Ready(Some((key, val)))
344 } else {
345 Poll::Ready(None)
346 }
347 }
348
349 fn size_hint(&self) -> (usize, Option<usize>) {
350 let mut lo: usize = 0;
351 let mut hi: Option<usize> = Some(0);
352 for (_, stream) in &self.entries {
353 let (a, b) = stream.size_hint();
354 lo = lo.saturating_add(a);
355 match (hi, b) {
356 (Some(x), Some(y)) => hi = x.checked_add(y),
357 (Some(_), None) => hi = None,
358 _ => {}
359 }
360 }
361 (lo, hi)
362 }
363}
364
365impl<K, V> FromIterator<(K, V)> for StreamMap<K, V>
366where
367 K: Hash + Eq + Clone,
368{
369 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
370 let iter = iter.into_iter();
371 let (lo, _) = iter.size_hint();
372 let mut map = Self::with_capacity(lo);
373 for (k, v) in iter {
374 map.insert(k, v);
375 }
376 map
377 }
378}
379
380impl<K, V> Extend<(K, V)> for StreamMap<K, V>
381where
382 K: Hash + Eq + Clone,
383{
384 fn extend<T>(&mut self, iter: T)
385 where
386 T: IntoIterator<Item = (K, V)>,
387 {
388 for (k, v) in iter {
390 self.insert(k, v);
391 }
392 }
393}