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}