Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(635)

Side by Side Diff: build_scheduler/go/db/memory.go

Issue 2226583003: Add build scheduler DB interface, dumb in-memory impl, cache (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: Address more comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build_scheduler/go/db/db_test.go ('k') | go/buildbucket/buildbucket.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 package db
2
3 import (
4 "sort"
5 "sync"
6 "time"
7
8 "github.com/satori/go.uuid"
9 "github.com/skia-dev/glog"
10 )
11
12 type BuildSlice []*Build
13
14 func (s BuildSlice) Len() int { return len(s) }
15
16 func (s BuildSlice) Less(i, j int) bool {
17 ts1, err := s[i].Created()
18 if err != nil {
19 glog.Errorf("Failed to parse CreatedTimestamp: %v", s[i])
20 }
21 ts2, err := s[j].Created()
22 if err != nil {
23 glog.Errorf("Failed to parse CreatedTimestamp: %v", s[j])
24 }
25 return ts1.Before(ts2)
26 }
27
28 func (s BuildSlice) Swap(i, j int) {
29 s[i], s[j] = s[j], s[i]
30 }
31
32 type inMemoryDB struct {
33 builds map[string]*Build
34 buildsMtx sync.RWMutex
35 modBuilds map[string]map[string]*Build
36 modExpire map[string]time.Time
37 modMtx sync.RWMutex
38 }
39
40 // See docs for DB interface.
41 func (db *inMemoryDB) Close() error {
42 return nil
43 }
44
45 // See docs for DB interface.
46 func (db *inMemoryDB) GetBuildsFromDateRange(start, end time.Time) ([]*Build, er ror) {
47 db.buildsMtx.RLock()
48 defer db.buildsMtx.RUnlock()
49
50 rv := []*Build{}
51 // TODO(borenet): Binary search.
52 for _, b := range db.builds {
53 created, err := b.Created()
54 if err != nil {
55 return nil, err
56 }
57 if (created.Equal(start) || created.After(start)) && created.Bef ore(end) {
58 rv = append(rv, b.Copy())
59 }
60 }
61 sort.Sort(BuildSlice(rv))
62 return rv, nil
63 }
64
65 // See docs for DB interface.
66 func (db *inMemoryDB) GetModifiedBuilds(id string) ([]*Build, error) {
67 db.modMtx.Lock()
68 defer db.modMtx.Unlock()
69 modifiedBuilds, ok := db.modBuilds[id]
70 if !ok {
71 return nil, ErrUnknownId
72 }
73 rv := make([]*Build, 0, len(modifiedBuilds))
74 for _, b := range modifiedBuilds {
75 rv = append(rv, b.Copy())
76 }
77 db.modExpire[id] = time.Now().Add(MODIFIED_BUILDS_TIMEOUT)
78 db.modBuilds[id] = map[string]*Build{}
79 sort.Sort(BuildSlice(rv))
80 return rv, nil
81 }
82
83 func (db *inMemoryDB) clearExpiredModifiedUsers() {
84 db.modMtx.Lock()
85 defer db.modMtx.Unlock()
86 for id, t := range db.modExpire {
87 if time.Now().After(t) {
88 delete(db.modBuilds, id)
89 delete(db.modExpire, id)
90 }
91 }
92 }
93
94 func (db *inMemoryDB) modify(b *Build) {
95 db.modMtx.Lock()
96 defer db.modMtx.Unlock()
97 for _, modBuilds := range db.modBuilds {
98 modBuilds[b.Id] = b.Copy()
99 }
100 }
101
102 // See docs for DB interface.
103 func (db *inMemoryDB) PutBuild(build *Build) error {
104 db.buildsMtx.Lock()
105 defer db.buildsMtx.Unlock()
106
107 // TODO(borenet): Keep builds in a sorted slice.
108 db.builds[build.Id] = build
109 db.modify(build)
110 return nil
111 }
112
113 // See docs for DB interface.
114 func (db *inMemoryDB) PutBuilds(builds []*Build) error {
115 for _, b := range builds {
116 if err := db.PutBuild(b); err != nil {
117 return err
118 }
119 }
120 return nil
121 }
122
123 // See docs for DB interface.
124 func (db *inMemoryDB) StartTrackingModifiedBuilds() (string, error) {
125 db.modMtx.Lock()
126 defer db.modMtx.Unlock()
127 if len(db.modBuilds) >= MAX_MODIFIED_BUILDS_USERS {
128 return "", ErrTooManyUsers
129 }
130 id := uuid.NewV5(uuid.NewV1(), uuid.NewV4().String()).String()
131 db.modBuilds[id] = map[string]*Build{}
132 db.modExpire[id] = time.Now().Add(MODIFIED_BUILDS_TIMEOUT)
133 return id, nil
134 }
135
136 // NewInMemoryDB returns an extremely simple, inefficient, in-memory DB implemen tation.
137 func NewInMemoryDB() DB {
138 db := &inMemoryDB{
139 builds: map[string]*Build{},
140 modBuilds: map[string]map[string]*Build{},
141 modExpire: map[string]time.Time{},
142 }
143 go func() {
144 for _ = range time.Tick(time.Minute) {
145 db.clearExpiredModifiedUsers()
146 }
147 }()
148 return db
149 }
OLDNEW
« no previous file with comments | « build_scheduler/go/db/db_test.go ('k') | go/buildbucket/buildbucket.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698