Skip to content

Commit f847835

Browse files
committed
try: cached source
1 parent c7e2ab1 commit f847835

File tree

3 files changed

+126
-27
lines changed

3 files changed

+126
-27
lines changed

Cargo.lock

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ rustc-hash = "2.1.0"
3737
dashmap = "6.1.0"
3838
memchr = "2.7.4"
3939
itertools = "0.13"
40-
40+
ouroboros = "0.18.4"
4141

4242
codspeed-criterion-compat = { version = "2.7.2", default-features = false, optional = true }
4343
static_assertions = "1.1.0"

src/cached_source.rs

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,58 +49,81 @@ use crate::{
4949
/// "Hello World\nconsole.log('test');\nconsole.log('test2');\nHello2\n"
5050
/// );
5151
/// ```
52-
pub struct CachedSource<T> {
52+
53+
pub struct CachedSource<T: 'static> {
54+
inner: CachedSourceInner<T>,
55+
}
56+
57+
#[ouroboros::self_referencing]
58+
pub struct CachedSourceInner<T: 'static> {
5359
inner: Arc<T>,
60+
#[not_covariant]
61+
#[borrows(inner)]
62+
cached_rope: Arc<OnceLock<Rope<'this>>>,
5463
cached_hash: Arc<OnceLock<u64>>,
5564
cached_maps:
5665
Arc<DashMap<MapOptions, Option<SourceMap>, BuildHasherDefault<FxHasher>>>,
5766
}
5867

68+
impl<T: Source> CachedSource<T> {
69+
fn get_rope(&self) -> &Rope<'_> {
70+
self
71+
.inner
72+
.with(|cache| cache.cached_rope.get_or_init(|| cache.inner.rope()))
73+
}
74+
}
75+
5976
impl<T> CachedSource<T> {
6077
/// Create a [CachedSource] with the original [Source].
6178
pub fn new(inner: T) -> Self {
6279
Self {
63-
inner: Arc::new(inner),
64-
cached_hash: Default::default(),
65-
cached_maps: Default::default(),
80+
inner: CachedSourceInner::new(
81+
Arc::new(inner),
82+
|_| Default::default(),
83+
Default::default(),
84+
Default::default(),
85+
),
6686
}
6787
}
6888

6989
/// Get the original [Source].
7090
pub fn original(&self) -> &T {
71-
&self.inner
91+
self.inner.borrow_inner()
7292
}
7393
}
7494

7595
impl<T: Source + Hash + PartialEq + Eq + 'static> Source for CachedSource<T> {
7696
fn source(&self) -> Cow<str> {
77-
self.inner.source()
97+
Cow::Owned(self.get_rope().to_string())
7898
}
7999

80100
fn rope(&self) -> Rope<'_> {
81-
self.inner.rope()
101+
self.get_rope().clone()
82102
}
83103

84104
fn buffer(&self) -> Cow<[u8]> {
85-
self.inner.buffer()
105+
self.inner.borrow_inner().buffer()
86106
}
87107

88108
fn size(&self) -> usize {
89109
self.source().len()
90110
}
91111

92112
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
93-
if let Some(map) = self.cached_maps.get(options) {
113+
if let Some(map) = self.inner.borrow_cached_maps().get(options) {
94114
map.clone()
95115
} else {
96-
let map = self.inner.map(options);
97-
self.cached_maps.insert(options.clone(), map.clone());
116+
let map = self.inner.borrow_inner().map(options);
117+
self
118+
.inner
119+
.borrow_cached_maps()
120+
.insert(options.clone(), map.clone());
98121
map
99122
}
100123
}
101124

102125
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
103-
self.inner.to_writer(writer)
126+
self.inner.borrow_inner().to_writer(writer)
104127
}
105128
}
106129

@@ -114,7 +137,7 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> StreamChunks
114137
on_source: crate::helpers::OnSource<'_, 'a>,
115138
on_name: crate::helpers::OnName<'_, 'a>,
116139
) -> crate::helpers::GeneratedInfo {
117-
let cached_map = self.cached_maps.entry(options.clone());
140+
let cached_map = self.inner.borrow_cached_maps().entry(options.clone());
118141
match cached_map {
119142
Entry::Occupied(entry) => {
120143
let source = self.rope();
@@ -138,7 +161,7 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> StreamChunks
138161
}
139162
Entry::Vacant(entry) => {
140163
let (generated_info, map) = stream_and_get_source_and_map(
141-
&self.inner as &T,
164+
self.inner.borrow_inner() as &T,
142165
options,
143166
on_chunk,
144167
on_source,
@@ -153,19 +176,21 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> StreamChunks
153176

154177
impl<T> Clone for CachedSource<T> {
155178
fn clone(&self) -> Self {
156-
Self {
157-
inner: self.inner.clone(),
158-
cached_hash: self.cached_hash.clone(),
159-
cached_maps: self.cached_maps.clone(),
160-
}
179+
// Self {
180+
// inner: self.inner.clone(),
181+
// cached_rope: Default::default(),
182+
// cached_hash: self.cached_hash.clone(),
183+
// cached_maps: self.cached_maps.clone(),
184+
// }
185+
todo!()
161186
}
162187
}
163188

164189
impl<T: Source + Hash + PartialEq + Eq + 'static> Hash for CachedSource<T> {
165190
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
166-
(self.cached_hash.get_or_init(|| {
191+
(self.inner.borrow_cached_hash().get_or_init(|| {
167192
let mut hasher = FxHasher::default();
168-
self.inner.hash(&mut hasher);
193+
self.original().hash(&mut hasher);
169194
hasher.finish()
170195
}))
171196
.hash(state);
@@ -174,7 +199,7 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Hash for CachedSource<T> {
174199

175200
impl<T: PartialEq> PartialEq for CachedSource<T> {
176201
fn eq(&self, other: &Self) -> bool {
177-
self.inner == other.inner
202+
self.inner.borrow_inner() == other.inner.borrow_inner()
178203
}
179204
}
180205

@@ -186,9 +211,12 @@ impl<T: std::fmt::Debug> std::fmt::Debug for CachedSource<T> {
186211
f: &mut std::fmt::Formatter<'_>,
187212
) -> Result<(), std::fmt::Error> {
188213
f.debug_struct("CachedSource")
189-
.field("inner", self.inner.as_ref())
190-
.field("cached_hash", self.cached_hash.as_ref())
191-
.field("cached_maps", &(!self.cached_maps.is_empty()))
214+
.field("inner", self.inner.borrow_inner().as_ref())
215+
.field("cached_hash", self.inner.borrow_cached_hash().as_ref())
216+
.field(
217+
"cached_maps",
218+
&(!self.inner.borrow_cached_maps().is_empty()),
219+
)
192220
.finish()
193221
}
194222
}
@@ -236,7 +264,12 @@ mod tests {
236264
source.map(&map_options);
237265

238266
assert_eq!(
239-
*clone.cached_maps.get(&map_options).unwrap().value(),
267+
*clone
268+
.inner
269+
.borrow_cached_maps()
270+
.get(&map_options)
271+
.unwrap()
272+
.value(),
240273
source.map(&map_options)
241274
);
242275
}

0 commit comments

Comments
 (0)