From 4d6f784cd2c7ffcc497e56469dd9f930b9f9752c Mon Sep 17 00:00:00 2001 From: Stephen Mwangi Date: Sun, 20 Oct 2024 10:52:11 +0300 Subject: [PATCH] fix(load balancer): update due dates histogram after review --- src/algorithms/osr/note-scheduling.ts | 3 +-- src/flashcard-review-sequencer.ts | 14 ++++++++++++++ tests/unit/scheduling.test.ts | 6 +++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/algorithms/osr/note-scheduling.ts b/src/algorithms/osr/note-scheduling.ts index 3272ffb7..3df9ef7c 100644 --- a/src/algorithms/osr/note-scheduling.ts +++ b/src/algorithms/osr/note-scheduling.ts @@ -43,8 +43,7 @@ export function osrSchedule( else if (interval < 30) fuzz = Math.max(2, Math.floor(interval * 0.15)); else fuzz = Math.max(4, Math.floor(interval * 0.05)); - const fuzzedInterval = dueDateHistogram.findLeastUsedIntervalOverRange(interval, fuzz); - interval = fuzzedInterval; + interval = dueDateHistogram.findLeastUsedIntervalOverRange(interval, fuzz); } } diff --git a/src/flashcard-review-sequencer.ts b/src/flashcard-review-sequencer.ts index fb7ff813..558022c6 100644 --- a/src/flashcard-review-sequencer.ts +++ b/src/flashcard-review-sequencer.ts @@ -2,6 +2,7 @@ import { ISrsAlgorithm } from "src/algorithms/base/isrs-algorithm"; import { RepItemScheduleInfo } from "src/algorithms/base/rep-item-schedule-info"; import { ReviewResponse } from "src/algorithms/base/repetition-item"; import { Card } from "src/card"; +import { TICKS_PER_DAY } from "src/constants"; import { DataStore } from "src/data-stores/base/data-store"; import { CardListType, Deck } from "src/deck"; import { IDeckTreeIterator } from "src/deck-tree-iterator"; @@ -11,6 +12,7 @@ import { Question, QuestionText } from "src/question"; import { IQuestionPostponementList } from "src/question-postponement-list"; import { SRSettings } from "src/settings"; import { TopicPath } from "src/topic-path"; +import { globalDateProvider } from "src/utils/dates"; export interface IFlashcardReviewSequencer { get hasCurrentCard(): boolean; @@ -146,6 +148,8 @@ export class FlashcardReviewSequencer implements IFlashcardReviewSequencer { async processReviewReviewMode(response: ReviewResponse): Promise { if (response != ReviewResponse.Reset || this.currentCard.hasSchedule) { + const oldSchedule = this.currentCard.scheduleInfo; + // We need to update the schedule if: // (1) the user reviewed with easy/good/hard (either a new or due card), // (2) or reset a due card @@ -154,6 +158,16 @@ export class FlashcardReviewSequencer implements IFlashcardReviewSequencer { // Update the source file with the updated schedule await DataStore.getInstance().questionWriteSchedule(this.currentQuestion); + + if (oldSchedule) { + const today: number = globalDateProvider.today.valueOf(); + const nDays: number = Math.ceil( + (oldSchedule.dueDateAsUnix - today) / TICKS_PER_DAY, + ); + + this.dueDateFlashcardHistogram.decrement(nDays); + } + this.dueDateFlashcardHistogram.increment(this.currentCard.scheduleInfo.interval); } // Move/delete the card diff --git a/tests/unit/scheduling.test.ts b/tests/unit/scheduling.test.ts index b73e90fb..984f9dcb 100644 --- a/tests/unit/scheduling.test.ts +++ b/tests/unit/scheduling.test.ts @@ -99,7 +99,7 @@ test("Test load balancing, small interval (load balancing disabled)", () => { const newInterval: number = 3; const dueDates = new DueDateHistogram({ 0: 1, - 1: 1, // key = originalInterval + 1: 1, 2: 1, 3: 4, }); @@ -121,9 +121,9 @@ test("Test load balancing, small interval (load balancing disabled)", () => { expect(dueDates).toEqual( new DueDateHistogram({ 0: 1, - 1: 0, // One less than before + 1: 0, 2: 1, - 3: 5, // One more than before + 3: 5, }), ); });