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

📄 blobcontainerimpl.java

📁 Java的面向对象数据库系统的源代码
💻 JAVA
字号:
// You can redistribute this software and/or modify it under the terms of
// the Ozone Library 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: BLOBContainerImpl.java,v 1.4 2003/04/11 14:47:40 per_nyfelt Exp $

package org.ozoneDB.blob;

import org.ozoneDB.DxLib.*;
import org.ozoneDB.OzoneObject;


/**
 * The BLOB implementation. The data are stored in several BLOBPages. The
 * data of the BLOB can be accessed through BLOBInOutputStreams.
 *
 *
 * @author <a href="http://www.softwarebuero.de/">SMB</a>
 * @version $Revision: 1.4 $Date: 2003/04/11 14:47:40 $
 */
public class BLOBContainerImpl extends OzoneObject implements BLOBContainer {

    protected final static int DEFAULT_PAGE_SIZE = 32 * 1024;

    protected boolean debug = false;

    protected DxVector pages;

    protected int pageSize = DEFAULT_PAGE_SIZE;


    public BLOBContainerImpl() {
        pages = new DxArrayBag();
        pageSize = DEFAULT_PAGE_SIZE;
    }


    public void init( int _pageSize ) {
        pageSize = _pageSize;
    }


    /**
     * Returns the available bytes of this BLOB beginning at index.
     *
     *   NEVER WRITE ON BLOB WHILE EXECUTING THIS METHOD!
     *
     *   @param _index the startposition
     *   @return the number of available bytes after _index
     *   @exception Exception (some kind of databaseexception ?)
     */
    public int available( int _index ) throws Exception {
        int pageNum = pageNum( _index );
        int pageOff = pageOff( _index );
        int lastNum = pages.count() - 1;
        int result = 0;

        if (debug) {
            System.out.println( "pageNum: " + pageNum );
            System.out.println( "pageOff: " + pageOff );
            System.out.println( "lastNum: " + lastNum );
        }

        if (pageNum <= lastNum) {

            if (pageNum < lastNum) {
                // index is not on last page
                // -> size of page where index points to
                result += (pageSize - pageOff);
                // + size of pages except startpage and last
                result += pageSize * (lastNum - pageNum - 1);
                // on last page now we?ll start at offset = 0
                pageOff = 0;
            }

            // + size of last page
            BLOBPage lastPage = (BLOBPage)pages.elementAtIndex( lastNum );
            result += Math.max( lastPage.size() - pageOff, 0 );
        }

        if (debug) {
            System.out.println( "available(): " + result + " bytes left" );
        }
        return result;
    }


    /**
     * Writes the content of the Array into the BLOB starting at index.
     *
     *   @param _index the write startposition in the BLOB
     *   @param b the bytearray to be stored
     *   @param off the startindex in the bytearray
     *   @param len the number of bytes to be written into the BLOB
     *   @exception Exception
     */
    public void write( int _index, byte[] b, int off, int len ) throws Exception {

        if (debug) {
            System.out.println( "start writing " + len + " bytes into BLOB..." );
        }

        len = len == -1 ? b.length : len;
        int pageNum;
        int pageOff;

        while (len > 0) {
            pageNum = pageNum( _index );
            pageOff = pageOff( _index );

            BLOBPage page;
            if (pageNum >= pages.size()) {
                page = (BLOBPage)database().createObject( BLOBPageImpl.class.getName() );
                page.init( pageSize );
                pages.add( page );

                if (debug) {
                    System.out.println( "\tnew Page Number " + pageNum + " created." );
                }
            } else {
                page = (BLOBPage)pages.elementAtIndex( pageNum );
            }

            int writeSize = pageSize - pageOff;
            writeSize = Math.min( len, writeSize );

            writeSize = (pageSize - page.size());
            writeSize = Math.min( len, writeSize );
            byte[] pageData = new byte[writeSize];

            System.arraycopy( b, off, pageData, 0, writeSize );
            page.write( pageData, pageOff );

            _index += writeSize;
            off += writeSize;
            len -= writeSize;

            if (debug) {
                System.out.println( "\tactual index in BLOB: " + _index + ", " + len + " bytes left to write." );
            }
        }

        // for the case of allowing rewrite to a BLOB we have to check, if we
        // need to cut off pages that were used before writing this and now are
        // left with undefined content. Else the available () method may return
        // undefined results!
        int lastNum;
        pageNum = pageNum( _index );
        while ((lastNum = (pages.count() - 1)) > pageNum) {
            BLOBPage page = (BLOBPage)pages.elementAtIndex( lastNum );
            database().deleteObject( page );
            pages.deleteAtIndex( lastNum );

            if (debug) {
                System.out.println( "\tPage Number " + lastNum + " deleted." );
            }
        }

        if (debug) {
            System.out.println( "writing into BLOB done." );
        }
    }


    public byte[] read( int index, int len ) throws Exception {

        if (debug) {
            System.out.println( "start reading " + len + " bytes from BLOB..." );
        }

        // calculate the real length
        len = Math.min( available( index ), len );

        byte[] result = new byte[len];
        int off = 0;

        while (len > 0) {
            int pageNum = pageNum( index );
            int pageOff = pageOff( index );
            int readSize = Math.min( pageSize - pageOff, len );
            // this is correct, because the calculating of the real length
            // saves me from reading more out of the page then it contains

            BLOBPage page = (BLOBPage)pages.elementAtIndex( pageNum );
            // this page exists because if not, available() would have returned 0
            // and this code is not reached.

            byte[] pageData = page.read( pageOff, readSize );
            System.arraycopy( pageData, 0, result, off, readSize );

            index += readSize;
            off += readSize;
            len -= readSize;

            if (debug) {
                System.out.println( "\tpage #" + pageNum + ", actual index in BLOB: " + index + ", " + len
                        + " bytes left to read." );
            }
        }

        if (debug) {
            System.out.println( "reading from BLOB done." );
        }
        return result;
    }


    /**
     *   This method must be called to kill all referenced BLOBpages.
     *   (hope the database does this for me...)
     */
    public void onDelete() {
        // iterate over all pages and delete them
        DxIterator iterator = pages.iterator();
        BLOBPage page;

        while (iterator.next() != null) {
            page = (BLOBPage)iterator.object();
            database().deleteObject( page );
        }
    }


    protected int pageNum( int index ) {
        return index / pageSize;
    }


    protected int pageOff( int index ) {
        return index % pageSize;
    }
}

⌨️ 快捷键说明

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