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

📄 dbcachechunk.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: 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 + -