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

📄 wizardobjectcontainer.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.
//
// The original code and portions created by SMB are
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
//
// $Id$

package org.ozoneDB.core.storage.wizardStore;

import java.io.*;

import org.ozoneDB.DxLib.DxCollection;
import org.ozoneDB.OzoneCompatible;
import org.ozoneDB.core.*;
import org.ozoneDB.core.storage.wizardStore.WizardCluster;
import org.ozoneDB.core.storage.StorageObjectContainer;
import org.ozoneDB.core.storage.Cluster;
import org.ozoneDB.util.LogWriter;


/**
 * The "Wizard" implementation of the ObjectContainer interface. Much of the
 * lock functionality is implemented in the WizardCluster class.
 *
 * Note: only the join/commit/abort methods are synchronized. All other methods
 * are guaranteed to run exclusively through the explicite locks
 *
 *
 * @author <a href="http://www.softwarebuero.de/">SMB</a>
 * @author <A HREF="http://www.medium.net/">Medium.net</A>
 * @version $Revision$Date$
 */
public class WizardObjectContainer extends StorageObjectContainer {

    protected final static long serialVersionUID = 1L;
    protected final static byte subSerialVersionUID = 2;

    /**
     * The currently commited target object of the container.
     */
    protected OzoneCompatible   target;

    protected ObjectID          objID;

    protected String            name;

    protected transient int     invokeCount;

    protected long              modTime;

    /**
     The garbage collection level of this ObjectContainer. This number is compared to the
     currentGarbageCollectionLevel of the database.
     Is this number smaller, then this object may be reachable.
     Is it equal, then this object is reachable, but it's descendants are not yet considered.
     Is it greater, then this object is reachable and this object is processed, it's descendants have been considered.
     At the end of the mark-process, every object which still is not reachable must be unreachable, so at this and,
     a smaller garbageCollectionLevel than currentGarbageCollectionLevel means that this object may be deleted.
     */
    protected int               garbageCollectionLevel;


    /**
     * Constructor for object serialization via Externalizable.
     */
    public WizardObjectContainer() {
    }


    public WizardObjectContainer(ObjectID _objID) {
        state = STATE_CREATED;
        objID = _objID;
    }

    public void setCluster(Cluster cluster) {
        this.cluster = cluster;
        if (cluster == null) {
            // cluster is invalidated by the ClusterStore
            if (Env.currentEnv().logWriter.hasTarget(LogWriter.DEBUG3)) {
                Env.currentEnv().logWriter.newEntry(this, "setCluster(null).", LogWriter.DEBUG3);
            }
        }
    }

    public Cluster getCluster() {
        return cluster;
    }


    public long modTime() {
        return getCluster().modTime();
    }


    public boolean isDeleted() {
        return (state() & ObjectContainer.STATE_DELETED) > 0;
    }


    protected boolean isCreated() {
        return (state() & ObjectContainer.STATE_CREATED) > 0;
    }


    /**
     * Returns the Class for the target object. This method is used by
     * AbstractObjectContainer.
     */
    public Class targetClass() {
        try {
            return target.getClass();
        } catch (NullPointerException e) {
            if (target != null) {
                throw e;
            } else {
                throw new NullPointerException(this + ": getCluster()=" + getCluster() + ": target=" + target + ".");
            }
        }
    }


    public synchronized void setTarget(OzoneCompatible _target) {
        if (target != null) {
            target.setContainer(null);
        }
        target = _target;
        target.setContainer(this);
    }


    public OzoneCompatible target() {
        return target;
    }


    public void touch() {
        getCluster().touch();
    }


    public Lock lock() {
        return getCluster().lock();
    }


    public synchronized void notifyAllTAs(Transaction ta) {
        getCluster().lock().notifyAll();
    }


    public Permissions permissions() {
        return getCluster().permissions();
    }


    public int lockLevel(Transaction ta) {
        return getCluster().lock().level(ta);
    }


    public boolean isInvoked() {
        // for performance reasons we assume that the specified transaction
        // is the locking transaction
        return invokeCount > 0;
    }


    public Object invokeTarget(Env env, String methodName, String sig, Object[] args) throws Exception {
        if (Env.currentEnv().logWriter.hasTarget(LogWriter.DEBUG3)) {
            Env.currentEnv().logWriter.newEntry(this, "invokeTarget(): " + target() + " " + methodName + ", " + sig + ", " + args, LogWriter.DEBUG3);
        }
        invokeCount++;

        Object result;

        try {
            result = super.invokeTarget(env, methodName, sig, args);
        } finally {
            invokeCount--;
        }

        return result;
    }

    public void invokeOnActivate() {
        invokeCount++;

        try {
            super.invokeOnActivate();
        } finally {
            invokeCount--;
        }
    }

    public void deleteTarget() {
        if (Env.currentEnv().logWriter.hasTarget(LogWriter.DEBUG3)) {
            Env.currentEnv().logWriter.newEntry(this, "deleteTarget(): ", LogWriter.DEBUG3);
        }
        raiseState(STATE_DELETED);
    }


    public synchronized void nameTarget(String _name) {
        if (Env.currentEnv().logWriter.hasTarget(LogWriter.DEBUG3)) {
            Env.currentEnv().logWriter.newEntry(this, "nameTarget(): ", LogWriter.DEBUG3);
        }
        name = _name;
    }


    public DxCollection allLockers() {
        return getCluster().allLockers();
    }


    public ObjectID id() {
        return objID;
    }


    public String name() {
        return name;
    }


    public void setName(String _name) {
        name = _name;
    }


    public void writeExternal(ObjectOutput out) throws IOException {
        // System.out.println ("container.writeExternal()...");
        out.writeByte(subSerialVersionUID);
        out.writeObject(target);
        // out.writeObject (objID);
        out.writeLong(objID.value());
        if (name == null) {
            out.writeByte(0);
        } else {
            out.writeByte(1);
            out.writeUTF(name);
        }
        out.writeByte((byte) state);
        out.writeInt(garbageCollectionLevel);
    }


    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        // System.out.println ("container.readExternal()...");
        byte streamVersion = in.readByte();
        target = (OzoneCompatible) in.readObject();
        if (target != null) {
            target.setContainer(this);
        }
        // objID = (ObjectID)in.readObject();
        objID = new ObjectID(in.readLong());
        name = null;
        if (in.readByte() != 0) {
            name = in.readUTF();
        }
        state = (int) in.readByte();
        if (streamVersion >= 2) {
            garbageCollectionLevel = in.readInt();
        } else {
            garbageCollectionLevel = 0;
        }
    }

    /**
     Ensures that the garbageCollectionLevel is at least the given currentGarbageCollectionLevel.
     The return value is meaningful if the supplied newGarbageCollectionLevel is the currentGarbageCollectionLevel

     @return
     <=0 if this object still has to be processed.
     This is the case if it belongs to the surelyReachable set but not to the processedReachable set
     > otherwise

     <0 if this object has been updated
     =0 if this object has not been updated, it is surelyReachable
     >0 if this object has not been updated, it is processedReachable
     */
    public int ensureGarbageCollectionLevel(int newGarbageCollectionLevel) {
        int difference = this.garbageCollectionLevel - newGarbageCollectionLevel;

        if (difference < 0) { // This object's garbageCollectionLevel must be updated
            this.garbageCollectionLevel = newGarbageCollectionLevel;
            touch();
        }

        return difference;
    }


    /**
     Returns the garbageCollectionLevel this ObjectContainer has reached due to (not) calling {@link #ensureGarbageCollectionLevel}.
     */
    public int getGarbageCollectionLevel() {
        return garbageCollectionLevel;
    }

    /**
     Pins this ObjectContainer.
     Every caller of this method must pair this call with a call to {@link #unpin}.
     An ObjectContainer remains in main memory at least as long as it is pinned.
     */
    public void pin() {
        Cluster cluster = getCluster();
        if (cluster instanceof WizardCluster) {
            ((WizardCluster)cluster).pin();
        }
    }

    /**
     Unpins this ObjectContainer.
     This method must be called exactly once for every call to {@link #pin}.
     */
    public void unpin() {
        Cluster cluster = getCluster();
        if (cluster instanceof WizardCluster) {
            ((WizardCluster)cluster).unpin();
        }
    }

    /**
     Returns wether this ObjectContainer is pinned.
     */
    public boolean isPinned() {
        Cluster cluster = getCluster();
        if (cluster instanceof WizardCluster) {
            return ((WizardCluster)cluster).isPinned();
        } else {
            return false;
        }
    }

    public boolean hasSameClusterAs(WizardObjectContainer container) {
        return container.getCluster() == getCluster();
    }

    public String toString() {
        if (name!=null) {
            return "WizardObjectContainer[target="+target+",objID="+objID+",name=\""+name+"\",modTime="+modTime+",cluster="+cluster+"]";
        } else {
            return "WizardObjectContainer[target="+target+",objID="+objID+",name="+name+",modTime="+modTime+",cluster="+cluster+"]";
        }
    }
}

// :indentSize=4:tabSize=4:noTabs=true:

⌨️ 快捷键说明

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