1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002, 2014 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 
8 package com.sleepycat.je.utilint;
9 
10 import java.io.PrintStream;
11 import java.util.concurrent.atomic.AtomicInteger;
12 
13 /**
14  * Internal class used for transient event tracing.  Subclass this with
15  * specific events.  Subclasses should have toString methods for display and
16  * events should be added by calling EventTrace.addEvent();
17  */
18 public class EventTrace {
19     private static int MAX_EVENTS = 100;
20 
21     public static final boolean TRACE_EVENTS = false;
22 
23     static AtomicInteger currentEvent = new AtomicInteger(0);
24 
25     static final EventTrace[] events = new EventTrace[MAX_EVENTS];
26     static final int[] threadIdHashes = new int[MAX_EVENTS];
27     public static volatile boolean disableEvents = false;
28 
29     protected String comment;
30 
EventTrace(String comment)31     public EventTrace(String comment) {
32         this.comment = comment;
33     }
34 
EventTrace()35     public EventTrace() {
36         comment = null;
37     }
38 
39     @Override
toString()40     public String toString() {
41         return comment;
42     }
43 
44     /**
45      * Always return true so this method can be used with asserts:
46      * i.e. assert addEvent(xxx);
47      */
addEvent(EventTrace event)48     public static boolean addEvent(EventTrace event) {
49         if (disableEvents) {
50             return true;
51         }
52         int nextEventIdx = currentEvent.getAndIncrement() % MAX_EVENTS;
53         events[nextEventIdx] = event;
54         threadIdHashes[nextEventIdx] =
55             System.identityHashCode(Thread.currentThread());
56         return true;
57     }
58 
59     /*
60      * Always return true so this method can be used with asserts:
61      * i.e. assert addEvent(xxx);
62      */
addEvent(String comment)63     public static boolean addEvent(String comment) {
64         if (disableEvents) {
65             return true;
66         }
67         return addEvent(new EventTrace(comment));
68     }
69 
dumpEvents()70     public static void dumpEvents() {
71         dumpEvents(System.out);
72     }
73 
dumpEvents(PrintStream out)74     public static void dumpEvents(PrintStream out) {
75 
76         if (disableEvents) {
77             return;
78         }
79         out.println("----- Event Dump -----");
80         EventTrace[] oldEvents = events;
81         int[] oldThreadIdHashes = threadIdHashes;
82         disableEvents = true;
83 
84         int j = 0;
85         for (int i = currentEvent.get(); j < MAX_EVENTS; i++) {
86             EventTrace ev = oldEvents[i % MAX_EVENTS];
87             if (ev != null) {
88                 int thisEventIdx = i % MAX_EVENTS;
89                 out.print(oldThreadIdHashes[thisEventIdx] + " ");
90                 out.println(j + "(" + thisEventIdx + "): " + ev);
91             }
92             j++;
93         }
94     }
95 
96     public static class ExceptionEventTrace extends EventTrace {
97         private Exception event;
98 
ExceptionEventTrace()99         public ExceptionEventTrace() {
100             event = new Exception();
101         }
102 
103         @Override
toString()104         public String toString() {
105             return LoggerUtils.getStackTrace(event);
106         }
107     }
108 }
109 
110     /*
111     public static class EvictEvent extends EventTrace {
112         long nodeId;
113         int addr;
114 
115         public EvictEvent(String comment, long nodeId, int addr) {
116             super(comment);
117             this.nodeId = nodeId;
118             this.addr = addr;
119         }
120 
121         public static void addEvent(String comment, IN node) {
122             long nodeId = node.getNodeId();
123             int addr = System.identityHashCode(node);
124             EventTrace.addEvent(new EvictEvent(comment, nodeId, addr));
125         }
126 
127         public String toString() {
128             StringBuilder sb = new StringBuilder(comment);
129             sb.append(" IN: ").append(nodeId);
130             sb.append(" sIH ").append(addr);
131             return sb.toString();
132         }
133     }
134 
135     public static class CursorTrace extends EventTrace {
136         long nodeId;
137         int index;
138 
139         public CursorTrace(String comment, long nodeId, int index) {
140             super(comment);
141             this.nodeId = nodeId;
142             this.index = index;
143         }
144 
145         public static void addEvent(String comment, CursorImpl cursor) {
146             long nodeId = cursor.getCurrentNodeId();
147             EventTrace.addEvent
148                 (new CursorTrace(comment, nodeId, cursor.getIndex()));
149         }
150 
151         public String toString() {
152             StringBuilder sb = new StringBuilder(comment);
153             sb.append(" BIN: ").append(nodeId);
154             sb.append(" idx: ").append(index);
155             return sb.toString();
156         }
157     }
158     */
159 
160 /*
161     class CursorEventTrace extends EventTrace {
162         private String comment;
163         private Node node1;
164         private Node node2;
165 
166         CursorEventTrace(String comment, Node node1, Node node2) {
167             this.comment = comment;
168             this.node1 = node1;
169             this.node2 = node2;
170         }
171 
172         public String toString() {
173             StringBuilder sb = new StringBuilder(comment);
174             if (node1 != null) {
175                 sb.append(" ");
176                 sb.append(node1.getNodeId());
177             }
178             if (node2 != null) {
179                 sb.append(" ");
180                 sb.append(node2.getNodeId());
181             }
182             return sb.toString();
183         }
184     }
185 
186 */
187 /*
188 
189     static class UndoEventTrace extends EventTrace {
190         private String comment;
191         private boolean success;
192         private Node node;
193         private DbLsn logLsn;
194         private Node parent;
195         private boolean found;
196         private boolean replaced;
197         private boolean inserted;
198         private DbLsn replacedLsn;
199         private DbLsn abortLsn;
200         private int index;
201 
202         UndoEventTrace(String comment) {
203             this.comment = comment;
204         }
205 
206         UndoEventTrace(boolean success,
207                        Node node,
208                        DbLsn logLsn,
209                        Node parent,
210                        boolean found,
211                        boolean replaced,
212                        boolean inserted,
213                        DbLsn replacedLsn,
214                        DbLsn abortLsn,
215                        int index) {
216             this.comment = null;
217             this.success = success;
218             this.node = node;
219             this.logLsn = logLsn;
220             this.parent = parent;
221             this.found = found;
222             this.replaced = replaced;
223             this.inserted = inserted;
224             this.replacedLsn = replacedLsn;
225             this.abortLsn = abortLsn;
226             this.index = index;
227         }
228 
229         public String toString() {
230             if (comment != null) {
231                 return comment;
232             }
233             StringBuilder sb = new StringBuilder();
234             sb.append(" success=").append(success);
235             sb.append(" node=");
236             sb.append(node.getNodeId());
237             sb.append(" logLsn=");
238             sb.append(logLsn.getNoFormatString());
239             if (parent != null) {
240                 sb.append(" parent=").append(parent.getNodeId());
241             }
242             sb.append(" found=");
243             sb.append(found);
244             sb.append(" replaced=");
245             sb.append(replaced);
246             sb.append(" inserted=");
247             sb.append(inserted);
248             if (replacedLsn != null) {
249                 sb.append(" replacedLsn=");
250                 sb.append(replacedLsn.getNoFormatString());
251             }
252             if (abortLsn != null) {
253                 sb.append(" abortLsn=");
254                 sb.append(abortLsn.getNoFormatString());
255             }
256             sb.append(" index=").append(index);
257             return sb.toString();
258         }
259     }
260  */
261 /*
262     class CursorAdjustEventTrace extends EventTrace {
263         private int insertIndex;
264         private int cursorIndex;
265         private long nodeId;
266 
267         CursorAdjustEventTrace(int insertIndex, int cursorIndex) {
268             this.insertIndex = insertIndex;
269             this.cursorIndex = cursorIndex;
270             this.nodeId = getNodeId();
271         }
272 
273         public String toString() {
274             StringBuilder sb = new StringBuilder("cursor adjust ");
275             sb.append(insertIndex).append(" ");
276             sb.append(cursorIndex).append(" ");
277             sb.append(nodeId);
278             return sb.toString();
279         }
280     }
281 
282 */
283 /*
284     class CompressEventTrace extends EventTrace {
285         private int entryIndex;
286         private long nodeId;
287 
288         CompressEventTrace(int entryIndex) {
289             this.entryIndex = entryIndex;
290             this.nodeId = getNodeId();
291         }
292 
293         public String toString() {
294             StringBuilder sb = new StringBuilder("bin compress ");
295             sb.append(entryIndex).append(" ");
296             sb.append(nodeId);
297             return sb.toString();
298         }
299     }
300 
301 */
302 /*
303     class TreeEventTrace extends EventTrace {
304         private String comment;
305         private Node node1;
306         private Node node2;
307 
308         TreeEventTrace(String comment, Node node1, Node node2) {
309             this.comment = comment;
310             this.node1 = node1;
311             this.node2 = node2;
312         }
313 
314         public String toString() {
315             StringBuilder sb = new StringBuilder(comment);
316             if (node1 != null) {
317                 sb.append(" ");
318                 sb.append(node1.getNodeId());
319             }
320             if (node2 != null) {
321                 sb.append(" ");
322                 sb.append(node2.getNodeId());
323             }
324             return sb.toString();
325         }
326     }
327 
328 */
329