Auto merge of #48587 - Zoxc:transitive-relation, r=nikomatsakis

Make TransitiveRelation thread safe. Avoid locking by using get_mut in some cases

r? @nikomatsakis
This commit is contained in:
bors 2018-03-04 09:41:32 +00:00
commit 9ff5cb5aea

View File

@ -10,16 +10,16 @@
use bitvec::BitMatrix;
use fx::FxHashMap;
use sync::Lock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use stable_hasher::{HashStable, StableHasher, StableHasherResult};
use std::cell::RefCell;
use std::fmt::Debug;
use std::hash::Hash;
use std::mem;
#[derive(Clone, Debug)]
pub struct TransitiveRelation<T: Clone + Debug + Eq + Hash + Clone> {
pub struct TransitiveRelation<T: Clone + Debug + Eq + Hash> {
// List of elements. This is used to map from a T to a usize.
elements: Vec<T>,
@ -32,14 +32,14 @@ pub struct TransitiveRelation<T: Clone + Debug + Eq + Hash + Clone> {
// This is a cached transitive closure derived from the edges.
// Currently, we build it lazilly and just throw out any existing
// copy whenever a new edge is added. (The RefCell is to permit
// copy whenever a new edge is added. (The Lock is to permit
// the lazy computation.) This is kind of silly, except for the
// fact its size is tied to `self.elements.len()`, so I wanted to
// wait before building it up to avoid reallocating as new edges
// are added with new elements. Perhaps better would be to ask the
// user for a batch of edges to minimize this effect, but I
// already wrote the code this way. :P -nmatsakis
closure: RefCell<Option<BitMatrix>>,
closure: Lock<Option<BitMatrix>>,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
@ -51,13 +51,13 @@ struct Edge {
target: Index,
}
impl<T: Clone + Debug + Eq + Hash + Clone> TransitiveRelation<T> {
impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
pub fn new() -> TransitiveRelation<T> {
TransitiveRelation {
elements: vec![],
map: FxHashMap(),
edges: vec![],
closure: RefCell::new(None),
closure: Lock::new(None),
}
}
@ -72,7 +72,7 @@ impl<T: Clone + Debug + Eq + Hash + Clone> TransitiveRelation<T> {
fn add_index(&mut self, a: T) -> Index {
let &mut TransitiveRelation {
ref mut elements,
ref closure,
ref mut closure,
ref mut map,
..
} = self;
@ -82,7 +82,7 @@ impl<T: Clone + Debug + Eq + Hash + Clone> TransitiveRelation<T> {
elements.push(a);
// if we changed the dimensions, clear the cache
*closure.borrow_mut() = None;
*closure.get_mut() = None;
Index(elements.len() - 1)
})
@ -122,7 +122,7 @@ impl<T: Clone + Debug + Eq + Hash + Clone> TransitiveRelation<T> {
self.edges.push(edge);
// added an edge, clear the cache
*self.closure.borrow_mut() = None;
*self.closure.get_mut() = None;
}
}
@ -443,7 +443,7 @@ impl<T> Decodable for TransitiveRelation<T>
.enumerate()
.map(|(index, elem)| (elem.clone(), Index(index)))
.collect();
Ok(TransitiveRelation { elements, edges, map, closure: RefCell::new(None) })
Ok(TransitiveRelation { elements, edges, map, closure: Lock::new(None) })
})
}
}