-
Notifications
You must be signed in to change notification settings - Fork 0
/
counter.go
122 lines (112 loc) · 2.63 KB
/
counter.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package rkive
import (
"github.com/philhofer/rkive/rpbc"
)
// Counter is a Riak CRDT that
// acts as a distributed counter. Counters
// only work in buckets with 'allow_mult' turned on.
type Counter struct {
key []byte
bucket []byte
val int64
parent *Client
}
// Val is the value of the counter
func (c *Counter) Val() int64 { return c.val }
// Bucket is the bucket of the counter
func (c *Counter) Bucket() string { return string(c.bucket) }
// Key is the key of the counter
func (c *Counter) Key() string { return string(c.key) }
// Add adds the value 'v' to the counter.
func (c *Counter) Add(v int64) error {
req := rpbc.RpbCounterUpdateReq{
Amount: &v, // new value
Returnvalue: &ptrTrue, // return new value
Key: c.key, // key
Bucket: c.bucket, // bucket
}
res := rpbc.RpbCounterUpdateResp{}
code, err := c.parent.req(&req, 50, &res)
if err != nil {
return err
}
if code != 51 {
return ErrUnexpectedResponse
}
c.val = res.GetValue()
return nil
}
// Refresh gets the latest value of the counter
// from the database.
func (c *Counter) Refresh() error {
req := rpbc.RpbCounterGetReq{
Key: c.key,
Bucket: c.bucket,
}
res := rpbc.RpbCounterGetResp{}
code, err := c.parent.req(&req, 52, &res)
if err != nil {
return err
}
if code != 53 {
return ErrUnexpectedResponse
}
c.val = res.GetValue()
return nil
}
// Destroy deletes the counter.
func (c *Counter) Destroy() error {
req := rpbc.RpbDelReq{
Bucket: c.bucket,
Key: c.key,
}
_, err := c.parent.req(&req, 13, nil)
return err
}
// NewCounter creates a new counter with
// an optional starting value. If the counter
// already exists, the value returned will be
// the existing value plus "start".
func (b *Bucket) NewCounter(name string, start int64) (*Counter, error) {
req := rpbc.RpbCounterUpdateReq{
Amount: &start,
Returnvalue: &ptrTrue,
Key: []byte(name),
Bucket: []byte(b.nm),
}
res := rpbc.RpbCounterUpdateResp{}
code, err := b.c.req(&req, 50, &res)
if err != nil {
return nil, err
}
if code != 51 {
return nil, ErrUnexpectedResponse
}
return &Counter{
key: req.Key,
bucket: req.Bucket,
val: res.GetValue(),
parent: b.c,
}, nil
}
// GetCounter gets a counter.
func (b *Bucket) GetCounter(name string) (*Counter, error) {
req := rpbc.RpbCounterGetReq{
Key: []byte(name),
Bucket: []byte(b.nm),
}
res := rpbc.RpbCounterGetResp{}
code, err := b.c.req(&req, 52, &res)
if err != nil {
return nil, err
}
if code != 53 {
return nil, ErrUnexpectedResponse
}
return &Counter{
key: req.Key,
bucket: req.Bucket,
val: res.GetValue(),
parent: b.c,
}, nil
}