⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gammatransaction.java

📁 Java的面向对象数据库系统的源代码
💻 JAVA
字号:
// You can redistribute this software and/or modify it under the terms of// the Ozone Core License version 1 published by ozone-db.org.//// Copyright (C) 2003-@year@, Leo Mekenkamp. All rights reserved.//// $Id: GammaTransaction.java,v 1.3 2004/01/03 10:39:41 per_nyfelt Exp $package org.ozoneDB.core.storage.gammaStore;import java.io.IOException;import java.io.ObjectOutputStream;import java.util.LinkedHashMap;import java.util.Map;import java.util.Properties;import org.ozoneDB.ObjectNotFoundException;import org.ozoneDB.OzoneInternalException;import org.ozoneDB.OzoneObjectException;import org.ozoneDB.OzoneRemoteException;import org.ozoneDB.TransactionException;import org.ozoneDB.core.Env;import org.ozoneDB.core.Lock;import org.ozoneDB.core.ObjectContainer;import org.ozoneDB.core.ObjectID;import org.ozoneDB.core.PermissionError;import org.ozoneDB.core.Transaction;import org.ozoneDB.core.TransactionError;import org.ozoneDB.core.User;import org.ozoneDB.core.storage.Cache;import org.ozoneDB.core.storage.FixedSizeCache;import org.ozoneDB.core.storage.WeakReferenceCache;import org.ozoneDB.util.LogWriter;/** * @author <a href="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a> * @version $Id: GammaTransaction.java,v 1.3 2004/01/03 10:39:41 per_nyfelt Exp $ */public class GammaTransaction extends Transaction {        // should be configurable settings    private static final int FIXME_MAX_OBJECT_IDS = 250;        private static final float FIXME_LOADFACTOR_OBJECT_IDS = 0.75F;        private static final String LOGPOSTFIX = ".txlog";        private GammaStore gammaStore;        private Storage logStorage;        /**     * Transactions have their own private cache. Should be a WeakReferenceCache     * because GammaStore has the last say in which objects should be cached.     * Having its own cache means this tx can find out when containers are no     * longer in memory. When a container is swapped out it can (through a     * shadow remover specified in this tx) write its object id to the log of     * this tx.      */     private Cache containerCache = new FixedSizeCache(new Properties(), "") {                public Object remove(Object key) {            GammaContainer result = (GammaContainer) super.remove(key);//            try {//                getLogStorage().writeObject(result.getObjectId());//            } catch (IOException e) {//                throw new OzoneInternalException("could not write object id " + result.getObjectId() + " to log stream " + getLogStream(), e);//            }            return result;        }            };    /**     * An unlimited number of objects might be changed during any transaction.     * It is impossible to keep track of all object ids in memory, instead this     * <code>LinkedHashMap</code> is used to keep the MRU in memory, while     * writing the LRU out to disk. We could use a <code>LinkedHashSet</code>     * instead (since we only use the keys, and not the values     */    private LinkedHashMap changedObjectIds;        public GammaTransaction(GammaStore gammaStore, StorageFactory logStorageFactory, Env env, User owner) {        super(env, owner);        try {            setGammaStore(gammaStore);            setLogStorage(logStorageFactory.createStorage(logFilename()));        } catch (IOException e) {            throw new OzoneInternalException("could not create transaction", e);        }        changedObjectIds = new LinkedHashMap(FIXME_MAX_OBJECT_IDS, FIXME_LOADFACTOR_OBJECT_IDS, true) {            public boolean removeEldestEntry(Map.Entry eldest) {                                // use -1 to make sure rehashing never takes place                boolean result = size() >= FIXME_MAX_OBJECT_IDS - 1;                if (result) {                    ObjectID objectID = (ObjectID) eldest.getValue();                    try {                        getLogStorage().writeLong(objectID.value());                    } catch (IOException e) {                        throw new OzoneInternalException("could not write object id", e);                    }                }                return result;            }        };    }    String logFilename() {        String result = Long.toString(taID().value()) + LOGPOSTFIX;        return result;    }        /**     * Blatantly stolen from <code>org.ozoneDB.core.Transaction</code>. Removed     * code dependent on WizardStore     */    protected ObjectContainer acquireContainer(ObjectContainer container, int lockLevel) throws PermissionError, TransactionException, TransactionError, IOException, ObjectNotFoundException, ClassNotFoundException {        if (stopped == true) {            throw new TransactionException("Stopped.", TransactionException.STOPPED);        }        maxLockLevel = lockLevel > maxLockLevel ? lockLevel : maxLockLevel;        acquireCount++;        // this should help to let the following code execute without        // interrupt and so ensure that the container that we retrieve from        // the store is not deactivated while this method is running        // Thread.currentThread().yield();        // transaktion als blockiert markieren (kante in lock-graphen einfuegen);        // vor deadlock-erkennung: es werden auch deadlocks mit        // transaktionen erkannt, die selber erstmal auf deadlock checken        // aber auf keinem fall zuwenige (race-cond. zwischen deadlock-pruefung        // und lock setzen)        blocker = container.id();        // this may happen when the container was deactivated between        // acquireObject() and this point; I'm not sure what to do here        // But I (Xu鈔 Baldauf, Medium.net) am (partly):        // If our caller is acquireContainer(), the container is pinned and thus may not be deactived inbetween.        // If our caller is createObject(), the container is pinned and thus may not be deactived inbetween.        if (container.lock() == null) {            throw new IllegalStateException("Container was wrongly deactivated. Increasing heap memory of the JVM may help.");        }        // try to aquire the lock of the container; wait until the locks is        // successfully aquired        int prevLevel = container.lock().tryAcquire(this, lockLevel);        if (prevLevel == Lock.NOT_ACQUIRED) {            synchronized (this) {                while (prevLevel == Lock.NOT_ACQUIRED) {                    try {                        if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {                            env.logWriter.newEntry(this, toString() + " blocked by lock " + container.lock() + "...", LogWriter.DEBUG2);                        }                        wait();                        if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {                            env.logWriter.newEntry(this, toString() + " checking lock again...", LogWriter.DEBUG2);                        }                    } catch (Exception e) {                        // do nothing; just proceed...                    }                    /*                        We have two cases:                        (1) We are called by acquireObject()                        (2) We are not called by acquireObject()                        In case (1), we do not need to reload, because the object is pinned.                        In case (2), we never come to this code location, because in this case, the objects are freshly created and thus never locked.                        Thus, we never need to reload.                        Oh, the reasoning above does not work out. If a cluster is pinned,                        it still may be aborted and thus need to reload. But maybe then the                        "pinned" concept is mood. Maybe pinned clusters which are arborted                        should be reloaded immediately.                    */                    // since the container was maybe deactivated while waiting we                    // reload it here again                    ObjectContainer newContainer = env.storeManager.containerForID(this, blocker);                    if (container == null) {                        throw new ObjectNotFoundException("No such object.");                    }                    // throw an exception if we are forced to abort because of a deadlock                    container.lock().checkDeadlock(this);                    prevLevel = container.lock().tryAcquire(this, lockLevel);                }            }        }        if (false) {            env.logWriter.newEntry(this, toString() + ".acquireContainer(" + blocker + "): successful.", LogWriter.DEBUG);        }        // transaction is no longer blocked        blocker = null;        // after acquiring the lock we update the lock level of the container        if (prevLevel < lockLevel) {            if (owner == null) {                throw new PermissionError("No such user.");            }            if (!env.userManager.checkPermission(owner, container, lockLevel)) {                throw new PermissionError("User does not have proper access rights.");            }            env.storeManager.updateLockLevel(this, container);        }        container.touch();                GammaContainer gammaContainer = (GammaContainer) container;        getContainerCache().put(gammaContainer.getObjectId(), gammaContainer);        return container;    }    // private so it can be inlined    private GammaStore getGammaStore() {        return gammaStore;    }        // private so it can be inlined    private void setGammaStore(GammaStore gammaStore) {        this.gammaStore = gammaStore;    }        Cache getContainerCache() {        return containerCache;    }        public ObjectContainer createObject(String className, int access, String name, String sig, Object[] args, ObjectID id) throws Exception, OzoneObjectException {        GammaContainer result;                result = (GammaContainer) super.createObject(className, access, name, sig, args, id);        getContainerCache().put(result.getObjectId(), result);        return result;    }        /** @param id     * @param methodName     * @param sig     * @param lockLevel     * @return the result of the invocation     *     */    public Object invokeObject(ObjectID id, String methodName, String sig, Object[] args, int lockLevel) throws Exception, OzoneObjectException {        Object retValue;                retValue = super.invokeObject(id, methodName, sig, args, lockLevel);        return retValue;    }        public Object invokeObject(ObjectID id, int methodIndex, Object[] args, int lockLevel) throws Exception, OzoneObjectException {        Object retValue;                retValue = super.invokeObject(id, methodIndex, args, lockLevel);        return retValue;    }        public void nameObject(ObjectID id, String name) throws Exception {        super.nameObject(id, name);    }        public void deleteObject(ObjectID id) throws ObjectNotFoundException, IOException, ClassNotFoundException, TransactionException, TransactionError, OzoneRemoteException, OzoneInternalException, OzoneObjectException {        super.deleteObject(id);    }        Storage getLogStorage() {        return logStorage;    }        private void setLogStorage(Storage logStorage) {        this.logStorage = logStorage;    }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -