1use std::borrow::Borrow;
2use std::future::Future;
3use std::hash::{Hash, BuildHasher};
4use std::pin::Pin;
5use std::task::{Context, Poll};
6
7use dashmap::DashMap;
8
9use crate::WaitEntry;
10use crate::WaitEntry::*;
11use crate::{Ref, RefMut};
12
13pub struct Wait<'a, 'b, K, V, S, Q> where
14 K: Hash + Eq + Borrow<Q>,
15 S: BuildHasher + Clone,
16 Q: ?Sized + Hash + Eq,
17{
18 map: &'a DashMap<K, WaitEntry<V>, S>,
19 key: &'b Q,
20 idx: usize,
21}
22
23impl<'a, 'b, K, V, S, Q> Wait<'a, 'b, K, V, S, Q> where
24 K: Hash + Eq + Borrow<Q>,
25 S: BuildHasher + Clone,
26 Q: ?Sized + Hash + Eq,
27{
28 pub(crate) fn new(map: &'a DashMap<K, WaitEntry<V>, S>, key: &'b Q) -> Self {
29 Wait { map, key, idx: std::usize::MAX }
30 }
31}
32
33impl<'a, 'b, K, V, S, Q> Future for Wait<'a, 'b, K, V, S, Q> where
34 K: Hash + Eq + Borrow<Q>,
35 S: BuildHasher + Clone,
36 Q: ?Sized + Hash + Eq,
37{
38 type Output = Option<Ref<'a, K, V, S>>;
39
40 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
41 match self.map.get_mut(self.key) {
42 Some(mut entry) => match entry.value_mut() {
43 Waiting(wakers) => {
44 wakers.replace(ctx.waker().clone(), &mut self.idx);
45 Poll::Pending
46 }
47 Filled(_) => {
48 let inner = entry.downgrade();
49 self.idx = std::usize::MAX;
50 Poll::Ready(Some(Ref { inner }))
51 }
52 }
53 None => Poll::Ready(None),
54 }
55 }
56}
57
58impl<'a, 'b, K, V, S, Q> Drop for Wait<'a, 'b, K, V, S, Q> where
59 K: Hash + Eq + Borrow<Q>,
60 S: BuildHasher + Clone,
61 Q: ?Sized + Hash + Eq,
62{
63 fn drop(&mut self) {
64 if self.idx == std::usize::MAX { return; }
65 if let Some(mut entry) = self.map.get_mut(self.key) {
66 if let Waiting(wakers) = entry.value_mut() {
67 wakers.remove(self.idx);
68 }
69 }
70 }
71}
72
73pub struct WaitMut<'a, 'b, K, V, S, Q> where
74 K: Hash + Eq + Borrow<Q>,
75 S: BuildHasher + Clone,
76 Q: ?Sized + Hash + Eq,
77{
78 map: &'a DashMap<K, WaitEntry<V>, S>,
79 key: &'b Q,
80 idx: usize,
81}
82
83impl<'a, 'b, K, V, S, Q> WaitMut<'a, 'b, K, V, S, Q> where
84 K: Hash + Eq + Borrow<Q>,
85 S: BuildHasher + Clone,
86 Q: ?Sized + Hash + Eq,
87{
88 pub(crate) fn new(map: &'a DashMap<K, WaitEntry<V>, S>, key: &'b Q) -> Self {
89 WaitMut { map, key, idx: std::usize::MAX }
90 }
91}
92
93impl<'a, 'b, K, V, S, Q> Future for WaitMut<'a, 'b, K, V, S, Q> where
94 K: Hash + Eq + Borrow<Q>,
95 S: BuildHasher + Clone,
96 Q: ?Sized + Hash + Eq,
97{
98 type Output = Option<RefMut<'a, K, V, S>>;
99
100 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
101 match self.map.get_mut(self.key) {
102 Some(mut entry) => match entry.value_mut() {
103 Waiting(wakers) => {
104 wakers.replace(ctx.waker().clone(), &mut self.idx);
105 Poll::Pending
106 }
107 Filled(_) => {
108 self.idx = std::usize::MAX;
109 Poll::Ready(Some(RefMut { inner: entry }))
110 }
111 }
112 None => Poll::Ready(None),
113 }
114 }
115}
116
117impl<'a, 'b, K, V, S, Q> Drop for WaitMut<'a, 'b, K, V, S, Q> where
118 K: Hash + Eq + Borrow<Q>,
119 S: BuildHasher + Clone,
120 Q: ?Sized + Hash + Eq,
121{
122 fn drop(&mut self) {
123 if self.idx == std::usize::MAX { return; }
124 if let Some(mut entry) = self.map.get_mut(self.key) {
125 if let Waiting(wakers) = entry.value_mut() {
126 wakers.remove(self.idx);
127 }
128 }
129 }
130}