FileDocCategorySizeDatePackage
CommitOrderCalculator.javaAPI DocGlassfish v2 API9917Tue May 22 16:54:42 BST 2007oracle.toplink.essentials.internal.sessions

CommitOrderCalculator

public class CommitOrderCalculator extends Object
This class calculates a commit order for a series of classes based on the dependencies between them. It builds up a graph of dependencies (CommitOrderDependencyNodes) then applies topological sort to them to get an ordering. This is a throwaway class, which exists only for the lifetime of the calculation. The algorithm is descrbied in the method comment for orderCommits(). This class also includes static methods for quicksort, copied from the standard libraries and adapted for these objects, since that seemed like the easiest way to sort.

Fields Summary
protected int
currentTime
protected Vector
nodes
protected Vector
orderedDescriptors
protected AbstractSession
session
Constructors Summary
public CommitOrderCalculator(AbstractSession session)

        super();
        this.currentTime = 0;
        this.nodes = new Vector(1);
        this.session = session;
    
Methods Summary
protected voidaddNode(oracle.toplink.essentials.descriptors.ClassDescriptor d)

        nodes.addElement(new CommitOrderDependencyNode(this, d, session));
    
public voidaddNodes(java.util.Vector descriptors)

        Enumeration descriptorsEnum = descriptors.elements();
        while (descriptorsEnum.hasMoreElements()) {
            ClassDescriptor descriptor = (ClassDescriptor)descriptorsEnum.nextElement();
            addNode(descriptor);
        }
    
public voidcalculateMappingDependencies()

        for (Enumeration e = nodes.elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode node = (CommitOrderDependencyNode)e.nextElement();
            node.recordMappingDependencies();
        }
    
public voidcalculateSpecifiedDependencies()

        for (Enumeration e = nodes.elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode node = (CommitOrderDependencyNode)e.nextElement();
            node.recordSpecifiedDependencies();
        }
    
public voiddepthFirstSearch()


        /*
         * Traverse the entire graph in breadth-first order. When finished, every node will have a
         * predecessor which indicates the node that came efore it in the search
         * It will also have a discovery time (the value of the counter when we first saw it) and
         * finishingTime (the value of the counter after we've visited all the adjacent nodes).
         * See Cormen, Leiserson and Rivest, Section 23.3, page 477 for a full explanation of the algorithm
         */

        //Setup
        for (Enumeration e = getNodes().elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode node = (CommitOrderDependencyNode)e.nextElement();
            node.markNotVisited();
            node.setPredecessor(null);
        }
        currentTime = 0;

        //Execution
        for (Enumeration e = getNodes().elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode node = (CommitOrderDependencyNode)e.nextElement();
            if (node.hasNotBeenVisited()) {
                node.visit();
            }
        }
    
private static intdoCompare(java.lang.Object o1, java.lang.Object o2)

        // I don't care if they're equal, and I want to sort largest first.
        int first;

        // I don't care if they're equal, and I want to sort largest first.
        int second;
        first = ((CommitOrderDependencyNode)o1).getFinishingTime();
        second = ((CommitOrderDependencyNode)o2).getFinishingTime();
        if (first >= second) {
            return 1;
        } else {
            return -1;
        }
    
private static intdoCompare(oracle.toplink.essentials.internal.sessions.CommitOrderDependencyNode o1, oracle.toplink.essentials.internal.sessions.CommitOrderDependencyNode o2)

        // I don't care if they're equal, and I want to sort largest first.
        int first;

        // I don't care if they're equal, and I want to sort largest first.
        int second;
        first = o1.getFinishingTime();
        second = o2.getFinishingTime();
        if (first >= second) {
            return 1;
        } else {
            return -1;
        }
    
public intgetNextTime()

        int result = currentTime;
        currentTime++;
        return result;
    
public java.util.VectorgetNodes()

        return nodes;
    
public java.util.VectorgetOrderedClasses()

        Vector orderedClasses = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(getOrderedDescriptors().size());
        for (Enumeration orderedDescriptorsEnum = getOrderedDescriptors().elements();
                 orderedDescriptorsEnum.hasMoreElements();) {
            orderedClasses.addElement(((ClassDescriptor)orderedDescriptorsEnum.nextElement()).getJavaClass());
        }

        return orderedClasses;
    
public java.util.VectorgetOrderedDescriptors()

        return orderedDescriptors;
    
public oracle.toplink.essentials.internal.sessions.CommitOrderDependencyNodenodeFor(java.lang.Class c)

        for (Enumeration e = nodes.elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode n = (CommitOrderDependencyNode)e.nextElement();
            if (n.getDescriptor().getJavaClass() == c) {
                return n;
            }
        }
        return null;
    
public oracle.toplink.essentials.internal.sessions.CommitOrderDependencyNodenodeFor(oracle.toplink.essentials.descriptors.ClassDescriptor d)

        for (Enumeration e = nodes.elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode n = (CommitOrderDependencyNode)e.nextElement();
            if (n.getDescriptor() == d) {
                return n;
            }
        }
        return null;
    
public voidorderCommits()

        depthFirstSearch();

        Object[] nodeArray = new Object[nodes.size()];
        nodes.copyInto(nodeArray);

        quicksort(nodeArray);
        Vector result = new Vector(nodes.size());
        for (int i = 0; i < nodes.size(); i++) {
            CommitOrderDependencyNode node = (CommitOrderDependencyNode)nodeArray[i];
            result.addElement(node.getDescriptor());
        }
        this.orderedDescriptors = result;
    
private static voidquicksort(java.lang.Object[] arr)

        quicksort(arr, 0, arr.length - 1);
    
private static voidquicksort(java.lang.Object[] arr, int left, int right)

        int i;
        int last;

        if (left >= right) {/* do nothing if array contains fewer than two */
            return;/* two elements */
        }
        swap(arr, left, (left + right) / 2);
        last = left;
        for (i = left + 1; i <= right; i++) {
            if (doCompare(arr[i], arr[left]) < 0) {
                swap(arr, ++last, i);
            }
        }
        swap(arr, left, last);
        quicksort(arr, left, last - 1);
        quicksort(arr, last + 1, right);
    
private static voidswap(java.lang.Object[] arr, int i, int j)

        Object tmp;

        tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;