swc_ecma_loader/resolvers/
lru.rs1use std::num::NonZeroUsize;
2
3use anyhow::Error;
4use lru::LruCache;
5use parking_lot::Mutex;
6use swc_common::FileName;
7
8use crate::resolve::{Resolution, Resolve};
9
10#[derive(Debug)]
11pub struct CachingResolver<R>
12where
13 R: Resolve,
14{
15 cache: Mutex<LruCache<(FileName, String), Resolution>>,
16 inner: R,
17}
18
19impl<R> Default for CachingResolver<R>
20where
21 R: Resolve + Default,
22{
23 fn default() -> Self {
24 Self::new(40, Default::default())
25 }
26}
27
28impl<R> CachingResolver<R>
29where
30 R: Resolve,
31{
32 pub fn new(cap: usize, inner: R) -> Self {
33 Self {
34 cache: Mutex::new(LruCache::new(
35 NonZeroUsize::try_from(cap).expect("cap == 0"),
36 )),
37 inner,
38 }
39 }
40}
41
42impl<R> Resolve for CachingResolver<R>
43where
44 R: Resolve,
45{
46 fn resolve(&self, base: &FileName, src: &str) -> Result<Resolution, Error> {
47 {
48 let mut lock = self.cache.lock();
49 if let Some(v) = lock.get(&(base.clone(), src.to_string())) {
51 return Ok(v.clone());
52 }
53 }
54
55 let resolved = self.inner.resolve(base, src)?;
56 {
57 let mut lock = self.cache.lock();
58 lock.put((base.clone(), src.to_string()), resolved.clone());
59 }
60
61 Ok(resolved)
62 }
63}