OLD | NEW |
| (Empty) |
1 package db | |
2 | |
3 import ( | |
4 "fmt" | |
5 "sort" | |
6 "sync" | |
7 "time" | |
8 | |
9 "go.skia.org/infra/go/util" | |
10 | |
11 "github.com/satori/go.uuid" | |
12 "github.com/skia-dev/glog" | |
13 ) | |
14 | |
15 type inMemoryDB struct { | |
16 tasks map[string]*Task | |
17 tasksMtx sync.RWMutex | |
18 modTasks ModifiedTasks | |
19 } | |
20 | |
21 // See docs for DB interface. Does not take any locks. | |
22 func (db *inMemoryDB) AssignId(t *Task) error { | |
23 if t.Id != "" { | |
24 return fmt.Errorf("Task Id already assigned: %v", t.Id) | |
25 } | |
26 t.Id = uuid.NewV5(uuid.NewV1(), uuid.NewV4().String()).String() | |
27 return nil | |
28 } | |
29 | |
30 // See docs for DB interface. | |
31 func (db *inMemoryDB) Close() error { | |
32 return nil | |
33 } | |
34 | |
35 // See docs for DB interface. | |
36 func (db *inMemoryDB) GetTaskById(id string) (*Task, error) { | |
37 db.tasksMtx.RLock() | |
38 defer db.tasksMtx.RUnlock() | |
39 if task := db.tasks[id]; task != nil { | |
40 return task.Copy(), nil | |
41 } | |
42 return nil, nil | |
43 } | |
44 | |
45 // See docs for DB interface. | |
46 func (db *inMemoryDB) GetTasksFromDateRange(start, end time.Time) ([]*Task, erro
r) { | |
47 db.tasksMtx.RLock() | |
48 defer db.tasksMtx.RUnlock() | |
49 | |
50 rv := []*Task{} | |
51 // TODO(borenet): Binary search. | |
52 for _, b := range db.tasks { | |
53 if (b.Created.Equal(start) || b.Created.After(start)) && b.Creat
ed.Before(end) { | |
54 rv = append(rv, b.Copy()) | |
55 } | |
56 } | |
57 sort.Sort(TaskSlice(rv)) | |
58 return rv, nil | |
59 } | |
60 | |
61 // See docs for DB interface. | |
62 func (db *inMemoryDB) GetModifiedTasks(id string) ([]*Task, error) { | |
63 return db.modTasks.GetModifiedTasks(id) | |
64 } | |
65 | |
66 // See docs for DB interface. | |
67 func (db *inMemoryDB) PutTask(task *Task) error { | |
68 db.tasksMtx.Lock() | |
69 defer db.tasksMtx.Unlock() | |
70 | |
71 if util.TimeIsZero(task.Created) { | |
72 return fmt.Errorf("Created not set. Task %s created time is %s.
%v", task.Id, task.Created, task) | |
73 } | |
74 | |
75 if task.Id == "" { | |
76 if err := db.AssignId(task); err != nil { | |
77 return err | |
78 } | |
79 } else if existing := db.tasks[task.Id]; existing != nil { | |
80 if !existing.DbModified.Equal(task.DbModified) { | |
81 glog.Warningf("Cached Task has been modified in the DB.
Current:\n%v\nCached:\n%v", existing, task) | |
82 return ErrConcurrentUpdate | |
83 } | |
84 } | |
85 task.DbModified = time.Now() | |
86 | |
87 // TODO(borenet): Keep tasks in a sorted slice. | |
88 db.tasks[task.Id] = task | |
89 db.modTasks.TrackModifiedTask(task) | |
90 return nil | |
91 } | |
92 | |
93 // See docs for DB interface. | |
94 func (db *inMemoryDB) PutTasks(tasks []*Task) error { | |
95 for _, t := range tasks { | |
96 if err := db.PutTask(t); err != nil { | |
97 return err | |
98 } | |
99 } | |
100 return nil | |
101 } | |
102 | |
103 // See docs for DB interface. | |
104 func (db *inMemoryDB) StartTrackingModifiedTasks() (string, error) { | |
105 return db.modTasks.StartTrackingModifiedTasks() | |
106 } | |
107 | |
108 // See docs for DB interface. | |
109 func (db *inMemoryDB) StopTrackingModifiedTasks(id string) { | |
110 db.modTasks.StopTrackingModifiedTasks(id) | |
111 } | |
112 | |
113 // NewInMemoryDB returns an extremely simple, inefficient, in-memory DB | |
114 // implementation. | |
115 func NewInMemoryDB() DB { | |
116 db := &inMemoryDB{ | |
117 tasks: map[string]*Task{}, | |
118 } | |
119 return db | |
120 } | |
OLD | NEW |