001: package com.quadcap.sql.file;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.IOException;
042:
043: import com.quadcap.util.Debug;
044:
045: /**
046: * A <code>RandomAccess</code> implementation using a byte array.
047: *
048: * @author Stan Bailes
049: */
050: public class BufferedRandomAccess extends RandomAccess {
051: static final int BUFSIZE = 16384;
052:
053: class Buffer {
054: byte[] buf = new byte[BUFSIZE];
055: long adr = -1;
056: boolean dty = false;
057:
058: //#ifdef DEBUG
059: public String toString() {
060: return "Buffer[" + adr + "]" + (dty ? "*" : "");
061: }
062: //#endif
063: }
064:
065: Buffer b1 = new Buffer();
066: Buffer b2 = new Buffer();
067: Buffer b = null;
068:
069: RandomAccess ra;
070: long size;
071:
072: public BufferedRandomAccess(RandomAccess ra) {
073: this .ra = ra;
074: size = ra.size();
075: }
076:
077: /**
078: * Return the size of the managed region.
079: */
080: public long size() {
081: return size;
082: }
083:
084: /**
085: * Resize the managed region.
086: */
087: public void resize(long newSize) throws IOException {
088: size = newSize;
089: ra.resize(newSize);
090: }
091:
092: /* Write <tt>len</tt> bytes from position <tt>offset</tt> in buffer
093: * <tt>buf</tt> to position <tt>pos</tt> bytes into the managed
094: * area.
095: */
096: public void write(long pos, byte[] buf, int offset, int len)
097: throws IOException {
098: do {
099: long pb = pos & ~(BUFSIZE - 1);
100: long pe = pb + BUFSIZE - 1;
101: if (pe >= size)
102: pe = size - 1;
103: int xlen = (int) (pe - pos + 1);
104: if (xlen > len)
105: xlen = len;
106: if (xlen > 0) {
107: getBuffer(pb);
108: System.arraycopy(buf, offset, b.buf, (int) (pos - pb),
109: xlen);
110: b.dty = true;
111: offset += xlen;
112: pos += xlen;
113: len -= xlen;
114: } else {
115: len = 0;
116: }
117: } while (len > 0);
118:
119: }
120:
121: /**
122: * Read <tt>len</tt> bytes from location <tt>pos</tt> of the region
123: * into the buffer <tt>buf</tt>, starting at <tt>offset</tt>.
124: */
125: public void read(long pos, byte[] buf, int offset, int len)
126: throws IOException {
127: do {
128: long pb = pos & ~(BUFSIZE - 1);
129: long pe = pb + BUFSIZE - 1;
130: if (pe >= size)
131: pe = size - 1;
132: int xlen = (int) (pe - pos + 1);
133: if (xlen > len)
134: xlen = len;
135: if (xlen > 0) {
136: getBuffer(pb);
137: System.arraycopy(b.buf, (int) (pos - pb), buf, offset,
138: xlen);
139: offset += xlen;
140: pos += xlen;
141: len -= xlen;
142: } else {
143: len = 0;
144: }
145: } while (len > 0);
146: }
147:
148: final void getBuffer(long addr) throws IOException {
149: if (addr == b1.adr) {
150: b = b1;
151: } else if (addr == b2.adr) {
152: b = b2;
153: } else {
154: b = (b == b1) ? b2 : b1;
155: if (b.dty)
156: flush(b);
157: b.adr = addr;
158: int xlen = (int) (ra.size() - addr);
159: if (xlen > BUFSIZE)
160: xlen = BUFSIZE;
161: ra.read(addr, b.buf, 0, xlen);
162: }
163: }
164:
165: /**
166: * Finalization...
167: */
168: public void close() throws IOException {
169: flush();
170: ra.close();
171: }
172:
173: final void flushBuffers() throws IOException {
174: flush(b1);
175: flush(b2);
176: }
177:
178: public void flush() throws IOException {
179: flushBuffers();
180: ra.flush();
181: }
182:
183: final void flush(Buffer b) throws IOException {
184: if (b.dty) {
185: int xlen = (int) (ra.size() - b.adr);
186: if (xlen > BUFSIZE)
187: xlen = BUFSIZE;
188: ra.write(b.adr, b.buf, 0, xlen);
189: b.dty = false;
190: }
191: }
192: }
|