-
Notifications
You must be signed in to change notification settings - Fork 3
/
counterstore.go
80 lines (61 loc) · 1.26 KB
/
counterstore.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
package orbitdb
import (
"sync"
"github.com/keks/go-ipfs-colog"
"github.com/keks/go-orbitdb/handler"
)
type ctrPayload struct {
handler.Op `json:"op"`
Value int `json:"value"`
}
func ctrCast(e *colog.Entry) (pl ctrPayload, err error) {
err = e.Get(&pl)
return pl, err
}
type ctrIndex struct {
l sync.Mutex
value int
}
func (idx *ctrIndex) handleCounter(e *colog.Entry) error {
pl, err := ctrCast(e)
if err != nil {
return err
}
idx.l.Lock()
idx.value += pl.Value
idx.l.Unlock()
return nil
}
func (idx *ctrIndex) Value() int {
idx.l.Lock()
defer idx.l.Unlock()
return idx.value
}
// CtrStore manages a counter stored in an OrbitDB.
type CtrStore struct {
db *OrbitDB
idx *ctrIndex
}
// NewCtrStore returns a CtrStore for the given OrbitDB.
func NewCtrStore(db *OrbitDB) *CtrStore {
s := &CtrStore{
db: db,
idx: &ctrIndex{},
}
mux := handler.NewMux()
mux.AddHandler(OpCounter, s.idx.handleCounter)
go db.Notify(mux)
return s
}
// Increment increments the counter by n.
func (cs *CtrStore) Increment(n int) (*colog.Entry, error) {
payload := ctrPayload{
Op: OpCounter,
Value: n,
}
return cs.db.Add(&payload)
}
// Value returns the current value of the counter.
func (cs *CtrStore) Value() int {
return cs.idx.Value()
}