--- /dev/null
+package org.simantics.db.impl.graph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.simantics.db.impl.query.CacheEntry;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
+
+public class BarrierTracing {
+
+ public static final boolean BOOKKEEPING = false;
+ static final boolean RESTART_GUARD = BOOKKEEPING && false;
+
+ public static Map<SessionTask,Exception> tasks = new HashMap<>();
+ public static final HashMap<AsyncBarrierImpl, Collection<AsyncBarrierImpl>> reverseLookup = new HashMap<>();
+ public static final HashMap<AsyncBarrierImpl, Debugger> debuggerMap = new HashMap<>();
+ public static final HashMap<AsyncBarrierImpl, CacheEntry<?>> entryMap = new HashMap<>();
+ public static final HashMap<AsyncBarrierImpl, Throwable> restartMap = new HashMap<>();
+ public static final HashMap<AsyncBarrierImpl, Throwable> startMap = new HashMap<>();
+
+ public static void trace(AsyncBarrierImpl barrier, CacheEntry<?> entry) {
+
+ if (RESTART_GUARD) {
+ synchronized (startMap) {
+ startMap.put(barrier, new Exception());
+ }
+ }
+ synchronized (entryMap) {
+ entryMap.put(barrier, entry);
+ }
+ synchronized (debuggerMap) {
+ debuggerMap.put(barrier, new Debugger());
+ }
+ synchronized (reverseLookup) {
+ Collection<AsyncBarrierImpl> barriers = reverseLookup
+ .get(barrier.caller);
+ if (barriers == null) {
+ barriers = new ArrayList<AsyncBarrierImpl>();
+ reverseLookup.put(barrier.caller, barriers);
+ }
+ barriers.add(barrier);
+ }
+
+ }
+
+ public static void inc(AsyncBarrierImpl barrier) {
+
+ barrier.inc(barrier, new Exception().getStackTrace()[2].toString());
+
+ if (RESTART_GUARD)
+ if(restartMap.containsKey(barrier)) {
+ startMap.get(barrier).printStackTrace();
+ restartMap.get(barrier).printStackTrace();
+ new Exception().printStackTrace();
+ throw new IllegalStateException("Unplanned restart");
+ }
+
+
+ }
+
+ public static void restart(AsyncBarrierImpl barrier) {
+ if (RESTART_GUARD)
+ BarrierTracing.restartMap.remove(barrier);
+ if (BOOKKEEPING)
+ BarrierTracing.debuggerMap.put(barrier, new Debugger());
+ }
+
+ public static void dec(AsyncBarrierImpl barrier, int count) {
+ if (count == 0) {
+ if (RESTART_GUARD) {
+ restartMap.put(barrier, new Exception());
+ }
+ debuggerMap.remove(barrier);
+ }
+ else if (count < 0) {
+ BarrierTracing.startMap.get(barrier).printStackTrace();
+ BarrierTracing.restartMap.get(barrier).printStackTrace();
+ new Exception().printStackTrace();
+ }
+ }
+
+ public static class Debugger {
+
+ public Map<AsyncBarrierImpl, String> infos = new HashMap<>();
+
+ public synchronized void inc(AsyncBarrierImpl id, String info) {
+ if (id == null)
+ return;
+ String exist = infos.get(id);
+ if (exist != null)
+ throw new IllegalStateException("Already existing info " + id + " " + info);
+ infos.put(id, exist);
+ }
+
+ public synchronized void dec(AsyncBarrierImpl id) {
+ if (id == null)
+ return;
+ String exist = infos.get(id);
+ if (exist == null) {
+ System.err.println("No data for " + id);
+ } else {
+ infos.remove(id);
+ }
+ }
+
+ @Override
+ public synchronized String toString() {
+ StringBuilder b = new StringBuilder();
+ for (String s : infos.values()) {
+ b.append("info " + s + "\r\n");
+ }
+ return b.toString();
+ }
+
+ public boolean isEmpty() {
+ return infos.isEmpty();
+ }
+
+ }
+
+}