📄 blobcontainerimpl.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 + -