1 package org.apache.lucene.store;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import java.io.IOException;
22 import org.apache.lucene.util.LuceneTestCase;
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
31 public class MockIndexOutputWrapper extends IndexOutput {
32 private MockDirectoryWrapper dir;
33 private final IndexOutput delegate;
34 private boolean first=true;
37 byte[] singleByte = new byte[1];
39 /** Construct an empty output buffer. */
40 public MockIndexOutputWrapper(MockDirectoryWrapper dir, IndexOutput delegate, String name) {
43 this.delegate = delegate;
47 public void close() throws IOException {
49 dir.maybeThrowDeterministicException();
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;
60 dir.removeIndexOutput(this, name);
65 public void flush() throws IOException {
66 dir.maybeThrowDeterministicException();
71 public void writeByte(byte b) throws IOException {
73 writeBytes(singleByte, 0, 1);
77 public void writeBytes(byte[] b, int offset, int len) throws IOException {
78 long freeSpace = dir.maxSize == 0 ? 0 : dir.maxSize - dir.sizeInBytes();
81 // If MockRAMDir crashed since we were opened, then
82 // don't write anything:
84 throw new IOException("MockRAMDirectory was crashed; cannot write to " + name);
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;
94 if (dir.maxSize != 0 && freeSpace <= len) {
96 realUsage += freeSpace;
97 delegate.writeBytes(b, offset, (int) freeSpace);
99 if (realUsage > dir.maxUsedSize) {
100 dir.maxUsedSize = realUsage;
102 String message = "fake disk full at " + dir.getRecomputedActualSizeInBytes() + " bytes when writing " + name + " (file length=" + delegate.length();
104 message += "; wrote " + freeSpace + " of " + len + " bytes";
107 if (LuceneTestCase.VERBOSE) {
108 System.out.println(Thread.currentThread().getName() + ": MDW: now throw fake disk full");
109 new Throwable().printStackTrace(System.out);
111 throw new IOException(message);
113 if (dir.randomState.nextInt(200) == 0) {
114 final int half = len/2;
115 delegate.writeBytes(b, offset, half);
117 delegate.writeBytes(b, offset+half, len-half);
119 delegate.writeBytes(b, offset, len);
123 dir.maybeThrowDeterministicException();
126 // Maybe throw random exception; only do this on first
127 // write to a new file:
129 dir.maybeThrowIOException();
134 public long getFilePointer() {
135 return delegate.getFilePointer();
139 public void seek(long pos) throws IOException {
144 public long length() throws IOException {
145 return delegate.length();
149 public void setLength(long length) throws IOException {
150 delegate.setLength(length);
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();