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