-
Notifications
You must be signed in to change notification settings - Fork 58
/
collection_stats.go
109 lines (89 loc) · 2.76 KB
/
collection_stats.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
// Copyright 2016-Present Couchbase, Inc.
//
// Use of this software is governed by the Business Source License included
// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
// in that file, in accordance with the Business Source License, use of this
// software will be governed by the Apache License, Version 2.0, included in
// the file licenses/APL2.txt.
package moss
import (
"reflect"
"sync/atomic"
"github.com/couchbase/ghistogram"
)
// Stats returns stats for this collection.
func (m *collection) Stats() (*CollectionStats, error) {
rv := &CollectionStats{}
m.stats.AtomicCopyTo(rv)
m.m.Lock()
m.statsSegmentsLOCKED(rv)
m.m.Unlock()
return rv, nil
}
func (m *collection) Histograms() ghistogram.Histograms {
histogramsSnapshot := make(ghistogram.Histograms)
histogramsSnapshot.AddAll(m.histograms)
return histogramsSnapshot
}
// statsSegmentsLOCKED retrieves stats related to segments.
func (m *collection) statsSegmentsLOCKED(rv *CollectionStats) {
var sssDirtyTop *SegmentStackStats
var sssDirtyMid *SegmentStackStats
var sssDirtyBase *SegmentStackStats
var sssClean *SegmentStackStats
if m.stackDirtyTop != nil {
sssDirtyTop = m.stackDirtyTop.Stats()
}
if m.stackDirtyMid != nil {
sssDirtyMid = m.stackDirtyMid.Stats()
}
if m.stackDirtyBase != nil {
sssDirtyBase = m.stackDirtyBase.Stats()
}
if m.stackClean != nil {
sssClean = m.stackClean.Stats()
}
sssDirty := &SegmentStackStats{}
sssDirtyTop.AddTo(sssDirty)
sssDirtyMid.AddTo(sssDirty)
sssDirtyBase.AddTo(sssDirty)
rv.CurDirtyOps = sssDirty.CurOps
rv.CurDirtyBytes = sssDirty.CurBytes
rv.CurDirtySegments = sssDirty.CurSegments
if sssDirtyTop != nil {
rv.CurDirtyTopOps = sssDirtyTop.CurOps
rv.CurDirtyTopBytes = sssDirtyTop.CurBytes
rv.CurDirtyTopSegments = sssDirtyTop.CurSegments
}
if sssDirtyMid != nil {
rv.CurDirtyMidOps = sssDirtyMid.CurOps
rv.CurDirtyMidBytes = sssDirtyMid.CurBytes
rv.CurDirtyMidSegments = sssDirtyMid.CurSegments
}
if sssDirtyBase != nil {
rv.CurDirtyBaseOps = sssDirtyBase.CurOps
rv.CurDirtyBaseBytes = sssDirtyBase.CurBytes
rv.CurDirtyBaseSegments = sssDirtyBase.CurSegments
}
if sssClean != nil {
rv.CurCleanOps = sssClean.CurOps
rv.CurCleanBytes = sssClean.CurBytes
rv.CurCleanSegments = sssClean.CurSegments
}
}
// AtomicCopyTo copies stats from s to r (from source to result).
func (s *CollectionStats) AtomicCopyTo(r *CollectionStats) {
rve := reflect.ValueOf(r).Elem()
sve := reflect.ValueOf(s).Elem()
svet := sve.Type()
for i := 0; i < svet.NumField(); i++ {
rvef := rve.Field(i)
svef := sve.Field(i)
if rvef.CanAddr() && svef.CanAddr() {
rvefp := rvef.Addr().Interface()
svefp := svef.Addr().Interface()
atomic.StoreUint64(rvefp.(*uint64),
atomic.LoadUint64(svefp.(*uint64)))
}
}
}