pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / store / BufferedIndexOutput.java
1 package org.apache.lucene.store;
2
3 /**
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 import java.io.IOException;
21
22 /** Base implementation class for buffered {@link IndexOutput}. */
23 public abstract class BufferedIndexOutput extends IndexOutput {
24   static final int BUFFER_SIZE = 16384;
25
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
29
30   /** Writes a single byte.
31    * @see IndexInput#readByte()
32    */
33   @Override
34   public void writeByte(byte b) throws IOException {
35     if (bufferPosition >= BUFFER_SIZE)
36       flush();
37     buffer[bufferPosition++] = b;
38   }
39
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)
44    */
45   @Override
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)
55         flush();
56     } else {
57       // is data larger then buffer?
58       if (length > BUFFER_SIZE) {
59         // we flush the buffer
60         if (bufferPosition > 0)
61           flush();
62         // and write data at once
63         flushBuffer(b, offset, length);
64         bufferStart += length;
65       } else {
66         // we fill/flush the buffer (until the input is written)
67         int pos = 0; // position in the input data
68         int pieceLength;
69         while (pos < length) {
70           pieceLength = (length - pos < bytesLeft) ? length - pos : bytesLeft;
71           System.arraycopy(b, pos + offset, buffer, bufferPosition, pieceLength);
72           pos += pieceLength;
73           bufferPosition += pieceLength;
74           // if the buffer is full, flush it
75           bytesLeft = BUFFER_SIZE - bufferPosition;
76           if (bytesLeft == 0) {
77             flush();
78             bytesLeft = BUFFER_SIZE;
79           }
80         }
81       }
82     }
83   }
84
85   /** Forces any buffered output to be written. */
86   @Override
87   public void flush() throws IOException {
88     flushBuffer(buffer, bufferPosition);
89     bufferStart += bufferPosition;
90     bufferPosition = 0;
91   }
92
93   /** Expert: implements buffer write.  Writes bytes at the current position in
94    * the output.
95    * @param b the bytes to write
96    * @param len the number of bytes to write
97    */
98   private void flushBuffer(byte[] b, int len) throws IOException {
99     flushBuffer(b, 0, len);
100   }
101
102   /** Expert: implements buffer write.  Writes bytes at the current position in
103    * the output.
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
107    */
108   protected abstract void flushBuffer(byte[] b, int offset, int len) throws IOException;
109   
110   /** Closes this stream to further operations. */
111   @Override
112   public void close() throws IOException {
113     flush();
114   }
115
116   /** Returns the current position in this file, where the next write will
117    * occur.
118    * @see #seek(long)
119    */
120   @Override
121   public long getFilePointer() {
122     return bufferStart + bufferPosition;
123   }
124
125   /** Sets current position in this file, where the next write will occur.
126    * @see #getFilePointer()
127    */
128   @Override
129   public void seek(long pos) throws IOException {
130     flush();
131     bufferStart = pos;
132   }
133
134   /** The number of bytes in the file. */
135   @Override
136   public abstract long length() throws IOException;
137
138
139 }