/
userpool.go
92 lines (77 loc) · 2.19 KB
/
userpool.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
package scenario
import (
"fmt"
"math/rand"
"net/url"
"sync"
"github.com/isucon/isucon11-final/benchmarker/model"
)
type userPool struct {
studentAccounts []*model.UserAccount
teachers []*model.Teacher
index int
useSampleStudent bool // sampleStudentを排出したかどうかのフラグ
teacherCount int // sampleTeacherの排出に使うカウント
sampleTeacher *model.Teacher
baseURL *url.URL
rmu sync.RWMutex
}
var (
sampleStudentCode = "S00000"
sampleStudentName = "isucon(学生)"
sampleStudentPass = "isucon"
sampleTeacherCode = "T00000"
sampleTeacherName = "isucon(教員)"
sampleTeacherPass = "isucon"
)
func NewUserPool(studentAccounts []*model.UserAccount, teachers []*model.Teacher, baseURL *url.URL) *userPool {
// shuffle studentDataSet order by Fisher–Yates shuffle
for i := len(studentAccounts) - 1; i >= 0; i-- {
j := rand.Intn(i + 1)
studentAccounts[i], studentAccounts[j] = studentAccounts[j], studentAccounts[i]
}
sampleTeacher := model.NewTeacher(&model.UserAccount{
Code: sampleTeacherCode,
Name: sampleTeacherName,
RawPassword: sampleTeacherPass,
IsAdmin: true,
}, baseURL)
return &userPool{
studentAccounts: studentAccounts,
teachers: teachers,
index: 0,
sampleTeacher: sampleTeacher,
baseURL: baseURL,
rmu: sync.RWMutex{},
}
}
func (p *userPool) newStudent() (*model.Student, error) {
p.rmu.Lock()
defer p.rmu.Unlock()
if !p.useSampleStudent {
p.useSampleStudent = true
return model.NewStudent(&model.UserAccount{
Code: sampleStudentCode,
Name: sampleStudentName,
RawPassword: sampleStudentPass,
IsAdmin: false,
}, p.baseURL), nil
}
if p.index >= len(p.studentAccounts) {
return nil, fmt.Errorf("student data has been out of stock")
}
student := model.NewStudent(p.studentAccounts[p.index], p.baseURL)
p.index++
return student, nil
}
func (p *userPool) randomTeacher() *model.Teacher {
p.rmu.Lock()
defer p.rmu.Unlock()
// 定期的にsampleTeacherを使う
if p.teacherCount%20 == 0 {
p.teacherCount++
return p.sampleTeacher
}
p.teacherCount++
return p.teachers[rand.Intn(len(p.teachers))]
}