diff --git a/pageserver/src/page_cache.rs b/pageserver/src/page_cache.rs index 0f18639354..82e03b8e51 100644 --- a/pageserver/src/page_cache.rs +++ b/pageserver/src/page_cache.rs @@ -831,8 +831,9 @@ impl PageCache { loop { thread::sleep(conf.gc_period); let last_lsn = self.get_last_valid_lsn(); - if last_lsn.0 > conf.gc_horizon { - let horizon = last_lsn - conf.gc_horizon; + + // checked_sub() returns None on overflow. + if let Some(horizon) = last_lsn.checked_sub(conf.gc_horizon) { let mut maxkey = CacheKey { tag: BufferTag { rel: RelTag { diff --git a/zenith_utils/src/lsn.rs b/zenith_utils/src/lsn.rs index a67b17b1e4..a1f48ddb84 100644 --- a/zenith_utils/src/lsn.rs +++ b/zenith_utils/src/lsn.rs @@ -1,7 +1,7 @@ #![warn(missing_docs)] use std::fmt; -use std::ops::{Add, AddAssign, Sub}; +use std::ops::{Add, AddAssign}; use std::path::Path; use std::str::FromStr; @@ -18,6 +18,12 @@ impl Lsn { /// Maximum possible value for an LSN pub const MAX: Lsn = Lsn(u64::MAX); + /// Subtract a number, returning None on overflow. + pub fn checked_sub>(self, other: T) -> Option { + let other: u64 = other.into(); + self.0.checked_sub(other).map(Lsn) + } + /// Parse an LSN from a filename in the form `0000000000000000` pub fn from_filename(filename: F) -> Result where @@ -86,15 +92,6 @@ impl fmt::Display for Lsn { } } -impl Sub for Lsn { - type Output = Lsn; - - fn sub(self, other: u64) -> Self::Output { - // panic if the subtraction overflows/underflows. - Lsn(self.0.checked_sub(other).unwrap()) - } -} - impl Add for Lsn { type Output = Lsn;