Skip to content

Commit

Permalink
Make TransitiveRelation thread safe. Avoid locking by using get_mut i…
Browse files Browse the repository at this point in the history
…n some cases.
  • Loading branch information
Zoxc committed Feb 27, 2018
1 parent 29f5c69 commit 89e55d1
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/librustc_data_structures/transitive_relation.rs
Expand Up @@ -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>,

Expand All @@ -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)]
Expand All @@ -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),
}
}

Expand All @@ -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;
Expand All @@ -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)
})
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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) })
})
}
}
Expand Down

0 comments on commit 89e55d1

Please sign in to comment.