Break up library into macros and map nested libraries for shared dependency with constant map macro.
This commit is contained in:
parent
805874a4c1
commit
d037e22164
8 changed files with 88 additions and 39 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +1,2 @@
|
||||||
/target
|
target
|
||||||
.idea
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,8 @@ edition = "2024"
|
||||||
[features]
|
[features]
|
||||||
bighash = []
|
bighash = []
|
||||||
assertions = []
|
assertions = []
|
||||||
messages = []
|
messages = []
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
macros = { path = "macros" }
|
||||||
|
map = { path = "map" }
|
||||||
16
macros/Cargo.toml
Normal file
16
macros/Cargo.toml
Normal 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
19
macros/src/lib.rs
Normal 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
6
map/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "map"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
@ -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 {
|
||||||
19
src/gc.rs
19
src/gc.rs
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue