diff options
| author | Daniel Csillag <dccsillag@gmail.com> | 2023-04-11 14:11:44 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-11 19:11:44 +0200 |
| commit | 5bc73be90fdb7d46ea67bc00babc5f4833854306 (patch) | |
| tree | 1eab135f5aeedfa95761b262f962a52c0270224d /src | |
| parent | 72d8785abeff66f6b832725e71fe65d9ded803ce (diff) | |
Optimization to `Introspector::extract` (#734)
Diffstat (limited to 'src')
| -rw-r--r-- | src/model/introspect.rs | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/src/model/introspect.rs b/src/model/introspect.rs index 31808872..9697f850 100644 --- a/src/model/introspect.rs +++ b/src/model/introspect.rs @@ -2,6 +2,8 @@ use std::fmt::{self, Debug, Formatter}; use std::hash::Hash; use std::num::NonZeroUsize; +use indexmap::IndexMap; + use super::{Content, Selector}; use crate::diag::StrResult; use crate::doc::{Frame, FrameItem, Meta, Position}; @@ -83,7 +85,7 @@ impl StabilityProvider { /// Can be queried for elements and their positions. pub struct Introspector { pages: usize, - elems: Vec<(Content, Position)>, + elems: IndexMap<Option<Location>, (Content, Position)>, // Indexed by page number. page_numberings: Vec<Value>, } @@ -93,7 +95,7 @@ impl Introspector { pub fn new(frames: &[Frame]) -> Self { let mut introspector = Self { pages: frames.len(), - elems: vec![], + elems: IndexMap::new(), page_numberings: vec![], }; for (i, frame) in frames.iter().enumerate() { @@ -105,7 +107,7 @@ impl Introspector { /// Iterate over all elements. pub fn all(&self) -> impl Iterator<Item = &Content> { - self.elems.iter().map(|(elem, _)| elem) + self.elems.values().map(|(elem, _)| elem) } /// Extract metadata from a frame. @@ -119,13 +121,14 @@ impl Introspector { self.extract(&group.frame, page, ts); } FrameItem::Meta(Meta::Elem(content), _) - if !self - .elems - .iter() - .any(|(prev, _)| prev.location() == content.location()) => + if !self.elems.contains_key(&content.location()) => { let pos = pos.transform(ts); - self.elems.push((content.clone(), Position { page, point: pos })); + let ret = self.elems.insert( + content.location(), + (content.clone(), Position { page, point: pos }), + ); + assert!(ret.is_none(), "duplicate locations"); } FrameItem::Meta(Meta::PageNumbering(numbering), _) => { self.page_numberings.push(numbering.clone()); @@ -202,8 +205,7 @@ impl Introspector { /// Find the position for the given location. pub fn position(&self, location: Location) -> Position { self.elems - .iter() - .find(|(elem, _)| elem.location() == Some(location)) + .get(&Some(location)) .map(|(_, loc)| *loc) .unwrap_or(Position { page: NonZeroUsize::ONE, point: Point::zero() }) } |
