1 package com.jofti.store; 2 3 import java.io.IOException ; 4 import java.nio.ByteBuffer ; 5 import java.util.Arrays ; 6 7 import org.apache.commons.logging.Log; 8 import org.apache.commons.logging.LogFactory; 9 10 import com.jofti.exception.JoftiException; 11 12 17 class BlockBuffer { 18 19 ByteBuffer buffer = null; 20 21 FileStore file = null; 22 23 int bufferSize = 4096; 25 26 int recordSize = 0; 27 28 int numberEntries=0; 29 40 int bytesUsed = 0; 41 42 FilePositionHolder positionHolder = null; 43 44 private static Log log = LogFactory.getLog(BlockBuffer.class); 45 46 50 int initCounter = 0; 51 52 62 final static int bufferHeaderSize = 7; 63 64 final int bytesUsedOffSet = 1; 65 66 69 final static int bufferFooterSize = 3; 70 71 75 76 82 private int recordHeaderSize = 4; 83 84 88 private byte[] CRLF = "\r\n".getBytes(); 89 90 private byte[] crlf = new byte[CRLF.length]; 91 92 95 private byte[] HEADER_ID = "H".getBytes(); 96 97 100 private byte[] FOOTER_ID = "F".getBytes(); 101 102 108 private int payloadSize; 109 110 113 BlockBuffer() { 114 115 } 116 117 public int remaining() { 118 return buffer.remaining() - (bufferFooterSize); 119 } 120 121 130 public void init(int bufferSize) throws JoftiException { 131 134 buffer = ByteBuffer.allocateDirect(bufferSize); 135 136 ++initCounter; 137 138 buffer.clear(); 139 140 payloadSize = ((bufferSize) - (bufferHeaderSize + bufferFooterSize)); 141 142 } 143 144 public void reset() { 145 buffer.clear(); 146 positionHolder = null; 147 file = null; 148 recordSize = 0; 149 bytesUsed = 0; 150 151 } 152 153 void writeFurniture(int numberRecords) { 154 buffer.put(HEADER_ID); 155 156 buffer.putShort((short) 0); 158 buffer.putShort((short)numberRecords); 159 buffer.put(CRLF); 160 161 } 162 163 164 int put(ByteBuffer buf, int offset) throws JoftiException { 165 166 int written = 0; 167 168 int remaining = buffer.remaining() - bufferFooterSize; 169 170 if (offset == 0 && recordHeaderSize <= remaining) { 173 remaining -= 4; 175 } else if (offset == 0 && recordHeaderSize > remaining) { 176 return written; 179 } 180 182 if (remaining > 0) { 184 185 int length = remaining; 186 written = length; 193 195 } 196 197 bytesUsed = buffer.position(); 198 return written; 199 } 200 201 void put(ByteBuffer buf) throws JoftiException { 202 203 buffer.put(buf); 206 208 bytesUsed = buffer.position(); 209 } 210 211 212 213 214 215 void writeFooter() { 216 if (buffer.position() != payloadSize + bufferHeaderSize) { 217 buffer.position(payloadSize + bufferHeaderSize); 218 } 219 220 buffer.put(FOOTER_ID); 221 buffer.put(CRLF); 222 223 } 224 225 228 void write() throws IOException { 229 231 buffer.putShort(bytesUsedOffSet, (short) bytesUsed); 233 234 writeFooter(); 235 try { 236 237 buffer.flip(); 238 file.write(this); 239 240 } catch (IOException e) { 241 throw e; 242 } 243 } 244 245 255 BlockBuffer read(FileStore store) throws JoftiException { 256 long position = positionHolder.position; 257 258 try { 259 int bytesRead = -1; 261 if (store.channel.size() > position) bytesRead = store.channel.read(buffer, position); 263 if (bytesRead == -1) { 264 return null; 266 } 267 268 if (bytesRead != buffer.capacity()) 269 throw new JoftiException("FILESIZE Error: bytesRead=" 270 + bytesRead); 271 272 buffer.clear(); 274 byte head = buffer.get(); 275 if (head != HEADER_ID[0]) 276 throw new JoftiException( 277 "HEADER_ID does not match for position " + position 278 + " in store " + store.fileId); 279 280 bytesUsed = buffer.getShort(); 282 if (bytesUsed < 0) 283 throw new JoftiException("data used: " + bytesUsed 284 + " for position " + position + " in store " 285 + store.fileId); 286 numberEntries = buffer.getShort(); 288 if (numberEntries < 0) 289 throw new JoftiException("entries: " + numberEntries 290 + " for position " + position + " in store " 291 + store.fileId); 292 293 buffer.get(crlf); 295 if (!Arrays.equals(crlf, CRLF)) 296 throw new JoftiException( 297 "HEADER_CRLF not present for position " + position 298 + " in store " + store.fileId); 299 300 buffer.mark(); 302 303 buffer.position(payloadSize + bufferHeaderSize); 305 306 byte footer = buffer.get(); 307 if (footer != FOOTER_ID[0]) { 308 throw new JoftiException("FOOTER_ID not present for position " 309 + position + " in store " + store.fileId); 310 } 311 312 buffer.get(crlf); 314 if (!Arrays.equals(crlf, CRLF)) 315 throw new JoftiException("FOOTER_CRLF not found for position " 316 + position + " in store " + store.fileId); 317 318 buffer.limit(bytesUsed); 320 322 buffer.reset(); 323 } catch (Exception e) { 324 throw new JoftiException(e); 325 } 326 return this; 327 } 328 329 334 String getStats() { 335 String name = this.getClass().getName(); 336 337 String result = "<LogBuffer class='" 338 + name 339 + "\n <timesUsed value='" 340 + initCounter 341 + "'>Number of times this buffer was initialized for use</timesUsed>" 342 + "\n</LogBuffer>" + "\n"; 343 344 return result; 345 } 346 347 public FileStore getFileStore() { 348 return file; 349 } 350 351 public void setFileStore(FileStore file) { 352 this.file = file; 353 } 354 355 public FilePositionHolder getPositionHolder() { 356 return positionHolder; 357 } 358 359 public void setPositionHolder(FilePositionHolder positionHolder) { 360 this.positionHolder = positionHolder; 361 } 362 } | Popular Tags |