-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathscheduler.go
95 lines (81 loc) · 1.96 KB
/
scheduler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package fsrs
import (
"fmt"
"math"
"time"
)
type Scheduler struct {
parameters *Parameters
last Card
current Card
now time.Time
next RecordLog
impl implScheduler
}
type implScheduler interface {
newState(Rating) SchedulingInfo
learningState(Rating) SchedulingInfo
reviewState(Rating) SchedulingInfo
}
func (s *Scheduler) Preview() RecordLog {
return RecordLog{
Again: s.Review(Again),
Hard: s.Review(Hard),
Good: s.Review(Good),
Easy: s.Review(Easy),
}
}
func (s *Scheduler) Review(grade Rating) SchedulingInfo {
state := s.last.State
var item SchedulingInfo
switch state {
case New:
item = s.impl.newState(grade)
case Learning, Relearning:
item = s.impl.learningState(grade)
case Review:
item = s.impl.reviewState(grade)
}
return item
}
func (s *Scheduler) initSeed() {
time := s.now
reps := s.current.Reps
mul := s.current.Difficulty * s.current.Stability
s.parameters.seed = fmt.Sprintf("%d_%d_%f", time.Unix(), reps, mul)
}
func (s *Scheduler) buildLog(rating Rating) ReviewLog {
return ReviewLog{
Rating: rating,
State: s.current.State,
ElapsedDays: s.current.ElapsedDays,
ScheduledDays: s.current.ScheduledDays,
Review: s.now,
}
}
func (p *Parameters) newScheduler(card Card, now time.Time, newImpl func(s *Scheduler) implScheduler) *Scheduler {
s := &Scheduler{
parameters: p,
next: make(RecordLog),
last: card,
current: card,
now: now,
}
var interval float64 = 0 // card.state === State.New => 0
if s.current.State != New && !s.current.LastReview.IsZero() {
interval = math.Floor(s.now.Sub(s.current.LastReview).Hours() / 24)
}
s.current.LastReview = s.now
s.current.ElapsedDays = uint64(interval)
s.current.Reps++
s.initSeed()
s.impl = newImpl(s)
return s
}
func (p *Parameters) scheduler(card Card, now time.Time) *Scheduler {
if p.EnableShortTerm {
return p.NewBasicScheduler(card, now)
} else {
return p.NewLongTermScheduler(card, now)
}
}