📄 magicobjectcontainer.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.magicStore;
import java.io.*;
import org.ozoneDB.DxLib.DxCollection;
import org.ozoneDB.OzoneCompatible;
import org.ozoneDB.core.*;
import org.ozoneDB.util.LogWriter;
/**
* The "Wizard" implementation of the ObjectContainer interface. Much of the
* lock functionality is implemented in the MagicCluster 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>
* @author Leo Mekenkamp
* @author Per Nyfelt
* @version $Revision$Date$
* We need to extend WizardObjectContainer to be compatible with wizardStore
* note: if we drop backward compatibility it should extend StorageObjectContainer
*/
public final class MagicObjectContainer extends org.ozoneDB.core.wizardStore.WizardObjectContainer implements Externalizable {
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 MagicObjectContainer() {
}
public MagicObjectContainer(ObjectID _objID) {
state = STATE_CREATED;
objID = _objID;
}
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 final 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 final 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;
}
public boolean hasSameClusterAs(MagicObjectContainer container) {
return container.getCluster() == getCluster();
}
public String toString() {
if (name!=null) {
return "MagicObjectContainer[target="+target+",objID="+objID+",name=\""+name+"\",modTime="+modTime+",cluster="+cluster+"]";
} else {
return "MagicObjectContainer[target="+target+",objID="+objID+",name="+name+",modTime="+modTime+",cluster="+cluster+"]";
}
}
public boolean isPinned() {
return false;
}
public void pin() {
// do nothing;
}
public void unpin() {
// do nothing
}
}
// :indentSize=4:tabSize=4:noTabs=true:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -