📄 dbcachechunk.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: DbCacheChunk.java,v 1.6 2003/03/12 12:30:23 per_nyfelt Exp $
package org.ozoneDB.core.DbRemote;
import java.io.*;
import java.lang.reflect.*;
import org.ozoneDB.DxLib.*;
import org.ozoneDB.*;
import org.ozoneDB.io.stream.ResolvingObjectInputStream;
import org.ozoneDB.core.*;
import org.ozoneDB.util.*;
/**
* Read/write a chunk of objects from/to the server. This is used by the
* {@link ClientCacheDatabase} to fetch/sync objects from/to the server.
*
*
* @author <a href="http://www.softwarebuero.de/">SMB</a>
* @version $Revision: 1.6 $Date: 2003/03/12 12:30:23 $
*/
public final class DbCacheChunk extends DbCommand implements Externalizable {
private final static byte MODE_READ = 1;
private final static byte MODE_WRITE = 2;
private byte mode;
private int size;
private ObjectID rootID;
private byte[] chunk;
public DbCacheChunk() {
}
/**
* Fetch objects from the server.
*/
public DbCacheChunk( ObjectID _rootID, int _size ) {
mode = MODE_READ;
rootID = _rootID;
size = _size;
}
/**
* Store objects in the server.
*/
public DbCacheChunk( byte[] _chunk ) {
mode = MODE_WRITE;
chunk = _chunk;
}
public void perform( Transaction ta ) throws Exception {
env.logWriter.newEntry( this, "DbCacheChunk.perform(): mode:" + mode, LogWriter.DEBUG );
switch (mode) {
case MODE_READ:
readChunk( ta );
break;
case MODE_WRITE:
writeChunk( ta );
break;
default:
throw new RuntimeException( "Unknown mode." );
}
}
protected void readChunk( Transaction ta ) throws Exception {
env.logWriter.newEntry( this, " readChunk()", LogWriter.DEBUG3 );
DxBag bag = env.storeManager.clusterOfID( rootID );
result = new DxArrayBag();
DxIterator it = bag.iterator();
ObjectID id = null;
while ((id = (ObjectID)it.next()) != null) {
try {
env.logWriter.newEntry( this, "readChunk(): " + id, LogWriter.DEBUG3 );
ObjectContainer container = ta.acquireObject( id, Lock.LEVEL_READ );
try {
// since the container link in the target is transient we can
// copy the target by just serializing it
CacheObjectContainer cc = new CacheObjectContainer( container );
((DxArrayBag)result).add( cc );
} finally {
container.unpin();
}
} catch (OzoneRemoteException e) {
env.logWriter.newEntry( this, " readChunk(): " + e.toString(), LogWriter.DEBUG3 );
// we don't handle ObjectNotFoundException and such things here
continue;
}
}
}
protected void writeChunk( Transaction ta ) throws Exception {
env.logWriter.newEntry( this, "writeChunk(): size:" + chunk.length, LogWriter.DEBUG3 );
// writeChunk can use byte[] chunks because proxies always assume
// that they are inside the server and so seting their link
// correctly, this differs from readChunk()
ByteArrayInputStream bin = new ByteArrayInputStream( chunk );
ObjectInputStream in = new ResolvingObjectInputStream( bin );
env.logWriter.newEntry( this, " available:" + bin.available(), LogWriter.DEBUG3 );
while (bin.available() > 0) {
CacheObjectContainer cacheContainer = (CacheObjectContainer)in.readObject();
env.logWriter.newEntry( this,
" container: id:" + cacheContainer.id() + " state:" + cacheContainer.state(), LogWriter.DEBUG3 );
if (cacheContainer.state() == ObjectContainer.STATE_CREATED) {
ObjectContainer container =
ta.createObject( null, cacheContainer.access(), cacheContainer.name(), null, null,
cacheContainer.id() );
try {
container.setTarget( cacheContainer.target() );
} finally {
container.unpin();
}
} else {
// this throws an exception if the container has been deleted already
ObjectContainer container = ta.acquireObject( cacheContainer.id(), Lock.LEVEL_WRITE );
// check the optimistic lock
if (container.modTime() > cacheContainer.modTime()) {
throw new TransactionException( "Object has been changed by another transaction.",
TransactionException.OPTIMISTIC );
}
if (cacheContainer.state() == ObjectContainer.STATE_DELETED) {
ta.deleteObject( container.id() );
} else if (cacheContainer.state() == ObjectContainer.STATE_MODIFIED) {
container.setTarget( cacheContainer.target() );
// do nothing if the names are the same
String name = cacheContainer.name();
// if (!(container.name() == null && name == null || container.name().equals (name)))
container.nameTarget( name );
} else {
throw new RuntimeException( "Wrong container state: " + container.state() );
}
}
}
}
/**
* Recursivly search the specified object and put all found OzoneProxies
* in the specified deque.
*/
protected void findProxies( Object obj, DxDeque deque ) {
String name = obj != null ? obj.getClass().getName() : "(null)";
System.out.println( "*** findProxies(): " + name );
if (obj == null) {
// do nothing
} else if (obj instanceof OzoneProxy) {
deque.pushTop( ((OzoneProxy)obj).remoteID() );
} else {
Class cl = obj.getClass();
int mdf = cl.getModifiers();
if (Modifier.isTransient( mdf ) || Modifier.isStatic( mdf ) || Modifier.isFinal( mdf )) {
// do nothing
System.out.println( "*** transient/static/final" + name );
} else if (cl.isPrimitive()) {
// do nothing
System.out.println( "*** primitive" + name );
} else if (cl.isArray()) {
System.out.println( "*** array" + name );
int len = Array.getLength( obj );
for (int j = 0; j < len; j++) {
Object member = Array.get( obj, j );
findProxies( member, deque );
}
} else {
Field[] fields = cl.getFields();
for (int i = 0; i < fields.length; i++) {
try {
System.out.println( "*** " + fields[i].toString() );
Object member = fields[i].get( obj );
findProxies( member, deque );
} catch (Exception e) {
// should never happen
System.out.println( "*** exception" + name );
}
}
}
}
}
public void writeExternal( ObjectOutput out ) throws IOException {
out.writeByte( mode );
switch (mode) {
case MODE_WRITE: {
out.writeObject( chunk );
break;
}
case MODE_READ: {
out.writeInt( size );
out.writeObject( rootID );
break;
}
default:
throw new RuntimeException( "Unknown mode." );
}
}
public synchronized void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException {
mode = in.readByte();
switch (mode) {
case MODE_WRITE: {
chunk = (byte[])in.readObject();
break;
}
case MODE_READ: {
size = in.readInt();
rootID = (ObjectID)in.readObject();
break;
}
default:
throw new RuntimeException( "Unknown mode." );
}
}
}
/**
* @author <a href="http://www.softwarebuero.de/">SMB</a>
* @version $Revision: 1.6 $Date: 2003/03/12 12:30:23 $
*/
final class RObjectOutputStream extends ObjectOutputStream {
private DxDeque deque;
public RObjectOutputStream( OutputStream out, DxDeque _deque ) throws IOException{
super( out );
deque = _deque;
System.out.println( getClass().getClassLoader() );
enableReplaceObject( true );
}
protected Object replaceObject( Object obj ) throws IOException {
String name = obj != null ? obj.getClass().getName() : "(null)";
System.out.println( "*** replaceObject():" + name );
if (obj instanceof OzoneProxy) {
System.out.println( "*** proxy!" );
deque.pushTop( ((OzoneProxy)obj).remoteID() );
}
return obj;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -