X-Git-Url: https://git.mdrn.pl/pylucene.git/blobdiff_plain/a2e61f0c04805cfcb8706176758d1283c7e3a55c..aaeed5504b982cf3545252ab528713250aa33eed:/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/store/RAMOutputStream.java diff --git a/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/store/RAMOutputStream.java b/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/store/RAMOutputStream.java new file mode 100644 index 0000000..b07fe07 --- /dev/null +++ b/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/store/RAMOutputStream.java @@ -0,0 +1,185 @@ +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; + +/** + * A memory-resident {@link IndexOutput} implementation. + * + * @lucene.internal + */ +public class RAMOutputStream extends IndexOutput { + static final int BUFFER_SIZE = 1024; + + private RAMFile file; + + private byte[] currentBuffer; + private int currentBufferIndex; + + private int bufferPosition; + private long bufferStart; + private int bufferLength; + + /** Construct an empty output buffer. */ + public RAMOutputStream() { + this(new RAMFile()); + } + + public RAMOutputStream(RAMFile f) { + file = f; + + // make sure that we switch to the + // first needed buffer lazily + currentBufferIndex = -1; + currentBuffer = null; + } + + /** Copy the current contents of this buffer to the named output. */ + public void writeTo(IndexOutput out) throws IOException { + flush(); + final long end = file.length; + long pos = 0; + int buffer = 0; + while (pos < end) { + int length = BUFFER_SIZE; + long nextPos = pos + length; + if (nextPos > end) { // at the last buffer + length = (int)(end - pos); + } + out.writeBytes(file.getBuffer(buffer++), length); + pos = nextPos; + } + } + + /** Resets this to an empty file. */ + public void reset() { + currentBuffer = null; + currentBufferIndex = -1; + bufferPosition = 0; + bufferStart = 0; + bufferLength = 0; + file.setLength(0); + } + + @Override + public void close() throws IOException { + flush(); + } + + @Override + public void seek(long pos) throws IOException { + // set the file length in case we seek back + // and flush() has not been called yet + setFileLength(); + if (pos < bufferStart || pos >= bufferStart + bufferLength) { + currentBufferIndex = (int) (pos / BUFFER_SIZE); + switchCurrentBuffer(); + } + + bufferPosition = (int) (pos % BUFFER_SIZE); + } + + @Override + public long length() { + return file.length; + } + + @Override + public void writeByte(byte b) throws IOException { + if (bufferPosition == bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + currentBuffer[bufferPosition++] = b; + } + + @Override + public void writeBytes(byte[] b, int offset, int len) throws IOException { + assert b != null; + while (len > 0) { + if (bufferPosition == bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + + int remainInBuffer = currentBuffer.length - bufferPosition; + int bytesToCopy = len < remainInBuffer ? len : remainInBuffer; + System.arraycopy(b, offset, currentBuffer, bufferPosition, bytesToCopy); + offset += bytesToCopy; + len -= bytesToCopy; + bufferPosition += bytesToCopy; + } + } + + private final void switchCurrentBuffer() throws IOException { + if (currentBufferIndex == file.numBuffers()) { + currentBuffer = file.addBuffer(BUFFER_SIZE); + } else { + currentBuffer = file.getBuffer(currentBufferIndex); + } + bufferPosition = 0; + bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; + bufferLength = currentBuffer.length; + } + + private void setFileLength() { + long pointer = bufferStart + bufferPosition; + if (pointer > file.length) { + file.setLength(pointer); + } + } + + @Override + public void flush() throws IOException { + file.setLastModified(System.currentTimeMillis()); + setFileLength(); + } + + @Override + public long getFilePointer() { + return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; + } + + /** Returns byte usage of all buffers. */ + public long sizeInBytes() { + return file.numBuffers() * BUFFER_SIZE; + } + + @Override + public void copyBytes(DataInput input, long numBytes) throws IOException { + assert numBytes >= 0: "numBytes=" + numBytes; + + while (numBytes > 0) { + if (bufferPosition == bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + + int toCopy = currentBuffer.length - bufferPosition; + if (numBytes < toCopy) { + toCopy = (int) numBytes; + } + input.readBytes(currentBuffer, bufferPosition, toCopy, false); + numBytes -= toCopy; + bufferPosition += toCopy; + } + + } + +}