1 package com.quadcap.sql.file; 2 3 40 41 import java.io.IOException ; 42 43 import com.quadcap.util.Debug; 44 45 50 public class BufferedRandomAccess extends RandomAccess { 51 static final int BUFSIZE = 16384; 52 53 class Buffer { 54 byte[] buf = new byte[BUFSIZE]; 55 long adr = -1; 56 boolean dty = false; 57 58 public String toString() { 60 return "Buffer[" + adr + "]" + (dty?"*":""); 61 } 62 } 64 Buffer b1 = new Buffer(); 65 Buffer b2 = new Buffer(); 66 Buffer b = null; 67 68 RandomAccess ra; 69 long size; 70 71 public BufferedRandomAccess(RandomAccess ra) { 72 this.ra = ra; 73 size = ra.size(); 74 } 75 76 79 public long size() { 80 return size; 81 } 82 83 86 public void resize(long newSize) throws IOException { 87 size = newSize; 88 ra.resize(newSize); 89 } 90 91 95 public void write(long pos, byte[] buf, int offset, int len) 96 throws IOException 97 { 98 do { 99 long pb = pos & ~(BUFSIZE-1); 100 long pe = pb + BUFSIZE-1; 101 if (pe >= size) pe = size-1; 102 int xlen = (int)(pe - pos + 1); 103 if (xlen > len) xlen = len; 104 if (xlen > 0) { 105 getBuffer(pb); 106 System.arraycopy(buf, offset, b.buf, (int)(pos-pb), xlen); 107 b.dty = true; 108 offset += xlen; 109 pos += xlen; 110 len -= xlen; 111 } else { 112 len = 0; 113 } 114 } while (len > 0); 115 116 } 117 118 122 public void read(long pos, byte[] buf, int offset, int len) 123 throws IOException 124 { 125 do { 126 long pb = pos & ~(BUFSIZE-1); 127 long pe = pb + BUFSIZE-1; 128 if (pe >= size) pe = size-1; 129 int xlen = (int)(pe - pos + 1); 130 if (xlen > len) xlen = len; 131 if (xlen > 0) { 132 getBuffer(pb); 133 System.arraycopy(b.buf, (int)(pos-pb), buf, offset, xlen); 134 offset += xlen; 135 pos += xlen; 136 len -= xlen; 137 } else { 138 len = 0; 139 } 140 } while (len > 0); 141 } 142 143 final void getBuffer(long addr) throws IOException { 144 if (addr == b1.adr) { 145 b = b1; 146 } else if (addr == b2.adr) { 147 b = b2; 148 } else { 149 b = (b == b1) ? b2 : b1; 150 if (b.dty) flush(b); 151 b.adr = addr; 152 int xlen = (int)(ra.size() - addr); 153 if (xlen > BUFSIZE) xlen = BUFSIZE; 154 ra.read(addr, b.buf, 0, xlen); 155 } 156 } 157 158 161 public void close() throws IOException { 162 flush(); 163 ra.close(); 164 } 165 166 final void flushBuffers() throws IOException { 167 flush(b1); 168 flush(b2); 169 } 170 171 public void flush() throws IOException { 172 flushBuffers(); 173 ra.flush(); 174 } 175 176 final void flush(Buffer b) throws IOException { 177 if (b.dty) { 178 int xlen = (int)(ra.size() - b.adr); 179 if (xlen > BUFSIZE) xlen = BUFSIZE; 180 ra.write(b.adr, b.buf, 0, xlen); 181 b.dty = false; 182 } 183 } 184 } 185 | Popular Tags |