switch next_day_at to a newtype

This commit is contained in:
Damien Elmes 2021-04-05 16:17:26 +10:00
parent 8d6b9d15a5
commit ebf7cc61d4
9 changed files with 51 additions and 40 deletions

View file

@ -180,7 +180,7 @@ impl From<crate::scheduler::timing::SchedTimingToday> for pb::SchedTimingTodayOu
fn from(t: crate::scheduler::timing::SchedTimingToday) -> pb::SchedTimingTodayOut {
pb::SchedTimingTodayOut {
days_elapsed: t.days_elapsed,
next_day_at: t.next_day_at,
next_day_at: t.next_day_at.0,
}
}
}

View file

@ -93,7 +93,7 @@ impl CardStateUpdater {
}
fn secs_until_rollover(&self) -> u32 {
(self.timing.next_day_at - self.now.0).max(0) as u32
self.timing.next_day_at.elapsed_secs_since(self.now) as u32
}
fn into_card(self) -> Card {
@ -197,7 +197,7 @@ impl Collection {
let collapse_time = self.learn_ahead_secs();
let now = TimestampSecs::now();
let timing = self.timing_for_timestamp(now)?;
let secs_until_rollover = (timing.next_day_at - now.0).max(0) as u32;
let secs_until_rollover = timing.next_day_at.elapsed_secs_since(now).max(0) as u32;
Ok(vec![
answer_button_time_collapsible(

View file

@ -66,7 +66,7 @@ impl CardQueues {
timing: SchedTimingToday,
) -> Option<LearningQueueEntry> {
// not due today?
if !card.is_intraday_learning() || card.due >= timing.next_day_at as i32 {
if !card.is_intraday_learning() || card.due >= timing.next_day_at.0 as i32 {
return None;
}

View file

@ -10,7 +10,7 @@ pub struct SchedTimingToday {
/// The number of days that have passed since the collection was created.
pub days_elapsed: u32,
/// Timestamp of the next day rollover.
pub next_day_at: i64,
pub next_day_at: TimestampSecs,
}
/// Timing information for the current day.
@ -34,11 +34,11 @@ pub fn sched_timing_today_v2_new(
// rollover
let rollover_today_datetime = today.and_hms(rollover_hour as u32, 0, 0);
let rollover_passed = rollover_today_datetime <= now_datetime;
let next_day_at = if rollover_passed {
let next_day_at = TimestampSecs(if rollover_passed {
(rollover_today_datetime + Duration::days(1)).timestamp()
} else {
rollover_today_datetime.timestamp()
};
});
// day count
let days_elapsed = days_elapsed(created_date, today, rollover_passed);
@ -119,7 +119,7 @@ fn v1_creation_date_adjusted_to_hour_inner(crt: i64, hour: u8, offset: FixedOffs
fn sched_timing_today_v1(crt: TimestampSecs, now: TimestampSecs) -> SchedTimingToday {
let days_elapsed = (now.0 - crt.0) / 86_400;
let next_day_at = crt.0 + (days_elapsed + 1) * 86_400;
let next_day_at = TimestampSecs(crt.0 + (days_elapsed + 1) * 86_400);
SchedTimingToday {
now,
days_elapsed: days_elapsed as u32,
@ -140,13 +140,14 @@ fn sched_timing_today_v2_legacy(
.timestamp();
let days_elapsed = (now.0 - crt_at_rollover) / 86_400;
let mut next_day_at = now
.datetime(current_utc_offset)
let mut next_day_at = TimestampSecs(
now.datetime(current_utc_offset)
.date()
.and_hms(rollover as u32, 0, 0)
.timestamp();
if next_day_at < now.0 {
next_day_at += 86_400;
.timestamp(),
);
if next_day_at < now {
next_day_at = next_day_at.adding_secs(86_400);
}
SchedTimingToday {
@ -321,7 +322,7 @@ mod test {
*now.offset(),
rollhour as u8,
);
assert_eq!(today.next_day_at, next_day_at.timestamp());
assert_eq!(today.next_day_at.0, next_day_at.timestamp());
// after the rollover, the next day should be the next day
let now = Local.ymd(2019, 1, 3).and_hms(rollhour, 0, 0);
@ -333,7 +334,7 @@ mod test {
*now.offset(),
rollhour as u8,
);
assert_eq!(today.next_day_at, next_day_at.timestamp());
assert_eq!(today.next_day_at.0, next_day_at.timestamp());
// after the rollover, the next day should be the next day
let now = Local.ymd(2019, 1, 3).and_hms(rollhour + 3, 0, 0);
@ -345,7 +346,7 @@ mod test {
*now.offset(),
rollhour as u8,
);
assert_eq!(today.next_day_at, next_day_at.timestamp());
assert_eq!(today.next_day_at.0, next_day_at.timestamp());
}
#[test]
@ -357,7 +358,7 @@ mod test {
SchedTimingToday {
now,
days_elapsed: 107,
next_day_at: 1584558000
next_day_at: TimestampSecs(1584558000)
}
);
@ -366,7 +367,7 @@ mod test {
SchedTimingToday {
now,
days_elapsed: 589,
next_day_at: 1584540000
next_day_at: TimestampSecs(1584540000)
}
);
@ -375,7 +376,7 @@ mod test {
SchedTimingToday {
now,
days_elapsed: 700,
next_day_at: 1584554400
next_day_at: TimestampSecs(1584554400)
}
);
}

View file

@ -210,8 +210,8 @@ impl SqlWriter<'_> {
fn write_rated(&mut self, op: &str, days: i64, ease: &RatingKind) -> Result<()> {
let today_cutoff = self.col.timing_today()?.next_day_at;
let target_cutoff_ms = (today_cutoff + 86_400 * days) * 1_000;
let day_before_cutoff_ms = (today_cutoff + 86_400 * (days - 1)) * 1_000;
let target_cutoff_ms = today_cutoff.adding_secs(86_400 * days).as_millis();
let day_before_cutoff_ms = today_cutoff.adding_secs(86_400 * (days - 1)).as_millis();
write!(self.sql, "c.id in (select cid from revlog where id").unwrap();
@ -224,13 +224,13 @@ impl SqlWriter<'_> {
self.sql,
" between {} and {}",
day_before_cutoff_ms,
target_cutoff_ms - 1
target_cutoff_ms.0 - 1
),
"!=" => write!(
self.sql,
" not between {} and {}",
day_before_cutoff_ms,
target_cutoff_ms - 1
target_cutoff_ms.0 - 1
),
_ => unreachable!("unexpected op"),
}
@ -479,14 +479,14 @@ impl SqlWriter<'_> {
fn write_added(&mut self, days: u32) -> Result<()> {
let timing = self.col.timing_today()?;
let cutoff = (timing.next_day_at - (86_400 * (days as i64))) * 1_000;
let cutoff = (timing.next_day_at.0 - (86_400 * (days as i64))) * 1_000;
write!(self.sql, "c.id > {}", cutoff).unwrap();
Ok(())
}
fn write_edited(&mut self, days: u32) -> Result<()> {
let timing = self.col.timing_today()?;
let cutoff = timing.next_day_at - (86_400 * (days as i64));
let cutoff = timing.next_day_at.0 - (86_400 * (days as i64));
write!(self.sql, "n.mod > {}", cutoff).unwrap();
Ok(())
}
@ -646,7 +646,7 @@ mod test {
let timing = ctx.timing_today().unwrap();
assert_eq!(
s(ctx, "added:3").0,
format!("(c.id > {})", (timing.next_day_at - (86_400 * 3)) * 1_000)
format!("(c.id > {})", (timing.next_day_at.0 - (86_400 * 3)) * 1_000)
);
assert_eq!(s(ctx, "added:0").0, s(ctx, "added:1").0,);
@ -730,14 +730,14 @@ mod test {
s(ctx, "rated:2").0,
format!(
"(c.id in (select cid from revlog where id >= {} and ease > 0))",
(timing.next_day_at - (86_400 * 2)) * 1_000
(timing.next_day_at.0 - (86_400 * 2)) * 1_000
)
);
assert_eq!(
s(ctx, "rated:400:1").0,
format!(
"(c.id in (select cid from revlog where id >= {} and ease = 1))",
(timing.next_day_at - (86_400 * 400)) * 1_000
(timing.next_day_at.0 - (86_400 * 400)) * 1_000
)
);
assert_eq!(s(ctx, "rated:0").0, s(ctx, "rated:1").0);
@ -747,7 +747,7 @@ mod test {
s(ctx, "resched:400").0,
format!(
"(c.id in (select cid from revlog where id >= {} and ease = 0))",
(timing.next_day_at - (86_400 * 400)) * 1_000
(timing.next_day_at.0 - (86_400 * 400)) * 1_000
)
);

View file

@ -22,11 +22,13 @@ impl Collection {
fn graph_data(&mut self, all: bool, days: u32) -> Result<pb::GraphsOut> {
let timing = self.timing_today()?;
let revlog_start = TimestampSecs(if days > 0 {
timing.next_day_at - (((days as i64) + 1) * 86_400)
let revlog_start = if days > 0 {
timing
.next_day_at
.adding_secs(-(((days as i64) + 1) * 86_400))
} else {
0
});
TimestampSecs(0)
};
let offset = self.local_utc_offset_for_user()?;
let local_offset_secs = offset.local_minus_utc() as i64;
@ -45,7 +47,7 @@ impl Collection {
cards: cards.into_iter().map(Into::into).collect(),
revlog,
days_elapsed: timing.days_elapsed,
next_day_at_secs: timing.next_day_at as u32,
next_day_at_secs: timing.next_day_at.0 as u32,
scheduler_version: self.scheduler_version() as u32,
local_offset_secs: local_offset_secs as i32,
})

View file

@ -169,7 +169,7 @@ impl super::SqliteStorage {
pub(crate) fn for_each_due_card_in_deck<F>(
&self,
day_cutoff: u32,
learn_cutoff: i64,
learn_cutoff: TimestampSecs,
deck: DeckId,
mut func: F,
) -> Result<()>

View file

@ -133,11 +133,11 @@ impl SqliteStorage {
.collect()
}
pub(crate) fn studied_today(&self, day_cutoff: i64) -> Result<StudiedToday> {
let start = (day_cutoff - 86_400) * 1_000;
pub(crate) fn studied_today(&self, day_cutoff: TimestampSecs) -> Result<StudiedToday> {
let start = day_cutoff.adding_secs(-86_400).as_millis();
self.db
.prepare_cached(include_str!("studied_today.sql"))?
.query_map(&[start, RevlogReviewKind::Manual as i64], |row| {
.query_map(&[start.0, RevlogReviewKind::Manual as i64], |row| {
Ok(StudiedToday {
cards: row.get(0)?,
seconds: row.get(1)?,

View file

@ -19,10 +19,18 @@ impl TimestampSecs {
Self(0)
}
pub fn elapsed_secs_since(self, other: TimestampSecs) -> i64 {
self.0 - other.0
}
pub fn elapsed_secs(self) -> u64 {
(Self::now().0 - self.0).max(0) as u64
}
pub fn as_millis(self) -> TimestampMillis {
TimestampMillis(self.0 * 1000)
}
/// YYYY-mm-dd
pub(crate) fn date_string(self) -> String {
Local.timestamp(self.0, 0).format("%Y-%m-%d").to_string()