blob: 40c9a364e90f8c986da9e8f0f714de1715e1753c [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 *
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08003 */
4package net.floodlightcontroller.util;
5
6import java.util.ArrayList;
7
8/**
9 * @author subrata
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080010 */
11
12public class EventHistory<T> {
13 public static final int EV_HISTORY_DEFAULT_SIZE = 1024;
14
Ray Milkey269ffb92014-04-03 14:43:30 -070015 public String description;
16 public int event_history_size;
17 public int current_index;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080018 public boolean full; // true if all are in use
19 public ArrayList<Event> events;
20
21 public String getDescription() {
22 return description;
23 }
Ray Milkey269ffb92014-04-03 14:43:30 -070024
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080025 public int getEvent_history_size() {
26 return event_history_size;
27 }
Ray Milkey269ffb92014-04-03 14:43:30 -070028
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080029 public int getCurrent_index() {
30 return current_index;
31 }
Ray Milkey269ffb92014-04-03 14:43:30 -070032
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080033 public boolean isFull() {
34 return full;
35 }
Ray Milkey269ffb92014-04-03 14:43:30 -070036
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080037 public ArrayList<Event> getEvents() {
38 return events;
39 }
40
41 public class Event {
42 public EventHistoryBaseInfo base_info;
43 public T info;
44 }
45
46 public enum EvState {
47 FREE, // no valid event written yet
48 BEING_MODIFIED, // event is being updated with new value, skip
49 ACTIVE, // event is active and can be displayed
50 }
51
52 public enum EvAction {
53 ADDED, // specific entry added
54 REMOVED, // specific entry removed
55 UPDATED, // Entry updated
56 BLOCKED, // Blocked - used for Attachment Points
57 UNBLOCKED,
58 CLEARED, // All entries are removed
59 PKT_IN,
60 PKT_OUT,
61 SWITCH_CONNECTED,
62 SWITCH_DISCONNECTED,
63 LINK_ADDED,
64 LINK_DELETED,
65 LINK_PORT_STATE_UPDATED,
66 CLUSTER_ID_CHANGED_FOR_CLUSTER,
67 CLUSTER_ID_CHANGED_FOR_A_SWITCH,
68 }
69
70 // Constructor
71 public EventHistory(int maxEvents, String desc) {
72 events = new ArrayList<Event>(maxEvents);
73
74 for (int idx = 0; idx < maxEvents; idx++) {
Ray Milkey269ffb92014-04-03 14:43:30 -070075 Event evH = new Event();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080076 evH.base_info = new EventHistoryBaseInfo();
Ray Milkey269ffb92014-04-03 14:43:30 -070077 evH.info = null;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080078 evH.base_info.state = EvState.FREE;
Ray Milkey269ffb92014-04-03 14:43:30 -070079 evH.base_info.idx = idx;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080080 events.add(idx, evH);
81 }
82
83 description = "Event-History:" + desc;
Ray Milkey269ffb92014-04-03 14:43:30 -070084 event_history_size = maxEvents;
85 current_index = 0;
86 full = false;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080087 }
88
89 // Constructor for default size
90 public EventHistory(String desc) {
91 this(EV_HISTORY_DEFAULT_SIZE, desc);
92 }
93
94 // Copy constructor - copy latest k items of the event history
95 public EventHistory(EventHistory<T> eventHist, int latestK) {
96
97 if (eventHist == null) {
98 description = "No event found";
99 return;
100 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 int curSize = (eventHist.full) ? eventHist.event_history_size :
102 eventHist.current_index;
103 int size = (latestK < curSize) ? latestK : curSize;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800104 int evIdx = eventHist.current_index;
Ray Milkey269ffb92014-04-03 14:43:30 -0700105 int topSz = (evIdx >= size) ? size : evIdx;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800106
107 // Need to create a new one since size is different
108 events = new ArrayList<Event>(size);
109
110 // Get the top part
111 int origIdx = evIdx;
112 for (int idx = 0; idx < topSz; idx++) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700113 Event evH = eventHist.events.get(--origIdx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800114 evH.base_info.idx = idx;
115 events.add(idx, evH);
116 }
117
118 // Get the bottom part
119 origIdx = eventHist.event_history_size;
120 for (int idx = topSz; idx < size; idx++) {
121 Event evH = eventHist.events.get(--origIdx);
122 evH.base_info.idx = idx;
123 events.add(idx, evH);
124 }
125
126 description = eventHist.description;
Ray Milkey269ffb92014-04-03 14:43:30 -0700127 event_history_size = size;
128 current_index = 0; // since it is full
129 full = true;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800130 }
131
132 // Get an index for writing a new event. This method is synchronized for
133 // this event history infra. to be thread-safe. Once the index is obtained
134 // by the caller event at the index is updated without any lock
135 public synchronized int NextIdx() {
136 // curIdx should be in the 0 to evArraySz-1
Ray Milkey269ffb92014-04-03 14:43:30 -0700137 if (current_index == (event_history_size - 1)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800138 current_index = 0;
139 full = true;
Ray Milkey269ffb92014-04-03 14:43:30 -0700140 return (event_history_size - 1);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800141 } else {
142 current_index++;
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 return (current_index - 1);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800144 }
145 }
146
147 /**
148 * Add an event to the event history
149 * Eliminate java garbage cration by reusing the same object T
150 * Supplied object t is used to populate the event history array
151 * and the current object at that array location is returned to the
152 * calling process so that the calling process can use that object
153 * for the next event of the same type
Ray Milkey269ffb92014-04-03 14:43:30 -0700154 *
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800155 * @param t
156 * @param op
157 * @return
158 */
159
160 public T put(T t, EvAction action) {
161 int idx = NextIdx();
162 Event evH = events.get(idx);
163 evH.base_info.state = EvState.BEING_MODIFIED;
164 evH.base_info.time_ms = System.currentTimeMillis();
165 evH.base_info.action = action;
166 T temp = evH.info;
167 evH.info = t;
168 evH.base_info.state = EvState.ACTIVE;
169 return temp;
170 }
171
Ray Milkey269ffb92014-04-03 14:43:30 -0700172 /**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800173 * Clear the event history, needs to be done under lock
174 */
175 public void clear() {
176 for (int idx = 0; idx < event_history_size; idx++) {
177 Event evH = events.get(idx);
178 evH.base_info.state = EvState.FREE;
179 current_index = 0;
180 full = false;
181 }
182 }
183}