2e0f9b8669da276cf724a8ff3b6897e7aeaa8719
[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         EventTimeCounter lookup = deviceEvents.get(event);
41         if (null == lookup) {
42             lookup = new EventTimeCounter();
43             deviceEvents.put(event, lookup);
44         }
45         return lookup;
46     }
47
48     private static Map<String, EventTimeCounter> getOrCreateCountersForDevice(final String deviceId) {
49         Map<String, EventTimeCounter> lookup = DEVICES_EVENTS.get(deviceId);
50         if (null == lookup) {
51             lookup = new HashMap<>();
52             DEVICES_EVENTS.put(deviceId, lookup);
53         }
54
55         return lookup;
56     }
57
58     public static List<String> provideTimes() {
59         List<String> dump = new ArrayList<>();
60         for (Map.Entry<String, Map<String, EventTimeCounter>> deviceEntry : DEVICES_EVENTS.entrySet()) {
61             Map<String, EventTimeCounter> eventsMap = deviceEntry.getValue();
62             dump.add("================================================");
63             dump.add(String.format("DEVICE : %s", deviceEntry.getKey()));
64             for (Map.Entry<String, EventTimeCounter> eventEntry : eventsMap.entrySet()) {
65                 final String eventName = eventEntry.getKey();
66                 final EventTimeCounter eventTimeCounter = eventEntry.getValue();
67                 dump.add(String.format("%s", eventName));
68                 dump.add(String.format("    MIN TIME (ms):  %d",
69                         TimeUnit.MILLISECONDS.convert(eventTimeCounter.getMinimum(), TimeUnit.NANOSECONDS)));
70                 dump.add(String.format("    MAX TIME (ms):  %d",
71                         TimeUnit.MILLISECONDS.convert(eventTimeCounter.getMaximum(), TimeUnit.NANOSECONDS)));
72                 dump.add(String.format("    AVG TIME (ms):  %d",
73                         TimeUnit.MILLISECONDS.convert(eventTimeCounter.getAverage(), TimeUnit.NANOSECONDS)));
74
75             }
76         }
77         return dump;
78     }
79
80     public static void resetAllCounters() {
81         DEVICES_EVENTS.clear();
82     }
83
84
85     private static final class EventTimeCounter {
86
87         private volatile long delta = 0;
88         private volatile long average = 0;
89         private volatile long minimum = 0;
90         private volatile long maximum = 0;
91         private volatile long summary = 0;
92         private volatile int counter = 0;
93
94         public synchronized void markStart() {
95             delta = System.nanoTime();
96         }
97
98         public synchronized void markEnd() {
99             if (0 == delta) {
100                 return;
101             }
102             counter++;
103             delta = System.nanoTime() - delta;
104
105             if (delta < minimum || minimum == 0) {
106                 minimum = delta;
107             }
108             if (delta > maximum) {
109                 maximum = delta;
110             }
111             if (average > 0 && delta > (average * 1.8)) {
112                 summary += average;
113             } else {
114                 summary += delta;
115             }
116             average = summary / counter;
117         }
118
119         public synchronized void resetCounters() {
120             delta = 0;
121             average = 0;
122             minimum = 0;
123             maximum = 0;
124             summary = 0;
125             counter = 0;
126
127         }
128
129         public synchronized long getAverage() {
130             return average;
131         }
132
133         public synchronized long getMinimum() {
134             return minimum;
135         }
136
137         public synchronized long getMaximum() {
138             return maximum;
139         }
140
141     }
142 }