Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created November 24, 2021 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snoyberg/c316c36eb73845731e00774e1d509965 to your computer and use it in GitHub Desktop.
Save snoyberg/c316c36eb73845731e00774e1d509965 to your computer and use it in GitHub Desktop.
Ouroboros append set
#![feature(hash_set_entry)]
use ouroboros::self_referencing;
use crate::append_set::AppendSet;
mod append_set {
use std::collections::HashSet;
use parking_lot::Mutex;
#[derive(Default)]
pub struct AppendSet<T>(Mutex<HashSet<T>>);
impl<T> AppendSet<T>
where
T: std::hash::Hash + Eq,
{
pub fn append(&self, value: T) -> &T {
let mut guard = self.0.lock();
let value_ref = guard.get_or_insert(value);
let value_ptr: *const T = &*value_ref;
unsafe { &*value_ptr }
}
}
}
#[self_referencing]
struct People {
names: AppendSet<String>,
#[borrows(names)]
#[covariant]
people: Vec<Person<'this>>,
}
#[derive(Debug)]
struct WastefulPerson {
first: String,
last: String,
}
#[derive(Debug)]
struct Person<'a> {
first: &'a str,
last: &'a str,
}
fn main() {
let wasteful_people = vec![
WastefulPerson {
first: "Alice".to_owned(),
last: "Smith".to_owned(),
},
WastefulPerson {
first: "Bob".to_owned().into(),
last: "Smith".to_owned().into(),
},
WastefulPerson {
first: "Charlie".to_owned(),
last: "Smith".to_owned(),
},
];
println!("{:?}", wasteful_people);
let people = People::new(AppendSet::default(), |names| {
wasteful_people
.into_iter()
.map(|person| Person {
first: names.append(person.first),
last: names.append(person.last),
})
.collect()
});
println!("{:?}", people.borrow_people());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment