Skip to content

Commit

Permalink
Don't convert SystemTime to DateTime<Utc> if cache has not expired
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Aug 18, 2024
1 parent 5ed160c commit 0964d50
Showing 1 changed file with 36 additions and 20 deletions.
56 changes: 36 additions & 20 deletions spdlog/src/formatter/local_time_cacher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ where

#[derive(Clone)]
pub(crate) struct LocalTimeCacher {
stored_key: i64,
stored_key: u64,
cache_values: Option<CacheValues>,
}

Expand Down Expand Up @@ -74,30 +74,19 @@ impl LocalTimeCacher {

#[must_use]
pub(crate) fn get(&mut self, system_time: SystemTime) -> TimeDate {
self.get_inner(system_time.into())
}

fn get_inner(&mut self, utc_time: DateTime<Utc>) -> TimeDate {
const LEAP_BOUNDARY: u32 = 1_000_000_000;

let nanosecond = utc_time.nanosecond();
let is_leap_second = nanosecond >= LEAP_BOUNDARY;
let reduced_nanosecond = if is_leap_second {
nanosecond - LEAP_BOUNDARY
} else {
nanosecond
};
let millisecond = reduced_nanosecond / 1_000_000;
let since_epoch = system_time.duration_since(SystemTime::UNIX_EPOCH).unwrap();
let nanosecond = since_epoch.subsec_nanos();
let millisecond = nanosecond / 1_000_000;

let cache_key = utc_time.timestamp();
let cache_key = since_epoch.as_secs();
if self.cache_values.is_none() || self.stored_key != cache_key {
self.cache_values = Some(CacheValues::new(utc_time));
self.cache_values = Some(CacheValues::new(system_time));
self.stored_key = cache_key;
}

TimeDate {
cached: self.cache_values.as_mut().unwrap(),
nanosecond: reduced_nanosecond,
nanosecond,
millisecond,
}
}
Expand Down Expand Up @@ -299,9 +288,9 @@ impl<'a> TimeDate<'a> {

impl CacheValues {
#[must_use]
fn new(utc_time: DateTime<Utc>) -> Self {
fn new(system_time: SystemTime) -> Self {
CacheValues {
local_time: utc_time.into(),
local_time: system_time.into(),
full_second_str: None,
year: None,
year_str: None,
Expand Down Expand Up @@ -372,3 +361,30 @@ impl fmt::Debug for TimeDateLazyLocked<'_> {
.finish()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn validation() {
let mut cacher = LocalTimeCacher::new();

let begin = SystemTime::now();
loop {
let now = SystemTime::now();
if now.duration_since(begin).unwrap().as_secs() >= 3 {
break;
}
let from_cache = cacher.get(now);
let from_chrono = DateTime::<Local>::from(now);

assert_eq!(
from_cache.cached.local_time.with_nanosecond(0),
from_chrono.with_nanosecond(0)
);
assert_eq!(from_cache.nanosecond, from_chrono.nanosecond());
assert_eq!(from_cache.millisecond, from_chrono.nanosecond() / 1_000_000);
}
}
}

0 comments on commit 0964d50

Please sign in to comment.