Vendor newer github.com/jbenet/go-datastore
Tommi Virtanen committed
Apr 28, 2015 at 19:02 UTC
2dd9b168786a15c2169f3ad8c29aa1d5f1a75a3c
3 files changed
+179
-1
Godeps/Godeps.json
+1
-1
@@ -153,7 +153,7 @@
153
},
154
{
155
"ImportPath": "github.com/jbenet/go-datastore",
156
- "Rev": "2525cae416316b9cf2eb66ec8d4792f567436efa"
156
+ "Rev": "751a1b4ad40b27c3f0993ba5e2bcf22ad941991b"
157
},
158
{
159
"ImportPath": "github.com/jbenet/go-detect-race",
Godeps/_workspace/src/github.com/jbenet/go-datastore/Godeps/Godeps.json
+8
@@ -14,6 +14,14 @@
14
"ImportPath": "github.com/codahale/blake2",
15
"Rev": "3fa823583afba430e8fc7cdbcc670dbf90bfacc4"
16
},
17
+ {
18
+ "ImportPath": "github.com/codahale/hdrhistogram",
19
+ "Rev": "5fd85ec0b4e2dd5d4158d257d943f2e586d86b62"
20
+ },
21
+ {
22
+ "ImportPath": "github.com/codahale/metrics",
23
+ "Rev": "7d3beb1b480077e77c08a6f6c65ea969f6e91420"
24
+ },
25
{
26
"ImportPath": "github.com/hashicorp/golang-lru",
27
"Rev": "4dfff096c4973178c8f35cf6dd1a732a0a139370"
Godeps/_workspace/src/github.com/jbenet/go-datastore/measure/measure.go
new
+170
@@ -0,0 +1,170 @@
1
+// Package measure provides a Datastore wrapper that records metrics
2
+// using github.com/codahale/metrics.
3
+package measure
4
+
5
+import (
6
+ "time"
7
+
8
+ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics"
9
+ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
10
+ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/query"
11
+)
12
+
13
+// Histogram measurements exceeding these limits are dropped. TODO
14
+// maybe it would be better to cap the value? Should we keep track of
15
+// drops?
16
+const (
17
+ maxLatency = int64(1 * time.Second)
18
+ maxSize = int64(1 << 32)
19
+)
20
+
21
+type DatastoreCloser interface {
22
+ datastore.Datastore
23
+ Close() error
24
+}
25
+
26
+// New wraps the datastore, providing metrics on the operations. The
27
+// metrics are registered with names starting with prefix and a dot.
28
+//
29
+// If prefix is not unique, New will panic. Call Close to release the
30
+// prefix.
31
+func New(prefix string, ds datastore.Datastore) DatastoreCloser {
32
+ m := &measure{
33
+ backend: ds,
34
+
35
+ putNum: metrics.Counter(prefix + ".Put.num"),
36
+ putErr: metrics.Counter(prefix + ".Put.err"),
37
+ putLatency: metrics.NewHistogram(prefix+".Put.latency", 0, maxLatency, 3),
38
+ putSize: metrics.NewHistogram(prefix+".Put.size", 0, maxSize, 3),
39
+
40
+ getNum: metrics.Counter(prefix + ".Get.num"),
41
+ getErr: metrics.Counter(prefix + ".Get.err"),
42
+ getLatency: metrics.NewHistogram(prefix+".Get.latency", 0, maxLatency, 3),
43
+ getSize: metrics.NewHistogram(prefix+".Get.size", 0, maxSize, 3),
44
+
45
+ hasNum: metrics.Counter(prefix + ".Has.num"),
46
+ hasErr: metrics.Counter(prefix + ".Has.err"),
47
+ hasLatency: metrics.NewHistogram(prefix+".Has.latency", 0, maxLatency, 3),
48
+
49
+ deleteNum: metrics.Counter(prefix + ".Delete.num"),
50
+ deleteErr: metrics.Counter(prefix + ".Delete.err"),
51
+ deleteLatency: metrics.NewHistogram(prefix+".Delete.latency", 0, maxLatency, 3),
52
+
53
+ queryNum: metrics.Counter(prefix + ".Query.num"),
54
+ queryErr: metrics.Counter(prefix + ".Query.err"),
55
+ queryLatency: metrics.NewHistogram(prefix+".Query.latency", 0, maxLatency, 3),
56
+ }
57
+ return m
58
+}
59
+
60
+type measure struct {
61
+ backend datastore.Datastore
62
+
63
+ putNum metrics.Counter
64
+ putErr metrics.Counter
65
+ putLatency *metrics.Histogram
66
+ putSize *metrics.Histogram
67
+
68
+ getNum metrics.Counter
69
+ getErr metrics.Counter
70
+ getLatency *metrics.Histogram
71
+ getSize *metrics.Histogram
72
+
73
+ hasNum metrics.Counter
74
+ hasErr metrics.Counter
75
+ hasLatency *metrics.Histogram
76
+
77
+ deleteNum metrics.Counter
78
+ deleteErr metrics.Counter
79
+ deleteLatency *metrics.Histogram
80
+
81
+ queryNum metrics.Counter
82
+ queryErr metrics.Counter
83
+ queryLatency *metrics.Histogram
84
+}
85
+
86
+var _ datastore.Datastore = (*measure)(nil)
87
+var _ DatastoreCloser = (*measure)(nil)
88
+
89
+func recordLatency(h *metrics.Histogram, start time.Time) {
90
+ elapsed := time.Now().Sub(start) / time.Microsecond
91
+ _ = h.RecordValue(int64(elapsed))
92
+}
93
+
94
+func (m *measure) Put(key datastore.Key, value interface{}) error {
95
+ defer recordLatency(m.putLatency, time.Now())
96
+ m.putNum.Add()
97
+ if b, ok := value.([]byte); ok {
98
+ _ = m.putSize.RecordValue(int64(len(b)))
99
+ }
100
+ err := m.backend.Put(key, value)
101
+ if err != nil {
102
+ m.putErr.Add()
103
+ }
104
+ return err
105
+}
106
+
107
+func (m *measure) Get(key datastore.Key) (value interface{}, err error) {
108
+ defer recordLatency(m.getLatency, time.Now())
109
+ m.getNum.Add()
110
+ value, err = m.backend.Get(key)
111
+ if err != nil {
112
+ m.getErr.Add()
113
+ } else {
114
+ if b, ok := value.([]byte); ok {
115
+ _ = m.getSize.RecordValue(int64(len(b)))
116
+ }
117
+ }
118
+ return value, err
119
+}
120
+
121
+func (m *measure) Has(key datastore.Key) (exists bool, err error) {
122
+ defer recordLatency(m.hasLatency, time.Now())
123
+ m.hasNum.Add()
124
+ exists, err = m.backend.Has(key)
125
+ if err != nil {
126
+ m.hasErr.Add()
127
+ }
128
+ return exists, err
129
+}
130
+
131
+func (m *measure) Delete(key datastore.Key) error {
132
+ defer recordLatency(m.deleteLatency, time.Now())
133
+ m.deleteNum.Add()
134
+ err := m.backend.Delete(key)
135
+ if err != nil {
136
+ m.deleteErr.Add()
137
+ }
138
+ return err
139
+}
140
+
141
+func (m *measure) Query(q query.Query) (query.Results, error) {
142
+ defer recordLatency(m.queryLatency, time.Now())
143
+ m.queryNum.Add()
144
+ res, err := m.backend.Query(q)
145
+ if err != nil {
146
+ m.queryErr.Add()
147
+ }
148
+ return res, err
149
+}
150
+
151
+func (m *measure) Close() error {
152
+ m.putNum.Remove()
153
+ m.putErr.Remove()
154
+ m.putLatency.Remove()
155
+ m.putSize.Remove()
156
+ m.getNum.Remove()
157
+ m.getErr.Remove()
158
+ m.getLatency.Remove()
159
+ m.getSize.Remove()
160
+ m.hasNum.Remove()
161
+ m.hasErr.Remove()
162
+ m.hasLatency.Remove()
163
+ m.deleteNum.Remove()
164
+ m.deleteErr.Remove()
165
+ m.deleteLatency.Remove()
166
+ m.queryNum.Remove()
167
+ m.queryErr.Remove()
168
+ m.queryLatency.Remove()
169
+ return nil
170
+}