Save This Page
Home » lucene-3.0.1-src » org.apache » lucene » store » [javadoc | source]
    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   /**
   23    * A memory-resident {@link IndexOutput} implementation.
   24    */
   25   
   26   public class RAMOutputStream extends IndexOutput {
   27     static final int BUFFER_SIZE = 1024;
   28   
   29     private RAMFile file;
   30   
   31     private byte[] currentBuffer;
   32     private int currentBufferIndex;
   33     
   34     private int bufferPosition;
   35     private long bufferStart;
   36     private int bufferLength;
   37   
   38     /** Construct an empty output buffer. */
   39     public RAMOutputStream() {
   40       this(new RAMFile());
   41     }
   42   
   43     RAMOutputStream(RAMFile f) {
   44       file = f;
   45   
   46       // make sure that we switch to the
   47       // first needed buffer lazily
   48       currentBufferIndex = -1;
   49       currentBuffer = null;
   50     }
   51   
   52     /** Copy the current contents of this buffer to the named output. */
   53     public void writeTo(IndexOutput out) throws IOException {
   54       flush();
   55       final long end = file.length;
   56       long pos = 0;
   57       int buffer = 0;
   58       while (pos < end) {
   59         int length = BUFFER_SIZE;
   60         long nextPos = pos + length;
   61         if (nextPos > end) {                        // at the last buffer
   62           length = (int)(end - pos);
   63         }
   64         out.writeBytes(file.getBuffer(buffer++), length);
   65         pos = nextPos;
   66       }
   67     }
   68   
   69     /** Resets this to an empty buffer. */
   70     public void reset() {
   71       try {
   72         seek(0);
   73       } catch (IOException e) {                     // should never happen
   74         throw new RuntimeException(e.toString());
   75       }
   76   
   77       file.setLength(0);
   78     }
   79   
   80     @Override
   81     public void close() throws IOException {
   82       flush();
   83     }
   84   
   85     @Override
   86     public void seek(long pos) throws IOException {
   87       // set the file length in case we seek back
   88       // and flush() has not been called yet
   89       setFileLength();
   90       if (pos < bufferStart || pos >= bufferStart + bufferLength) {
   91         currentBufferIndex = (int) (pos / BUFFER_SIZE);
   92         switchCurrentBuffer();
   93       }
   94   
   95       bufferPosition = (int) (pos % BUFFER_SIZE);
   96     }
   97   
   98     @Override
   99     public long length() {
  100       return file.length;
  101     }
  102   
  103     @Override
  104     public void writeByte(byte b) throws IOException {
  105       if (bufferPosition == bufferLength) {
  106         currentBufferIndex++;
  107         switchCurrentBuffer();
  108       }
  109       currentBuffer[bufferPosition++] = b;
  110     }
  111   
  112     @Override
  113     public void writeBytes(byte[] b, int offset, int len) throws IOException {
  114       assert b != null;
  115       while (len > 0) {
  116         if (bufferPosition ==  bufferLength) {
  117           currentBufferIndex++;
  118           switchCurrentBuffer();
  119         }
  120   
  121         int remainInBuffer = currentBuffer.length - bufferPosition;
  122         int bytesToCopy = len < remainInBuffer ? len : remainInBuffer;
  123         System.arraycopy(b, offset, currentBuffer, bufferPosition, bytesToCopy);
  124         offset += bytesToCopy;
  125         len -= bytesToCopy;
  126         bufferPosition += bytesToCopy;
  127       }
  128     }
  129   
  130     private final void switchCurrentBuffer() throws IOException {
  131       if (currentBufferIndex == file.numBuffers()) {
  132         currentBuffer = file.addBuffer(BUFFER_SIZE);
  133       } else {
  134         currentBuffer = file.getBuffer(currentBufferIndex);
  135       }
  136       bufferPosition = 0;
  137       bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
  138       bufferLength = currentBuffer.length;
  139     }
  140   
  141     private void setFileLength() {
  142       long pointer = bufferStart + bufferPosition;
  143       if (pointer > file.length) {
  144         file.setLength(pointer);
  145       }
  146     }
  147   
  148     @Override
  149     public void flush() throws IOException {
  150       file.setLastModified(System.currentTimeMillis());
  151       setFileLength();
  152     }
  153   
  154     @Override
  155     public long getFilePointer() {
  156       return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition;
  157     }
  158   
  159     /** Returns byte usage of all buffers. */
  160     public long sizeInBytes() {
  161       return file.numBuffers() * BUFFER_SIZE;
  162     }
  163   }

Save This Page
Home » lucene-3.0.1-src » org.apache » lucene » store » [javadoc | source]