Index: src/test/org/apache/lucene/StoreTest.java =================================================================== --- src/test/org/apache/lucene/StoreTest.java (revision 355961) +++ src/test/org/apache/lucene/StoreTest.java (working copy) @@ -28,14 +28,13 @@ class StoreTest { public static void main(String[] args) { try { - test(1000, true); + test(1000, true, true); } catch (Exception e) { - System.out.println(" caught a " + e.getClass() + - "\n with message: " + e.getMessage()); + e.printStackTrace(); } } - public static void test(int count, boolean ram) + public static void test(int count, boolean ram, boolean buffered) throws Exception { Random gen = new Random(1251971); int i; @@ -51,6 +50,8 @@ final int LENGTH_MASK = 0xFFF; + final byte[] buffer = new byte[LENGTH_MASK]; + for (i = 0; i < count; i++) { String name = i + ".dat"; int length = gen.nextInt() & LENGTH_MASK; @@ -59,8 +60,14 @@ IndexOutput file = store.createOutput(name); - for (int j = 0; j < length; j++) - file.writeByte(b); + if (buffered) { + for (int j = 0; j < length; j++) + buffer[j] = b; + file.writeBytes(buffer, length); + } else { + for (int j = 0; j < length; j++) + file.writeByte(b); + } file.close(); } @@ -89,9 +96,18 @@ if (file.length() != length) throw new Exception("length incorrect"); - for (int j = 0; j < length; j++) - if (file.readByte() != b) - throw new Exception("contents incorrect"); + byte[] content = new byte[length]; + if (buffered) { + file.readBytes(content, 0, length); + // check the buffer + for (int j = 0; j < length; j++) + if (content[j] != b) + throw new Exception("contents incorrect"); + } else { + for (int j = 0; j < length; j++) + if (file.readByte() != b) + throw new Exception("contents incorrect"); + } file.close(); } Index: src/java/org/apache/lucene/store/RAMOutputStream.java =================================================================== --- src/java/org/apache/lucene/store/RAMOutputStream.java (revision 355961) +++ src/java/org/apache/lucene/store/RAMOutputStream.java (working copy) @@ -66,27 +66,27 @@ } public void flushBuffer(byte[] src, int len) { - int bufferNumber = pointer/BUFFER_SIZE; - int bufferOffset = pointer%BUFFER_SIZE; - int bytesInBuffer = BUFFER_SIZE - bufferOffset; - int bytesToCopy = bytesInBuffer >= len ? len : bytesInBuffer; + byte[] buffer; + int bufferPos = 0; + while (bufferPos != len) { + int bufferNumber = pointer/BUFFER_SIZE; + int bufferOffset = pointer%BUFFER_SIZE; + int bytesInBuffer = BUFFER_SIZE - bufferOffset; + int remainInSrcBuffer = len - bufferPos; + int bytesToCopy = bytesInBuffer >= remainInSrcBuffer ? remainInSrcBuffer : bytesInBuffer; - if (bufferNumber == file.buffers.size()) - file.buffers.addElement(new byte[BUFFER_SIZE]); + if (bufferNumber == file.buffers.size()) { + buffer = new byte[BUFFER_SIZE]; + file.buffers.addElement(buffer); + } else { + buffer = (byte[]) file.buffers.elementAt(bufferNumber); + } - byte[] buffer = (byte[])file.buffers.elementAt(bufferNumber); - System.arraycopy(src, 0, buffer, bufferOffset, bytesToCopy); + System.arraycopy(src, bufferPos, buffer, bufferOffset, bytesToCopy); + bufferPos += bytesToCopy; + pointer += bytesToCopy; + } - if (bytesToCopy < len) { // not all in one buffer - int srcOffset = bytesToCopy; - bytesToCopy = len - bytesToCopy; // remaining bytes - bufferNumber++; - if (bufferNumber == file.buffers.size()) - file.buffers.addElement(new byte[BUFFER_SIZE]); - buffer = (byte[])file.buffers.elementAt(bufferNumber); - System.arraycopy(src, srcOffset, buffer, 0, bytesToCopy); - } - pointer += len; if (pointer > file.length) file.length = pointer; Index: src/java/org/apache/lucene/store/BufferedIndexOutput.java =================================================================== --- src/java/org/apache/lucene/store/BufferedIndexOutput.java (revision 355961) +++ src/java/org/apache/lucene/store/BufferedIndexOutput.java (working copy) @@ -41,8 +41,42 @@ * @see IndexInput#readBytes(byte[],int,int) */ public void writeBytes(byte[] b, int length) throws IOException { - for (int i = 0; i < length; i++) - writeByte(b[i]); + int bytesLeft = BUFFER_SIZE - bufferPosition; + System.out.println("Writing " + length + " bytes"); + // is there enough space in the buffer? + if (bytesLeft >= length) { + // we add the data to the end of the buffer + System.arraycopy(b, 0, buffer, bufferPosition, length); + bufferPosition += length; + // if the buffer is full, flush it + if (BUFFER_SIZE - bufferPosition == 0) + flush(); + } else { + // is data larger then buffer? + if (length > BUFFER_SIZE) { + // we flush the buffer + if (bufferPosition > 0) + flush(); + // and write data at once + flushBuffer(b, length); + } else { + // we fill/flush the buffer (until the input is written) + int pos = 0; // position in the input data + int pieceLength; + while (pos < length) { + pieceLength = (length - pos < bytesLeft) ? length - pos : bytesLeft; + System.arraycopy(b, pos, buffer, bufferPosition, pieceLength); + pos += pieceLength; + bufferPosition += pieceLength; + // if the buffer is full, flush it + bytesLeft = BUFFER_SIZE - bufferPosition; + if (bytesLeft == 0) { + flush(); + bytesLeft = BUFFER_SIZE; + } + } + } + } } /** Forces any buffered output to be written. */