mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-12 08:36:03 +00:00
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:
commit
9ff5cb5aea
@ -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) })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user