Created
March 7, 2021 21:25
-
-
Save cswiercz/597b28a3064940e7cd073c4dcf3ff186 to your computer and use it in GitHub Desktop.
Shared memory access in random cut trees
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// A forest contains a collection of trees and a shared storage for | |
/// points in the tree. However, each of the trees need to mutably access | |
/// the point store. For convenience, the trees are initialized using a | |
/// pointer to the shared point store. | |
/// | |
/// This code shows one way to perform this two-way mutable share where the | |
/// forest owns all of the constituent data structures. | |
/// | |
/// * Rc: allows multiple (reference counted) pointers to a type | |
/// * RefCell: wraps the type in a mechanism that allows mutation through | |
/// shared references. | |
/// | |
/// Rc.clone() does not clone the data but, rather, produces a new pointer to | |
/// the same heap allocation. The Rc type tracks how many references are still | |
/// in scope. | |
/// | |
use std::cell::RefCell; | |
use std::collections::HashMap; | |
use std::rc::Rc; | |
type PointStore<T> = HashMap<usize,Vec<T>>; | |
#[derive(Debug)] | |
struct Tree<T> { | |
id: usize, | |
point_store: Rc<RefCell<PointStore<T>>>, | |
} | |
impl<T> Tree<T> { | |
fn new(id: usize, point_store: Rc<RefCell<PointStore<T>>>) -> Self { | |
Tree { | |
id: id, | |
point_store: point_store, | |
} | |
} | |
fn add_point(&mut self, index: usize, point: Vec<T>) { | |
self.point_store.borrow_mut().insert(index, point); | |
} | |
fn delete_point(&mut self, index: &usize) { | |
self.point_store.borrow_mut().remove(index); | |
} | |
} | |
#[derive(Debug)] | |
struct Forest<T> { | |
point_store: Rc<RefCell<PointStore<T>>>, | |
trees: Vec<Tree<T>>, | |
} | |
impl<T> Forest<T> { | |
fn new(num_trees: usize) -> Self { | |
let point_store = Rc::new(RefCell::new(PointStore::new())); | |
let trees = (0..num_trees).map(|i| Tree::new(i, point_store.clone())).collect(); | |
Forest { | |
point_store: point_store.clone(), | |
trees: trees, | |
} | |
} | |
} | |
fn main() { | |
let mut forest = Forest::<f32>::new(2); | |
println!("Point Store: {:?}", forest.point_store); | |
{ | |
for tree in forest.trees.iter_mut() { | |
tree.add_point(tree.id, vec![tree.id as f32, 0.0]); | |
} | |
} | |
println!("Point Store: {:?}", forest.point_store); | |
{ | |
for tree in forest.trees.iter_mut() { | |
let index = tree.id; | |
tree.delete_point(&index); | |
} | |
} | |
println!("Point Store: {:?}", forest.point_store); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment