
Since it's inception a long time ago, the parallel compiler and its cfgs have been a maintenance burden. This was a necessary evil the allow iteration while not degrading performance because of synchronization overhead. But this time is over. Thanks to the amazing work by the parallel working group (and the dyn sync crimes), the parallel compiler has now been fast enough to be shipped by default in nightly for quite a while now. Stable and beta have still been on the serial compiler, because they can't use `-Zthreads` anyways. But this is quite suboptimal: - the maintenance burden still sucks - we're not testing the serial compiler in nightly Because of these reasons, it's time to end it. The serial compiler has served us well in the years since it was split from the parallel one, but it's over now. Let the knight slay one head of the two-headed dragon!
74 lines
1.7 KiB
Rust
74 lines
1.7 KiB
Rust
use std::marker::PhantomData;
|
|
|
|
use rustc_index::Idx;
|
|
|
|
#[derive(Default)]
|
|
pub struct AppendOnlyIndexVec<I: Idx, T: Copy> {
|
|
vec: elsa::sync::LockFreeFrozenVec<T>,
|
|
_marker: PhantomData<fn(&I)>,
|
|
}
|
|
|
|
impl<I: Idx, T: Copy> AppendOnlyIndexVec<I, T> {
|
|
pub fn new() -> Self {
|
|
Self { vec: elsa::sync::LockFreeFrozenVec::new(), _marker: PhantomData }
|
|
}
|
|
|
|
pub fn push(&self, val: T) -> I {
|
|
let i = self.vec.push(val);
|
|
I::new(i)
|
|
}
|
|
|
|
pub fn get(&self, i: I) -> Option<T> {
|
|
let i = i.index();
|
|
self.vec.get(i)
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct AppendOnlyVec<T: Copy> {
|
|
vec: parking_lot::RwLock<Vec<T>>,
|
|
}
|
|
|
|
impl<T: Copy> AppendOnlyVec<T> {
|
|
pub fn new() -> Self {
|
|
Self { vec: Default::default() }
|
|
}
|
|
|
|
pub fn push(&self, val: T) -> usize {
|
|
let mut v = self.vec.write();
|
|
let n = v.len();
|
|
v.push(val);
|
|
n
|
|
}
|
|
|
|
pub fn get(&self, i: usize) -> Option<T> {
|
|
self.vec.read().get(i).copied()
|
|
}
|
|
|
|
pub fn iter_enumerated(&self) -> impl Iterator<Item = (usize, T)> + '_ {
|
|
(0..)
|
|
.map(|i| (i, self.get(i)))
|
|
.take_while(|(_, o)| o.is_some())
|
|
.filter_map(|(i, o)| Some((i, o?)))
|
|
}
|
|
|
|
pub fn iter(&self) -> impl Iterator<Item = T> + '_ {
|
|
(0..).map(|i| self.get(i)).take_while(|o| o.is_some()).flatten()
|
|
}
|
|
}
|
|
|
|
impl<T: Copy + PartialEq> AppendOnlyVec<T> {
|
|
pub fn contains(&self, val: T) -> bool {
|
|
self.iter_enumerated().any(|(_, v)| v == val)
|
|
}
|
|
}
|
|
|
|
impl<A: Copy> FromIterator<A> for AppendOnlyVec<A> {
|
|
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
|
|
let this = Self::new();
|
|
for val in iter {
|
|
this.push(val);
|
|
}
|
|
this
|
|
}
|
|
}
|