PersistGraph.java :  » Testing » PolePosition-0.20 » com » versant » core » server » Java Open Source

Java Open Source » Testing » PolePosition 0.20 
PolePosition 0.20 » com » versant » core » server » PersistGraph.java

/*
 * Copyright (c) 1998 - 2005 Versant Corporation
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Versant Corporation - initial API and implementation
 */
package com.versant.core.server;

import com.versant.core.common.Debug;
import com.versant.core.common.OID;
import com.versant.core.common.State;
import com.versant.core.metadata.ModelMetaData;

import java.util.Date;
import java.util.Map;
import java.util.HashMap;

/**
 * A graph of OID's and State's used to represent a collection of objects
 * to be persisted. This class implements algorithms to sort the graph
 * for persisting in the correct order and to detect cycles. This class
 * only does a partial sort of the graph and is suitable for graphs that
 * do not contain any new instances with post-insert key generators.
 */
public class PersistGraph extends OIDGraph {

    protected ModelMetaData jmd;
    protected OID[] oids;
    protected State[] oldStates;
    protected State[] newStates;
    protected Map oidIndexMap;
    
    public boolean optimistic; // Carries this flag for VDS transaction

    public PersistGraph(ModelMetaData jmd, int maxSize) {
        this.jmd = jmd;
        oids = new OID[maxSize];
        oldStates = new State[maxSize];
        newStates = new State[maxSize];
        size = 0;
        oidIndexMap = new HashMap();
    }

    /**
     * Empty the graph so it can be reused.
     */
    public void clear() {
        for (int i = size - 1; i >= 0; i--) {
            oids[i] = null;
            oldStates[i] = null;
            newStates[i] = null;
        }
        size = 0;
        oidIndexMap.clear();
    }

    /**
     * Add a node to the graph.
     */
    public void add(OID oid, State oldState, State newState) {
        oids[size] = oid;
        oldStates[size] = oldState;
        newStates[size] = newState;
        oidIndexMap.put(oid, new Integer(size++));
    }

    /**
     * How many nodes are in the graph?
     */
    public int size() {
        return size;
    }

    /**
     * Get the OID at index.
     */
    public OID getOID(int index) {
        return oids[index];
    }

    /**
     * Get the old State at index.
     */
    public State getOldState(int index) {
        return oldStates[index];
    }

    /**
     * Get the new State at index.
     */
    public State getNewState(int index) {
        return newStates[index];
    }

    /**
     * Dump the graph to System.out for debugging.
     */
    public void dump() {
        for (int i = 0; i < size; i++) dump(i);
    }

    /**
     * Dump entries at index to System.out for debugging.
     */
    public void dump(int index) {
        if (Debug.DEBUG) {
            System.out.println("[" + index + "] " + oids[index] + " " +
                    newStates[index]);
        }
    }

    /**
     * Find the index of OID in the graph or less than 0 if not found.
     * Calling this method after persist has been called will return incorrect
     * results.
     *
     * @see #indexOfAfterPersist
     */
    public int indexOf(OID oid) {
        Object o = oidIndexMap.get(oid);
        return o == null ? -1 : ((Integer)o).intValue();
    }

    /**
     * Find the index of OID in the graph or less than 0 if not found.
     * This method may be called after persist has been called. It will
     * build the OID to index map the first time it is called.
     *
     * @see #indexOf
     */
    public int indexOfAfterPersist(OID oid) {
        if (oidIndexMap.size() == 0) {
            OID[] oids = this.oids;
            for (int i = size - 1; i >= 0; i--) {
                oidIndexMap.put(oids[i], new Integer(i));
            }
        }
        Object o = oidIndexMap.get(oid);
        return o == null ? -1 : ((Integer)o).intValue();
    }

    /**
     * Bump up timestamps etc.
     */
    public void doAutoSets() {
        Date now = new Date();
        for (int i = 0; i < size; i++) {
            OID oid = oids[i];
            State ns = newStates[i];
            if (ns == null) break;
            ns.setClassMetaData(oid.getClassMetaData());
            if (oid.isNew()) {
                ns.updateAutoSetFieldsCreated(now);
            } else {
                ns.updateAutoSetFieldsModified(now, oldStates[i]);
            }
        }
    }

    /**
     * Compare graph entries at and a and b. Return 0 if equal, less than 0
     * if a is less than b or greater than 0 if a is greater than b. This
     * orders entries by class referenceGraphIndex, by new objects first,
     * by field numbers.
     */
    protected int compare(int a, int b) {
        final OID oidA = oids[a];
        final OID oidB = oids[b];

        int diff = oidB.getClassMetaData().referenceGraphIndex
                - oidA.getClassMetaData().referenceGraphIndex;
        if (diff != 0) return diff;

        // by new objects
        boolean newA = oidA.isNew();
        boolean newB = oidB.isNew();
        if (newA && !newB) return -1;
        if (!newA && newB) return +1;

        // by field numbers
        return newStates[a].compareToPass1(newStates[b]);
    }

    /**
     * Swap entries.
     */
    protected void swap(int index1, int index2) {
        OID tempStr = oids[index1];
        State tempOldState = oldStates[index1];
        State tempNewState = newStates[index1];

        oids[index1] = oids[index2];
        oldStates[index1] = oldStates[index2];
        newStates[index1] = newStates[index2];

        oids[index2] = tempStr;
        oldStates[index2] = tempOldState;
        newStates[index2] = tempNewState;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.