pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / store / RAMInputStream.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 import java.io.EOFException;
22
23 /** A memory-resident {@link IndexInput} implementation. 
24  *  
25  *  @lucene.internal */
26 public class RAMInputStream extends IndexInput implements Cloneable {
27   static final int BUFFER_SIZE = RAMOutputStream.BUFFER_SIZE;
28
29   private RAMFile file;
30   private long length;
31
32   private byte[] currentBuffer;
33   private int currentBufferIndex;
34   
35   private int bufferPosition;
36   private long bufferStart;
37   private int bufferLength;
38
39   /** Please pass String name */
40   @Deprecated
41   public RAMInputStream(RAMFile f) throws IOException {
42     this("anonymous", f);
43   }
44
45   public RAMInputStream(String name, RAMFile f) throws IOException {
46     super("RAMInputStream(name=" + name + ")");
47     file = f;
48     length = file.length;
49     if (length/BUFFER_SIZE >= Integer.MAX_VALUE) {
50       throw new IOException("RAMInputStream too large length=" + length + ": " + name); 
51     }
52
53     // make sure that we switch to the
54     // first needed buffer lazily
55     currentBufferIndex = -1;
56     currentBuffer = null;
57   }
58
59   @Override
60   public void close() {
61     // nothing to do here
62   }
63
64   @Override
65   public long length() {
66     return length;
67   }
68
69   @Override
70   public byte readByte() throws IOException {
71     if (bufferPosition >= bufferLength) {
72       currentBufferIndex++;
73       switchCurrentBuffer(true);
74     }
75     return currentBuffer[bufferPosition++];
76   }
77
78   @Override
79   public void readBytes(byte[] b, int offset, int len) throws IOException {
80     while (len > 0) {
81       if (bufferPosition >= bufferLength) {
82         currentBufferIndex++;
83         switchCurrentBuffer(true);
84       }
85
86       int remainInBuffer = bufferLength - bufferPosition;
87       int bytesToCopy = len < remainInBuffer ? len : remainInBuffer;
88       System.arraycopy(currentBuffer, bufferPosition, b, offset, bytesToCopy);
89       offset += bytesToCopy;
90       len -= bytesToCopy;
91       bufferPosition += bytesToCopy;
92     }
93   }
94
95   private final void switchCurrentBuffer(boolean enforceEOF) throws IOException {
96     bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
97     if (currentBufferIndex >= file.numBuffers()) {
98       // end of file reached, no more buffers left
99       if (enforceEOF) {
100         throw new EOFException("Read past EOF (resource: " + this + ")");
101       } else {
102         // Force EOF if a read takes place at this position
103         currentBufferIndex--;
104         bufferPosition = BUFFER_SIZE;
105       }
106     } else {
107       currentBuffer = file.getBuffer(currentBufferIndex);
108       bufferPosition = 0;
109       long buflen = length - bufferStart;
110       bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int) buflen;
111     }
112   }
113
114   @Override
115   public void copyBytes(IndexOutput out, long numBytes) throws IOException {
116     assert numBytes >= 0: "numBytes=" + numBytes;
117     
118     long left = numBytes;
119     while (left > 0) {
120       if (bufferPosition == bufferLength) {
121         ++currentBufferIndex;
122         switchCurrentBuffer(true);
123       }
124       
125       final int bytesInBuffer = bufferLength - bufferPosition;
126       final int toCopy = (int) (bytesInBuffer < left ? bytesInBuffer : left);
127       out.writeBytes(currentBuffer, bufferPosition, toCopy);
128       bufferPosition += toCopy;
129       left -= toCopy;
130     }
131     
132     assert left == 0: "Insufficient bytes to copy: numBytes=" + numBytes + " copied=" + (numBytes - left);
133   }
134   
135   @Override
136   public long getFilePointer() {
137     return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition;
138   }
139
140   @Override
141   public void seek(long pos) throws IOException {
142     if (currentBuffer==null || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE) {
143       currentBufferIndex = (int) (pos / BUFFER_SIZE);
144       switchCurrentBuffer(false);
145     }
146     bufferPosition = (int) (pos % BUFFER_SIZE);
147   }
148 }