KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > file > Block


1 package com.quadcap.sql.file;
2
3 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.IOException JavaDoc;
42
43 import com.quadcap.util.ConfigNumber;
44 import com.quadcap.util.Debug;
45 import com.quadcap.util.Util;
46
47 /**
48  * This class represents a block/page of data in a random access file,
49  * which may be cached. The key is an Integer specifying the block
50  * number, while the data is a byte array containing the actual
51  * data.
52  *
53  * @author Stan Bailes
54  */

55 public class Block extends Cacheable implements Page {
56     private byte[] buf;
57
58     public long getPageNum() { return key; }
59
60     /**
61      * Initialize this block. Create the buffer if necessary, and initialize
62      * the buffer contents from the underlying store. We assume that the
63      * <code>BlockStore.read()</code> method will fill the buffer with zeros
64      * if we're attempting to "read" a block that doesn't exist yet.
65      *
66      * @param store the underlying <code>BlockStore</code> which manages
67      * the blocks.
68      * @param key an <code>Integer</code> specifying the block number.
69      */

70     public void init(Object JavaDoc store, long key) throws IOException JavaDoc {
71     //#ifdef DEBUG
72
if (Trace.bit(0)) {
73         Debug.println("Block.init(" + store + ", " + key + ")");
74     }
75     //#endif
76
super.init(store, key);
77     BlockStore bs = (BlockStore)store;
78     if (buf == null) buf = new byte[bs.blockSize()];
79     bs.read(getPageNum(), buf);
80         setDirty(false);
81     }
82
83     /**
84      * Write the contents of the buffer back to the underlying store.
85      */

86     public final void flush() throws IOException JavaDoc {
87     //#ifdef DEBUG
88
if (Trace.bit(1)) {
89         Debug.println(0, "Block[" + key + "].flush()");
90     }
91     //#endif
92
if (dirty) {
93         //#ifdef DEBUG
94
if (Trace.bit(0)) {
95         Debug.println("flush [" + getPageNum() + "]");
96         }
97         //#endif
98
BlockStore bs = (BlockStore)store;
99             bs.write(getPageNum(), buf);
100             setDirty(false);
101     }
102     }
103
104     /**
105      * From the Cacheable class, return the underlying data object.
106      * When used as a <tt>Block</tt>, we typically use the <tt>read()</tt>
107      * and <tt>write</tt> methods to access the underlying data...
108      */

109     public final Object JavaDoc getData() { return buf; }
110
111     /**
112      * Return a reference to the array containing the data for this
113      * block, and create a new buffer, so that the reference returned
114      * can be used in a subsequent <code>setData</code> call to another
115      * buffer. This allows the contents of one block to be moved to
116      * another block with a minimum of array copying.
117      */

118     public byte[] getDataAndReset() {
119     //#ifdef DEBUG
120
if (Trace.bit(0)) {
121         Debug.println("Block[" + key + "].getDataAndReset()");
122     }
123     //#endif
124
byte[] r = buf;
125     buf = new byte[r.length];
126     setDirty(true);
127     return r;
128     }
129
130     /**
131      * From the Cacheable class, set the underlying data object.
132      * When used as a <tt>Block</tt>, we typically use the <tt>read()</tt>
133      * and <tt>write</tt> methods to access the underlying data...
134      */

135     public void setData(Object JavaDoc obj) {
136     //#ifdef DEBUG
137
if (Trace.bit(0)) {
138         Debug.println("Block[" + key + "].setData(" + obj + ")");
139     }
140     //#endif
141
byte[] r = (byte[])obj;
142     if (r.length != buf.length) {
143         throw new RuntimeException JavaDoc("Bad buffer length!");
144     }
145     buf = r;
146     setDirty(true);
147     }
148
149     /**
150      * Only a debugging version implemented so far...
151      */

152     public String JavaDoc toString() {
153     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
154     sb.append("[key(" + getKey() + "), dirty(" + dirty + "), refcount(" +
155           refCount + ")]");
156     return sb.toString();
157     }
158
159     /**
160      * Read a range of bytes from the page.
161      *
162      * @param pos the offset in the page of the first byte to read
163      * @param pbuf the buffer into which the bytes are placed.
164      * @param offset the offset in <code>pbuf</code> where the first byte
165      * is placed.
166      * @param len the number of bytes to read
167      */

168     public final int read(int pos, byte[] pbuf, int offset, int len) {
169     //#ifdef DEBUG
170
if (Trace.bit(1)) {
171         Debug.println("Block[" + key + "].read(" + pos + ", " + len + ")" +
172               ", offset = " + offset + ", buf.len = " + buf.length +
173               ", pbuf.len = " + pbuf.length);
174     }
175     //#endif
176

177     System.arraycopy(buf, pos, pbuf, offset, len);
178     //#ifdef DEBUG
179
if (Trace.bit(0)) {
180         Debug.println("Block[" + key + "].read(" + pos + ", " + len +
181               "): " + Util.strBytes(pbuf, offset, len));
182     }
183     //#endif
184
return len;
185     }
186
187     /**
188      * Write a range of bytes to the page.
189      *
190      * @param pos the offset in the page of the first byte to write
191      * @param pbuf the buffer from which the bytes are obtained
192      * @param offset the offset in <code>pbuf</code> of the first byte
193      * to write
194      * @param len the number of bytes to write
195      */

196     public final int write(int pos, byte[] pbuf, int offset, int len) {
197     //#ifdef DEBUG
198
if (Trace.bit(0)) {
199         Debug.println("Block[" + key + "].write(" + pos + ", " +
200               Util.strBytes(pbuf, offset, len) + ")");
201     }
202     //#endif
203
System.arraycopy(pbuf, offset, buf, pos, len);
204     setDirty(true);
205     return len;
206     }
207
208     public final byte readByte(int pos) {
209     //#ifdef DEBUG
210
if (Trace.bit(1)) {
211         Debug.println("Block[" + key + "].read(" + (pos) + "): " + buf[pos]);
212     }
213     //#endif
214
return buf[pos];
215     }
216
217     public final void writeByte(int pos, byte val) {
218     //#ifdef DEBUG
219
if (Trace.bit(0)) {
220         Debug.println("Block[" + key + "].write(" + pos + "): " + val);
221     }
222     //#endif
223
buf[pos] = val;
224         setDirty(true);
225     }
226
227     /**
228      * Read a short (2-byte) value from the page.
229      *
230      * @param pos the offset in the page of the short.
231      */

232     public final short readShort(int pos) {
233         short ret = ByteUtil.getShort(buf, pos);
234         //#ifdef DEBUG
235
if (Trace.bit(1)) {
236             Debug.println("Block[" + key + "].readShort(" + pos + ") = " + ret);
237         }
238         //#endif
239
return ret;
240     }
241
242     /**
243      * Write a short (2-byte) value to the page.
244      *
245      * @param pos the offset in the page of the short.
246      * @param val the short value to write.
247      */

248     public final void writeShort(int pos, short val) {
249         //#ifdef DEBUG
250
if (Trace.bit(0)) {
251             Debug.println("Block[" + key + "].writeShort(" + pos + ", " +
252                           val + ")");
253         }
254         //#endif
255
ByteUtil.putShort(buf, pos, val);
256     setDirty(true);
257     }
258
259     /**
260      * Read an integer (4-byte) value from the page.
261      *
262      * @param pos the offset in the page of the integer.
263      */

264     public final int readInt(int pos) {
265         int ret = ByteUtil.getInt(buf, pos);
266         //#ifdef DEBUG
267
if (Trace.bit(1)) {
268             Debug.println("Block[" + key + "].readInt(" + pos + ") = " + ret);
269         }
270         //#endif
271
return ret;
272     }
273
274     /**
275      * Write an integer (4-byte) value to the page.
276      *
277      * @param pos the offset in the page of the integer.
278      * @param val the integer value to write.
279      */

280     public final void writeInt(int pos, int val) {
281         //#ifdef DEBUG
282
if (Trace.bit(0)) {
283             Debug.println("Block[" + key + "].writeInt(" + pos + ", " +
284                           val + ")");
285         }
286         //#endif
287
ByteUtil.putInt(buf, pos, val);
288     setDirty(true);
289     }
290
291     /**
292      * Read a long (8-byte) value from the page.
293      *
294      * @param pos the offset in the page of the long.
295      */

296     public final long readLong(int pos) {
297         long ret = ByteUtil.getLong(buf, pos);
298         //#ifdef DEBUG
299
if (Trace.bit(1)) {
300             Debug.println("Block[" + key + "].readLong(" + pos + ") = " + ret);
301         }
302         //#endif
303
return ret;
304     }
305
306     /**
307      * Write a long (8-byte) value to the page.
308      *
309      * @param pos the offset in the page of the long.
310      * @param val the long value to write.
311      */

312     public final void writeLong(int pos, long val) {
313         //#ifdef DEBUG
314
if (Trace.bit(0)) {
315             Debug.println("Block[" + key + "].writeLong(" + pos + ", " +
316                           val + ")");
317         }
318         //#endif
319
ByteUtil.putLong(buf, pos, val);
320     setDirty(true);
321     }
322
323     public final void takeData(Page p) {
324     setData(((Block)p).getDataAndReset());
325     }
326
327     public void clear() {
328         for (int i = 0; i < buf.length; i++) buf[i] = 0;
329         setDirty(true);
330     }
331
332     //#ifdef DEBUG
333
// used for test below
334
void init() {
335     buf = new byte[32];
336     }
337
338     // A 12 bit (two base64 chars) signature. Live dangerously.
339
public String JavaDoc signature() {
340         return signature(buf);
341     }
342     
343     public static String JavaDoc signature(byte[] buf) {
344         return signature(buf, 0, buf.length);
345     }
346     public static String JavaDoc signature(byte[] buf, int off, int cnt) {
347         byte[] b = com.quadcap.io.Base64OutputStream.base64;
348         int h = 31415;
349         long tot = 0;
350         for (int i = 0; i < cnt; i++) {
351             tot += buf[off+i];
352             h ^= (h << 7) ^ (h >> 3) ^ buf[off + i];
353         }
354         return "" + (char)b[(h >> 1) & 63] + (char)b[(h >> 8) & 63] + (char)b[(h >> 16) & 63] +
355             ((tot == 0) ? "*" : "");
356     }
357         
358
359     public static void main(String JavaDoc args[]) {
360     Block b = new Block();
361     b.init();
362     b.writeInt(20, 128);
363     byte[] bufx = new byte[32];
364     b.read(20, bufx, 0, 4);
365     int v = b.readInt(20);
366     }
367     //#endif
368
}
369
Popular Tags