package org.apache.blur.mapreduce.lib; /** * 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; import java.util.Collection; import org.apache.blur.log.Log; import org.apache.blur.log.LogFactory; import org.apache.hadoop.util.Progressable; import org.apache.lucene.store.BufferedIndexInput; import org.apache.lucene.store.BufferedIndexOutput; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.Lock; import org.apache.lucene.store.LockFactory; /** * The {@link ProgressableDirectory} allows for progress to be recorded while * Lucene is blocked and merging. This prevents the Task from being killed after * not reporting progress because of the blocked merge. */ public class ProgressableDirectory extends Directory { private static final Log LOG = LogFactory.getLog(ProgressableDirectory.class); private final Directory _directory; private final Progressable _progressable; public ProgressableDirectory(Directory directory, Progressable progressable) { _directory = directory; if (progressable == null) { LOG.warn("Progressable is null."); _progressable = new Progressable() { @Override public void progress() { } }; } else { _progressable = progressable; } } @Override public void clearLock(String name) throws IOException { _directory.clearLock(name); } @Override public void close() throws IOException { _directory.close(); } private IndexInput wrapInput(String name, IndexInput openInput) { return new ProgressableIndexInput(name, openInput, 16384, _progressable); } private IndexOutput wrapOutput(IndexOutput createOutput) { return new ProgressableIndexOutput(createOutput, _progressable); } public IndexOutput createOutput(String name, IOContext context) throws IOException { return wrapOutput(_directory.createOutput(name, context)); } @Override public void deleteFile(String name) throws IOException { _directory.deleteFile(name); } @Override public boolean equals(Object obj) { return _directory.equals(obj); } @Override public boolean fileExists(String name) throws IOException { return _directory.fileExists(name); } @Override public long fileLength(String name) throws IOException { return _directory.fileLength(name); } @Override public LockFactory getLockFactory() { return _directory.getLockFactory(); } @Override public String getLockID() { return _directory.getLockID(); } @Override public int hashCode() { return _directory.hashCode(); } @Override public String[] listAll() throws IOException { return _directory.listAll(); } @Override public Lock makeLock(String name) { return _directory.makeLock(name); } @Override public IndexInput openInput(String name, IOContext context) throws IOException { return wrapInput(name, _directory.openInput(name, context)); } @Override public void setLockFactory(LockFactory lockFactory) throws IOException { _directory.setLockFactory(lockFactory); } @Override public void sync(Collection<String> names) throws IOException { _directory.sync(names); } @Override public String toString() { return _directory.toString(); } static class ProgressableIndexOutput extends BufferedIndexOutput { private Progressable _progressable; private IndexOutput _indexOutput; public ProgressableIndexOutput(IndexOutput indexOutput, Progressable progressable) { _indexOutput = indexOutput; _progressable = progressable; } @Override protected void flushBuffer(byte[] b, int offset, int len) throws IOException { _indexOutput.writeBytes(b, offset, len); _progressable.progress(); } @Override public long length() throws IOException { return _indexOutput.length(); } @Override public void close() throws IOException { super.close(); _indexOutput.close(); _progressable.progress(); } } static class ProgressableIndexInput extends BufferedIndexInput { private IndexInput _indexInput; private final long _length; private Progressable _progressable; ProgressableIndexInput(String name, IndexInput indexInput, int buffer, Progressable progressable) { super("ProgressableIndexInput(" + indexInput.toString() + ")", buffer); _indexInput = indexInput; _length = indexInput.length(); _progressable = progressable; } @Override protected void readInternal(byte[] b, int offset, int length) throws IOException { long filePointer = getFilePointer(); if (filePointer != _indexInput.getFilePointer()) { _indexInput.seek(filePointer); } _indexInput.readBytes(b, offset, length); _progressable.progress(); } @Override protected void seekInternal(long pos) throws IOException { } @Override public void close() throws IOException { _indexInput.close(); } @Override public long length() { return _length; } @Override public ProgressableIndexInput clone() { ProgressableIndexInput clone = (ProgressableIndexInput) super.clone(); clone._indexInput = (IndexInput) _indexInput.clone(); return clone; } } }