mirror of
https://github.com/typst/typst
synced 2025-05-20 20:15:29 +08:00
Code review: Reverse temperature
This commit is contained in:
parent
6f518c1728
commit
e9960b8942
@ -26,6 +26,11 @@ impl LayoutCache {
|
|||||||
self.frames.clear();
|
self.frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Amount of items in the cache.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.frames.iter().map(|(_, e)| e.len()).sum()
|
||||||
|
}
|
||||||
|
|
||||||
/// Retains all elements for which the closure on the level returns `true`.
|
/// Retains all elements for which the closure on the level returns `true`.
|
||||||
pub fn retain<F>(&mut self, mut f: F)
|
pub fn retain<F>(&mut self, mut f: F)
|
||||||
where
|
where
|
||||||
@ -41,9 +46,10 @@ impl LayoutCache {
|
|||||||
self.age += 1;
|
self.age += 1;
|
||||||
for entry in self.frames.iter_mut().flat_map(|(_, x)| x.iter_mut()) {
|
for entry in self.frames.iter_mut().flat_map(|(_, x)| x.iter_mut()) {
|
||||||
for i in 0 .. (entry.temperature.len() - 1) {
|
for i in 0 .. (entry.temperature.len() - 1) {
|
||||||
entry.temperature[i] = entry.temperature[i + 1];
|
entry.temperature[i + 1] = entry.temperature[i];
|
||||||
}
|
}
|
||||||
*entry.temperature.last_mut().unwrap() = 0;
|
entry.temperature[0] = 0;
|
||||||
|
entry.age += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,12 +105,11 @@ pub struct FramesEntry {
|
|||||||
pub frames: Vec<Constrained<Rc<Frame>>>,
|
pub frames: Vec<Constrained<Rc<Frame>>>,
|
||||||
/// How nested the frame was in the context is was originally appearing in.
|
/// How nested the frame was in the context is was originally appearing in.
|
||||||
pub level: usize,
|
pub level: usize,
|
||||||
/// How much the element was accessed during the last five compilations, the
|
|
||||||
/// most recent one being the last element. `None` variants indicate that
|
|
||||||
/// the element is younger than five compilations.
|
|
||||||
temperature: [usize; 5],
|
|
||||||
/// For how long the element already exists.
|
/// For how long the element already exists.
|
||||||
age: usize,
|
age: usize,
|
||||||
|
/// How much the element was accessed during the last five compilations, the
|
||||||
|
/// most recent one being the first element.
|
||||||
|
temperature: [usize; 5],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FramesEntry {
|
impl FramesEntry {
|
||||||
@ -113,8 +118,8 @@ impl FramesEntry {
|
|||||||
Self {
|
Self {
|
||||||
frames,
|
frames,
|
||||||
level,
|
level,
|
||||||
temperature: [0; 5],
|
|
||||||
age: 1,
|
age: 1,
|
||||||
|
temperature: [0; 5],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +131,7 @@ impl FramesEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.temperature[4] = self.temperature[4] + 1;
|
self.temperature[0] += 1;
|
||||||
|
|
||||||
Some(self.frames.clone())
|
Some(self.frames.clone())
|
||||||
}
|
}
|
||||||
@ -141,16 +146,11 @@ impl FramesEntry {
|
|||||||
/// been used.
|
/// been used.
|
||||||
pub fn cooldown(&self) -> usize {
|
pub fn cooldown(&self) -> usize {
|
||||||
let mut cycle = 0;
|
let mut cycle = 0;
|
||||||
for (i, &temp) in self.temperature.iter().enumerate().rev() {
|
for &temp in &self.temperature[.. self.age] {
|
||||||
if self.age > i {
|
if temp > 0 {
|
||||||
if temp > 0 {
|
|
||||||
return self.temperature.len() - 1 - i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return cycle;
|
return cycle;
|
||||||
}
|
}
|
||||||
|
cycle += 1;
|
||||||
cycle += 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle
|
cycle
|
||||||
@ -158,7 +158,7 @@ impl FramesEntry {
|
|||||||
|
|
||||||
/// Whether this element was used in the last compilation cycle.
|
/// Whether this element was used in the last compilation cycle.
|
||||||
pub fn hit(&self) -> bool {
|
pub fn hit(&self) -> bool {
|
||||||
self.temperature.last().unwrap() != &0
|
self.temperature[0] != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,10 +213,10 @@ impl Constraints {
|
|||||||
let base = regions.base.to_spec();
|
let base = regions.base.to_spec();
|
||||||
let current = regions.current.to_spec();
|
let current = regions.current.to_spec();
|
||||||
|
|
||||||
current.eq_by(&self.min, |&x, y| y.map_or(true, |y| x.fits(y)))
|
current.eq_by(&self.min, |x, y| y.map_or(true, |y| x.fits(y)))
|
||||||
&& current.eq_by(&self.max, |x, y| y.map_or(true, |y| x < &y))
|
&& current.eq_by(&self.max, |x, y| y.map_or(true, |y| x < &y))
|
||||||
&& current.eq_by(&self.exact, |&x, y| y.map_or(true, |y| x.approx_eq(y)))
|
&& current.eq_by(&self.exact, |x, y| y.map_or(true, |y| x.approx_eq(y)))
|
||||||
&& base.eq_by(&self.base, |&x, y| y.map_or(true, |y| x.approx_eq(y)))
|
&& base.eq_by(&self.base, |x, y| y.map_or(true, |y| x.approx_eq(y)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes all constraints by adding the `size` to them if they are `Some`.
|
/// Changes all constraints by adding the `size` to them if they are `Some`.
|
||||||
@ -235,18 +235,13 @@ impl Constraints {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.exact = override_if_some(self.exact, regions.current.to_spec());
|
let current = regions.current.to_spec();
|
||||||
self.base = override_if_some(self.base, regions.base.to_spec());
|
let base = regions.base.to_spec();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn override_if_some(
|
self.exact.horizontal.set_if_some(current.horizontal);
|
||||||
one: Spec<Option<Length>>,
|
self.exact.vertical.set_if_some(current.vertical);
|
||||||
other: Spec<Length>,
|
self.base.horizontal.set_if_some(base.horizontal);
|
||||||
) -> Spec<Option<Length>> {
|
self.base.vertical.set_if_some(base.vertical);
|
||||||
Spec {
|
|
||||||
vertical: one.vertical.map(|_| other.vertical),
|
|
||||||
horizontal: one.horizontal.map(|_| other.horizontal),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,9 +267,13 @@ pub trait OptionExt {
|
|||||||
// Sets `other` as the value if the Option is `None` or if it contains a
|
// Sets `other` as the value if the Option is `None` or if it contains a
|
||||||
// value larger than `other`.
|
// value larger than `other`.
|
||||||
fn set_min(&mut self, other: Length);
|
fn set_min(&mut self, other: Length);
|
||||||
|
|
||||||
// Sets `other` as the value if the Option is `None` or if it contains a
|
// Sets `other` as the value if the Option is `None` or if it contains a
|
||||||
// value smaller than `other`.
|
// value smaller than `other`.
|
||||||
fn set_max(&mut self, other: Length);
|
fn set_max(&mut self, other: Length);
|
||||||
|
|
||||||
|
/// Sets `other` as the value if the Option is `Some`.
|
||||||
|
fn set_if_some(&mut self, other: Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OptionExt for Option<Length> {
|
impl OptionExt for Option<Length> {
|
||||||
@ -291,4 +290,10 @@ impl OptionExt for Option<Length> {
|
|||||||
None => *self = Some(other),
|
None => *self = Some(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_if_some(&mut self, other: Length) {
|
||||||
|
if self.is_some() {
|
||||||
|
*self = Some(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,11 @@ impl Layout for PadNode {
|
|||||||
ctx: &mut LayoutContext,
|
ctx: &mut LayoutContext,
|
||||||
regions: &Regions,
|
regions: &Regions,
|
||||||
) -> Vec<Constrained<Rc<Frame>>> {
|
) -> Vec<Constrained<Rc<Frame>>> {
|
||||||
let mut original = regions.clone();
|
let mut regions = regions.clone();
|
||||||
let mut regions = regions.map(|size| size - self.padding.resolve(size).size());
|
let mut frames = self.child.layout(
|
||||||
|
ctx,
|
||||||
let mut frames = self.child.layout(ctx, ®ions);
|
®ions.map(|size| size - self.padding.resolve(size).size()),
|
||||||
|
);
|
||||||
|
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
let padded = solve(self.padding, frame.size);
|
let padded = solve(self.padding, frame.size);
|
||||||
@ -29,19 +30,19 @@ impl Layout for PadNode {
|
|||||||
let prev = std::mem::take(&mut frame.item);
|
let prev = std::mem::take(&mut frame.item);
|
||||||
new.push_frame(origin, prev);
|
new.push_frame(origin, prev);
|
||||||
|
|
||||||
frame.constraints.mutate(padding.size(), &original);
|
frame.constraints.mutate(padding.size(), ®ions);
|
||||||
|
|
||||||
if self.padding.left.is_relative() || self.padding.right.is_relative() {
|
if self.padding.left.is_relative() || self.padding.right.is_relative() {
|
||||||
frame.constraints.base.horizontal = Some(original.base.width);
|
frame.constraints.base.horizontal = Some(regions.base.width);
|
||||||
}
|
}
|
||||||
if self.padding.top.is_relative() || self.padding.bottom.is_relative() {
|
if self.padding.top.is_relative() || self.padding.bottom.is_relative() {
|
||||||
frame.constraints.base.vertical = Some(original.base.height);
|
frame.constraints.base.vertical = Some(regions.base.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
regions.next();
|
regions.next();
|
||||||
original.next();
|
|
||||||
*Rc::make_mut(&mut frame.item) = new;
|
*Rc::make_mut(&mut frame.item) = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
frames
|
frames
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,9 +217,11 @@ impl<'a> ParLayouter<'a> {
|
|||||||
// Again, the line must not fit. It would if the space taken up
|
// Again, the line must not fit. It would if the space taken up
|
||||||
// plus the line height would fit, therefore the constraint
|
// plus the line height would fit, therefore the constraint
|
||||||
// below.
|
// below.
|
||||||
stack.constraints.max.vertical.set_min(
|
stack
|
||||||
stack.full.height - stack.regions.current.height + line.size.height,
|
.constraints
|
||||||
);
|
.max
|
||||||
|
.vertical
|
||||||
|
.set_min(stack.size.height + line.size.height);
|
||||||
stack.finish_region(ctx);
|
stack.finish_region(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,9 +232,11 @@ impl<'a> ParLayouter<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.constraints.max.vertical.set_min(
|
stack
|
||||||
stack.full.height - stack.regions.current.height + line.size.height,
|
.constraints
|
||||||
);
|
.max
|
||||||
|
.vertical
|
||||||
|
.set_min(stack.size.height + line.size.height);
|
||||||
stack.finish_region(ctx);
|
stack.finish_region(ctx);
|
||||||
}
|
}
|
||||||
// If the line does not fit horizontally or we have a mandatory
|
// If the line does not fit horizontally or we have a mandatory
|
||||||
|
@ -88,12 +88,12 @@ impl<'a> StackLayouter<'a> {
|
|||||||
Self {
|
Self {
|
||||||
stack,
|
stack,
|
||||||
main,
|
main,
|
||||||
constraints: Constraints::new(expand),
|
|
||||||
expand,
|
expand,
|
||||||
regions,
|
regions,
|
||||||
full,
|
full,
|
||||||
used: Gen::zero(),
|
used: Gen::zero(),
|
||||||
ruler: Align::Start,
|
ruler: Align::Start,
|
||||||
|
constraints: Constraints::new(expand),
|
||||||
overflowing: false,
|
overflowing: false,
|
||||||
frames: vec![],
|
frames: vec![],
|
||||||
finished: vec![],
|
finished: vec![],
|
||||||
@ -154,7 +154,7 @@ impl<'a> StackLayouter<'a> {
|
|||||||
self.constraints
|
self.constraints
|
||||||
.max
|
.max
|
||||||
.get_mut(self.main)
|
.get_mut(self.main)
|
||||||
.set_min(size.main + self.used.main);
|
.set_min(self.used.main + size.main);
|
||||||
self.finish_region();
|
self.finish_region();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ use walkdir::WalkDir;
|
|||||||
|
|
||||||
use typst::cache::Cache;
|
use typst::cache::Cache;
|
||||||
use typst::color;
|
use typst::color;
|
||||||
use typst::diag::{Diag, DiagSet, Level, Pass};
|
use typst::diag::{Diag, DiagSet, Level};
|
||||||
use typst::eval::{eval, EvalContext, FuncArgs, FuncValue, Scope, Value};
|
use typst::eval::{eval, EvalContext, FuncArgs, FuncValue, Scope, Value};
|
||||||
use typst::exec::{exec, State};
|
use typst::exec::{exec, State};
|
||||||
use typst::geom::{self, Length, Point, Sides, Size};
|
use typst::geom::{self, Length, Point, Sides, Size};
|
||||||
@ -233,14 +233,12 @@ fn test_part(
|
|||||||
&scope,
|
&scope,
|
||||||
);
|
);
|
||||||
let executed = exec(&evaluated.output.template, state.clone());
|
let executed = exec(&evaluated.output.template, state.clone());
|
||||||
let layouted = layout(loader, cache, &executed.output);
|
let mut layouted = layout(loader, cache, &executed.output);
|
||||||
|
|
||||||
let mut diags = parsed.diags;
|
let mut diags = parsed.diags;
|
||||||
diags.extend(evaluated.diags);
|
diags.extend(evaluated.diags);
|
||||||
diags.extend(executed.diags);
|
diags.extend(executed.diags);
|
||||||
|
|
||||||
let mut pass = Pass::new(layouted, diags);
|
|
||||||
|
|
||||||
let mut ok = true;
|
let mut ok = true;
|
||||||
|
|
||||||
for panic in &*panics.borrow() {
|
for panic in &*panics.borrow() {
|
||||||
@ -255,11 +253,11 @@ fn test_part(
|
|||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if pass.diags != ref_diags {
|
if diags != ref_diags {
|
||||||
println!(" Subtest {} does not match expected diagnostics. ❌", i);
|
println!(" Subtest {} does not match expected diagnostics. ❌", i);
|
||||||
ok = false;
|
ok = false;
|
||||||
|
|
||||||
for diag in &pass.diags {
|
for diag in &diags {
|
||||||
if !ref_diags.contains(diag) {
|
if !ref_diags.contains(diag) {
|
||||||
print!(" Not annotated | ");
|
print!(" Not annotated | ");
|
||||||
print_diag(diag, &map, lines);
|
print_diag(diag, &map, lines);
|
||||||
@ -267,7 +265,7 @@ fn test_part(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for diag in &ref_diags {
|
for diag in &ref_diags {
|
||||||
if !pass.diags.contains(diag) {
|
if !diags.contains(diag) {
|
||||||
print!(" Not emitted | ");
|
print!(" Not emitted | ");
|
||||||
print_diag(diag, &map, lines);
|
print_diag(diag, &map, lines);
|
||||||
}
|
}
|
||||||
@ -302,7 +300,7 @@ fn test_part(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cached_result != pass.output {
|
if cached_result != layouted {
|
||||||
ok = false;
|
ok = false;
|
||||||
println!(
|
println!(
|
||||||
" Recompilation of subtest {} differs from clean pass ❌",
|
" Recompilation of subtest {} differs from clean pass ❌",
|
||||||
@ -315,10 +313,10 @@ fn test_part(
|
|||||||
cache.layout.turnaround();
|
cache.layout.turnaround();
|
||||||
|
|
||||||
if !compare_ref {
|
if !compare_ref {
|
||||||
pass.output.clear();
|
layouted.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
(ok, compare_ref, pass.output)
|
(ok, compare_ref, layouted)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) {
|
fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user