pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / test-framework / java / org / apache / lucene / store / MockIndexOutputWrapper.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 import org.apache.lucene.util.LuceneTestCase;
23
24 /**
25  * Used by MockRAMDirectory to create an output stream that
26  * will throw an IOException on fake disk full, track max
27  * disk space actually used, and maybe throw random
28  * IOExceptions.
29  */
30
31 public class MockIndexOutputWrapper extends IndexOutput {
32   private MockDirectoryWrapper dir;
33   private final IndexOutput delegate;
34   private boolean first=true;
35   final String name;
36   
37   byte[] singleByte = new byte[1];
38
39   /** Construct an empty output buffer. */
40   public MockIndexOutputWrapper(MockDirectoryWrapper dir, IndexOutput delegate, String name) {
41     this.dir = dir;
42     this.name = name;
43     this.delegate = delegate;
44   }
45
46   @Override
47   public void close() throws IOException {
48     try {
49       dir.maybeThrowDeterministicException();
50     } finally {
51       delegate.close();
52       if (dir.trackDiskUsage) {
53         // Now compute actual disk usage & track the maxUsedSize
54         // in the MockDirectoryWrapper:
55         long size = dir.getRecomputedActualSizeInBytes();
56         if (size > dir.maxUsedSize) {
57           dir.maxUsedSize = size;
58         }
59       }
60       dir.removeIndexOutput(this, name);
61     }
62   }
63
64   @Override
65   public void flush() throws IOException {
66     dir.maybeThrowDeterministicException();
67     delegate.flush();
68   }
69
70   @Override
71   public void writeByte(byte b) throws IOException {
72     singleByte[0] = b;
73     writeBytes(singleByte, 0, 1);
74   }
75   
76   @Override
77   public void writeBytes(byte[] b, int offset, int len) throws IOException {
78     long freeSpace = dir.maxSize == 0 ? 0 : dir.maxSize - dir.sizeInBytes();
79     long realUsage = 0;
80
81     // If MockRAMDir crashed since we were opened, then
82     // don't write anything:
83     if (dir.crashed)
84       throw new IOException("MockRAMDirectory was crashed; cannot write to " + name);
85
86     // Enforce disk full:
87     if (dir.maxSize != 0 && freeSpace <= len) {
88       // Compute the real disk free.  This will greatly slow
89       // down our test but makes it more accurate:
90       realUsage = dir.getRecomputedActualSizeInBytes();
91       freeSpace = dir.maxSize - realUsage;
92     }
93
94     if (dir.maxSize != 0 && freeSpace <= len) {
95       if (freeSpace > 0) {
96         realUsage += freeSpace;
97         delegate.writeBytes(b, offset, (int) freeSpace);
98       }
99       if (realUsage > dir.maxUsedSize) {
100         dir.maxUsedSize = realUsage;
101       }
102       String message = "fake disk full at " + dir.getRecomputedActualSizeInBytes() + " bytes when writing " + name + " (file length=" + delegate.length();
103       if (freeSpace > 0) {
104         message += "; wrote " + freeSpace + " of " + len + " bytes";
105       }
106       message += ")";
107       if (LuceneTestCase.VERBOSE) {
108         System.out.println(Thread.currentThread().getName() + ": MDW: now throw fake disk full");
109         new Throwable().printStackTrace(System.out);
110       }
111       throw new IOException(message);
112     } else {
113       if (dir.randomState.nextInt(200) == 0) {
114         final int half = len/2;
115         delegate.writeBytes(b, offset, half);
116         Thread.yield();
117         delegate.writeBytes(b, offset+half, len-half);
118       } else {
119         delegate.writeBytes(b, offset, len);
120       }
121     }
122
123     dir.maybeThrowDeterministicException();
124
125     if (first) {
126       // Maybe throw random exception; only do this on first
127       // write to a new file:
128       first = false;
129       dir.maybeThrowIOException();
130     }
131   }
132
133   @Override
134   public long getFilePointer() {
135     return delegate.getFilePointer();
136   }
137
138   @Override
139   public void seek(long pos) throws IOException {
140     delegate.seek(pos);
141   }
142
143   @Override
144   public long length() throws IOException {
145     return delegate.length();
146   }
147
148   @Override
149   public void setLength(long length) throws IOException {
150     delegate.setLength(length);
151   }
152
153   @Override
154   public void copyBytes(DataInput input, long numBytes) throws IOException {
155     delegate.copyBytes(input, numBytes);
156     // TODO: we may need to check disk full here as well
157     dir.maybeThrowDeterministicException();
158   }
159 }