pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / store / BufferedIndexOutput.java
diff --git a/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/store/BufferedIndexOutput.java b/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/store/BufferedIndexOutput.java
new file mode 100644 (file)
index 0000000..1dfbcec
--- /dev/null
@@ -0,0 +1,139 @@
+package org.apache.lucene.store;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+/** Base implementation class for buffered {@link IndexOutput}. */
+public abstract class BufferedIndexOutput extends IndexOutput {
+  static final int BUFFER_SIZE = 16384;
+
+  private final byte[] buffer = new byte[BUFFER_SIZE];
+  private long bufferStart = 0;           // position in file of buffer
+  private int bufferPosition = 0;         // position in buffer
+
+  /** Writes a single byte.
+   * @see IndexInput#readByte()
+   */
+  @Override
+  public void writeByte(byte b) throws IOException {
+    if (bufferPosition >= BUFFER_SIZE)
+      flush();
+    buffer[bufferPosition++] = b;
+  }
+
+  /** Writes an array of bytes.
+   * @param b the bytes to write
+   * @param length the number of bytes to write
+   * @see IndexInput#readBytes(byte[],int,int)
+   */
+  @Override
+  public void writeBytes(byte[] b, int offset, int length) throws IOException {
+    int bytesLeft = BUFFER_SIZE - bufferPosition;
+    // is there enough space in the buffer?
+    if (bytesLeft >= length) {
+      // we add the data to the end of the buffer
+      System.arraycopy(b, offset, 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, offset, length);
+        bufferStart += 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 + offset, 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. */
+  @Override
+  public void flush() throws IOException {
+    flushBuffer(buffer, bufferPosition);
+    bufferStart += bufferPosition;
+    bufferPosition = 0;
+  }
+
+  /** Expert: implements buffer write.  Writes bytes at the current position in
+   * the output.
+   * @param b the bytes to write
+   * @param len the number of bytes to write
+   */
+  private void flushBuffer(byte[] b, int len) throws IOException {
+    flushBuffer(b, 0, len);
+  }
+
+  /** Expert: implements buffer write.  Writes bytes at the current position in
+   * the output.
+   * @param b the bytes to write
+   * @param offset the offset in the byte array
+   * @param len the number of bytes to write
+   */
+  protected abstract void flushBuffer(byte[] b, int offset, int len) throws IOException;
+  
+  /** Closes this stream to further operations. */
+  @Override
+  public void close() throws IOException {
+    flush();
+  }
+
+  /** Returns the current position in this file, where the next write will
+   * occur.
+   * @see #seek(long)
+   */
+  @Override
+  public long getFilePointer() {
+    return bufferStart + bufferPosition;
+  }
+
+  /** Sets current position in this file, where the next write will occur.
+   * @see #getFilePointer()
+   */
+  @Override
+  public void seek(long pos) throws IOException {
+    flush();
+    bufferStart = pos;
+  }
+
+  /** The number of bytes in the file. */
+  @Override
+  public abstract long length() throws IOException;
+
+
+}