interval sorting

This commit is contained in:
Damien Elmes 2021-03-01 21:20:13 +10:00
parent 4387e3ed86
commit c74a71a6d7
3 changed files with 32 additions and 17 deletions

View file

@ -26,8 +26,8 @@ pub(crate) struct DueCard {
pub note_id: NoteID, pub note_id: NoteID,
pub mtime: TimestampSecs, pub mtime: TimestampSecs,
pub due: i32, pub due: i32,
/// Used to store interval, and for shuffling pub interval: u32,
pub extra: u64, pub hash: u64,
} }
/// Temporary holder for new cards that will be built into a queue. /// Temporary holder for new cards that will be built into a queue.

View file

@ -10,7 +10,7 @@ impl QueueBuilder {
match self.new_order { match self.new_order {
NewCardOrder::Random => { NewCardOrder::Random => {
self.new.iter_mut().for_each(NewCard::hash_id_and_mtime); self.new.iter_mut().for_each(NewCard::hash_id_and_mtime);
self.new.sort_unstable_by(|a, b| a.extra.cmp(&b.extra)); self.new.sort_unstable_by(shuffle_new_card);
} }
NewCardOrder::Due => { NewCardOrder::Due => {
self.new.sort_unstable_by(|a, b| a.due.cmp(&b.due)); self.new.sort_unstable_by(|a, b| a.due.cmp(&b.due));
@ -30,30 +30,48 @@ impl QueueBuilder {
self.day_learning.sort_unstable_by(shuffle_by_day); self.day_learning.sort_unstable_by(shuffle_by_day);
} }
ReviewCardOrder::Shuffled => { ReviewCardOrder::Shuffled => {
self.review.sort_unstable_by(|a, b| a.extra.cmp(&b.extra)); self.review.sort_unstable_by(shuffle_due_card);
self.day_learning self.day_learning.sort_unstable_by(shuffle_due_card);
.sort_unstable_by(|a, b| a.extra.cmp(&b.extra));
} }
ReviewCardOrder::IntervalsAscending => { ReviewCardOrder::IntervalsAscending => {
// fixme: implement; may require separate field if we want self.review.sort_unstable_by(intervals_ascending);
// to shuffle cards that share an interval self.day_learning.sort_unstable_by(shuffle_due_card);
} }
ReviewCardOrder::IntervalsDescending => { ReviewCardOrder::IntervalsDescending => {
// fixme: implement; may require separate field if we want self.review
// to shuffle cards that share an interval .sort_unstable_by(|a, b| intervals_ascending(b, a));
self.day_learning.sort_unstable_by(shuffle_due_card);
} }
} }
} }
} }
fn shuffle_new_card(a: &NewCard, b: &NewCard) -> Ordering {
a.extra.cmp(&b.extra)
}
fn shuffle_by_day(a: &DueCard, b: &DueCard) -> Ordering {
(a.due, a.hash).cmp(&(b.due, b.hash))
}
fn shuffle_due_card(a: &DueCard, b: &DueCard) -> Ordering {
a.hash.cmp(&b.hash)
}
fn intervals_ascending(a: &DueCard, b: &DueCard) -> Ordering {
(a.interval, a.hash).cmp(&(a.interval, b.hash))
}
// We sort based on a hash so that if the queue is rebuilt, remaining // We sort based on a hash so that if the queue is rebuilt, remaining
// cards come back in the same order. // cards come back in the same approximate order (mixing + due learning cards
// may still result in a different card)
impl DueCard { impl DueCard {
fn hash_id_and_mtime(&mut self) { fn hash_id_and_mtime(&mut self) {
let mut hasher = FnvHasher::default(); let mut hasher = FnvHasher::default();
hasher.write_i64(self.id.0); hasher.write_i64(self.id.0);
hasher.write_i64(self.mtime.0); hasher.write_i64(self.mtime.0);
self.extra = hasher.finish(); self.hash = hasher.finish();
} }
} }
@ -65,7 +83,3 @@ impl NewCard {
self.extra = hasher.finish(); self.extra = hasher.finish();
} }
} }
fn shuffle_by_day(a: &DueCard, b: &DueCard) -> Ordering {
(a.due, a.extra).cmp(&(b.due, b.extra))
}

View file

@ -189,8 +189,9 @@ impl super::SqliteStorage {
id: row.get(1)?, id: row.get(1)?,
note_id: row.get(2)?, note_id: row.get(2)?,
due: row.get(3).ok().unwrap_or_default(), due: row.get(3).ok().unwrap_or_default(),
extra: row.get::<_, u32>(4)? as u64, interval: row.get(4)?,
mtime: row.get(5)?, mtime: row.get(5)?,
hash: 0,
}, },
) { ) {
break; break;