/**
* Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*/
package at.iaik.suraq.util;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*
*/
public final class DagOperationManager {
/**
* global counter to keep track of running DAG traversals.
*/
private static long operationCount = 0;
/**
* The list of operations which have already finished.
*/
private static final List<Long> finishedOperations = new ArrayList<Long>();
/**
* Stores the number of nodes which have been visitied by each operation.
*/
private static final Map<Long, Long> nodeCounterPerOperation = new HashMap<Long, Long>();
/**
* Stores for each operation after how many nodes a message should be
* displayed.
*/
private static final Map<Long, Long> progressIncrement = new HashMap<Long, Long>();
/**
* Optionally stores a textual name for an operation.
*/
private static final Map<Long, String> operationNames = new HashMap<Long, String>();
/**
* A formatter for printing numbers.
*/
public static final DecimalFormat myFormatter = new DecimalFormat(
"###,###,###");
/**
* @return the <code>operationCount</code>
*/
public static long getOperationCount() {
return DagOperationManager.operationCount;
}
/**
* start a new DAG operation. increments global operation counter and
* provides a unique operation id.
*
* @return unique operation id.
*/
public static long startDAGOperation() {
DagOperationManager.operationCount++;
assert (DagOperationManager.operationCount > 0);
// System.out.println("Starting DAG operation " + Z3Proof.operationCount
// + " in thread " + Thread.currentThread());
return DagOperationManager.operationCount;
}
/**
* Starts a new DAG operation and stores the given name for it.
*
* @param name
* the name of the operation.
* @return a unique operation id.
*/
public static long startDAGOperation(String name) {
System.out
.println("PROGRESS-INFO: DAG operation " + name + " started.");
long operationId = DagOperationManager.startDAGOperation();
DagOperationManager.operationNames.put(operationId, name);
return operationId;
}
/**
* ends a DAG operation. decrements the global operation counter and removes
* all <code>visitedByOperation</code> list entries for this operation in
* all nodes.
*
* @param operationId
* unique id of the operation to end.
*/
public static void endDAGOperation(long operationId) {
assert (DagOperationManager.operationCount >= operationId);
DagOperationManager.finishedOperations.add(operationId);
String operationName = DagOperationManager.operationNames
.get(operationId);
if (operationName != null) {
Long counterObj = DagOperationManager.nodeCounterPerOperation
.get(operationId);
String counterString = counterObj == null ? "(<increment)"
: DagOperationManager.myFormatter.format(counterObj
.longValue());
System.out.println("PROGRESS-INFO: DAG operation " + operationName
+ " finished with node counter value " + counterString
+ ".");
}
// System.out.println("Stopped DAG operation " + Z3Proof.operationCount
// + " in thread " + Thread.currentThread());
// Reusing operation-IDs seems to cause problems under some
// circumstances.
// In particular, when the structure of the DAG is modified by the
// operation. Thus, do not reuse operation-IDs.
// Z3Proof.operationCount--;
}
/**
* Increments the node counter for the given operation
*
* @param operationId
*/
public static void incrementNodeCounter(long operationId) {
Long currentValueObj = DagOperationManager.nodeCounterPerOperation
.get(operationId);
long currentValue = (currentValueObj == null ? 0 : currentValueObj
.longValue()) + 1;
Long increment = DagOperationManager.progressIncrement.get(operationId);
if (increment != null) {
if (currentValue % increment.longValue() == 0) {
String operationString = DagOperationManager
.getOperationName(operationId);
if (operationString.equals(""))
operationString = DagOperationManager.myFormatter
.format(operationId);
String counterString = DagOperationManager.myFormatter
.format(currentValue);
System.out.println("PROGRESS-INFO: DAG operation "
+ operationString + " is at node counter value "
+ counterString + ".");
}
}
DagOperationManager.nodeCounterPerOperation.put(operationId,
currentValue);
}
public static void setMessageInterval(long operationId, long increment) {
DagOperationManager.progressIncrement.put(operationId, increment);
}
/**
*
* @return a read-only version of the list of finished operations.
*/
public static List<Long> getFinishedOperations() {
return Collections
.unmodifiableList(DagOperationManager.finishedOperations);
}
/**
* Returns the name of an operation
*
* @param operationId
* the id of the operation for which the name is seeked.
* @return the name of the operation or an empty string, if none is found.
*/
public static String getOperationName(long operationId) {
String result = DagOperationManager.operationNames.get(operationId);
return ((result == null) ? "" : result);
}
/**
*
* @param operationId
* @return the node current node count of the given operation, or 0, if the
* operation is not found in the map.
*/
public static long getNodeCounterForOperation(long operationId) {
Long result = DagOperationManager.nodeCounterPerOperation
.get(operationId);
return result == null ? 0L : result.longValue();
}
}