Break up library into macros and map nested libraries for shared dependency with constant map macro.

This commit is contained in:
paladin 2026-10-02 10:02:13 +01:00
parent 805874a4c1
commit d037e22164
8 changed files with 88 additions and 39 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
/target target
.idea .idea

View file

@ -7,3 +7,7 @@ edition = "2024"
bighash = [] bighash = []
assertions = [] assertions = []
messages = [] messages = []
[dependencies]
macros = { path = "macros" }
map = { path = "map" }

16
macros/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "macros"
version = "0.0.0"
authors = ["paladin <christian.lincoln25@ic.ac.uk>"]
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" }

19
macros/src/lib.rs Normal file
View file

@ -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()
}

6
map/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "map"
version = "0.1.0"
edition = "2024"
[dependencies]

View file

@ -18,7 +18,6 @@ Notes:
- Values would only need to be shuffled around closer to their 'home' during a resize. - 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. - 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::fmt::Debug;
use std::hash::{DefaultHasher, Hash, Hasher}; use std::hash::{DefaultHasher, Hash, Hasher};
@ -51,22 +50,6 @@ impl Hashes for &str {
} }
} }
impl<T> Hashes for Id<T> {
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<Self> + Hashes { pub trait TableEntry: Equivalent<Self> + Hashes {
const VACANT: Self; const VACANT: Self;
fn is_vacant(&self) -> bool; fn is_vacant(&self) -> bool;
@ -95,6 +78,25 @@ pub struct DisplacementSet<E: TableEntry> {
map_count: usize, // number of elements in table map_count: usize, // number of elements in table
} }
pub fn get<E: TableEntry + Equivalent<K> ,K: Hashes>(map: &[Entry<E>], 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<E: TableEntry> DisplacementSet<E> { impl<E: TableEntry> DisplacementSet<E> {
fn exchange(&mut self, len: usize) { fn exchange(&mut self, len: usize) {
let old = std::mem::replace( let old = std::mem::replace(
@ -202,8 +204,8 @@ impl<E: TableEntry> DisplacementSet<E> {
} }
pub fn remove<K>(&mut self, index: K) pub fn remove<K>(&mut self, index: K)
where where
E: Equivalent<K>, E: Equivalent<K>,
K: Hashes, K: Hashes,
{ {
if self.map.len() == 0 { if self.map.len() == 0 {
return; return;
@ -265,22 +267,7 @@ impl<E: TableEntry> DisplacementSet<E> {
E: Equivalent<K>, E: Equivalent<K>,
K: Hashes, K: Hashes,
{ {
if self.map.len() == 0 { get(self.map.as_slice(),index)
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
}
} }
pub fn new() -> DisplacementSet<E> { pub fn new() -> DisplacementSet<E> {
DisplacementSet { DisplacementSet {

View file

@ -1,6 +1,7 @@
use std::hash::{Hash, Hasher}; use std::hash::{DefaultHasher, Hash, Hasher};
use std::marker::{PhantomData}; use std::marker::{PhantomData};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use map::{Hashed, Hashes};
type Index = u32; type Index = u32;
@ -288,3 +289,19 @@ pub trait Traverse<C>: Sized {
fn traverse(id: &Id<Self>, context: &mut C); fn traverse(id: &Id<Self>, context: &mut C);
fn collect(self); fn collect(self);
} }
impl<T> Hashes for Id<T> {
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
}
}

View file

@ -1,5 +1,5 @@
pub mod gc; pub mod gc;
pub mod map; pub use macros;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]