1//  Copyright (c) 2017 Couchbase, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// 		http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package scorch
16
17import (
18	"encoding/json"
19	"reflect"
20	"sync/atomic"
21)
22
23// Stats tracks statistics about the index, fields that are
24// prefixed like CurXxxx are gauges (can go up and down),
25// and fields that are prefixed like TotXxxx are monotonically
26// increasing counters.
27type Stats struct {
28	TotUpdates uint64
29	TotDeletes uint64
30
31	TotBatches        uint64
32	TotBatchesEmpty   uint64
33	TotBatchIntroTime uint64
34	MaxBatchIntroTime uint64
35
36	CurRootEpoch       uint64
37	LastPersistedEpoch uint64
38	LastMergedEpoch    uint64
39
40	TotOnErrors uint64
41
42	TotAnalysisTime uint64
43	TotIndexTime    uint64
44
45	TotIndexedPlainTextBytes uint64
46
47	TotTermSearchersStarted  uint64
48	TotTermSearchersFinished uint64
49
50	TotEventTriggerStarted   uint64
51	TotEventTriggerCompleted uint64
52
53	TotIntroduceLoop       uint64
54	TotIntroduceSegmentBeg uint64
55	TotIntroduceSegmentEnd uint64
56	TotIntroducePersistBeg uint64
57	TotIntroducePersistEnd uint64
58	TotIntroduceMergeBeg   uint64
59	TotIntroduceMergeEnd   uint64
60	TotIntroduceRevertBeg  uint64
61	TotIntroduceRevertEnd  uint64
62
63	TotIntroducedItems         uint64
64	TotIntroducedSegmentsBatch uint64
65	TotIntroducedSegmentsMerge uint64
66
67	TotPersistLoopBeg          uint64
68	TotPersistLoopErr          uint64
69	TotPersistLoopProgress     uint64
70	TotPersistLoopWait         uint64
71	TotPersistLoopWaitNotified uint64
72	TotPersistLoopEnd          uint64
73
74	TotPersistedItems    uint64
75	TotItemsToPersist    uint64
76	TotPersistedSegments uint64
77
78	TotPersisterSlowMergerPause  uint64
79	TotPersisterSlowMergerResume uint64
80
81	TotPersisterNapPauseCompleted uint64
82	TotPersisterMergerNapBreak    uint64
83
84	TotFileMergeLoopBeg uint64
85	TotFileMergeLoopErr uint64
86	TotFileMergeLoopEnd uint64
87
88	TotFileMergeForceOpsStarted   uint64
89	TotFileMergeForceOpsCompleted uint64
90
91	TotFileMergePlan     uint64
92	TotFileMergePlanErr  uint64
93	TotFileMergePlanNone uint64
94	TotFileMergePlanOk   uint64
95
96	TotFileMergePlanTasks              uint64
97	TotFileMergePlanTasksDone          uint64
98	TotFileMergePlanTasksErr           uint64
99	TotFileMergePlanTasksSegments      uint64
100	TotFileMergePlanTasksSegmentsEmpty uint64
101
102	TotFileMergeSegmentsEmpty uint64
103	TotFileMergeSegments      uint64
104	TotFileSegmentsAtRoot     uint64
105	TotFileMergeWrittenBytes  uint64
106
107	TotFileMergeZapBeg              uint64
108	TotFileMergeZapEnd              uint64
109	TotFileMergeZapTime             uint64
110	MaxFileMergeZapTime             uint64
111	TotFileMergeZapIntroductionTime uint64
112	MaxFileMergeZapIntroductionTime uint64
113
114	TotFileMergeIntroductions          uint64
115	TotFileMergeIntroductionsDone      uint64
116	TotFileMergeIntroductionsSkipped   uint64
117	TotFileMergeIntroductionsObsoleted uint64
118
119	CurFilesIneligibleForRemoval     uint64
120	TotSnapshotsRemovedFromMetaStore uint64
121
122	TotMemMergeBeg          uint64
123	TotMemMergeErr          uint64
124	TotMemMergeDone         uint64
125	TotMemMergeZapBeg       uint64
126	TotMemMergeZapEnd       uint64
127	TotMemMergeZapTime      uint64
128	MaxMemMergeZapTime      uint64
129	TotMemMergeSegments     uint64
130	TotMemorySegmentsAtRoot uint64
131}
132
133// atomically populates the returned map
134func (s *Stats) ToMap() map[string]interface{} {
135	m := map[string]interface{}{}
136	sve := reflect.ValueOf(s).Elem()
137	svet := sve.Type()
138	for i := 0; i < svet.NumField(); i++ {
139		svef := sve.Field(i)
140		if svef.CanAddr() {
141			svefp := svef.Addr().Interface()
142			m[svet.Field(i).Name] = atomic.LoadUint64(svefp.(*uint64))
143		}
144	}
145	return m
146}
147
148// MarshalJSON implements json.Marshaler, and in contrast to standard
149// json marshaling provides atomic safety
150func (s *Stats) MarshalJSON() ([]byte, error) {
151	return json.Marshal(s.ToMap())
152}
153