ObjectStore.java :  » Database-DBMS » myoodb-2.2.1 » org » myoodb » core » storage » Java Open Source

Java Open Source » Database DBMS » myoodb 2.2.1 
myoodb 2.2.1 » org » myoodb » core » storage » ObjectStore.java
///////////////////////////////////////////////////////////////////////////////
//
//   Copyright (C) 2003-@year@ by Thomas M. Hazel, MyOODB (www.myoodb.org)
//
//                          All Rights Reserved
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License and GNU Library
//   General Public License as published by the Free Software Foundation;
//   either version 2, or (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//   GNU General Public License and GNU Library General Public License
//   for more details.
//
//   You should have received a copy of the GNU General Public License
//   and GNU Library General Public License along with this program; if
//   not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
//   MA 02139, USA.
//
///////////////////////////////////////////////////////////////////////////////
package org.myoodb.core.storage;

import java.io.*;
import java.util.*;

import org.myoodb.*;
import org.myoodb.core.*;
import org.myoodb.tools.*;
import org.myoodb.exception.*;

public final class ObjectStore extends AbstractManager implements AbstractStorage
{
    private static final org.myoodb.util.Logger LOGGER = org.myoodb.util.Logger.getLogger(ObjectStore.class);

    protected final static String OBJ_DIR = "objs";
    protected final static String ROOT_DIR = "roots";
    protected final static String JRNL_DIR = "jrnl";

    private HashMap m_rootTable;
    private HashMap m_defragTable;

    private volatile boolean m_verifying;
    private volatile boolean m_defragging;
    private volatile boolean m_backingUp;
    private volatile boolean m_restoring;

    protected ClusterStore m_clusterStore;

    public ObjectStore()
    {
        m_verifying = false;
        m_defragging = false;
        m_backingUp = false;
        m_restoring = false;

        initialize();
    }

    private void initialize()
    {
        m_rootTable = new HashMap(100);
        m_clusterStore = new ClusterStore();
    }

    private void systemMaintenanceCheck() throws InterruptedException
    {
        if (performingDatabaseMaintenance() == true)
        {
            if (@waitForMaintenance@ == true)
            {
                while (performingDatabaseMaintenance() == true)
                {
                    synchronized(this)
                    {
                        if (LOGGER.isDebugEnabled() == true)
                        {
                            LOGGER.debug("Waiting for Maintenance to complete: " + Thread.currentThread());
                        }

                        wait(1000);
                    }
                }
            }
            else
            {
                if (isVerifyingDatabase() == true)
                {
                    throw new org.myoodb.exception.VerifyException("Currently verifying the database");
                }
                else if (isDefraggingDatabase() == true)
                {
                    throw new org.myoodb.exception.DefragException("Currently defragging the database");
                }
                else if (isBackingUpDatabase() == true)
                {
                    throw new org.myoodb.exception.BackupException("Currently backing up the database");
                }
                else if (isRestoringDatabase() == true)
                {
                    throw new org.myoodb.exception.VerifyException("Currently restoring the database");
                }
            }
        }
    }

    private void verifyRoots(boolean loadRoots) throws Exception
    {
        m_verifying = true;

        // Gather id(s) and clean up uncompleted transactions
        LinkedList list = new LinkedList();
        m_clusterStore.getRootClusterIdentifiers(list, true, MyOodbManager.getTheManager().getDatabaseDirectory());

        if (loadRoots == true)
        {
            if (LOGGER.isInfoEnabled() == true)
            {
                LOGGER.info("Verifying Database Roots...");
            }

            m_rootTable.clear();

            // Start Verifying
            Cluster cluster = null;
            Iterator iter = list.iterator();
            while (iter.hasNext())
            {
                Identifier objectId = (Identifier) iter.next();

                if (LOGGER.isDebugEnabled() == true)
                {
                    LOGGER.debug("  checking root cluster: " + objectId);
                }

                try
                {
                    cluster = (Cluster) m_clusterStore.loadCluster(objectId);
                }
                catch (Exception e)
                {
                    LOGGER.error("\nRoot cluster is invalid: " + objectId, e);

                    //Cluster.delete(objectId);
                    //continue;

                    throw e;
                }

                AbstractObjectContainer container = cluster.getContainer();

                try
                {
                    m_rootTable.put(((RootContainer) container).getName(), container.getObjectIdentifier());
                }
                catch (Exception e)
                {
                    LOGGER.error("\nRoot container is invalid: " + objectId);

                    //Cluster.delete(objectId);
                    //continue;

                    throw e;
                }

                m_clusterStore.unloadCluster(objectId);

            }

            if (LOGGER.isInfoEnabled() == true)
            {
                LOGGER.info("Verifying Roots Complete!");
            }
        }

        m_verifying = false;
    }

    private void verifyObjects(boolean loadObjects) throws Exception
    {
        m_verifying = true;

        // Gather id(s) and clean up uncompleted transactions
        LinkedList list = new LinkedList();
        m_clusterStore.getObjectClusterIdentifiers(list, true, MyOodbManager.getTheManager().getDatabaseDirectory());

        if (loadObjects == true)
        {
            if (LOGGER.isInfoEnabled() == true)
            {
                LOGGER.info("Verifying Database Objects...");
            }

            // Start Verifying
            Cluster cluster = null;
            Iterator iter = list.iterator();
            while (iter.hasNext())
            {
                Identifier objectId = (Identifier) iter.next();

                if (LOGGER.isDebugEnabled() == true)
                {
                    LOGGER.debug(" checking object cluster: " + objectId);
                }

                try
                {
                    cluster = (Cluster) m_clusterStore.loadCluster(objectId);
                }
                catch (Exception e)
                {
                    LOGGER.error("\nObject cluster is invalid: " + objectId, e);

                    //Cluster.delete(objectId);
                    //continue;

                    throw e;
                }

                m_clusterStore.unloadCluster(objectId);
            }

            if (LOGGER.isInfoEnabled() == true)
            {
                LOGGER.info("Verifying Objects Complete!");
            }
        }

        m_verifying = false;
    }

    private void defragDatabase(boolean exit) throws Exception
    {
        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Defragging Database...");
        }

        initialize();

        m_defragging = true;
        m_defragTable = new HashMap(500);

        MyOodbManager manager = MyOodbManager.getTheManager();

        // Delete last old 
        org.myoodb.core.FileHelper.delete(manager.getDatabaseDirectory() + "old." + ObjectStore.OBJ_DIR);
        org.myoodb.core.FileHelper.delete(manager.getDatabaseDirectory() + "old." + ObjectStore.ROOT_DIR);

        // Save away id(s)
        String targetPath = manager.getDatabaseDirectory() + "old." + MyOodbManager.ID_FILE;
        File ifile = new File(targetPath);
        if (ifile.exists() == true)
        {
            org.myoodb.core.FileHelper.delete(ifile);
        }

        String sourcePath = manager.getDatabaseDirectory() + MyOodbManager.ID_FILE;
        org.myoodb.core.FileHelper.rename(sourcePath, targetPath);

        // Re-initialize
        m_rootTable.clear();
        manager.getIdentifierManager().reset();
        manager.getIdentifierProperties().setLongProperty(IdentifierManager.XID, 0);

        // Get Identifiers
        LinkedList rootList = new LinkedList();
        m_clusterStore.getRootClusterIdentifiers(rootList, true, MyOodbManager.getTheManager().getDatabaseDirectory());

        LinkedList objectList = new LinkedList();
        m_clusterStore.getObjectClusterIdentifiers(objectList, true, MyOodbManager.getTheManager().getDatabaseDirectory());

        // Start Defrag
        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Defragging Roots...");
        }

        Iterator iter = rootList.iterator();
        while (iter.hasNext())
        {
            Identifier oldObjectId = (Identifier) iter.next();
            Identifier newObjectId = new Identifier(manager.getIdentifierManager().getNextObjectId(), true);
            m_defragTable.put(oldObjectId, newObjectId);
        }

        iter = objectList.iterator();
        while (iter.hasNext())
        {
            Identifier oldObjectId = (Identifier) iter.next();
            Identifier newObjectId = new Identifier(manager.getIdentifierManager().getNextObjectId(), false);
            m_defragTable.put(oldObjectId, newObjectId);
        }

        // Defrag Roots
        iter = rootList.iterator();
        rootList = new LinkedList();
        while (iter.hasNext())
        {
            Identifier oldObjectId = (Identifier) iter.next();

            if (LOGGER.isDebugEnabled() == true)
            {
                LOGGER.debug("  defrag root cluster: " + oldObjectId);
            }

            try
            {
                Cluster cluster = (Cluster) m_clusterStore.loadCluster(oldObjectId);
                rootList.add(cluster);
            }
            catch (Exception e)
            {
                LOGGER.error("\nRoot cluster is invalid: " + oldObjectId, e);

                //Cluster.delete(oldObjectId);

                throw e;
            }
        }

        ifile = new File(manager.getDatabaseDirectory() + "new." + ObjectStore.ROOT_DIR);
        ifile.mkdirs();

        String rootPath = manager.getDatabaseDirectory() + "new.";
        iter = rootList.iterator();
        while (iter.hasNext())
        {
            Cluster cluster = (Cluster) iter.next();
            AbstractObjectContainer container = cluster.getContainer();

            if (container != null)
            {
                cluster.write(rootPath);
            }
        }

        // Save away roots
        sourcePath = manager.getDatabaseDirectory() + ObjectStore.ROOT_DIR;
        targetPath = manager.getDatabaseDirectory() + "old." + ObjectStore.ROOT_DIR;
        org.myoodb.core.FileHelper.rename(sourcePath, targetPath);

        // Load in new roots
        sourcePath = manager.getDatabaseDirectory() + "new." + ObjectStore.ROOT_DIR;
        targetPath = manager.getDatabaseDirectory() + ObjectStore.ROOT_DIR;
        org.myoodb.core.FileHelper.rename(sourcePath, targetPath);

        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Defragging Objects...");
        }

        // Defrag Objects
        iter = objectList.iterator();
        objectList = new LinkedList();
        while (iter.hasNext())
        {
            Identifier oldObjectId = (Identifier) iter.next();

            if (LOGGER.isDebugEnabled() == true)
            {
                LOGGER.debug("  defrag object cluster: " + oldObjectId);
            }

            try
            {
                Cluster cluster = (Cluster) m_clusterStore.loadCluster(oldObjectId);
                objectList.add(cluster);
            }
            catch (Exception e)
            {
                LOGGER.error("\nObject cluster is invalid: " + oldObjectId, e);

                //Cluster.delete(oldObjectId);

                throw e;
            }
        }

        ifile = new File(manager.getDatabaseDirectory() + "new." + ObjectStore.OBJ_DIR);
        ifile.mkdirs();

        String objectPath = manager.getDatabaseDirectory() + "new.";
        iter = objectList.iterator();
        while (iter.hasNext())
        {
            Cluster cluster = (Cluster) iter.next();
            AbstractObjectContainer container = cluster.getContainer();

            if (container != null)
            {
                cluster.write(objectPath);
            }
        }

        // Save away objects
        sourcePath = manager.getDatabaseDirectory() + ObjectStore.OBJ_DIR;
        targetPath = manager.getDatabaseDirectory() + "old." + ObjectStore.OBJ_DIR;
        org.myoodb.core.FileHelper.rename(sourcePath, targetPath);

        // Load in new objects
        sourcePath = manager.getDatabaseDirectory() + "new." + ObjectStore.OBJ_DIR;
        targetPath = manager.getDatabaseDirectory() + ObjectStore.OBJ_DIR;
        org.myoodb.core.FileHelper.rename(sourcePath, targetPath);

        m_defragTable = null;
        m_defragging = false;

        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Defragmentation Complete!");
        }

        /*
        if (exit == true)
        {
            System.exit(1);
        }
        */
    }

    private void backingUpDatabase(String targetPath) throws Exception
    {
        MyOodbManager manager = MyOodbManager.getTheManager();

        if (targetPath.endsWith(manager.getDatabaseName()) == false)
        {
            targetPath = targetPath + File.separator + manager.getDatabaseName();
        }

        String sourcePath = manager.getDatabaseDirectory();

        if (sourcePath.endsWith(File.separator) == true)
        {
            sourcePath = sourcePath.substring(0, sourcePath.length() - 1);
        }

        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Backing Up Database ( "  + sourcePath + " to " + targetPath + " ) ...");
        }

        m_backingUp = true;

        org.myoodb.core.FileHelper.delete(targetPath);
        org.myoodb.core.FileHelper.copy(sourcePath, targetPath + ".part", true);

        String id = File.separator + "id.properties";
        org.myoodb.core.FileHelper.copy(sourcePath + id, targetPath + ".part" + id, false);

        String user = File.separator + "user.properties";
        org.myoodb.core.FileHelper.copy(sourcePath + user, targetPath + ".part" + user, false);

        org.myoodb.core.FileHelper.rename(targetPath + ".part", targetPath);

        m_backingUp = false;

        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Backup Complete!");
        }
    }

    private void restoringDatabase(String targetPath) throws Exception
    {
        MyOodbManager manager = MyOodbManager.getTheManager();

        if (targetPath.endsWith(File.separator) == true)
        {
            targetPath = targetPath.substring(0, targetPath.length() - 1);
        }

        if (targetPath.endsWith(manager.getDatabaseName() + File.separator) == false)
        {
            targetPath = targetPath + File.separator + manager.getDatabaseName() + File.separator;
        }

        // XXX: check if backup source existence and whether or not complete
        if (new File(targetPath).exists() == false)
        {
            throw new RestoreException("Restore target not found: " + targetPath);
        }
        else if (new File(targetPath + "id.properties").exists() == false)
        {
            throw new RestoreException("Restore target identifiers not found: " + targetPath);
        }
        else if (new File(targetPath + "user.properties").exists() == false)
        {
            throw new RestoreException("Restore target users not found: " + targetPath);
        }
        else if (new File(targetPath + ObjectStore.ROOT_DIR).exists() == false)
        {
            throw new RestoreException("Restore target roots not found: " + targetPath);
        }
        else if (new File(targetPath + ObjectStore.OBJ_DIR).exists() == false)
        {
            throw new RestoreException("Restore target objs not found: " + targetPath);
        }

        if (targetPath.endsWith(File.separator) == true)
        {
            targetPath = targetPath.substring(0, targetPath.length() - 1);
        }

        String sourcePath = manager.getDatabaseDirectory();

        if (sourcePath.endsWith(File.separator) == true)
        {
            sourcePath = sourcePath.substring(0, sourcePath.length() - 1);
        }

        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Restoring Database ( "  + targetPath + " to " + sourcePath + " ) ...");
        }

        m_restoring = true;

        org.myoodb.core.FileHelper.delete(sourcePath + ".part");
        org.myoodb.core.FileHelper.copy(targetPath, sourcePath + ".part", false);

        org.myoodb.core.FileHelper.delete(sourcePath);
        org.myoodb.core.FileHelper.rename(sourcePath + ".part", sourcePath);

        // Re-initialize
        emptyMemoryCache();
        m_rootTable.clear();
        manager.getIdentifierManager().reset();

        // Get Identifiers
        LinkedList rootList = new LinkedList();
        m_clusterStore.getRootClusterIdentifiers(rootList, true, sourcePath);

        LinkedList objectList = new LinkedList();
        m_clusterStore.getObjectClusterIdentifiers(objectList, true, sourcePath);

        // Start Roots Restore
        String rootPath = sourcePath + ObjectStore.ROOT_DIR;
        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Restoring Roots ( "  + rootPath + " ) ...");
        }

        Iterator iter = rootList.iterator();
        while (iter.hasNext())
        {
            Identifier id = (Identifier) iter.next();

            try
            {
                m_clusterStore.loadCluster(id, sourcePath);
            }
            catch (Exception e)
            {
                LOGGER.error("\nRoot cluster is invalid: " + id, e);

                //Cluster.delete(id);

                throw e;
            }
        }

        // Start Objects Restore
        String objectPath = sourcePath + ObjectStore.OBJ_DIR;
        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Restoring Objects ( "  + objectPath + " ) ...");
        }

        iter = objectList.iterator();
        while (iter.hasNext())
        {
            Identifier id = (Identifier) iter.next();

            try
            {
                m_clusterStore.loadCluster(id, sourcePath);
            }
            catch (Exception e)
            {
                LOGGER.error("\nObject cluster is invalid: " + id, e);

                //Cluster.delete(id);

                throw e;
            }
        }

        m_restoring = false;

        if (LOGGER.isInfoEnabled() == true)
        {
            LOGGER.info("Restore Complete!");
        }
    }

    private void journalDatabase() throws Exception
    {
        String targetPath = MyOodbManager.getTheManager().getDatabaseDirectory();
        m_clusterStore.getRootClusterIdentifiers(null, true, targetPath);
        m_clusterStore.getObjectClusterIdentifiers(null, true, targetPath);

        File djrnl = new File(MyOodbManager.getTheManager().getDatabaseDirectory() + ObjectStore.JRNL_DIR);
        djrnl.mkdir();

        String[] journalList = djrnl.list(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                return (name.endsWith(ClusterStore.JOURNAL_EXT) == true);
            }
        });

        if (journalList != null)
        {
            for (int i = 0; i < journalList.length; i++)
            {
                org.myoodb.core.FileHelper.delete(djrnl.getPath() + File.separator + journalList[i]);
            }
        }
    }

    public void startup() throws Exception
    {
        m_clusterStore.startup();

        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            journalDatabase();

            if (@defragmentDatabase@ == true)
            {
                defragDatabase(false);
            }

            if (@verifyIntegrity@ == true)
            {
                verifyDatabase();
            }
            else
            {
                verifyRoots(true);
                verifyObjects(false);
            }
       }
    }

    public void shutdown() throws Exception
    {
        m_clusterStore.shutdown();
    }

    public boolean isVerifyingDatabase()
    {
        return m_verifying;
    }

    public boolean isDefraggingDatabase()
    {
        return m_defragging;
    }

    public boolean isBackingUpDatabase()
    {
        return m_backingUp;
    }

    public boolean isRestoringDatabase()
    {
        return m_restoring;
    }

    public boolean performingDatabaseMaintenance()
    {
        return (m_verifying || m_defragging || m_backingUp || m_restoring);
    }

    public void verifyDatabase() throws Exception
    {
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            synchronized(this)
            {
                try
                {
                    verifyRoots(true);
                    verifyObjects(true);
                }
                finally
                {
                    m_verifying = false;

                    notifyAll();
                }
            }
        }
    }

    public void defragDatabase() throws Exception
    {
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            synchronized(this)
            {
                try
                {
                    defragDatabase(true);
                }
                finally
                {
                    m_defragging = false;

                    notifyAll();
                }
            }
        }
    }

    public void backupDatabase(String location) throws Exception
    {
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            synchronized(this)
            {
                try
                {
                    backingUpDatabase(location);
                }
                finally
                {
                    m_backingUp = false;

                    notifyAll();
                }
            }
        }
    }

    public void restoreDatabase(String location) throws Exception
    {
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            synchronized(this)
            {
                try
                {
                    restoringDatabase(location);
                }
                finally
                {
                    m_restoring = false;

                    notifyAll();
                }
            }
        }
    }

    public HashMap getDefraggedContainerIdentifierMap()
    {
        return m_defragTable;
    }

    public AbstractObjectContainer createContainer(AbstractTransaction atx, Identifier objectId, String rootName) throws IOException, ClassNotFoundException
    {
        Transaction tx = (Transaction) atx;
        AbstractObjectContainer container = null;

        if (rootName != null)
        {
            synchronized(this)
            {
                if (m_rootTable.get(rootName) != null)
                {
                    throw new PermissionException("Invalid create (root name '" + rootName + "' already exists)");
                }

                container = new RootContainer(objectId, rootName);
                m_rootTable.put(rootName, objectId);
            }
        }
        else
        {
            container = new ObjectContainer(objectId);
        }

        m_clusterStore.createCluster(container, tx);
        tx.getObjectIdentifiers().add(container);

        return container;
    }

    public AbstractObjectContainer getContainer(String rootName, Identifier objectId) throws IOException, ClassNotFoundException, ObjectNotFoundException
    {
        Cluster cluster = null;

        if (objectId == null)
        {
            if (rootName == null)
            {
               throw new PermissionException("Root Name nor Object Identifier has been specified");
            }

            synchronized(this)
            {
                objectId = (Identifier) m_rootTable.get(rootName);

                if (objectId == null)
                {
                    //throw new ObjectNotFoundException("No such root: " + rootName);

                    return null;
                }
            }
        }

        try
        {
            cluster = m_clusterStore.loadCluster(objectId);
        }
        catch (java.io.FileNotFoundException e)
        {
            // nothing to do
        }

        if (cluster == null)
        {
            throw new ObjectNotFoundException("No such object (level 1): " + objectId);
        }

        AbstractObjectContainer container = cluster.getContainer();

        if (container == null)
        {
            m_clusterStore.unloadCluster(objectId);

            throw new ObjectNotFoundException("No such object (level 2): " + objectId);
        }
        else if (container.getTargets() == null)
        {
            m_clusterStore.unloadCluster(objectId);

            throw new ObjectNotFoundException("No such object (level 3): " + objectId);
        }

        // XXX: pending clean up ( return null-ed container )
        if (container.isDeleted() == true)
        {
            container = null;
        }

        return container;
    }

    public LinkedList getContainerIdentifiers(boolean finishTransactions) throws Exception
    {
        LinkedList list = new LinkedList();

        String targetPath = MyOodbManager.getTheManager().getDatabaseDirectory();
        m_clusterStore.getRootClusterIdentifiers(list, finishTransactions, targetPath);
        m_clusterStore.getObjectClusterIdentifiers(list, finishTransactions, targetPath);

        return list;
    }

    public AbstractTransaction createTransaction(User user)
    {
        return new Transaction(user);
    }

    public void setAssociatedTransaction(AbstractTransaction atx, AbstractObjectContainer container) throws IOException
    {
        // TODO: support memory only transactions
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            Transaction tx = (Transaction) atx;

            synchronized(container.getObjectIdentifier())
            {
                m_clusterStore.setAssociatedTransaction(container, tx); 
            }

            tx.getObjectIdentifiers().add(container);
        }
    }

    public void prepareTransaction(AbstractTransaction atx) throws IOException, ClassNotFoundException
    {
        // TODO: support memory only transactions
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            Transaction tx = (Transaction) atx;

            Iterator iter = tx.getObjectIdentifiers().iterator();
            while (iter.hasNext())
            {
                AbstractObjectContainer container = (AbstractObjectContainer) iter.next();

                if ((tx.getSnapShotFlag() == true) && (container.getDirtyFlag() == false))
                {
                    continue;
                }

                try
                {
                    synchronized(container.getObjectIdentifier())
                    {
                        m_clusterStore.prepareCluster(tx, container.getObjectIdentifier());
                    }
                }
                catch (java.io.FileNotFoundException e)
                {
                    iter.remove();

                    // if one creates then deletes in the same transactions 
                    if (LOGGER.isDebugEnabled() == true)
                    {
                        LOGGER.debug("Prepare AbstractTransaction: " + e);
                    }
                }
            }
        }
    }

    public void commitTransaction(AbstractTransaction atx) throws IOException, ClassNotFoundException, InterruptedException
    {
        // TODO: support memory only transactions
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            Transaction tx = (Transaction) atx;

            if (tx.getSnapShotFlag() == false)
            {
                systemMaintenanceCheck();
            }

            File journal = new File(MyOodbManager.getTheManager().getDatabaseDirectory() +
                                    ObjectStore.JRNL_DIR + File.separator +
                                    tx.getTransactionIdentifier() +
                                    ClusterStore.SUFFIX_SEPARATOR +
                                    ClusterStore.JOURNAL_EXT);

            if (journal.createNewFile() == false)
            {
                throw new IOException("Unable to create journal - " + journal + " " + tx);
            }

            try
            {
                Iterator iter = tx.getObjectIdentifiers().iterator();
                while (iter.hasNext())
                {
                    AbstractObjectContainer container = (AbstractObjectContainer) iter.next();

                    if ((tx.getSnapShotFlag() == true) && (container.getDirtyFlag() == false))
                    {
                        continue;
                    }

                    synchronized(container.getObjectIdentifier())
                    {
                        m_clusterStore.commitCluster(tx, container.getObjectIdentifier(), 1 /* phase 1 */);
                        container.setDirtyFlag(false);
                    }

                    java.lang.reflect.Method method = MyOodbManager.getTheManager().getCommitObjectCallback();
                    if ((method != null) && (container.getTarget() != null))
                    {
                        try
                        {
                            method.invoke(null, new Object[] {container.getTarget()});
                        }
                        catch (Exception e)
                        {
                            LOGGER.error(null, e);
                        }
                    }
                }
            }
            finally
            {
                org.myoodb.core.FileHelper.delete(journal);
            }

            if (tx.getParentTransaction() == null)
            {
                Iterator iter = tx.getObjectIdentifiers().iterator();
                while (iter.hasNext())
                {
                    AbstractObjectContainer container = (AbstractObjectContainer) iter.next();

                    if ((tx.getSnapShotFlag() == true) && (container.getDirtyFlag() == false))
                    {
                        continue;
                    }

                    m_clusterStore.commitCluster(tx, container.getObjectIdentifier(), 2 /* phase 2 */);
                }
            }
        }
    }

    public void abortTransaction(AbstractTransaction atx) throws IOException, ClassNotFoundException, InterruptedException
    {
        // TODO: support memory only transactions
        if (org.myoodb.core.FileHelper.getMemoryResidentFlag() == false)
        {
            Transaction tx = (Transaction) atx;

            if (tx.getSnapShotFlag() == false)
            {
                systemMaintenanceCheck();
            }

            Iterator iter = tx.getObjectIdentifiers().iterator();
            while (iter.hasNext())
            {
                AbstractObjectContainer container = (AbstractObjectContainer) iter.next();

                synchronized(container.getObjectIdentifier())
                {
                    m_clusterStore.abortCluster(tx, container.getObjectIdentifier());
                }

                java.lang.reflect.Method method = MyOodbManager.getTheManager().getRollbackObjectCallback();
                if ((method != null) && (container.getTarget() != null))
                {
                    try
                    {
                        method.invoke(null, new Object[] {container.getTarget()});
                    }
                    catch (Exception e)
                    {
                        LOGGER.error(null, e);
                    }
                }
            }
        }
    }

    public void setStoreAsXmlFlag(boolean flag)
    {
        m_clusterStore.setStoreAsXmlFlag(flag);
    }

    public boolean getStoreAsXmlFlag()
    {
        return m_clusterStore.getStoreAsXmlFlag();
    }

    public void staleMemoryCheck() throws InterruptedException
    {
        m_clusterStore.staleMemoryCheck();
    }

    public void emptyMemoryCache()
    {
        m_clusterStore.emptyMemoryCache();
    }
}
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.