synthphonia/forward/data/
len.rs

1
2use std::{
3    cell::UnsafeCell, collections::{hash_map}, hash::Hash, ops::Index, task::Poll
4};
5
6use derive_more::{Constructor, Deref, From, Into, TryInto};
7use futures::StreamExt;
8use itertools::Itertools;
9use simple_rc_async::sync::broadcast;
10
11use crate::{
12    debg, expr::Expr, forward::executor::Executor, galloc::AllocForAny, info, log, utils::UnsafeCellExt, value::Value
13};
14
15/// Term Dispatcher for length
16pub struct Data {
17    found: HashMap<Vec<usize>, Vec<Value>>,
18    event: HashMap<Vec<usize>, broadcast::Sender<Value>>,
19    len_limit: usize,
20}
21
22use ahash::AHashMap as HashMap;
23
24
25impl Default for Data {
26    fn default() -> Self {
27        Self::new()
28    }
29}
30
31impl Data {
32    pub fn new() -> Self { Data{ found: HashMap::new(), event: HashMap::new(), len_limit: 3 } }
33    #[inline]
34    pub fn update(&mut self, value: Value, exec: &'static Executor) {
35        if exec.size() > self.len_limit { return; }
36        if !matches!(value, Value::ListStr(_)) { return; }
37        let s: &[&[&str]] = value.try_into().unwrap();
38        let a = value.length_inside().unwrap();
39        if let Some(chan) =  self.event.get(&a) {
40            chan.send(value);
41        }
42        match self.found.entry(a.clone()) {
43            hash_map::Entry::Occupied(mut o) => { o.get_mut().push(value); }
44            hash_map::Entry::Vacant(v) => { v.insert(vec![value]); }
45        }
46    }
47    pub fn listen_at(&mut self, v: Vec<usize>) -> broadcast::Reciever<Value> {
48        match self.event.entry(v) {
49            hash_map::Entry::Occupied(o) => o.get().reciever(),
50            hash_map::Entry::Vacant(v) => v.insert(broadcast::channel()).reciever(),
51        }
52    }
53    #[inline(always)]
54    pub async fn listen_for_each<T>(&mut self, value: Vec<usize>, mut f: impl FnMut(Value) -> Option<T>) -> T {
55        if let Some(vec) = self.found.get(&value) {
56            for v in vec {
57                if let Some(t) = f(*v) { return t; }
58            }
59        }
60
61        let mut rv = self.listen_at(value);
62        loop {
63            if let Some(t) = f(rv.next().await.unwrap()) { return t; }
64        }
65    }
66    #[inline(always)]
67    pub async fn listen_once(&mut self, value: Value) -> Value {
68        let v = value.length_inside().unwrap();
69
70        if let Some(vec) = self.found.get(&v) {
71            if let Some(v) = vec.first() {
72                return *v;
73            }
74        }
75
76        self.listen_at(v).next().await.unwrap()
77    }
78}