From d037e221643a500dcd2f9ee89c6b6484ed0b24ae Mon Sep 17 00:00:00 2001 From: paladin Date: Fri, 2 Oct 2026 10:02:13 +0100 Subject: [PATCH] Break up library into macros and map nested libraries for shared dependency with constant map macro. --- .gitignore | 2 +- Cargo.toml | 6 +++- macros/Cargo.toml | 16 ++++++++++ macros/src/lib.rs | 19 ++++++++++++ map/Cargo.toml | 6 ++++ src/map.rs => map/src/lib.rs | 57 ++++++++++++++---------------------- src/gc.rs | 19 +++++++++++- src/lib.rs | 2 +- 8 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 macros/Cargo.toml create mode 100644 macros/src/lib.rs create mode 100644 map/Cargo.toml rename src/map.rs => map/src/lib.rs (91%) diff --git a/.gitignore b/.gitignore index 3a8cabc..c507849 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -/target +target .idea diff --git a/Cargo.toml b/Cargo.toml index 05d2d35..c4d9815 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,8 @@ edition = "2024" [features] bighash = [] assertions = [] -messages = [] \ No newline at end of file +messages = [] + +[dependencies] +macros = { path = "macros" } +map = { path = "map" } \ No newline at end of file diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 0000000..f4df0bf --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "macros" +version = "0.0.0" +authors = ["paladin "] +description = "Procedural macros for Deimos" +keywords = ["template", "proc_macro", "procmacro"] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1" +proc-macro2 = "1.0" +syn = "1.0" +map = { path = "../map" } \ No newline at end of file diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 0000000..41edcd1 --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,19 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +use syn::{parse_macro_input, DeriveInput}; +use quote::quote; + +/// Example of [function-like procedural macro][1]. +/// +/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros +#[proc_macro] +pub fn map(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + let tokens = quote! { + const + }; + + tokens.into() +} \ No newline at end of file diff --git a/map/Cargo.toml b/map/Cargo.toml new file mode 100644 index 0000000..88e4b56 --- /dev/null +++ b/map/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "map" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/src/map.rs b/map/src/lib.rs similarity index 91% rename from src/map.rs rename to map/src/lib.rs index 583a47d..063c53e 100644 --- a/src/map.rs +++ b/map/src/lib.rs @@ -18,7 +18,6 @@ Notes: - Values would only need to be shuffled around closer to their 'home' during a resize. - It is unlikely the displacement would large value without a resize amending that problem. */ -use crate::gc::{AnyId, Id}; use std::fmt::Debug; use std::hash::{DefaultHasher, Hash, Hasher}; @@ -51,22 +50,6 @@ impl Hashes for &str { } } -impl Hashes for Id { - fn hashed(&self) -> Hashed { - let mut hasher = DefaultHasher::new(); - self.index.hash(&mut hasher); - hasher.finish() as Hashed - } -} - -impl Hashes for AnyId { - fn hashed(&self) -> Hashed { - let mut hasher = DefaultHasher::new(); - self.index.hash(&mut hasher); - hasher.finish() as Hashed - } -} - pub trait TableEntry: Equivalent + Hashes { const VACANT: Self; fn is_vacant(&self) -> bool; @@ -95,6 +78,25 @@ pub struct DisplacementSet { map_count: usize, // number of elements in table } +pub fn get ,K: Hashes>(map: &[Entry], index: K) -> Option<&E> { + if map.len() == 0 { + return None; + } + let location = index.hashed() as usize % map.len(); + let home = &map[location]; + if home.entry.matches(&index) { + Some(&home.entry) + } else { + for i in 1..home.displacement as usize { + let neighbour = &map[(location + i) % map.len()]; + if neighbour.entry.matches(&index) { + return Some(&neighbour.entry); + } + } + None + } +} + impl DisplacementSet { fn exchange(&mut self, len: usize) { let old = std::mem::replace( @@ -202,8 +204,8 @@ impl DisplacementSet { } pub fn remove(&mut self, index: K) where - E: Equivalent, - K: Hashes, + E: Equivalent, + K: Hashes, { if self.map.len() == 0 { return; @@ -265,22 +267,7 @@ impl DisplacementSet { E: Equivalent, K: Hashes, { - if self.map.len() == 0 { - return None; - } - let location = index.hashed() as usize % self.map.len(); - let home = &self.map[location]; - if home.entry.matches(&index) { - Some(&home.entry) - } else { - for i in 1..home.displacement as usize { - let neighbour = &self.map[(location + i) % self.map.len()]; - if neighbour.entry.matches(&index) { - return Some(&neighbour.entry); - } - } - None - } + get(self.map.as_slice(),index) } pub fn new() -> DisplacementSet { DisplacementSet { diff --git a/src/gc.rs b/src/gc.rs index 73b3068..046101c 100644 --- a/src/gc.rs +++ b/src/gc.rs @@ -1,6 +1,7 @@ -use std::hash::{Hash, Hasher}; +use std::hash::{DefaultHasher, Hash, Hasher}; use std::marker::{PhantomData}; use std::ops::{Deref, DerefMut}; +use map::{Hashed, Hashes}; type Index = u32; @@ -288,3 +289,19 @@ pub trait Traverse: Sized { fn traverse(id: &Id, context: &mut C); fn collect(self); } + +impl Hashes for Id { + fn hashed(&self) -> Hashed { + let mut hasher = DefaultHasher::new(); + self.index.hash(&mut hasher); + hasher.finish() as Hashed + } +} + +impl Hashes for AnyId { + fn hashed(&self) -> Hashed { + let mut hasher = DefaultHasher::new(); + self.index.hash(&mut hasher); + hasher.finish() as Hashed + } +} diff --git a/src/lib.rs b/src/lib.rs index c321a90..6d83946 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ pub mod gc; -pub mod map; +pub use macros; #[cfg(test)] mod tests { #[test]