Remove decorum

This commit is contained in:
Laurenz 2021-11-22 15:50:35 +01:00
parent 0a974d86ba
commit 02f114d072
18 changed files with 248 additions and 94 deletions

View File

@ -19,7 +19,6 @@ debug = 0
opt-level = 2 opt-level = 2
[dependencies] [dependencies]
decorum = { version = "0.3.1", default-features = false, features = ["serialize-serde"] }
fxhash = "0.2.1" fxhash = "0.2.1"
image = { version = "0.23", default-features = false, features = ["png", "jpeg"] } image = { version = "0.23", default-features = false, features = ["png", "jpeg"] }
itertools = "0.10" itertools = "0.10"

View File

@ -17,7 +17,7 @@ pub enum Align {
impl Align { impl Align {
/// The axis this alignment belongs to if it is specific. /// The axis this alignment belongs to if it is specific.
pub fn axis(self) -> Option<SpecAxis> { pub const fn axis(self) -> Option<SpecAxis> {
match self { match self {
Self::Left => Some(SpecAxis::Horizontal), Self::Left => Some(SpecAxis::Horizontal),
Self::Top => Some(SpecAxis::Vertical), Self::Top => Some(SpecAxis::Vertical),
@ -28,7 +28,7 @@ impl Align {
} }
/// The inverse alignment. /// The inverse alignment.
pub fn inv(self) -> Self { pub const fn inv(self) -> Self {
match self { match self {
Self::Left => Self::Right, Self::Left => Self::Right,
Self::Top => Self::Bottom, Self::Top => Self::Bottom,

View File

@ -3,12 +3,12 @@ use super::*;
/// An angle. /// An angle.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Angle(N64); pub struct Angle(Scalar);
impl Angle { impl Angle {
/// The zero angle. /// The zero angle.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self(N64::from(0.0)) Self(Scalar(0.0))
} }
/// Create an angle from a number of radians. /// Create an angle from a number of radians.
@ -22,8 +22,8 @@ impl Angle {
} }
/// Create an angle from a number of raw units. /// Create an angle from a number of raw units.
pub fn raw(raw: f64) -> Self { pub const fn raw(raw: f64) -> Self {
Self(N64::from(raw)) Self(Scalar(raw))
} }
/// Convert this to a number of radians. /// Convert this to a number of radians.
@ -37,13 +37,13 @@ impl Angle {
} }
/// Get the value of this angle in raw units. /// Get the value of this angle in raw units.
pub fn to_raw(self) -> f64 { pub const fn to_raw(self) -> f64 {
self.0.into() (self.0).0
} }
/// Create an angle from a value in a unit. /// Create an angle from a value in a unit.
pub fn with_unit(val: f64, unit: AngularUnit) -> Self { pub fn with_unit(val: f64, unit: AngularUnit) -> Self {
Self(N64::from(val * unit.raw_scale())) Self(Scalar(val * unit.raw_scale()))
} }
/// Get the value of this length in unit. /// Get the value of this length in unit.

View File

@ -15,7 +15,7 @@ pub enum Dir {
impl Dir { impl Dir {
/// The side this direction starts at. /// The side this direction starts at.
pub fn start(self) -> Side { pub const fn start(self) -> Side {
match self { match self {
Self::LTR => Side::Left, Self::LTR => Side::Left,
Self::RTL => Side::Right, Self::RTL => Side::Right,
@ -25,7 +25,7 @@ impl Dir {
} }
/// The side this direction ends at. /// The side this direction ends at.
pub fn end(self) -> Side { pub const fn end(self) -> Side {
match self { match self {
Self::LTR => Side::Right, Self::LTR => Side::Right,
Self::RTL => Side::Left, Self::RTL => Side::Left,
@ -35,7 +35,7 @@ impl Dir {
} }
/// The specific axis this direction belongs to. /// The specific axis this direction belongs to.
pub fn axis(self) -> SpecAxis { pub const fn axis(self) -> SpecAxis {
match self { match self {
Self::LTR | Self::RTL => SpecAxis::Horizontal, Self::LTR | Self::RTL => SpecAxis::Horizontal,
Self::TTB | Self::BTT => SpecAxis::Vertical, Self::TTB | Self::BTT => SpecAxis::Vertical,
@ -45,7 +45,7 @@ impl Dir {
/// Whether this direction points into the positive coordinate direction. /// Whether this direction points into the positive coordinate direction.
/// ///
/// The positive directions are left-to-right and top-to-bottom. /// The positive directions are left-to-right and top-to-bottom.
pub fn is_positive(self) -> bool { pub const fn is_positive(self) -> bool {
match self { match self {
Self::LTR | Self::TTB => true, Self::LTR | Self::TTB => true,
Self::RTL | Self::BTT => false, Self::RTL | Self::BTT => false,
@ -56,12 +56,12 @@ impl Dir {
/// ///
/// - `1.0` if the direction is positive. /// - `1.0` if the direction is positive.
/// - `-1.0` if the direction is negative. /// - `-1.0` if the direction is negative.
pub fn factor(self) -> f64 { pub const fn factor(self) -> f64 {
if self.is_positive() { 1.0 } else { -1.0 } if self.is_positive() { 1.0 } else { -1.0 }
} }
/// The inverse direction. /// The inverse direction.
pub fn inv(self) -> Self { pub const fn inv(self) -> Self {
match self { match self {
Self::LTR => Self::RTL, Self::LTR => Self::RTL,
Self::RTL => Self::LTR, Self::RTL => Self::LTR,

View File

@ -5,27 +5,27 @@ use super::*;
/// `1em` is the same as the font size. /// `1em` is the same as the font size.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Em(N64); pub struct Em(Scalar);
impl Em { impl Em {
/// The zero length. /// The zero length.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self(N64::from(0.0)) Self(Scalar(0.0))
} }
/// The font size. /// The font size.
pub fn one() -> Self { pub const fn one() -> Self {
Self(N64::from(1.0)) Self(Scalar(1.0))
} }
/// Create an font-relative length. /// Create an font-relative length.
pub fn new(em: f64) -> Self { pub const fn new(em: f64) -> Self {
Self(N64::from(em)) Self(Scalar(em))
} }
/// Create font units at the given units per em. /// Create font units at the given units per em.
pub fn from_units(units: impl Into<f64>, units_per_em: f64) -> Self { pub fn from_units(units: impl Into<f64>, units_per_em: f64) -> Self {
Self(N64::from(units.into() / units_per_em)) Self(Scalar(units.into() / units_per_em))
} }
/// Convert to a length at the given font size. /// Convert to a length at the given font size.
@ -34,8 +34,8 @@ impl Em {
} }
/// The number of em units. /// The number of em units.
pub fn get(self) -> f64 { pub const fn get(self) -> f64 {
self.0.into() (self.0).0
} }
/// Whether the length is zero. /// Whether the length is zero.

View File

@ -2,27 +2,27 @@ use super::*;
/// A fractional length. /// A fractional length.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Fractional(N64); pub struct Fractional(Scalar);
impl Fractional { impl Fractional {
/// Takes up zero space: `0fr`. /// Takes up zero space: `0fr`.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self(N64::from(0.0)) Self(Scalar(0.0))
} }
/// Takes up as much space as all other items with this fractional size: `1fr`. /// Takes up as much space as all other items with this fractional size: `1fr`.
pub fn one() -> Self { pub const fn one() -> Self {
Self(N64::from(1.0)) Self(Scalar(1.0))
} }
/// Create a new fractional value. /// Create a new fractional value.
pub fn new(ratio: f64) -> Self { pub const fn new(ratio: f64) -> Self {
Self(N64::from(ratio)) Self(Scalar(ratio))
} }
/// Get the underlying ratio. /// Get the underlying ratio.
pub fn get(self) -> f64 { pub const fn get(self) -> f64 {
self.0.into() (self.0).0
} }
/// Whether the ratio is zero. /// Whether the ratio is zero.

View File

@ -11,7 +11,7 @@ pub struct Gen<T> {
impl<T> Gen<T> { impl<T> Gen<T> {
/// Create a new instance from the two components. /// Create a new instance from the two components.
pub fn new(inline: T, block: T) -> Self { pub const fn new(inline: T, block: T) -> Self {
Self { inline, block } Self { inline, block }
} }

View File

@ -4,17 +4,17 @@ use super::*;
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(transparent)] #[serde(transparent)]
pub struct Length(N64); pub struct Length(Scalar);
impl Length { impl Length {
/// The zero length. /// The zero length.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self(N64::from(0.0)) Self(Scalar(0.0))
} }
/// The inifinite length. /// The inifinite length.
pub fn inf() -> Self { pub const fn inf() -> Self {
Self(N64::from(f64::INFINITY)) Self(Scalar(f64::INFINITY))
} }
/// Create a length from a number of points. /// Create a length from a number of points.
@ -38,8 +38,8 @@ impl Length {
} }
/// Create a length from a number of raw units. /// Create a length from a number of raw units.
pub fn raw(raw: f64) -> Self { pub const fn raw(raw: f64) -> Self {
Self(N64::from(raw)) Self(Scalar(raw))
} }
/// Convert this to a number of points. /// Convert this to a number of points.
@ -63,13 +63,13 @@ impl Length {
} }
/// Get the value of this length in raw units. /// Get the value of this length in raw units.
pub fn to_raw(self) -> f64 { pub const fn to_raw(self) -> f64 {
self.0.into() (self.0).0
} }
/// Create a length from a value in a unit. /// Create a length from a value in a unit.
pub fn with_unit(val: f64, unit: LengthUnit) -> Self { pub fn with_unit(val: f64, unit: LengthUnit) -> Self {
Self(N64::from(val * unit.raw_scale())) Self(Scalar(val * unit.raw_scale()))
} }
/// Get the value of this length in unit. /// Get the value of this length in unit.
@ -79,17 +79,17 @@ impl Length {
/// Whether the length is zero. /// Whether the length is zero.
pub fn is_zero(self) -> bool { pub fn is_zero(self) -> bool {
self.0 == 0.0 self.to_raw() == 0.0
} }
/// Whether the length is finite. /// Whether the length is finite.
pub fn is_finite(self) -> bool { pub fn is_finite(self) -> bool {
self.0.into_inner().is_finite() self.to_raw().is_finite()
} }
/// Whether the length is infinite. /// Whether the length is infinite.
pub fn is_infinite(self) -> bool { pub fn is_infinite(self) -> bool {
self.0.into_inner().is_infinite() self.to_raw().is_infinite()
} }
/// The absolute value of the this length. /// The absolute value of the this length.
@ -211,14 +211,14 @@ assign_impl!(Length *= f64);
assign_impl!(Length /= f64); assign_impl!(Length /= f64);
impl Sum for Length { impl Sum for Length {
fn sum<I: Iterator<Item = Length>>(iter: I) -> Self { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Length::zero(), Add::add) Self(iter.map(|s| s.0).sum())
} }
} }
impl<'a> Sum<&'a Length> for Length { impl<'a> Sum<&'a Self> for Length {
fn sum<I: Iterator<Item = &'a Length>>(iter: I) -> Self { fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.copied().fold(Length::zero(), Add::add) Self(iter.map(|s| s.0).sum())
} }
} }

View File

@ -11,7 +11,7 @@ pub struct Linear {
impl Linear { impl Linear {
/// The zero linear. /// The zero linear.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self { Self {
rel: Relative::zero(), rel: Relative::zero(),
abs: Length::zero(), abs: Length::zero(),
@ -19,7 +19,7 @@ impl Linear {
} }
/// The linear with a relative part of `100%` and no absolute part. /// The linear with a relative part of `100%` and no absolute part.
pub fn one() -> Self { pub const fn one() -> Self {
Self { Self {
rel: Relative::one(), rel: Relative::one(),
abs: Length::zero(), abs: Length::zero(),
@ -27,7 +27,7 @@ impl Linear {
} }
/// Create a new linear. /// Create a new linear.
pub fn new(rel: Relative, abs: Length) -> Self { pub const fn new(rel: Relative, abs: Length) -> Self {
Self { rel, abs } Self { rel, abs }
} }

View File

@ -14,6 +14,7 @@ mod paint;
mod path; mod path;
mod point; mod point;
mod relative; mod relative;
mod scalar;
mod sides; mod sides;
mod size; mod size;
mod spec; mod spec;
@ -30,16 +31,18 @@ pub use paint::*;
pub use path::*; pub use path::*;
pub use point::*; pub use point::*;
pub use relative::*; pub use relative::*;
pub use scalar::*;
pub use sides::*; pub use sides::*;
pub use size::*; pub use size::*;
pub use spec::*; pub use spec::*;
use std::cmp::Ordering;
use std::f64::consts::PI; use std::f64::consts::PI;
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::iter::Sum; use std::iter::Sum;
use std::ops::*; use std::ops::*;
use decorum::N64;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Generic access to a structure's components. /// Generic access to a structure's components.

View File

@ -16,7 +16,7 @@ pub enum PathElement {
impl Path { impl Path {
/// Create an empty path. /// Create an empty path.
pub fn new() -> Self { pub const fn new() -> Self {
Self(vec![]) Self(vec![])
} }

View File

@ -11,22 +11,22 @@ pub struct Point {
impl Point { impl Point {
/// The origin point. /// The origin point.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self { x: Length::zero(), y: Length::zero() } Self { x: Length::zero(), y: Length::zero() }
} }
/// Create a new point from x and y coordinate. /// Create a new point from x and y coordinate.
pub fn new(x: Length, y: Length) -> Self { pub const fn new(x: Length, y: Length) -> Self {
Self { x, y } Self { x, y }
} }
/// Create an instance with two equal components. /// Create an instance with two equal components.
pub fn splat(value: Length) -> Self { pub const fn splat(value: Length) -> Self {
Self { x: value, y: value } Self { x: value, y: value }
} }
/// Convert to the generic representation. /// Convert to the generic representation.
pub fn to_gen(self, block: SpecAxis) -> Gen<Length> { pub const fn to_gen(self, block: SpecAxis) -> Gen<Length> {
match block { match block {
SpecAxis::Horizontal => Gen::new(self.y, self.x), SpecAxis::Horizontal => Gen::new(self.y, self.x),
SpecAxis::Vertical => Gen::new(self.x, self.y), SpecAxis::Vertical => Gen::new(self.x, self.y),

View File

@ -5,27 +5,27 @@ use super::*;
/// _Note_: `50%` is represented as `0.5` here, but stored as `50.0` in the /// _Note_: `50%` is represented as `0.5` here, but stored as `50.0` in the
/// corresponding [literal](crate::syntax::ast::LitKind::Percent). /// corresponding [literal](crate::syntax::ast::LitKind::Percent).
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Relative(N64); pub struct Relative(Scalar);
impl Relative { impl Relative {
/// A ratio of `0%` represented as `0.0`. /// A ratio of `0%` represented as `0.0`.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self(N64::from(0.0)) Self(Scalar(0.0))
} }
/// A ratio of `100%` represented as `1.0`. /// A ratio of `100%` represented as `1.0`.
pub fn one() -> Self { pub const fn one() -> Self {
Self(N64::from(1.0)) Self(Scalar(1.0))
} }
/// Create a new relative value. /// Create a new relative value.
pub fn new(ratio: f64) -> Self { pub const fn new(ratio: f64) -> Self {
Self(N64::from(ratio)) Self(Scalar(ratio))
} }
/// Get the underlying ratio. /// Get the underlying ratio.
pub fn get(self) -> f64 { pub const fn get(self) -> f64 {
self.0.into() (self.0).0
} }
/// Resolve this relative to the given `length`. /// Resolve this relative to the given `length`.

152
src/geom/scalar.rs Normal file
View File

@ -0,0 +1,152 @@
use super::*;
/// A 64-bit float that implements `Eq`, `Ord` and `Hash`.
///
/// Panics if its `NaN` during any of those operations.
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Scalar(pub f64);
impl From<f64> for Scalar {
fn from(float: f64) -> Self {
Self(float)
}
}
impl From<Scalar> for f64 {
fn from(scalar: Scalar) -> Self {
scalar.0
}
}
impl Debug for Scalar {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl Ord for Scalar {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(&other).expect("float is NaN")
}
}
impl PartialOrd for Scalar {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
fn lt(&self, other: &Self) -> bool {
self.0 < other.0
}
fn le(&self, other: &Self) -> bool {
self.0 <= other.0
}
fn gt(&self, other: &Self) -> bool {
self.0 > other.0
}
fn ge(&self, other: &Self) -> bool {
self.0 >= other.0
}
}
impl Eq for Scalar {}
impl PartialEq for Scalar {
fn eq(&self, other: &Self) -> bool {
assert!(!self.0.is_nan() && !other.0.is_nan(), "float is NaN");
self.0 == other.0
}
}
impl PartialEq<f64> for Scalar {
fn eq(&self, other: &f64) -> bool {
self == &Self(*other)
}
}
impl Hash for Scalar {
fn hash<H: Hasher>(&self, state: &mut H) {
debug_assert!(!self.0.is_nan(), "float is NaN");
self.0.to_bits().hash(state);
}
}
impl Neg for Scalar {
type Output = Self;
fn neg(self) -> Self::Output {
Self(-self.0)
}
}
impl<T: Into<Self>> Add<T> for Scalar {
type Output = Self;
fn add(self, rhs: T) -> Self::Output {
Self(self.0 + rhs.into().0)
}
}
impl<T: Into<Self>> AddAssign<T> for Scalar {
fn add_assign(&mut self, rhs: T) {
self.0 += rhs.into().0;
}
}
impl<T: Into<Self>> Sub<T> for Scalar {
type Output = Self;
fn sub(self, rhs: T) -> Self::Output {
Self(self.0 - rhs.into().0)
}
}
impl<T: Into<Self>> SubAssign<T> for Scalar {
fn sub_assign(&mut self, rhs: T) {
self.0 -= rhs.into().0;
}
}
impl<T: Into<Self>> Mul<T> for Scalar {
type Output = Self;
fn mul(self, rhs: T) -> Self::Output {
Self(self.0 * rhs.into().0)
}
}
impl<T: Into<Self>> MulAssign<T> for Scalar {
fn mul_assign(&mut self, rhs: T) {
self.0 *= rhs.into().0;
}
}
impl<T: Into<Self>> Div<T> for Scalar {
type Output = Self;
fn div(self, rhs: T) -> Self::Output {
Self(self.0 / rhs.into().0)
}
}
impl<T: Into<Self>> DivAssign<T> for Scalar {
fn div_assign(&mut self, rhs: T) {
self.0 /= rhs.into().0;
}
}
impl Sum for Scalar {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
Self(iter.map(|s| s.0).sum())
}
}
impl<'a> Sum<&'a Self> for Scalar {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
Self(iter.map(|s| s.0).sum())
}
}

View File

@ -15,7 +15,7 @@ pub struct Sides<T> {
impl<T> Sides<T> { impl<T> Sides<T> {
/// Create a new instance from the four components. /// Create a new instance from the four components.
pub fn new(left: T, top: T, right: T, bottom: T) -> Self { pub const fn new(left: T, top: T, right: T, bottom: T) -> Self {
Self { left, top, right, bottom } Self { left, top, right, bottom }
} }

View File

@ -11,17 +11,17 @@ pub struct Size {
impl Size { impl Size {
/// The zero size. /// The zero size.
pub fn zero() -> Self { pub const fn zero() -> Self {
Self { w: Length::zero(), h: Length::zero() } Self { w: Length::zero(), h: Length::zero() }
} }
/// Create a new size from width and height. /// Create a new size from width and height.
pub fn new(w: Length, h: Length) -> Self { pub const fn new(w: Length, h: Length) -> Self {
Self { w, h } Self { w, h }
} }
/// Create an instance with two equal components. /// Create an instance with two equal components.
pub fn splat(v: Length) -> Self { pub const fn splat(v: Length) -> Self {
Self { w: v, h: v } Self { w: v, h: v }
} }
@ -41,17 +41,17 @@ impl Size {
} }
/// Convert to a point. /// Convert to a point.
pub fn to_point(self) -> Point { pub const fn to_point(self) -> Point {
Point::new(self.w, self.h) Point::new(self.w, self.h)
} }
/// Convert to a Spec. /// Convert to a Spec.
pub fn to_spec(self) -> Spec<Length> { pub const fn to_spec(self) -> Spec<Length> {
Spec::new(self.w, self.h) Spec::new(self.w, self.h)
} }
/// Convert to the generic representation. /// Convert to the generic representation.
pub fn to_gen(self, block: SpecAxis) -> Gen<Length> { pub const fn to_gen(self, block: SpecAxis) -> Gen<Length> {
match block { match block {
SpecAxis::Horizontal => Gen::new(self.h, self.w), SpecAxis::Horizontal => Gen::new(self.h, self.w),
SpecAxis::Vertical => Gen::new(self.w, self.h), SpecAxis::Vertical => Gen::new(self.w, self.h),

View File

@ -11,7 +11,7 @@ pub struct Spec<T> {
impl<T> Spec<T> { impl<T> Spec<T> {
/// Create a new instance from the two components. /// Create a new instance from the two components.
pub fn new(x: T, y: T) -> Self { pub const fn new(x: T, y: T) -> Self {
Self { x, y } Self { x, y }
} }

View File

@ -2,11 +2,11 @@ use std::cmp::Reverse;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use decorum::N32;
use itertools::Itertools; use itertools::Itertools;
use super::{Constrained, Regions}; use super::{Constrained, Regions};
use crate::frame::Frame; use crate::frame::Frame;
use crate::geom::Scalar;
const TEMP_LEN: usize = 5; const TEMP_LEN: usize = 5;
const TEMP_LAST: usize = TEMP_LEN - 1; const TEMP_LAST: usize = TEMP_LEN - 1;
@ -135,28 +135,27 @@ impl LayoutCache {
.0; .0;
for entries in self.frames.values_mut() { for entries in self.frames.values_mut() {
entries.retain(|e| e.cooldown() < threshold); entries.retain(|f| f.cooldown() < threshold);
} }
} }
EvictionPolicy::LeastFrequentlyUsed => { EvictionPolicy::LeastFrequentlyUsed => {
let threshold = self let threshold = self
.entries() .entries()
.map(|f| N32::from(f.hits() as f32 / f.age() as f32)) .map(|f| Scalar(f.hits() as f64 / f.age() as f64))
.k_smallest(len - self.max_size) .k_smallest(len - self.max_size)
.last() .last()
.unwrap(); .unwrap()
.0;
for entries in self.frames.values_mut() { for entries in self.frames.values_mut() {
entries.retain(|f| { entries.retain(|f| f.hits() as f64 / f.age() as f64 > threshold);
f.hits() as f32 / f.age() as f32 > threshold.into_inner()
});
} }
} }
EvictionPolicy::Random => { EvictionPolicy::Random => {
// Fraction of items that should be kept. // Fraction of items that should be kept.
let threshold = self.max_size as f32 / len as f32; let threshold = self.max_size as f64 / len as f64;
for entries in self.frames.values_mut() { for entries in self.frames.values_mut() {
entries.retain(|_| rand::random::<f32>() > threshold); entries.retain(|_| rand::random::<f64>() > threshold);
} }
} }
EvictionPolicy::Patterns => { EvictionPolicy::Patterns => {
@ -170,15 +169,16 @@ impl LayoutCache {
let threshold = self let threshold = self
.entries() .entries()
.filter(|f| !f.properties().must_keep()) .filter(|f| !f.properties().must_keep())
.map(|f| N32::from(f.hits() as f32 / f.age() as f32)) .map(|f| Scalar(f.hits() as f64 / f.age() as f64))
.k_smallest((len - kept) - remaining_capacity) .k_smallest((len - kept) - remaining_capacity)
.last() .last()
.unwrap(); .unwrap()
.0;
for (_, entries) in self.frames.iter_mut() { for entries in self.frames.values_mut() {
entries.retain(|f| { entries.retain(|f| {
f.properties().must_keep() f.properties().must_keep()
|| f.hits() as f32 / f.age() as f32 > threshold.into_inner() || f.hits() as f64 / f.age() as f64 > threshold
}); });
} }
} }