1 /*
2 * #%L
3 * ProfilingStatus.java - mongodb-async-driver - Allanbank Consulting, Inc.
4 * %%
5 * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6 * %%
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * #L%
19 */
20 package com.allanbank.mongodb;
21
22 import java.io.Serializable;
23
24 /**
25 * ProfilingStatus provides a container for the {@link Level} and number of
26 * milliseconds beyond which to consider an operation to be slow.
27 *
28 * @api.yes This class is part of the driver's API. Public and protected members
29 * will be deprecated for at least 1 non-bugfix release (version
30 * numbers are <major>.<minor>.<bugfix>) before being
31 * removed or modified.
32 * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
33 */
34 public class ProfilingStatus implements Comparable<ProfilingStatus>,
35 Serializable {
36
37 /**
38 * The default threshold ({@value} )for the number of milliseconds beyond
39 * considering an operation slow.
40 */
41 public static final long DEFAULT_SLOW_MS = 100;
42
43 /** The off profiling state. */
44 public static final ProfilingStatus OFF = new ProfilingStatus(Level.NONE);
45
46 /** The all profiling state. */
47 public static final ProfilingStatus ON = new ProfilingStatus(Level.ALL);
48
49 /** The serialization version of the class. */
50 private static final long serialVersionUID = 181636899391154872L;
51
52 /**
53 * Creates a profiling state to profile operations taking more than
54 * {@code slowMillis} to complete.
55 *
56 * @param slowMillis
57 * The number of milliseconds beyond which to consider an
58 * operation to be slow.
59 * @return The slow profiling state.
60 */
61 public static final ProfilingStatus slow(final int slowMillis) {
62 return new ProfilingStatus(Level.SLOW_ONLY, slowMillis);
63 }
64
65 /** The profiling level. */
66 private final Level myLevel;
67
68 /**
69 * The number of milliseconds beyond which to consider an operation to be
70 * slow.
71 */
72 private final long mySlowMillisThreshold;
73
74 /**
75 * Creates a new ProfilingStatus.
76 *
77 * @param level
78 * The profiling level to use.
79 */
80 private ProfilingStatus(final Level level) {
81 this(level, DEFAULT_SLOW_MS);
82 }
83
84 /**
85 * Creates a new ProfilingStatus.
86 *
87 * @param level
88 * The profiling level to use.
89 * @param slowMillis
90 * The number of milliseconds beyond which to consider an
91 * operation to be slow.
92 */
93 private ProfilingStatus(final Level level, final long slowMillis) {
94 myLevel = level;
95 mySlowMillisThreshold = slowMillis;
96 }
97
98 /**
99 * {@inheritDoc}
100 * <p>
101 * Overridden to return an ordering based on the tuple ordering of (level,
102 * slowMs).
103 * </p>
104 */
105 @Override
106 public int compareTo(final ProfilingStatus other) {
107 int diff = myLevel.getValue() - other.myLevel.getValue();
108 if (diff == 0) {
109 if (mySlowMillisThreshold < other.mySlowMillisThreshold) {
110 diff = -1;
111 }
112 else if (mySlowMillisThreshold == other.mySlowMillisThreshold) {
113 diff = 0;
114 }
115 else {
116 diff = 1;
117 }
118
119 }
120 return diff;
121 }
122
123 /**
124 * {@inheritDoc}
125 * <p>
126 * Overridden to compare this object to the passed object.
127 * </p>
128 */
129 @Override
130 public boolean equals(final Object object) {
131 boolean result = false;
132 if (this == object) {
133 result = true;
134 }
135 else if ((object != null) && (getClass() == object.getClass())) {
136 final ProfilingStatus other = (ProfilingStatus) object;
137
138 result = (myLevel == other.myLevel)
139 && (mySlowMillisThreshold == other.mySlowMillisThreshold);
140 }
141 return result;
142 }
143
144 /**
145 * Returns the profiling level to use.
146 *
147 * @return The profiling level to use.
148 */
149 public Level getLevel() {
150 return myLevel;
151 }
152
153 /**
154 * Returns the number of milliseconds beyond which to consider an operation
155 * to be slow.
156 *
157 * @return The number of milliseconds beyond which to consider an operation
158 * to be slow.
159 */
160 public long getSlowMillisThreshold() {
161 return mySlowMillisThreshold;
162 }
163
164 /**
165 * {@inheritDoc}
166 * <p>
167 * Overridden to generate a suitable hash of the objects state.
168 * </p>
169 */
170 @Override
171 public int hashCode() {
172 int result = 1;
173 result = (31 * result) + ((myLevel == null) ? 0 : myLevel.hashCode());
174 result = (31 * result)
175 + (int) (mySlowMillisThreshold ^ (mySlowMillisThreshold >>> 32));
176 return result;
177 }
178
179 /**
180 * {@inheritDoc}
181 * <p>
182 * Overridden to return a readable form of the object.
183 * </p>
184 */
185 @Override
186 public String toString() {
187 if (myLevel == Level.SLOW_ONLY) {
188 return myLevel.name() + "(" + mySlowMillisThreshold + " ms)";
189 }
190 return myLevel.name();
191 }
192
193 /**
194 * Hook into serialization to replace <tt>this</tt> object with the local
195 * {@link #ON} or {@link #OFF} instance as appropriate.
196 *
197 * @return Either the {@link #ON} or {@link #OFF} instance if <tt>this</tt>
198 * instance equals one of those instances otherwise <tt>this</tt>
199 * instance.
200 */
201 private Object readResolve() {
202 if (this.equals(ON)) {
203 return ON;
204 }
205 else if (this.equals(OFF)) {
206 return OFF;
207 }
208 else {
209 return this;
210 }
211 }
212
213 /**
214 * Level provides the set of available profiling levels provided by the
215 * MongoDB server.
216 *
217 * @api.yes This class is part of the driver's API. Public and protected
218 * members will be deprecated for at least 1 non-bugfix release
219 * (version numbers are <major>.<minor>.<bugfix>)
220 * before being removed or modified.
221 * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
222 */
223 public static enum Level {
224
225 /** Profile all operations. */
226 ALL(2),
227
228 /** Profile no operations. */
229 NONE(0),
230
231 /** Only profile slow operations. */
232 SLOW_ONLY(1);
233
234 /**
235 * Returns the {@link Level} for the specified value.
236 *
237 * @param value
238 * The value of the profile level.
239 * @return The profile level for the value.
240 */
241 public static Level fromValue(final int value) {
242 for (final Level level : values()) {
243 if (level.getValue() == value) {
244 return level;
245 }
246 }
247
248 return null;
249 }
250
251 /** The profile level value to send to MongoDB. */
252 private final int myValue;
253
254 /**
255 * Creates a new Level.
256 *
257 * @param value
258 * The profile level value to send to MongoDB.
259 */
260 private Level(final int value) {
261 myValue = value;
262 }
263
264 /**
265 * Returns the profile level value to send to MongoDB.
266 *
267 * @return The profile level value to send to MongoDB.
268 */
269 public int getValue() {
270 return myValue;
271 }
272 }
273 }