001: package org.apache.lucene.store;
002:
003: import java.io.IOException;
004:
005: /**
006: * A simple base class that performs index output memory based buffering. The buffer size if configurable.
007: *
008: * @author kimchy
009: */
010: // NEED TO BE MONITORED AGAINST LUCENE
011: public abstract class ConfigurableBufferedIndexOutput extends
012: IndexOutput {
013:
014: public static final int DEFAULT_BUFFER_SIZE = 16384;
015:
016: private byte[] buffer;
017: private long bufferStart = 0; // position in file of buffer
018: private int bufferPosition = 0; // position in buffer
019:
020: protected int bufferSize = DEFAULT_BUFFER_SIZE;
021:
022: protected void initBuffer(int bufferSize) {
023: this .bufferSize = bufferSize;
024: this .buffer = new byte[bufferSize];
025: }
026:
027: /**
028: * Writes a single byte.
029: *
030: * @see IndexInput#readByte()
031: */
032: public void writeByte(byte b) throws IOException {
033: if (bufferPosition >= bufferSize)
034: flush();
035: buffer[bufferPosition++] = b;
036: }
037:
038: /**
039: * Writes an array of bytes.
040: *
041: * @param b the bytes to write
042: * @param length the number of bytes to write
043: * @see IndexInput#readBytes(byte[],int,int)
044: */
045: public void writeBytes(byte[] b, int offset, int length)
046: throws IOException {
047: int bytesLeft = bufferSize - bufferPosition;
048: // is there enough space in the buffer?
049: if (bytesLeft >= length) {
050: // we add the data to the end of the buffer
051: System.arraycopy(b, offset, buffer, bufferPosition, length);
052: bufferPosition += length;
053: // if the buffer is full, flush it
054: if (bufferSize - bufferPosition == 0)
055: flush();
056: } else {
057: // is data larger then buffer?
058: if (length > bufferSize) {
059: // we flush the buffer
060: if (bufferPosition > 0)
061: flush();
062: // and write data at once
063: flushBuffer(b, offset, length);
064: bufferStart += length;
065: } else {
066: // we fill/flush the buffer (until the input is written)
067: int pos = 0; // position in the input data
068: int pieceLength;
069: while (pos < length) {
070: pieceLength = (length - pos < bytesLeft) ? length
071: - pos : bytesLeft;
072: System.arraycopy(b, pos + offset, buffer,
073: bufferPosition, pieceLength);
074: pos += pieceLength;
075: bufferPosition += pieceLength;
076: // if the buffer is full, flush it
077: bytesLeft = bufferSize - bufferPosition;
078: if (bytesLeft == 0) {
079: flush();
080: bytesLeft = bufferSize;
081: }
082: }
083: }
084: }
085: }
086:
087: /**
088: * Forces any buffered output to be written.
089: */
090: public void flush() throws IOException {
091: flushBuffer(buffer, bufferPosition);
092: bufferStart += bufferPosition;
093: bufferPosition = 0;
094: }
095:
096: /**
097: * Expert: implements buffer write. Writes bytes at the current position in
098: * the output.
099: *
100: * @param b the bytes to write
101: * @param len the number of bytes to write
102: */
103: private void flushBuffer(byte[] b, int len) throws IOException {
104: flushBuffer(b, 0, len);
105: }
106:
107: /**
108: * Expert: implements buffer write. Writes bytes at the current position in
109: * the output.
110: *
111: * @param b the bytes to write
112: * @param offset the offset in the byte array
113: * @param len the number of bytes to write
114: */
115: protected abstract void flushBuffer(byte[] b, int offset, int len)
116: throws IOException;
117:
118: /**
119: * Closes this stream to further operations.
120: */
121: public void close() throws IOException {
122: flush();
123: }
124:
125: /**
126: * Returns the current position in this file, where the next write will
127: * occur.
128: *
129: * @see #seek(long)
130: */
131: public long getFilePointer() {
132: return bufferStart + bufferPosition;
133: }
134:
135: /**
136: * Sets current position in this file, where the next write will occur.
137: *
138: * @see #getFilePointer()
139: */
140: public void seek(long pos) throws IOException {
141: flush();
142: bufferStart = pos;
143: }
144:
145: /**
146: * The number of bytes in the file.
147: */
148: public abstract long length() throws IOException;
149:
150: }
|