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 mtime: TimestampSecs,
pub due: i32,
/// Used to store interval, and for shuffling
pub extra: u64,
pub interval: u32,
pub hash: u64,
}
/// Temporary holder for new cards that will be built into a queue.

View File

@ -10,7 +10,7 @@ impl QueueBuilder {
match self.new_order {
NewCardOrder::Random => {
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 => {
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);
}
ReviewCardOrder::Shuffled => {
self.review.sort_unstable_by(|a, b| a.extra.cmp(&b.extra));
self.day_learning
.sort_unstable_by(|a, b| a.extra.cmp(&b.extra));
self.review.sort_unstable_by(shuffle_due_card);
self.day_learning.sort_unstable_by(shuffle_due_card);
}
ReviewCardOrder::IntervalsAscending => {
// fixme: implement; may require separate field if we want
// to shuffle cards that share an interval
self.review.sort_unstable_by(intervals_ascending);
self.day_learning.sort_unstable_by(shuffle_due_card);
}
ReviewCardOrder::IntervalsDescending => {
// fixme: implement; may require separate field if we want
// to shuffle cards that share an interval
self.review
.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
// 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 {
fn hash_id_and_mtime(&mut self) {
let mut hasher = FnvHasher::default();
hasher.write_i64(self.id.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();
}
}
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)?,
note_id: row.get(2)?,
due: row.get(3).ok().unwrap_or_default(),
extra: row.get::<_, u32>(4)? as u64,
interval: row.get(4)?,
mtime: row.get(5)?,
hash: 0,
},
) {
break;