diff --git a/backend/common/src/assign_id.rs b/backend/common/src/assign_id.rs index ea35dca..1bcd42f 100644 --- a/backend/common/src/assign_id.rs +++ b/backend/common/src/assign_id.rs @@ -1,10 +1,13 @@ use bimap::BiMap; use std::hash::Hash; -/// A struct that allows you to assign an ID to an arbitrary set of +/// A struct that allows you to assign an Id to an arbitrary set of /// details (so long as they are Eq+Hash+Clone), and then access -/// the assigned ID given those details or access the details given -/// the ID. +/// the assigned Id given those details or access the details given +/// the Id. +/// +/// The Id can be any type that's convertible to/from a `usize`. Using +/// a custom type is recommended for increased type safety. #[derive(Debug)] pub struct AssignId { current_id: usize, diff --git a/backend/common/src/dense_map.rs b/backend/common/src/dense_map.rs index f1fe33b..edc267f 100644 --- a/backend/common/src/dense_map.rs +++ b/backend/common/src/dense_map.rs @@ -1,3 +1,12 @@ +/// This stores items in contiguous memory, making a note of free +/// slots when items are removed again so that they can be reused. +/// +/// This is particularly efficient when items are often added and +/// seldom removed. +/// +/// Items are keyed by an Id, which can be any type you wish, but +/// must be convertible to/from a `usize`. This promotes using a +/// custom Id type to talk about items in the map. pub struct DenseMap { /// List of retired indexes that can be re-used retired: Vec, diff --git a/backend/common/src/id_type.rs b/backend/common/src/id_type.rs index 669fed6..d3165a5 100644 --- a/backend/common/src/id_type.rs +++ b/backend/common/src/id_type.rs @@ -2,7 +2,7 @@ /// and serialized/deserialized transparently into the inner type. #[macro_export] macro_rules! id_type { - ($( #[$attrs:meta] )* $vis:vis $ty:ident ( $inner:ident ) $(;)? ) => { + ($( #[$attrs:meta] )* $vis:vis struct $ty:ident ( $inner:ident ) $(;)? ) => { #[derive(Debug,Clone,Copy,PartialEq,Eq,Hash)] $( #[$attrs] )* $vis struct $ty($inner); @@ -30,26 +30,45 @@ macro_rules! id_type { #[cfg(test)] mod test { + //! Mostly we're just checking that everything compiles OK + //! when the macro is used as expected.. + + // A basic definition is possible: + id_type! { + struct Foo(usize) + } + + // We can add a ';' on the end: + id_type! { + struct Bar(usize); + } + + // Visibility qualifiers are allowed: + id_type! { + pub struct Wibble(u64) + } + + // Doc strings are possible + id_type! { + /// We can have doc strings, too + pub(crate) struct Wobble(u16) + } + + // In fact, any attributes can be added (common + // derives are added already): + id_type! { + /// We can have doc strings, too + #[derive(serde::Serialize)] + #[serde(transparent)] + pub(crate) struct Lark(u16) + } #[test] fn create_and_use_new_id_type() { - id_type! { - Foo(usize) - }; let _ = Foo::new(123); let id = Foo::from(123); - let _: usize = id.into(); + let id_num: usize = id.into(); - // Check that these don't lead to compile errors: - id_type! { - Bar(usize); - }; - id_type! { - pub Wibble(u64) - }; - id_type! { - /// We can have doc strings, too - pub(crate) Wobble(u16) - }; + assert_eq!(id_num, 123); } } diff --git a/backend/common/src/internal_messages.rs b/backend/common/src/internal_messages.rs index f111174..b6a2330 100644 --- a/backend/common/src/internal_messages.rs +++ b/backend/common/src/internal_messages.rs @@ -9,7 +9,7 @@ id_type! { /// The shard-local ID of a given node, where a single connection /// might send data on behalf of more than one chain. #[derive(serde::Serialize, serde::Deserialize)] - pub ShardNodeId(usize); + pub struct ShardNodeId(usize); } /// Message sent from the shard to the backend core diff --git a/backend/telemetry/src/aggregator/aggregator.rs b/backend/telemetry/src/aggregator/aggregator.rs index a8ae177..e04a419 100644 --- a/backend/telemetry/src/aggregator/aggregator.rs +++ b/backend/telemetry/src/aggregator/aggregator.rs @@ -12,7 +12,7 @@ id_type! { /// A unique Id is assigned per websocket connection (or more accurately, /// per feed socket and per shard socket). This can be combined with the /// [`LocalId`] of messages to give us a global ID. - pub ConnId(u64) + pub struct ConnId(u64) } #[derive(Clone)] diff --git a/backend/telemetry/src/state/chain.rs b/backend/telemetry/src/state/chain.rs index 5a00ee7..08ee985 100644 --- a/backend/telemetry/src/state/chain.rs +++ b/backend/telemetry/src/state/chain.rs @@ -12,7 +12,7 @@ use super::node::Node; id_type! { /// A Node ID that is unique to the chain it's in. - pub ChainNodeId(usize) + pub struct ChainNodeId(usize) } pub type Label = Box; diff --git a/backend/telemetry/src/state/state.rs b/backend/telemetry/src/state/state.rs index 5ae06c7..f1ac6bc 100644 --- a/backend/telemetry/src/state/state.rs +++ b/backend/telemetry/src/state/state.rs @@ -11,7 +11,7 @@ use super::chain::{self, Chain, ChainNodeId}; id_type! { /// A globally unique Chain ID. - pub ChainId(usize) + pub struct ChainId(usize) } /// A "global" Node ID is a composite of the ID of the chain it's