mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Reduce amount of hashing
This commit is contained in:
parent
f2732bb7b2
commit
89cf4054d6
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -286,9 +286,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comemo"
|
name = "comemo"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22bf2c21093020535dd771993fedae8dd55393a4258cca501a9b55a962d350a5"
|
checksum = "70b396e6f0a1a7d2c1d588fd8a255a8c30a8edeef65bc96b4afb3fdb8a8bf281"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"comemo-macros",
|
"comemo-macros",
|
||||||
"siphasher",
|
"siphasher",
|
||||||
@ -296,9 +296,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comemo-macros"
|
name = "comemo-macros"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9faa23f4534253fa656b176ff524d5cd7306a6fed3048929f9cc01ab38ab5a5a"
|
checksum = "421c3e125e48959f3b6a18c0d266f3c228f6e28464c73cc44cff24e808fcda2d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -23,7 +23,7 @@ bench = false
|
|||||||
typst-macros = { path = "macros" }
|
typst-macros = { path = "macros" }
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
bytemuck = "1"
|
bytemuck = "1"
|
||||||
comemo = "0.2"
|
comemo = "0.2.1"
|
||||||
ecow = "0.1"
|
ecow = "0.1"
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
if_chain = "1"
|
if_chain = "1"
|
||||||
|
@ -23,7 +23,7 @@ typst = { path = ".." }
|
|||||||
typst-library = { path = "../library" }
|
typst-library = { path = "../library" }
|
||||||
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
||||||
codespan-reporting = "0.11"
|
codespan-reporting = "0.11"
|
||||||
comemo = "0.2"
|
comemo = "0.2.1"
|
||||||
dirs = "4"
|
dirs = "4"
|
||||||
elsa = "1.7"
|
elsa = "1.7"
|
||||||
memmap2 = "0.5"
|
memmap2 = "0.5"
|
||||||
|
@ -15,7 +15,7 @@ typst-library = { path = "../library" }
|
|||||||
unscanny = "0.1"
|
unscanny = "0.1"
|
||||||
include_dir = "0.7"
|
include_dir = "0.7"
|
||||||
pulldown-cmark = "0.9"
|
pulldown-cmark = "0.9"
|
||||||
comemo = "0.2"
|
comemo = "0.2.1"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
heck = "0.4"
|
heck = "0.4"
|
||||||
|
@ -16,7 +16,7 @@ bench = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
typst = { path = ".." }
|
typst = { path = ".." }
|
||||||
comemo = "0.2"
|
comemo = "0.2.1"
|
||||||
csv = "1"
|
csv = "1"
|
||||||
ecow = "0.1"
|
ecow = "0.1"
|
||||||
hayagriva = "0.3"
|
hayagriva = "0.3"
|
||||||
|
@ -3,7 +3,7 @@ use std::fmt::{self, Debug, Formatter, Write};
|
|||||||
use std::iter::Sum;
|
use std::iter::Sum;
|
||||||
use std::ops::{Add, AddAssign};
|
use std::ops::{Add, AddAssign};
|
||||||
|
|
||||||
use comemo::Tracked;
|
use comemo::{Prehashed, Tracked};
|
||||||
use ecow::{eco_format, EcoString, EcoVec};
|
use ecow::{eco_format, EcoString, EcoVec};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -29,8 +29,8 @@ pub struct Content {
|
|||||||
enum Attr {
|
enum Attr {
|
||||||
Span(Span),
|
Span(Span),
|
||||||
Field(EcoString),
|
Field(EcoString),
|
||||||
Value(Value),
|
Value(Prehashed<Value>),
|
||||||
Child(Content),
|
Child(Prehashed<Content>),
|
||||||
Styles(Styles),
|
Styles(Styles),
|
||||||
Prepared,
|
Prepared,
|
||||||
Guard(Guard),
|
Guard(Guard),
|
||||||
@ -54,9 +54,11 @@ impl Content {
|
|||||||
let Some(first) = iter.next() else { return Self::empty() };
|
let Some(first) = iter.next() else { return Self::empty() };
|
||||||
let Some(second) = iter.next() else { return first };
|
let Some(second) = iter.next() else { return first };
|
||||||
let mut content = Content::empty();
|
let mut content = Content::empty();
|
||||||
content.attrs.push(Attr::Child(first));
|
content.attrs.push(Attr::Child(Prehashed::new(first)));
|
||||||
content.attrs.push(Attr::Child(second));
|
content.attrs.push(Attr::Child(Prehashed::new(second)));
|
||||||
content.attrs.extend(iter.map(Attr::Child));
|
content
|
||||||
|
.attrs
|
||||||
|
.extend(iter.map(|child| Attr::Child(Prehashed::new(child))));
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,10 +166,10 @@ impl Content {
|
|||||||
Attr::Field(field) => *field == name,
|
Attr::Field(field) => *field == name,
|
||||||
_ => false,
|
_ => false,
|
||||||
}) {
|
}) {
|
||||||
self.attrs.make_mut()[i + 1] = Attr::Value(value.into());
|
self.attrs.make_mut()[i + 1] = Attr::Value(Prehashed::new(value.into()));
|
||||||
} else {
|
} else {
|
||||||
self.attrs.push(Attr::Field(name));
|
self.attrs.push(Attr::Field(name));
|
||||||
self.attrs.push(Attr::Value(value.into()));
|
self.attrs.push(Attr::Value(Prehashed::new(value.into())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +287,7 @@ impl Content {
|
|||||||
self
|
self
|
||||||
} else {
|
} else {
|
||||||
let mut content = Content::new(StyledElem::func());
|
let mut content = Content::new(StyledElem::func());
|
||||||
content.attrs.push(Attr::Child(self));
|
content.attrs.push(Attr::Child(Prehashed::new(self)));
|
||||||
content.attrs.push(Attr::Styles(styles));
|
content.attrs.push(Attr::Styles(styles));
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
@ -466,11 +468,11 @@ impl Add for Content {
|
|||||||
lhs
|
lhs
|
||||||
}
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
lhs.attrs.push(Attr::Child(rhs));
|
lhs.attrs.push(Attr::Child(Prehashed::new(rhs)));
|
||||||
lhs
|
lhs
|
||||||
}
|
}
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
rhs.attrs.insert(0, Attr::Child(lhs));
|
rhs.attrs.insert(0, Attr::Child(Prehashed::new(lhs)));
|
||||||
rhs
|
rhs
|
||||||
}
|
}
|
||||||
(false, false) => Self::sequence([lhs, rhs]),
|
(false, false) => Self::sequence([lhs, rhs]),
|
||||||
|
@ -2,8 +2,10 @@ use std::any::{Any, TypeId};
|
|||||||
use std::fmt::{self, Debug, Formatter, Write};
|
use std::fmt::{self, Debug, Formatter, Write};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ptr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use comemo::Prehashed;
|
||||||
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
||||||
|
|
||||||
use super::{Content, ElemFunc, Element, Introspector, Label, Location, Vt};
|
use super::{Content, ElemFunc, Element, Introspector, Label, Location, Vt};
|
||||||
@ -15,7 +17,7 @@ use crate::util::pretty_array_like;
|
|||||||
|
|
||||||
/// A list of style properties.
|
/// A list of style properties.
|
||||||
#[derive(Default, PartialEq, Clone, Hash)]
|
#[derive(Default, PartialEq, Clone, Hash)]
|
||||||
pub struct Styles(EcoVec<Style>);
|
pub struct Styles(EcoVec<Prehashed<Style>>);
|
||||||
|
|
||||||
impl Styles {
|
impl Styles {
|
||||||
/// Create a new, empty style list.
|
/// Create a new, empty style list.
|
||||||
@ -34,7 +36,7 @@ impl Styles {
|
|||||||
/// style map, `self` contributes the outer values and `value` is the inner
|
/// style map, `self` contributes the outer values and `value` is the inner
|
||||||
/// one.
|
/// one.
|
||||||
pub fn set(&mut self, style: impl Into<Style>) {
|
pub fn set(&mut self, style: impl Into<Style>) {
|
||||||
self.0.push(style.into());
|
self.0.push(Prehashed::new(style.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the style that was last set.
|
/// Remove the style that was last set.
|
||||||
@ -51,20 +53,22 @@ impl Styles {
|
|||||||
/// Apply one outer styles. Like [`chain_one`](StyleChain::chain_one), but
|
/// Apply one outer styles. Like [`chain_one`](StyleChain::chain_one), but
|
||||||
/// in-place.
|
/// in-place.
|
||||||
pub fn apply_one(&mut self, outer: Style) {
|
pub fn apply_one(&mut self, outer: Style) {
|
||||||
self.0.insert(0, outer);
|
self.0.insert(0, Prehashed::new(outer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply a slice of outer styles.
|
/// Apply a slice of outer styles.
|
||||||
pub fn apply_slice(&mut self, outer: &[Style]) {
|
pub fn apply_slice(&mut self, outer: &[Prehashed<Style>]) {
|
||||||
self.0 = outer.iter().cloned().chain(mem::take(self).0.into_iter()).collect();
|
self.0 = outer.iter().cloned().chain(mem::take(self).0.into_iter()).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an origin span to all contained properties.
|
/// Add an origin span to all contained properties.
|
||||||
pub fn spanned(mut self, span: Span) -> Self {
|
pub fn spanned(mut self, span: Span) -> Self {
|
||||||
for entry in self.0.make_mut() {
|
for entry in self.0.make_mut() {
|
||||||
if let Style::Property(property) = entry {
|
entry.update(|entry| {
|
||||||
property.span = Some(span);
|
if let Style::Property(property) = entry {
|
||||||
}
|
property.span = Some(span);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -73,7 +77,7 @@ impl Styles {
|
|||||||
/// styles for the given element.
|
/// styles for the given element.
|
||||||
pub fn interruption<T: Element>(&self) -> Option<Option<Span>> {
|
pub fn interruption<T: Element>(&self) -> Option<Option<Span>> {
|
||||||
let func = T::func();
|
let func = T::func();
|
||||||
self.0.iter().find_map(|entry| match entry {
|
self.0.iter().find_map(|entry| match &**entry {
|
||||||
Style::Property(property) => property.is_of(func).then_some(property.span),
|
Style::Property(property) => property.is_of(func).then_some(property.span),
|
||||||
Style::Recipe(recipe) => recipe.is_of(func).then_some(Some(recipe.span)),
|
Style::Recipe(recipe) => recipe.is_of(func).then_some(Some(recipe.span)),
|
||||||
})
|
})
|
||||||
@ -82,7 +86,7 @@ impl Styles {
|
|||||||
|
|
||||||
impl From<Style> for Styles {
|
impl From<Style> for Styles {
|
||||||
fn from(entry: Style) -> Self {
|
fn from(entry: Style) -> Self {
|
||||||
Self(eco_vec![entry])
|
Self(eco_vec![Prehashed::new(entry)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +570,7 @@ cast_from_value! {
|
|||||||
#[derive(Default, Clone, Copy, Hash)]
|
#[derive(Default, Clone, Copy, Hash)]
|
||||||
pub struct StyleChain<'a> {
|
pub struct StyleChain<'a> {
|
||||||
/// The first link of this chain.
|
/// The first link of this chain.
|
||||||
head: &'a [Style],
|
head: &'a [Prehashed<Style>],
|
||||||
/// The remaining links in the chain.
|
/// The remaining links in the chain.
|
||||||
tail: Option<&'a Self>,
|
tail: Option<&'a Self>,
|
||||||
}
|
}
|
||||||
@ -590,14 +594,6 @@ impl<'a> StyleChain<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make the given style the first link of the this chain.
|
|
||||||
pub fn chain_one<'b>(&'b self, style: &'b Style) -> StyleChain<'b> {
|
|
||||||
StyleChain {
|
|
||||||
head: std::slice::from_ref(style),
|
|
||||||
tail: Some(self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cast the first value for the given property in the chain.
|
/// Cast the first value for the given property in the chain.
|
||||||
pub fn get<T: Cast>(
|
pub fn get<T: Cast>(
|
||||||
self,
|
self,
|
||||||
@ -733,16 +729,6 @@ impl<'a> StyleChain<'a> {
|
|||||||
fn pop(&mut self) {
|
fn pop(&mut self) {
|
||||||
*self = self.tail.copied().unwrap_or_default();
|
*self = self.tail.copied().unwrap_or_default();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether two style chains contain the same pointers.
|
|
||||||
fn ptr_eq(self, other: Self) -> bool {
|
|
||||||
std::ptr::eq(self.head, other.head)
|
|
||||||
&& match (self.tail, other.tail) {
|
|
||||||
(Some(a), Some(b)) => std::ptr::eq(a, b),
|
|
||||||
(None, None) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for StyleChain<'_> {
|
impl Debug for StyleChain<'_> {
|
||||||
@ -756,13 +742,18 @@ impl Debug for StyleChain<'_> {
|
|||||||
|
|
||||||
impl PartialEq for StyleChain<'_> {
|
impl PartialEq for StyleChain<'_> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.ptr_eq(*other) || crate::util::hash128(self) == crate::util::hash128(other)
|
ptr::eq(self.head, other.head)
|
||||||
|
&& match (self.tail, other.tail) {
|
||||||
|
(Some(a), Some(b)) => ptr::eq(a, b),
|
||||||
|
(None, None) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over the entries in a style chain.
|
/// An iterator over the entries in a style chain.
|
||||||
struct Entries<'a> {
|
struct Entries<'a> {
|
||||||
inner: std::slice::Iter<'a, Style>,
|
inner: std::slice::Iter<'a, Prehashed<Style>>,
|
||||||
links: Links<'a>,
|
links: Links<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,7 +778,7 @@ impl<'a> Iterator for Entries<'a> {
|
|||||||
struct Links<'a>(Option<StyleChain<'a>>);
|
struct Links<'a>(Option<StyleChain<'a>>);
|
||||||
|
|
||||||
impl<'a> Iterator for Links<'a> {
|
impl<'a> Iterator for Links<'a> {
|
||||||
type Item = &'a [Style];
|
type Item = &'a [Prehashed<Style>];
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let StyleChain { head, tail } = self.0?;
|
let StyleChain { head, tail } = self.0?;
|
||||||
|
@ -110,9 +110,7 @@ impl Source {
|
|||||||
pub fn edit(&mut self, replace: Range<usize>, with: &str) -> Range<usize> {
|
pub fn edit(&mut self, replace: Range<usize>, with: &str) -> Range<usize> {
|
||||||
let start_byte = replace.start;
|
let start_byte = replace.start;
|
||||||
let start_utf16 = self.byte_to_utf16(replace.start).unwrap();
|
let start_utf16 = self.byte_to_utf16(replace.start).unwrap();
|
||||||
let mut text = std::mem::take(&mut self.text).into_inner();
|
self.text.update(|text| text.replace_range(replace.clone(), with));
|
||||||
text.replace_range(replace.clone(), with);
|
|
||||||
self.text = Prehashed::new(text);
|
|
||||||
|
|
||||||
// Remove invalidated line starts.
|
// Remove invalidated line starts.
|
||||||
let line = self.byte_to_line(start_byte).unwrap();
|
let line = self.byte_to_line(start_byte).unwrap();
|
||||||
@ -128,10 +126,8 @@ impl Source {
|
|||||||
.extend(lines_from(start_byte, start_utf16, &self.text[start_byte..]));
|
.extend(lines_from(start_byte, start_utf16, &self.text[start_byte..]));
|
||||||
|
|
||||||
// Incrementally reparse the replaced range.
|
// Incrementally reparse the replaced range.
|
||||||
let mut root = std::mem::take(&mut self.root).into_inner();
|
self.root
|
||||||
let range = reparse(&mut root, &self.text, replace, with.len());
|
.update(|root| reparse(root, &self.text, replace, with.len()))
|
||||||
self.root = Prehashed::new(root);
|
|
||||||
range
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the length of the file in UTF-8 encoded bytes.
|
/// Get the length of the file in UTF-8 encoded bytes.
|
||||||
|
@ -8,7 +8,7 @@ publish = false
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
typst = { path = ".." }
|
typst = { path = ".." }
|
||||||
typst-library = { path = "../library" }
|
typst-library = { path = "../library" }
|
||||||
comemo = "0.2"
|
comemo = "0.2.1"
|
||||||
elsa = "1.7"
|
elsa = "1.7"
|
||||||
iai = { git = "https://github.com/reknih/iai" }
|
iai = { git = "https://github.com/reknih/iai" }
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Loading…
x
Reference in New Issue
Block a user