1 package org.apache.lucene.store;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.IOException;
22 /** Base implementation class for buffered {@link IndexOutput}. */
23 public abstract class BufferedIndexOutput extends IndexOutput {
24 static final int BUFFER_SIZE = 16384;
26 private final byte[] buffer = new byte[BUFFER_SIZE];
27 private long bufferStart = 0; // position in file of buffer
28 private int bufferPosition = 0; // position in buffer
30 /** Writes a single byte.
31 * @see IndexInput#readByte()
34 public void writeByte(byte b) throws IOException {
35 if (bufferPosition >= BUFFER_SIZE)
37 buffer[bufferPosition++] = b;
40 /** Writes an array of bytes.
41 * @param b the bytes to write
42 * @param length the number of bytes to write
43 * @see IndexInput#readBytes(byte[],int,int)
46 public void writeBytes(byte[] b, int offset, int length) throws IOException {
47 int bytesLeft = BUFFER_SIZE - bufferPosition;
48 // is there enough space in the buffer?
49 if (bytesLeft >= length) {
50 // we add the data to the end of the buffer
51 System.arraycopy(b, offset, buffer, bufferPosition, length);
52 bufferPosition += length;
53 // if the buffer is full, flush it
54 if (BUFFER_SIZE - bufferPosition == 0)
57 // is data larger then buffer?
58 if (length > BUFFER_SIZE) {
59 // we flush the buffer
60 if (bufferPosition > 0)
62 // and write data at once
63 flushBuffer(b, offset, length);
64 bufferStart += length;
66 // we fill/flush the buffer (until the input is written)
67 int pos = 0; // position in the input data
69 while (pos < length) {
70 pieceLength = (length - pos < bytesLeft) ? length - pos : bytesLeft;
71 System.arraycopy(b, pos + offset, buffer, bufferPosition, pieceLength);
73 bufferPosition += pieceLength;
74 // if the buffer is full, flush it
75 bytesLeft = BUFFER_SIZE - bufferPosition;
78 bytesLeft = BUFFER_SIZE;
85 /** Forces any buffered output to be written. */
87 public void flush() throws IOException {
88 flushBuffer(buffer, bufferPosition);
89 bufferStart += bufferPosition;
93 /** Expert: implements buffer write. Writes bytes at the current position in
95 * @param b the bytes to write
96 * @param len the number of bytes to write
98 private void flushBuffer(byte[] b, int len) throws IOException {
99 flushBuffer(b, 0, len);
102 /** Expert: implements buffer write. Writes bytes at the current position in
104 * @param b the bytes to write
105 * @param offset the offset in the byte array
106 * @param len the number of bytes to write
108 protected abstract void flushBuffer(byte[] b, int offset, int len) throws IOException;
110 /** Closes this stream to further operations. */
112 public void close() throws IOException {
116 /** Returns the current position in this file, where the next write will
121 public long getFilePointer() {
122 return bufferStart + bufferPosition;
125 /** Sets current position in this file, where the next write will occur.
126 * @see #getFilePointer()
129 public void seek(long pos) throws IOException {
134 /** The number of bytes in the file. */
136 public abstract long length() throws IOException;