Skip to main content

yog_event/
address.rs

1//! Addresses as numbers. An address is its name's atom (`yog_data::Atom`):
2//! the same number in every binary of the process — the runtime, each mod,
3//! the host's Java. A message type keeps its own once it's resolved, so a
4//! call after the first passes a number, no string looked up.
5
6use yog_sync::atomic::{AtomicU32, Ordering};
7
8/// An address: its name's atom number.
9pub type Address = u32;
10
11/// No address: what an empty name resolves to (`yog_abi::NO_ADDRESS`).
12pub const NO_ADDRESS: Address = u32::MAX;
13
14/// `name`'s address.
15pub fn resolve(name: &str) -> Address {
16    if name.is_empty() {
17        NO_ADDRESS
18    } else {
19        yog_data::Atom::new(name).number()
20    }
21}
22
23/// A message type's address, resolved the first time it's asked for.
24pub struct Cached(AtomicU32);
25
26impl Cached {
27    /// Not resolved yet ([`NO_ADDRESS`] is never cached: it costs nothing to resolve).
28    const UNSET: u32 = NO_ADDRESS;
29
30    pub const fn new() -> Self {
31        Cached(AtomicU32::new(Self::UNSET))
32    }
33
34    /// `name`'s address (always the same name for this cache).
35    pub fn get(&self, name: &str) -> Address {
36        let n = self.0.load(Ordering::Relaxed);
37        if n != Self::UNSET {
38            return n;
39        }
40        let n = resolve(name);
41        self.0.store(n, Ordering::Relaxed);
42        n
43    }
44}
45
46impl Default for Cached {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52/// Where a message goes: its own address (cached), or for a key its
53/// branch's, resolved each time.
54pub(crate) fn of(cached: &Cached, address: &'static str, key: Option<&str>) -> Address {
55    match key {
56        None => cached.get(address),
57        Some(key) => resolve(&crate::keyed(address, key)),
58    }
59}