Skip to main content

dope_core/driver/settings/
routes.rs

1use crate::driver::route;
2
3/// Words in one route set; its bit count equals the complete route namespace.
4const WORDS: usize = 4;
5
6/// The non-framework route identities owned by one component or topology.
7#[derive(Clone, Copy, Default, PartialEq, Eq)]
8pub struct Routes([u64; WORDS]);
9
10impl Routes {
11    pub const EMPTY: Self = Self([0; WORDS]);
12
13    /// Builds the route set holding exactly one application identity.
14    pub const fn singleton<T: route::App>() -> Self {
15        Self::singleton_id(T::ID)
16    }
17
18    /// Builds a route set from a value-level ID for generated aggregates.
19    pub const fn singleton_id(id: route::Id) -> Self {
20        let mut words = [0; WORDS];
21        let word = id.raw() as usize / u64::BITS as usize;
22        let bit = id.raw() as usize % u64::BITS as usize;
23        words[word] |= 1u64 << bit;
24        Self(words)
25    }
26
27    #[must_use]
28    pub const fn has_route(self, route: route::Route) -> bool {
29        let Some(id) = route.app() else {
30            return false;
31        };
32        let word = id.raw() as usize / u64::BITS as usize;
33        let bit = id.raw() as usize % u64::BITS as usize;
34        self.0[word] & (1u64 << bit) != 0
35    }
36
37    /// Finds an overlapping identity inside the complete, u8-bounded route bitset.
38    pub(in crate::driver::settings) const fn overlap(self, other: Self) -> Option<route::Id> {
39        const { assert!(WORDS * (u64::BITS as usize) == route::CAPACITY) };
40        let mut word = 0;
41        while word < WORDS {
42            let overlap = self.0[word] & other.0[word];
43            if overlap != 0 {
44                let base = (word as u8) * (u64::BITS as u8);
45                return route::Route::from_bits(base + overlap.trailing_zeros() as u8).app();
46            }
47            word += 1;
48        }
49        None
50    }
51
52    /// Joins application route ownership as an idempotent set union.
53    pub const fn join(self, other: Self) -> Self {
54        Self([
55            self.0[0] | other.0[0],
56            self.0[1] | other.0[1],
57            self.0[2] | other.0[2],
58            self.0[3] | other.0[3],
59        ])
60    }
61}