Fix codestyle
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / statistics / ofpspecific / EventsTimeCounter.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowplugin.impl.statistics.ofpspecific;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.concurrent.TimeUnit;
16 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
17
18 public final class EventsTimeCounter {
19
20     private static final Map<String, Map<String, EventTimeCounter>> DEVICES_EVENTS = new HashMap<>();
21
22     private EventsTimeCounter() {
23         // Hiding implicit constructor
24     }
25
26     public static void markStart(final EventIdentifier eventIdentifier) {
27         Map<String, EventTimeCounter> deviceEvents = getOrCreateCountersForDevice(eventIdentifier.getDeviceId());
28         EventTimeCounter eventTimeCounter = getOrCreateEventOfType(eventIdentifier.getEventName(), deviceEvents);
29         eventTimeCounter.markStart();
30     }
31
32     public static void markEnd(final EventIdentifier eventIdentifier) {
33         Map<String, EventTimeCounter> deviceEvents = getOrCreateCountersForDevice(eventIdentifier.getDeviceId());
34         EventTimeCounter eventTimeCounter = getOrCreateEventOfType(eventIdentifier.getEventName(), deviceEvents);
35         eventTimeCounter.markEnd();
36     }
37
38     private static EventTimeCounter getOrCreateEventOfType(final String event,
39                                                            final Map<String, EventTimeCounter> deviceEvents) {
40         return deviceEvents.computeIfAbsent(event, k -> new EventTimeCounter());
41     }
42
43     private static Map<String, EventTimeCounter> getOrCreateCountersForDevice(final String deviceId) {
44         return DEVICES_EVENTS.computeIfAbsent(deviceId, k -> new HashMap<>());
45     }
46
47     public static List<String> provideTimes() {
48         List<String> dump = new ArrayList<>();
49         for (Map.Entry<String, Map<String, EventTimeCounter>> deviceEntry : DEVICES_EVENTS.entrySet()) {
50             Map<String, EventTimeCounter> eventsMap = deviceEntry.getValue();
51             dump.add("================================================");
52             dump.add(String.format("DEVICE : %s", deviceEntry.getKey()));
53             for (Map.Entry<String, EventTimeCounter> eventEntry : eventsMap.entrySet()) {
54                 final String eventName = eventEntry.getKey();
55                 final EventTimeCounter eventTimeCounter = eventEntry.getValue();
56                 dump.add(String.format("%s", eventName));
57                 dump.add(String.format("    MIN TIME (ms):  %d",
58                         TimeUnit.MILLISECONDS.convert(eventTimeCounter.getMinimum(), TimeUnit.NANOSECONDS)));
59                 dump.add(String.format("    MAX TIME (ms):  %d",
60                         TimeUnit.MILLISECONDS.convert(eventTimeCounter.getMaximum(), TimeUnit.NANOSECONDS)));
61                 dump.add(String.format("    AVG TIME (ms):  %d",
62                         TimeUnit.MILLISECONDS.convert(eventTimeCounter.getAverage(), TimeUnit.NANOSECONDS)));
63
64             }
65         }
66         return dump;
67     }
68
69     public static void resetAllCounters() {
70         DEVICES_EVENTS.clear();
71     }
72
73
74     private static final class EventTimeCounter {
75
76         private volatile long delta = 0;
77         private volatile long average = 0;
78         private volatile long minimum = 0;
79         private volatile long maximum = 0;
80         private volatile long summary = 0;
81         private volatile int counter = 0;
82
83         public synchronized void markStart() {
84             delta = System.nanoTime();
85         }
86
87         public synchronized void markEnd() {
88             if (0 == delta) {
89                 return;
90             }
91             counter++;
92             delta = System.nanoTime() - delta;
93
94             if (delta < minimum || minimum == 0) {
95                 minimum = delta;
96             }
97             if (delta > maximum) {
98                 maximum = delta;
99             }
100             if (average > 0 && delta > (average * 1.8)) {
101                 summary += average;
102             } else {
103                 summary += delta;
104             }
105             average = summary / counter;
106         }
107
108         public synchronized void resetCounters() {
109             delta = 0;
110             average = 0;
111             minimum = 0;
112             maximum = 0;
113             summary = 0;
114             counter = 0;
115
116         }
117
118         public synchronized long getAverage() {
119             return average;
120         }
121
122         public synchronized long getMinimum() {
123             return minimum;
124         }
125
126         public synchronized long getMaximum() {
127             return maximum;
128         }
129
130     }
131 }