mirror of
https://github.com/typst/typst
synced 2025-07-27 22:37:54 +08:00
Prehashed query result
This commit is contained in:
parent
af173acd59
commit
5764c65ec9
@ -79,6 +79,7 @@ fn retrieve(
|
|||||||
Ok(document
|
Ok(document
|
||||||
.introspector
|
.introspector
|
||||||
.query(&selector.0)
|
.query(&selector.0)
|
||||||
|
.into_inner()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Vec<_>>())
|
.collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ const OUTLINE_RULE: ShowFn<OutlineElem> = |elem, engine, styles| {
|
|||||||
let depth = elem.depth.get(styles).unwrap_or(NonZeroUsize::MAX);
|
let depth = elem.depth.get(styles).unwrap_or(NonZeroUsize::MAX);
|
||||||
|
|
||||||
// Build the outline entries.
|
// Build the outline entries.
|
||||||
for elem in elems {
|
for elem in elems.into_inner() {
|
||||||
let Some(outlinable) = elem.with::<dyn Outlinable>() else {
|
let Some(outlinable) = elem.with::<dyn Outlinable>() else {
|
||||||
bail!(span, "cannot outline {}", elem.func().name());
|
bail!(span, "cannot outline {}", elem.func().name());
|
||||||
};
|
};
|
||||||
|
@ -312,7 +312,7 @@ impl Counter {
|
|||||||
let mut page = NonZeroUsize::ONE;
|
let mut page = NonZeroUsize::ONE;
|
||||||
let mut stops = eco_vec![(state.clone(), page)];
|
let mut stops = eco_vec![(state.clone(), page)];
|
||||||
|
|
||||||
for elem in introspector.query(&self.selector()) {
|
for elem in introspector.query(&self.selector()).into_inner() {
|
||||||
if self.is_page() {
|
if self.is_page() {
|
||||||
let prev = page;
|
let prev = page;
|
||||||
page = introspector.page(elem.location().unwrap());
|
page = introspector.page(elem.location().unwrap());
|
||||||
|
@ -4,6 +4,7 @@ use std::hash::Hash;
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
|
use comemo::Prehashed;
|
||||||
use ecow::{EcoString, EcoVec};
|
use ecow::{EcoString, EcoVec};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use typst_utils::NonZeroExt;
|
use typst_utils::NonZeroExt;
|
||||||
@ -108,7 +109,7 @@ impl Introspector {
|
|||||||
#[comemo::track]
|
#[comemo::track]
|
||||||
impl Introspector {
|
impl Introspector {
|
||||||
/// Query for all matching elements.
|
/// Query for all matching elements.
|
||||||
pub fn query(&self, selector: &Selector) -> EcoVec<Content> {
|
pub fn query(&self, selector: &Selector) -> Prehashed<EcoVec<Content>> {
|
||||||
let hash = typst_utils::hash128(selector);
|
let hash = typst_utils::hash128(selector);
|
||||||
if let Some(output) = self.queries.get(hash) {
|
if let Some(output) = self.queries.get(hash) {
|
||||||
return output;
|
return output;
|
||||||
@ -131,7 +132,7 @@ impl Introspector {
|
|||||||
.collect(),
|
.collect(),
|
||||||
Selector::Or(selectors) => selectors
|
Selector::Or(selectors) => selectors
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|sel| self.query(sel))
|
.flat_map(|sel| self.query(sel).into_inner())
|
||||||
.map(|elem| self.elem_index(&elem))
|
.map(|elem| self.elem_index(&elem))
|
||||||
.collect::<BTreeSet<usize>>()
|
.collect::<BTreeSet<usize>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -139,7 +140,7 @@ impl Introspector {
|
|||||||
.collect(),
|
.collect(),
|
||||||
Selector::And(selectors) => {
|
Selector::And(selectors) => {
|
||||||
let mut results: Vec<_> =
|
let mut results: Vec<_> =
|
||||||
selectors.iter().map(|sel| self.query(sel)).collect();
|
selectors.iter().map(|sel| self.query(sel).into_inner()).collect();
|
||||||
|
|
||||||
// Extract the smallest result list and then keep only those
|
// Extract the smallest result list and then keep only those
|
||||||
// elements in the smallest list that are also in all other
|
// elements in the smallest list that are also in all other
|
||||||
@ -161,7 +162,7 @@ impl Introspector {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
Selector::Before { selector, end, inclusive } => {
|
Selector::Before { selector, end, inclusive } => {
|
||||||
let mut list = self.query(selector);
|
let mut list = self.query(selector).into_inner();
|
||||||
if let Some(end) = self.query_first(end) {
|
if let Some(end) = self.query_first(end) {
|
||||||
// Determine which elements are before `end`.
|
// Determine which elements are before `end`.
|
||||||
let split = match self.binary_search(&list, &end) {
|
let split = match self.binary_search(&list, &end) {
|
||||||
@ -175,7 +176,7 @@ impl Introspector {
|
|||||||
list
|
list
|
||||||
}
|
}
|
||||||
Selector::After { selector, start, inclusive } => {
|
Selector::After { selector, start, inclusive } => {
|
||||||
let mut list = self.query(selector);
|
let mut list = self.query(selector).into_inner();
|
||||||
if let Some(start) = self.query_first(start) {
|
if let Some(start) = self.query_first(start) {
|
||||||
// Determine which elements are after `start`.
|
// Determine which elements are after `start`.
|
||||||
let split = match self.binary_search(&list, &start) {
|
let split = match self.binary_search(&list, &start) {
|
||||||
@ -192,6 +193,7 @@ impl Introspector {
|
|||||||
Selector::Can(_) | Selector::Regex(_) => EcoVec::new(),
|
Selector::Can(_) | Selector::Regex(_) => EcoVec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let output = Prehashed::new(output);
|
||||||
self.queries.insert(hash, output.clone());
|
self.queries.insert(hash, output.clone());
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
@ -223,6 +225,7 @@ impl Introspector {
|
|||||||
bail!("selector matches multiple elements",);
|
bail!("selector matches multiple elements",);
|
||||||
}
|
}
|
||||||
elems
|
elems
|
||||||
|
.into_inner()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| "selector does not match any element".into())
|
.ok_or_else(|| "selector does not match any element".into())
|
||||||
@ -340,14 +343,14 @@ impl<K, V> Default for MultiMap<K, V> {
|
|||||||
|
|
||||||
/// Caches queries.
|
/// Caches queries.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct QueryCache(RwLock<HashMap<u128, EcoVec<Content>>>);
|
struct QueryCache(RwLock<HashMap<u128, Prehashed<EcoVec<Content>>>>);
|
||||||
|
|
||||||
impl QueryCache {
|
impl QueryCache {
|
||||||
fn get(&self, hash: u128) -> Option<EcoVec<Content>> {
|
fn get(&self, hash: u128) -> Option<Prehashed<EcoVec<Content>>> {
|
||||||
self.0.read().unwrap().get(&hash).cloned()
|
self.0.read().unwrap().get(&hash).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&self, hash: u128, output: EcoVec<Content>) {
|
fn insert(&self, hash: u128, output: Prehashed<EcoVec<Content>>) {
|
||||||
self.0.write().unwrap().insert(hash, output);
|
self.0.write().unwrap().insert(hash, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,5 +149,5 @@ pub fn query(
|
|||||||
) -> HintedStrResult<Array> {
|
) -> HintedStrResult<Array> {
|
||||||
context.introspect()?;
|
context.introspect()?;
|
||||||
let vec = engine.introspector.query(&target.0);
|
let vec = engine.introspector.query(&target.0);
|
||||||
Ok(vec.into_iter().map(Value::Content).collect())
|
Ok(vec.into_inner().into_iter().map(Value::Content).collect())
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ impl State {
|
|||||||
let mut state = self.init.clone();
|
let mut state = self.init.clone();
|
||||||
let mut stops = eco_vec![state.clone()];
|
let mut stops = eco_vec![state.clone()];
|
||||||
|
|
||||||
for elem in introspector.query(&self.selector()) {
|
for elem in introspector.query(&self.selector()).into_inner() {
|
||||||
let elem = elem.to_packed::<StateUpdateElem>().unwrap();
|
let elem = elem.to_packed::<StateUpdateElem>().unwrap();
|
||||||
match &elem.update {
|
match &elem.update {
|
||||||
StateUpdate::Set(value) => state = value.clone(),
|
StateUpdate::Set(value) => state = value.clone(),
|
||||||
|
@ -563,7 +563,7 @@ impl<'a> Generator<'a> {
|
|||||||
introspector: Tracked<Introspector>,
|
introspector: Tracked<Introspector>,
|
||||||
) -> StrResult<Self> {
|
) -> StrResult<Self> {
|
||||||
let bibliography = BibliographyElem::find(introspector)?;
|
let bibliography = BibliographyElem::find(introspector)?;
|
||||||
let groups = introspector.query(&CiteGroup::ELEM.select());
|
let groups = introspector.query(&CiteGroup::ELEM.select()).into_inner();
|
||||||
let infos = Vec::with_capacity(groups.len());
|
let infos = Vec::with_capacity(groups.len());
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
routines,
|
routines,
|
||||||
|
@ -656,7 +656,7 @@ fn query_prefix_widths(
|
|||||||
) -> SmallVec<[Option<Abs>; 4]> {
|
) -> SmallVec<[Option<Abs>; 4]> {
|
||||||
let mut widths = SmallVec::<[Option<Abs>; 4]>::new();
|
let mut widths = SmallVec::<[Option<Abs>; 4]>::new();
|
||||||
let elems = introspector.query(&select_where!(PrefixInfo, key => outline_loc));
|
let elems = introspector.query(&select_where!(PrefixInfo, key => outline_loc));
|
||||||
for elem in &elems {
|
for elem in &elems.into_inner() {
|
||||||
let info = elem.to_packed::<PrefixInfo>().unwrap();
|
let info = elem.to_packed::<PrefixInfo>().unwrap();
|
||||||
let level = info.level.get();
|
let level = info.level.get();
|
||||||
if widths.len() < level {
|
if widths.len() < level {
|
||||||
|
@ -13,7 +13,7 @@ pub(crate) fn embed_files(
|
|||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
let elements = typst_doc.introspector.query(&EmbedElem::ELEM.select());
|
let elements = typst_doc.introspector.query(&EmbedElem::ELEM.select());
|
||||||
|
|
||||||
for elem in &elements {
|
for elem in &elements.into_inner() {
|
||||||
let embed = elem.to_packed::<EmbedElem>().unwrap();
|
let embed = elem.to_packed::<EmbedElem>().unwrap();
|
||||||
let span = embed.span();
|
let span = embed.span();
|
||||||
let derived_path = &embed.path.derived;
|
let derived_path = &embed.path.derived;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user