-
Notifications
You must be signed in to change notification settings - Fork 32
/
rating.go
70 lines (56 loc) · 1.51 KB
/
rating.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
// Package rating defines types and methods for setting/getting ratings for paths and
// persisting this data.
package rating
import (
"fmt"
"sync"
"tchaik.com/index"
)
// Value is a type which represents a rating value.
type Value uint
// None is the Value used to mark a path as having no rating.
const None Value = 0
// IsValid returns true if the Value is valid.
func (v Value) IsValid() bool {
return 0 <= v && v <= 5
}
// Store is an interface which defines methods necessary for setting and getting ratings for
// index paths.
type Store interface {
// Set the rating for the path.
Set(index.Path, Value) error
// Get the rating for the path.
Get(index.Path) Value
}
// NewStore creates a basic implementation of a ratings store, using the given path as the
// source of data. Note: we do not enforce any locking on the underlying file, which is read
// once to initialise the store, and then overwritten after each call to Set.
func NewStore(path string) (Store, error) {
m := make(map[string]Value)
s, err := index.NewPersistStore(path, &m)
if err != nil {
return nil, err
}
return &store{
m: m,
store: s,
}, nil
}
type store struct {
sync.RWMutex
m map[string]Value
store index.PersistStore
}
// Set implements Store.
func (s *store) Set(p index.Path, v Value) error {
s.Lock()
defer s.Unlock()
s.m[fmt.Sprintf("%v", p)] = v
return s.store.Persist(&s.m)
}
// Get implements Store.
func (s *store) Get(p index.Path) Value {
s.RLock()
defer s.RUnlock()
return s.m[fmt.Sprintf("%v", p)]
}