KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > blob > BLOBContainerImpl


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Library License version 1 published by ozone-db.org.
3
//
4
// The original code and portions created by SMB are
5
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
6
//
7
// $Id: BLOBContainerImpl.java,v 1.4 2003/04/11 14:47:40 per_nyfelt Exp $
8

9 package org.ozoneDB.blob;
10
11 import org.ozoneDB.DxLib.*;
12 import org.ozoneDB.OzoneObject;
13
14
15 /**
16  * The BLOB implementation. The data are stored in several BLOBPages. The
17  * data of the BLOB can be accessed through BLOBInOutputStreams.
18  *
19  *
20  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
21  * @version $Revision: 1.4 $Date: 2003/04/11 14:47:40 $
22  */

23 public class BLOBContainerImpl extends OzoneObject implements BLOBContainer {
24
25     protected final static int DEFAULT_PAGE_SIZE = 32 * 1024;
26
27     protected boolean debug = false;
28
29     protected DxVector pages;
30
31     protected int pageSize = DEFAULT_PAGE_SIZE;
32
33
34     public BLOBContainerImpl() {
35         pages = new DxArrayBag();
36         pageSize = DEFAULT_PAGE_SIZE;
37     }
38
39
40     public void init( int _pageSize ) {
41         pageSize = _pageSize;
42     }
43
44
45     /**
46      * Returns the available bytes of this BLOB beginning at index.
47      *
48      * NEVER WRITE ON BLOB WHILE EXECUTING THIS METHOD!
49      *
50      * @param _index the startposition
51      * @return the number of available bytes after _index
52      * @exception Exception (some kind of databaseexception ?)
53      */

54     public int available( int _index ) throws Exception JavaDoc {
55         int pageNum = pageNum( _index );
56         int pageOff = pageOff( _index );
57         int lastNum = pages.count() - 1;
58         int result = 0;
59
60         if (debug) {
61             System.out.println( "pageNum: " + pageNum );
62             System.out.println( "pageOff: " + pageOff );
63             System.out.println( "lastNum: " + lastNum );
64         }
65
66         if (pageNum <= lastNum) {
67
68             if (pageNum < lastNum) {
69                 // index is not on last page
70
// -> size of page where index points to
71
result += (pageSize - pageOff);
72                 // + size of pages except startpage and last
73
result += pageSize * (lastNum - pageNum - 1);
74                 // on last page now we?ll start at offset = 0
75
pageOff = 0;
76             }
77
78             // + size of last page
79
BLOBPage lastPage = (BLOBPage)pages.elementAtIndex( lastNum );
80             result += Math.max( lastPage.size() - pageOff, 0 );
81         }
82
83         if (debug) {
84             System.out.println( "available(): " + result + " bytes left" );
85         }
86         return result;
87     }
88
89
90     /**
91      * Writes the content of the Array into the BLOB starting at index.
92      *
93      * @param _index the write startposition in the BLOB
94      * @param b the bytearray to be stored
95      * @param off the startindex in the bytearray
96      * @param len the number of bytes to be written into the BLOB
97      * @exception Exception
98      */

99     public void write( int _index, byte[] b, int off, int len ) throws Exception JavaDoc {
100
101         if (debug) {
102             System.out.println( "start writing " + len + " bytes into BLOB..." );
103         }
104
105         len = len == -1 ? b.length : len;
106         int pageNum;
107         int pageOff;
108
109         while (len > 0) {
110             pageNum = pageNum( _index );
111             pageOff = pageOff( _index );
112
113             BLOBPage page;
114             if (pageNum >= pages.size()) {
115                 page = (BLOBPage)database().createObject( BLOBPageImpl.class.getName() );
116                 page.init( pageSize );
117                 pages.add( page );
118
119                 if (debug) {
120                     System.out.println( "\tnew Page Number " + pageNum + " created." );
121                 }
122             } else {
123                 page = (BLOBPage)pages.elementAtIndex( pageNum );
124             }
125
126             int writeSize = pageSize - pageOff;
127             writeSize = Math.min( len, writeSize );
128
129             writeSize = (pageSize - page.size());
130             writeSize = Math.min( len, writeSize );
131             byte[] pageData = new byte[writeSize];
132
133             System.arraycopy( b, off, pageData, 0, writeSize );
134             page.write( pageData, pageOff );
135
136             _index += writeSize;
137             off += writeSize;
138             len -= writeSize;
139
140             if (debug) {
141                 System.out.println( "\tactual index in BLOB: " + _index + ", " + len + " bytes left to write." );
142             }
143         }
144
145         // for the case of allowing rewrite to a BLOB we have to check, if we
146
// need to cut off pages that were used before writing this and now are
147
// left with undefined content. Else the available () method may return
148
// undefined results!
149
int lastNum;
150         pageNum = pageNum( _index );
151         while ((lastNum = (pages.count() - 1)) > pageNum) {
152             BLOBPage page = (BLOBPage)pages.elementAtIndex( lastNum );
153             database().deleteObject( page );
154             pages.deleteAtIndex( lastNum );
155
156             if (debug) {
157                 System.out.println( "\tPage Number " + lastNum + " deleted." );
158             }
159         }
160
161         if (debug) {
162             System.out.println( "writing into BLOB done." );
163         }
164     }
165
166
167     public byte[] read( int index, int len ) throws Exception JavaDoc {
168
169         if (debug) {
170             System.out.println( "start reading " + len + " bytes from BLOB..." );
171         }
172
173         // calculate the real length
174
len = Math.min( available( index ), len );
175
176         byte[] result = new byte[len];
177         int off = 0;
178
179         while (len > 0) {
180             int pageNum = pageNum( index );
181             int pageOff = pageOff( index );
182             int readSize = Math.min( pageSize - pageOff, len );
183             // this is correct, because the calculating of the real length
184
// saves me from reading more out of the page then it contains
185

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

190             byte[] pageData = page.read( pageOff, readSize );
191             System.arraycopy( pageData, 0, result, off, readSize );
192
193             index += readSize;
194             off += readSize;
195             len -= readSize;
196
197             if (debug) {
198                 System.out.println( "\tpage #" + pageNum + ", actual index in BLOB: " + index + ", " + len
199                         + " bytes left to read." );
200             }
201         }
202
203         if (debug) {
204             System.out.println( "reading from BLOB done." );
205         }
206         return result;
207     }
208
209
210     /**
211      * This method must be called to kill all referenced BLOBpages.
212      * (hope the database does this for me...)
213      */

214     public void onDelete() {
215         // iterate over all pages and delete them
216
DxIterator iterator = pages.iterator();
217         BLOBPage page;
218
219         while (iterator.next() != null) {
220             page = (BLOBPage)iterator.object();
221             database().deleteObject( page );
222         }
223     }
224
225
226     protected int pageNum( int index ) {
227         return index / pageSize;
228     }
229
230
231     protected int pageOff( int index ) {
232         return index % pageSize;
233     }
234 }
235
Popular Tags