package org.simantics.db.impl.graph;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.RuntimeDatabaseException;
+import org.simantics.db.impl.query.CacheEntry;
import org.simantics.db.impl.query.QueryProcessor.AsyncBarrier;
final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrier {
private static final long serialVersionUID = 4724463372850048672L;
static final HashMap<AsyncBarrierImpl, Collection<AsyncBarrierImpl>> reverseLookup = new HashMap<AsyncBarrierImpl, Collection<AsyncBarrierImpl>>();
- static final HashMap<AsyncBarrierImpl, Debugger> debuggerMap = new HashMap<AsyncBarrierImpl, Debugger>();
+ public static final HashMap<AsyncBarrierImpl, Debugger> debuggerMap = new HashMap<AsyncBarrierImpl, Debugger>();
+ static final HashMap<AsyncBarrierImpl, CacheEntry> entryMap = new HashMap<AsyncBarrierImpl, CacheEntry>();
static final HashMap<AsyncBarrierImpl, Boolean> restartMap = new HashMap<AsyncBarrierImpl, Boolean>();
static final int WAIT_TIME = 600;
- public static final boolean BOOKKEEPING = false;
+ public static final boolean BOOKKEEPING = true;
public static final boolean PRINT = false;
- static final boolean RESTART_GUARD = false;
+ static final boolean RESTART_GUARD = true;
- final private AsyncBarrierImpl caller;
+ final public AsyncBarrierImpl caller;
//private final Semaphore sema = new Semaphore(0);
- public AsyncBarrierImpl(AsyncBarrierImpl caller) {
+ public AsyncBarrierImpl(AsyncBarrierImpl caller, CacheEntry entry) {
super(0);
if (BOOKKEEPING) {
+ synchronized (entryMap) {
+ entryMap.put(this, entry);
+ }
synchronized (debuggerMap) {
debuggerMap.put(this, new Debugger());
}
}
public class Debugger {
- public HashMap<Object, ArrayList<String>> infos = new HashMap<Object, ArrayList<String>>();
+
+ public Map<AsyncBarrierImpl, String> infos = new HashMap<>();
- public synchronized void inc(Object id, String info) {
+ public synchronized void inc(AsyncBarrierImpl id, String info) {
if (id == null)
return;
- ArrayList<String> exist = infos.get(id);
- if (exist == null) {
- exist = new ArrayList<String>();
- infos.put(id, exist);
- } else {
- // System.err.println("Appending " + id + " += " + info);
- }
- exist.add(info);
- // String exist = infos.put(id, info);
- // if(exist != null) System.err.println("replacing " + exist +
- // " => " + info + " for " + id);
+ String exist = infos.get(id);
+ if (exist != null)
+ throw new IllegalStateException("Already existing info " + id + " " + info);
+ infos.put(id, exist);
}
- public synchronized void dec(Object id) {
+ public synchronized void dec(AsyncBarrierImpl id) {
if (id == null)
return;
- ArrayList<String> exist = infos.get(id);
+ String exist = infos.get(id);
if (exist == null) {
System.err.println("No data for " + id);
} else {
- exist.remove(0);
- if (exist.isEmpty())
- infos.remove(id);
+ infos.remove(id);
}
}
@Override
public synchronized String toString() {
StringBuilder b = new StringBuilder();
- for (ArrayList<String> ss : infos.values()) {
- for (String s : ss)
- b.append("info " + s + "\r\n");
+ for (String s : infos.values()) {
+ b.append("info " + s + "\r\n");
}
return b.toString();
}
-
- public synchronized void toErr(int indent) {
- char[] spaces = new char[indent];
- Arrays.fill(spaces, ' ');
- for (ArrayList<String> ss : infos.values()) {
- for (String s : ss) {
- if (!s.startsWith("#"))
- continue;
- StringBuilder b = new StringBuilder();
- b.append(spaces);
- b.append(s);
- System.err.println(b.toString());
- }
- }
+
+ public boolean isEmpty() {
+ return infos.isEmpty();
}
- }
-
- public void inc() {
-
- if (BOOKKEEPING)
- inc(new Object(), new Exception().getStackTrace()[1].toString());
- else
- inc(null, null);
}
- public void inc(String debug) {
+ public void inc() {
if (BOOKKEEPING)
- inc(new Object(), new Exception().getStackTrace()[1].toString());
+ inc(this, new Exception().getStackTrace()[2].toString());
else
inc(null, null);
+
+ if (RESTART_GUARD)
+ if(restartMap.containsKey(this))
+ throw new IllegalStateException("Unplanned restart");
}
- public void inc(Object id, String info) {
+ private void inc(Object id, String info) {
// if (PRINT) {
// if (get() < 5)
// }
if (BOOKKEEPING) {
- Debugger debugger = debuggerMap.get(this);
- if (debugger != null)
- debugger.inc(id, info);
- // StackTraceElement[] tr = new Exception().getStackTrace();
- // if(tr.length == 4)
- // debugger.inc(new String[] { debug, tr[2].toString(),
- // tr[3].toString() });
- // else if(tr.length == 5)
- // debugger.inc(new String[] { debug, tr[2].toString(),
- // tr[3].toString(), tr[4].toString() });
- // else if(tr.length == 6)
- // debugger.inc(new String[] { debug, tr[2].toString(),
- // tr[3].toString(), tr[4].toString(), tr[5].toString() });
- // else
- // debugger.inc(new String[] { debug, tr[2].toString(),
- // tr[3].toString(), tr[4].toString(), tr[5].toString(),
- // tr[6].toString() });
+// Debugger debugger = debuggerMap.get(this);
+// if (debugger != null)
+// debugger.inc(id, info);
}
- // new Exception().printStackTrace();
-
if(PRINT) {
System.err.println("inc barrier[" + get() + "] " + this);
}
if (BOOKKEEPING) {
- Debugger debugger = debuggerMap.get(this);
- if (debugger != null)
- debugger.dec(id);
- // StackTraceElement[] tr = new Exception().getStackTrace();
- // if(tr.length == 3)
- // debugger.dec(new String[] { debug, tr[2].toString() });
- // else if(tr.length == 4)
- // debugger.dec(new String[] { debug, tr[2].toString(),
- // tr[3].toString() });
- // else
- // debugger.dec(new String[] { debug, tr[2].toString(),
- // tr[3].toString(), tr[4].toString() });
+// Debugger debugger = debuggerMap.get(this);
+// if (debugger != null) {
+// debugger.dec(id);
+// if(debugger.isEmpty())
+// debuggerMap.remove(this);
+// }
}
- // System.err.println("barrier " + this);
- // StackTraceElement[] elems = new Exception().getStackTrace();
- // for(int i=0;i<3;i++) System.err.println(elems[i]);
- // new Exception().printStackTrace();
-
int count = decrementAndGet();
if (count < 1) {
if (count == 0) {
+ debuggerMap.remove(this);
if (caller != null)
caller.dec(this);
if (RESTART_GUARD)
restartMap.put(this, true);
- // sema.release();
- // if(DEBUGGER) {
- // debuggerMap.remove(this);
- // }
- // if(REVERSE_LOOKUP) {
- // reverseLookup.remove(this);
- // }
}
if (count < 0) {
Logger.defaultLogError(
"Database request processing error. The application code has performed illegal actions (probably called multiple times the execute or exception method of a single result request.",
new Exception());
- // String message = ;
- // System.out.println(message);
- // if (DEBUGGER) {
- // JOptionPane.showMessageDialog(null, message);
- // System.out.println(debugger);
- // }
- // sema.release();
System.exit(-1);
}
assert (count >= 0);
}
}
- private static void printReverse(AsyncBarrierImpl barrier, int indent) {
+ public static String report(AsyncBarrierImpl barrier) {
+ CacheEntry e = entryMap.get(barrier);
+ if(e != null) return e.toString();
+ else return "Barrier@" + System.identityHashCode(barrier);
+ }
+
+ public static void printReverse(AsyncBarrierImpl barrier, int indent) {
if (barrier.get() == 0)
return;
for (int i = 0; i < indent; i++)
System.err.print(" ");
- System.err.println("[" + barrier.get() + " requests]: " + barrier);
- if (BOOKKEEPING) {
- Debugger debugger = debuggerMap.get(barrier);
- debugger.toErr(indent + 2);
- }
+ System.err.println("[" + barrier.get() + " requests]: " + report(barrier));
+// if (BOOKKEEPING) {
+// Debugger debugger = debuggerMap.get(barrier);
+// debugger.toErr(indent + 2);
+// }
Collection<AsyncBarrierImpl> children = reverseLookup.get(barrier);
if (children != null) {
@Override
public String toString() {
- return "AsyncBarrierImpl@" + System.identityHashCode(this)
- + " - counter = " + get() + " - caller = " + caller;
+ return report(this);
+// return "AsyncBarrierImpl@" + System.identityHashCode(this)
+// + " - counter = " + get() + " - caller = " + caller;
}
}