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.BlockingAsyncProcedure; 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 tasks = new HashMap<>(); public static final HashMap> reverseLookup = new HashMap<>(); public static final HashMap debuggerMap = new HashMap<>(); public static final HashMap> entryMap = new HashMap<>(); public static final HashMap restartMap = new HashMap<>(); public static final HashMap startMap = new HashMap<>(); public static final HashMap baps = new HashMap<>(); synchronized public static void registerBAP(BlockingAsyncProcedure bap) { baps.put(bap, new Exception()); } synchronized public static void unregisterBAP(BlockingAsyncProcedure bap) { baps.remove(bap); } synchronized public static void printBAPS() { for(BlockingAsyncProcedure bap : baps.keySet()) { Throwable e = baps.get(bap); System.err.println("BlockingAsyncProcedure"); System.err.println("-key: " + bap.key); System.err.println("-queryGraph: " + bap.queryGraph); System.err.println("-callerGraph: " + bap.callerGraph); System.err.println("-procedure: " + bap.procedure); System.err.println("-pendingTaskSupport: " + bap.pendingTaskSupport); System.err.println("-result: " + bap.result); System.err.println("-exception: " + bap.exception); e.printStackTrace(); } } 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 barriers = reverseLookup .get(barrier.caller); if (barriers == null) { barriers = new ArrayList(); 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 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(); } } }