Skip to content

Commit

Permalink
dev(compiler): cheaper path clone
Browse files Browse the repository at this point in the history
  • Loading branch information
Myriad-Dreamin committed Sep 27, 2023
1 parent 930fe60 commit 785030e
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 50 deletions.
4 changes: 2 additions & 2 deletions compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use typst::{
diag::{At, FileResult, SourceResult},
syntax::Span,
};
use typst_ts_core::{Bytes, TypstFileId};
use typst_ts_core::{Bytes, ImmutPath, TypstFileId};
use vfs::notify::FilesystemEvent;

/// Latest version of the shadow api, which is in beta.
Expand Down Expand Up @@ -137,7 +137,7 @@ pub trait ShadowApi {

/// Latest version of the notify api, which is in beta.
pub trait NotifyApi {
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a Path, instant::SystemTime));
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime));

fn notify_fs_event(&mut self, event: FilesystemEvent);
}
4 changes: 2 additions & 2 deletions compiler/src/service/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ where
// Notify the new file dependencies.
let mut deps = vec![];
self.compiler
.iter_dependencies(&mut |dep, _| deps.push(dep.to_owned()));
.iter_dependencies(&mut |dep, _| deps.push(dep.clone()));
send(Notify(NotifyMessage::SyncDependency(deps)));
}

Expand Down Expand Up @@ -288,7 +288,7 @@ where
self.dirty_shadow_logical_tick = self.logical_tick;
send(Notify(NotifyMessage::UpstreamUpdate(
crate::vfs::notify::UpstreamUpdateEvent {
invalidates: files.iter().map(|e| e.as_ref().to_owned()).collect(),
invalidates: files.into_iter().collect(),
opaque: Box::new(TaggedMemoryEvent {
logical_tick: self.logical_tick,
event,
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/service/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{

use crate::{NotifyApi, ShadowApi};
use typst::{diag::SourceResult, syntax::VirtualPath, World};
use typst_ts_core::{path::PathClean, Bytes, TypstFileId};
use typst_ts_core::{path::PathClean, Bytes, ImmutPath, TypstFileId};

use super::{Compiler, WorkspaceProvider};

Expand Down Expand Up @@ -97,7 +97,7 @@ impl<W: World + WorkspaceProvider + NotifyApi> Compiler for CompileDriverImpl<W>
self._relevant(event).unwrap_or(true)
}

fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a Path, instant::SystemTime)) {
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime)) {
self.world.iter_dependencies(f)
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use typst::{
syntax::Span,
World,
};
use typst_ts_core::{Bytes, TypstFileId};
use typst_ts_core::{Bytes, ImmutPath, TypstFileId};

// todo: remove cfg feature here
#[cfg(feature = "system-compile")]
Expand Down Expand Up @@ -91,7 +91,7 @@ pub trait Compiler {

/// Iterate over the dependencies of found by the compiler.
/// Note: reset the compiler will clear the dependencies cache.
fn iter_dependencies<'a>(&'a self, _f: &mut dyn FnMut(&'a Path, instant::SystemTime)) {}
fn iter_dependencies<'a>(&'a self, _f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime)) {}

fn notify_fs_event(&mut self, _event: FilesystemEvent) {}

Expand Down Expand Up @@ -239,7 +239,7 @@ impl<T: WrappedCompiler> Compiler for T {
}

#[inline]
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a Path, instant::SystemTime)) {
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime)) {
self.inner().iter_dependencies(f)
}

Expand Down
17 changes: 9 additions & 8 deletions compiler/src/service/watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
//! Hopefully, one day a reliable file watching/walking crate appears on
//! crates.io, and we can reduce this to trivial glue code.
use std::{collections::HashMap, fs, path::PathBuf};
use std::{collections::HashMap, fs};

use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use tokio::sync::mpsc;
use typst::diag::{FileError, FileResult};

use typst_ts_core::Bytes;
use typst_ts_core::{Bytes, ImmutPath};

use crate::vfs::{
notify::{FileChangeSet, FilesystemEvent, NotifyFile, NotifyMessage, UpstreamUpdateEvent},
Expand All @@ -25,7 +25,7 @@ use crate::vfs::{

type WatcherPair = (RecommendedWatcher, mpsc::UnboundedReceiver<NotifyEvent>);
type NotifyEvent = notify::Result<notify::Event>;
type FileEntry = (/* key */ PathBuf, /* value */ NotifyFile);
type FileEntry = (/* key */ ImmutPath, /* value */ NotifyFile);
type NotifyFilePair = FileResult<(
/* mtime */ instant::SystemTime,
/* content */ Bytes,
Expand Down Expand Up @@ -79,7 +79,7 @@ struct UndeterminedNotifyEvent {
/// The logical tick when the event is produced.
at_logical_tick: usize,
/// The path of the file.
path: PathBuf,
path: ImmutPath,
}

// Drop order is significant.
Expand Down Expand Up @@ -111,7 +111,7 @@ pub struct NotifyActor {
undetermined_recv: mpsc::UnboundedReceiver<UndeterminedNotifyEvent>,

/// The holded entries for watching, one entry for per file.
watched_entries: HashMap<PathBuf, WatchedEntry>,
watched_entries: HashMap<ImmutPath, WatchedEntry>,

/// The builtin watcher object.
watcher: Option<WatcherPair>,
Expand Down Expand Up @@ -219,7 +219,7 @@ impl NotifyActor {
}

/// Update the watches of corresponding files.
fn update_watches(&mut self, paths: &[PathBuf]) -> Option<FileChangeSet> {
fn update_watches(&mut self, paths: &[ImmutPath]) -> Option<FileChangeSet> {
// Increase the lifetime per external message.
self.lifetime += 1;

Expand Down Expand Up @@ -331,7 +331,8 @@ impl NotifyActor {
// Account file updates.
let mut changeset = FileChangeSet::default();
for path in event.paths.into_iter() {
changeset.may_insert(self.notify_entry_update(path.clone(), None));
// todo: remove this clone: path.into()
changeset.may_insert(self.notify_entry_update(path.into(), None));
}

// Send file updates.
Expand All @@ -343,7 +344,7 @@ impl NotifyActor {
/// Notify any update of the file entry
fn notify_entry_update(
&mut self,
path: PathBuf,
path: ImmutPath,
meta: Option<std::fs::Metadata>,
) -> Option<FileEntry> {
let meta = meta.or_else(|| fs::metadata(&path).ok())?;
Expand Down
25 changes: 11 additions & 14 deletions compiler/src/vfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@ pub(crate) mod writable;
pub use writable::Vfs as MemVfs;
pub use writable::{ChangeKind, ChangedFile};

use std::{
collections::HashMap,
ffi::OsStr,
hash::Hash,
path::{Path, PathBuf},
sync::Arc,
};
use std::{collections::HashMap, ffi::OsStr, hash::Hash, path::Path, sync::Arc};

use append_only_vec::AppendOnlyVec;
use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard};
Expand All @@ -47,7 +41,7 @@ use typst::{
syntax::Source,
};

use typst_ts_core::{path::PathClean, Bytes, QueryRef, TypstFileId};
use typst_ts_core::{path::PathClean, Bytes, ImmutPath, QueryRef, TypstFileId};

use crate::{parser::reparse, time::SystemTime};

Expand Down Expand Up @@ -85,7 +79,7 @@ type FileQuery<T> = QueryRef<T, FileError>;
/// Holds canonical data for all paths pointing to the same entity.
pub struct PathSlot {
idx: FileId,
sampled_path: once_cell::sync::OnceCell<PathBuf>,
sampled_path: once_cell::sync::OnceCell<ImmutPath>,
mtime: FileQuery<SystemTime>,
source: FileQuery<Source>,
buffer: FileQuery<Bytes>,
Expand Down Expand Up @@ -182,28 +176,31 @@ impl<M: AccessModel + Sized> Vfs<M> {
}

/// Get all the files in the VFS.
pub fn iter_dependencies(&self) -> impl Iterator<Item = (&Path, SystemTime)> {
pub fn iter_dependencies(&self) -> impl Iterator<Item = (&ImmutPath, SystemTime)> {
self.slots.iter().map(|slot| {
let dep_path = slot.sampled_path.get().unwrap();
let dep_mtime = slot
.mtime
.compute(|| Err(other_reason("vfs: uninitialized")))
.unwrap();

(dep_path.as_path(), *dep_mtime)
(dep_path, *dep_mtime)
})
}

/// Get all the files in the VFS.
pub fn iter_dependencies_dyn<'a>(&'a self, f: &mut dyn FnMut(&'a Path, instant::SystemTime)) {
pub fn iter_dependencies_dyn<'a>(
&'a self,
f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime),
) {
for slot in self.slots.iter() {
let dep_path = slot.sampled_path.get().unwrap();
let dep_mtime = slot
.mtime
.compute(|| Err(other_reason("vfs: uninitialized")))
.unwrap();

f(dep_path.as_path(), *dep_mtime)
f(dep_path, *dep_mtime)
}
}

Expand Down Expand Up @@ -245,7 +242,7 @@ impl<M: AccessModel + Sized> Vfs<M> {
}

let slot = &self.slots[idx];
slot.sampled_path.get_or_init(|| origin_path.to_path_buf());
slot.sampled_path.get_or_init(|| origin_path.into());
Ok(&self.slots[idx])
}

Expand Down
25 changes: 11 additions & 14 deletions compiler/src/vfs/notify.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use std::{collections::HashMap, path::Path};

use typst::diag::FileResult;
use typst_ts_core::Bytes;
use typst_ts_core::{Bytes, ImmutPath};

use crate::vfs::AccessModel;

Expand Down Expand Up @@ -51,9 +48,9 @@ impl From<FileResult<(instant::SystemTime, Bytes)>> for NotifyFile {
#[derive(Debug, Clone, Default)]
pub struct FileChangeSet {
/// Files to remove
pub removes: Vec<PathBuf>,
pub removes: Vec<ImmutPath>,
/// Files to insert or update
pub inserts: Vec<(PathBuf, NotifyFile)>,
pub inserts: Vec<(ImmutPath, NotifyFile)>,
}

impl FileChangeSet {
Expand All @@ -63,30 +60,30 @@ impl FileChangeSet {
}

/// Create a new changeset with removing files
pub fn new_removes(removes: Vec<PathBuf>) -> Self {
pub fn new_removes(removes: Vec<ImmutPath>) -> Self {
Self {
removes,
inserts: vec![],
}
}

/// Create a new changeset with inserting files
pub fn new_inserts(inserts: Vec<(PathBuf, NotifyFile)>) -> Self {
pub fn new_inserts(inserts: Vec<(ImmutPath, NotifyFile)>) -> Self {
Self {
removes: vec![],
inserts,
}
}

/// Utility function to insert a possible file to insert or update
pub fn may_insert(&mut self, v: Option<(PathBuf, NotifyFile)>) {
pub fn may_insert(&mut self, v: Option<(ImmutPath, NotifyFile)>) {
if let Some(v) = v {
self.inserts.push(v);
}
}

/// Utility function to insert multiple possible files to insert or update
pub fn may_extend(&mut self, v: Option<impl Iterator<Item = (PathBuf, NotifyFile)>>) {
pub fn may_extend(&mut self, v: Option<impl Iterator<Item = (ImmutPath, NotifyFile)>>) {
if let Some(v) = v {
self.inserts.extend(v);
}
Expand Down Expand Up @@ -119,7 +116,7 @@ pub enum MemoryEvent {
#[derive(Debug)]
pub struct UpstreamUpdateEvent {
/// Associated files that the event causes to invalidate
pub invalidates: Vec<PathBuf>,
pub invalidates: Vec<ImmutPath>,
/// Opaque data that is passed to the file watcher
pub opaque: Box<dyn std::any::Any + Send>,
}
Expand All @@ -141,7 +138,7 @@ pub enum FilesystemEvent {
#[derive(Debug)]
pub enum NotifyMessage {
/// override all dependencies
SyncDependency(Vec<PathBuf>),
SyncDependency(Vec<ImmutPath>),
/// upstream invalidation This is very important to make some atomic changes
///
/// Example:
Expand Down Expand Up @@ -170,7 +167,7 @@ pub enum NotifyMessage {
/// Notify shadowing access model, which the typical underlying access model is
/// [`crate::vfs::system::SystemAccessModel`]
pub struct NotifyAccessModel<M: AccessModel> {
files: HashMap<PathBuf, NotifyFile>,
files: HashMap<ImmutPath, NotifyFile>,
pub inner: M,
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use typst::{

use typst_ts_core::{
font::{FontProfile, FontResolverImpl},
Bytes, FontResolver, TypstFileId as FileId,
Bytes, FontResolver, ImmutPath, TypstFileId as FileId,
};

use crate::{
Expand Down Expand Up @@ -190,7 +190,7 @@ impl<F: CompilerFeat> CompilerWorld<F> {
pub fn get_dependencies(&self) -> DependencyTree {
let t = self.vfs.iter_dependencies();
let vfs_dependencies = t.map(|(path, mtime)| DependentFileInfo {
path: (*path).to_owned(),
path: path.as_ref().to_owned(),
mtime: mtime
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
Expand Down Expand Up @@ -251,7 +251,7 @@ impl<F: CompilerFeat> ShadowApi for CompilerWorld<F> {

impl<F: CompilerFeat> NotifyApi for CompilerWorld<F> {
#[inline]
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a Path, instant::SystemTime)) {
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime)) {
self.vfs.iter_dependencies_dyn(f)
}

Expand Down
5 changes: 5 additions & 0 deletions core/src/concepts/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod takable;
use std::{path::Path, sync::Arc};

pub use takable::*;

mod hash;
Expand All @@ -16,3 +18,6 @@ pub use marker::*;
/// Re-export of the typst crate.
mod typst;
pub use self::typst::*;

pub type ImmutStr = Arc<str>;
pub type ImmutPath = Arc<Path>;
5 changes: 3 additions & 2 deletions core/src/vector/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
StaticHash128,
};

pub type ImmutStr = Arc<str>;
pub use crate::ImmutStr;

pub use super::geom::*;

Expand Down Expand Up @@ -108,7 +108,8 @@ pub struct FontRef {
/// Reference a glyph item in a more friendly format to compress and store
/// information. The glyphs are locally stored in the svg module.
/// With a glyph reference, we can get both the font metric and the glyph data.
/// The `font_hash` is to let it safe to be cached, please see [`FontItem`] for more details.
/// The `font_hash` is to let it safe to be cached, please see [`FontItem`] for
/// more details.
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "rkyv", derive(Archive, rDeser, rSer))]
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
Expand Down

0 comments on commit 785030e

Please sign in to comment.