001    /*
002     * $Id: SimpleProfileMonitor.java,v 1.10 2014/04/28 17:36:37 oboehm Exp $
003     *
004     * Copyright (c) 2008 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     *
018     * (c)reated 19.12.2008 by oliver (ob@oasd.de)
019     */
020    package patterntesting.runtime.monitor;
021    
022    import java.util.*;
023    import java.util.concurrent.ConcurrentLinkedQueue;
024    
025    import org.aspectj.lang.Signature;
026    import org.slf4j.*;
027    
028    import patterntesting.runtime.util.SignatureHelper;
029    
030    /**
031     * The Class SimpleProfileMonitor.
032     *
033     * @author <a href="boehm@javatux.de">oliver</a>
034     * @since 19.12.2008
035     * @version $Revision: 1.10 $
036     */
037    public final class SimpleProfileMonitor extends AbstractProfileMonitor {
038    
039        private static final Logger log = LoggerFactory.getLogger(SimpleProfileMonitor.class);
040        private SimpleProfileMonitor parent;
041        private Collection<SimpleProfileMonitor> childs;
042        private final String label;
043        /** start time in nanoseconds */
044        private long startTime;
045        /** the measured time in milliseconds */
046        private double total;
047        private double lastValue;
048        private double min;
049        private double max;
050        /** number of calls (or "hits") */
051        private int hits;
052    
053        /**
054         * Instantiates a new simple profile monitor.
055         */
056        public SimpleProfileMonitor() {
057            this("root");
058        }
059    
060        /**
061         * Instantiates a new simple profile monitor.
062         *
063         * @param rootLabel the root label
064         */
065        public SimpleProfileMonitor(final String rootLabel) {
066            this.reset();
067            this.label = rootLabel;
068        }
069    
070        /**
071         * Reset.
072         *
073         * @see ProfileMonitor#reset()
074         */
075        public void reset() {
076            this.total = 0.0;
077            this.lastValue = 0.0;
078            this.min = Double.MAX_VALUE;
079            this.max = 0.0;
080            this.hits = 0;
081            this.parent = null;
082            this.childs = new ConcurrentLinkedQueue<SimpleProfileMonitor>();
083        }
084    
085        /**
086         * Instantiates a new simple profile monitor.
087         *
088         * @param label the label
089         * @param parent the parent
090         */
091        public SimpleProfileMonitor(final Signature label, final SimpleProfileMonitor parent) {
092            this(SignatureHelper.getAsString(label), parent);
093        }
094    
095        /**
096         * Instantiates a new simple profile monitor.
097         *
098         * @param label the label
099         * @param parent the parent
100         */
101        public SimpleProfileMonitor(final String label, final SimpleProfileMonitor parent) {
102            this.reset();
103            this.label = label;
104            this.parent = parent;
105            this.parent.addChild(this);
106        }
107    
108        /**
109         * Adds the child.
110         *
111         * @param child the child
112         */
113        protected void addChild(final SimpleProfileMonitor child) {
114            this.childs.add(child);
115        }
116    
117        /**
118         * Adds the children.
119         *
120         * @param labels the labels
121         */
122        public void addChildren(final List<String> labels) {
123            for (String lbl : labels) {
124                addChild(lbl);
125            }
126        }
127    
128        /**
129         * Adds the child.
130         *
131         * @param lbl the label
132         */
133        public void addChild(final String lbl) {
134            try {
135                Signature sig = SignatureHelper.getAsSignature(lbl);
136                SimpleProfileMonitor child = new SimpleProfileMonitor(sig, this);
137                addChild(child);
138            } catch (Exception e) {
139                log.debug("can't add " + lbl, e);
140            }
141        }
142    
143        /**
144         * Gets the monitors.
145         *
146         * @return the monitors
147         * @see ProfileMonitor#getMonitors()
148         */
149        public ProfileMonitor[] getMonitors() {
150            return childs.toArray(new SimpleProfileMonitor[childs
151                    .size()]);
152        }
153    
154        /**
155         * We use now the signature without the return value. That's enough.
156         *
157         * @param sig the sig
158         *
159         * @return the monitor for sig
160         */
161        public SimpleProfileMonitor getMonitor(final Signature sig) {
162            String lbl = SignatureHelper.getAsString(sig);
163            return getMonitor(lbl);
164        }
165    
166        /**
167         * Gets the monitor.
168         *
169         * @param lbl the label as String
170         * @return the monitor
171         * @since 1.4.2
172         */
173        public SimpleProfileMonitor getMonitor(final String lbl) {
174            for (SimpleProfileMonitor mon : childs) {
175                if (lbl.equals(mon.label)) {
176                    return mon;
177                }
178            }
179            return null;
180        }
181    
182        /**
183         * Start.
184         *
185         * @see ProfileMonitor#start()
186         */
187        public void start() {
188            this.startTime = System.nanoTime();
189        }
190    
191        /**
192         * Stop.
193         *
194         * @see ProfileMonitor#stop()
195         */
196        public void stop() {
197            long time = System.nanoTime() - startTime;
198            this.add(time / 1000000.0);
199        }
200    
201        /**
202         * Adds the.
203         *
204         * @param value the measured time
205         * @see ProfileMonitor#add(double)
206         */
207        public void add(final double value) {
208            this.lastValue = value;
209            this.total += value;
210            this.hits++;
211            if (this.parent != null) {
212                this.parent.add(value);
213            }
214            if (value < this.min) {
215                this.min = value;
216            }
217            if (value > this.max) {
218                this.max = value;
219            }
220        }
221    
222        /**
223         * Gets the total.
224         *
225         * @return the total
226         * @see ProfileMonitor#getTotal()
227         */
228        public double getTotal() {
229            return this.total;
230        }
231    
232        /**
233         * Gets the last value.
234         *
235         * @return the last value
236         * @see ProfileMonitor#getLastValue()
237         */
238        public double getLastValue() {
239            return this.lastValue;
240        }
241    
242        /**
243         * Gets the max.
244         *
245         * @return the max
246         * @see ProfileMonitor#getMax()
247         */
248        public double getMax() {
249            return this.max;
250        }
251    
252        /**
253         * Gets the min.
254         *
255         * @return the min
256         * @see ProfileMonitor#getMin()
257         */
258        public double getMin() {
259            return this.min;
260        }
261    
262        /**
263         * Gets the hits.
264         *
265         * @return the hits
266         * @see ProfileMonitor#getHits()
267         */
268        public int getHits() {
269            return this.hits;
270        }
271    
272        /**
273         * Gets the avg.
274         *
275         * @return the avg
276         * @see ProfileMonitor#getAvg()
277         */
278        public double getAvg() {
279            return this.total / this.hits;
280        }
281    
282        /**
283         * Gets the label.
284         *
285         * @return the label
286         * @see ProfileMonitor#getLabel()
287         */
288        public String getLabel() {
289            return this.label;
290        }
291    
292        /**
293         * To string.
294         *
295         * @return the string
296         * @see java.lang.Object#toString()
297         */
298        @Override
299        public String toString() {
300            return this.getLabel() + " - " + toShortString();
301        }
302    
303        /**
304         * To short string.
305         *
306         * @return the string
307         * @see ProfileMonitor#toShortString()
308         */
309        public String toShortString() {
310            return "total: " + this.total + " ms / avg: "
311            + this.getAvg() + " ms / hits: " + this.hits;
312        }
313    
314        /**
315         * To csv headline.
316         *
317         * @return the string
318         * @see ProfileMonitor#toCsvHeadline()
319         */
320        public String toCsvHeadline() {
321            return "Label; Unit; Total; Avg; Hits; Max; Min";
322        }
323    
324        /**
325         * To csv string.
326         *
327         * @return the string
328         * @see ProfileMonitor#toCsvString()
329         */
330        public String toCsvString() {
331                    return '"' + this.getLabel() + "\"; ms; " + this.total + "; "
332                                    + this.getAvg() + "; " + this.hits + "; " + this.getMax() + "; "
333                                    + this.getMin();
334            }
335    
336        /**
337         * Gets the units.
338         *
339         * @return the units
340         * @see ProfileMonitor#getUnits()
341         */
342        public String getUnits() {
343            return "ms";
344        }
345    
346        /**
347         * Gets the active.
348         *
349         * @return the active
350         * @see ProfileMonitor#getActive()
351         */
352        public double getActive() {
353            return 0.0;
354        }
355    
356        /**
357         * Gets the avg active.
358         *
359         * @return the avg active
360         * @see ProfileMonitor#getAvgActive()
361         */
362        public double getAvgActive() {
363            return 0.0;
364        }
365    
366        /**
367         * Gets the first access.
368         *
369         * @return the first access
370         * @see ProfileMonitor#getFirstAccess()
371         */
372        public Date getFirstAccess() {
373            return null;
374        }
375    
376        /**
377         * Gets the last access.
378         *
379         * @return the last access
380         * @see ProfileMonitor#getLastAccess()
381         */
382        public Date getLastAccess() {
383            return null;
384        }
385    
386        /**
387         * Gets the max active.
388         *
389         * @return the max active
390         * @see ProfileMonitor#getMaxActive()
391         */
392        public double getMaxActive() {
393            return 0.0;
394        }
395    
396    }