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
|
||||
|
|
|
|||
|
|
@ -6,4 +6,8 @@ edition = "2024"
|
|||
[features]
|
||||
bighash = []
|
||||
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.
|
||||
- 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<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 {
|
||||
const VACANT: Self;
|
||||
fn is_vacant(&self) -> bool;
|
||||
|
|
@ -95,6 +78,25 @@ pub struct DisplacementSet<E: TableEntry> {
|
|||
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> {
|
||||
fn exchange(&mut self, len: usize) {
|
||||
let old = std::mem::replace(
|
||||
|
|
@ -202,8 +204,8 @@ impl<E: TableEntry> DisplacementSet<E> {
|
|||
}
|
||||
pub fn remove<K>(&mut self, index: K)
|
||||
where
|
||||
E: Equivalent<K>,
|
||||
K: Hashes,
|
||||
E: Equivalent<K>,
|
||||
K: Hashes,
|
||||
{
|
||||
if self.map.len() == 0 {
|
||||
return;
|
||||
|
|
@ -265,22 +267,7 @@ impl<E: TableEntry> DisplacementSet<E> {
|
|||
E: Equivalent<K>,
|
||||
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<E> {
|
||||
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::ops::{Deref, DerefMut};
|
||||
use map::{Hashed, Hashes};
|
||||
|
||||
type Index = u32;
|
||||
|
||||
|
|
@ -288,3 +289,19 @@ pub trait Traverse<C>: Sized {
|
|||
fn traverse(id: &Id<Self>, context: &mut C);
|
||||
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 map;
|
||||
pub use macros;
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue