/** * 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. */ package org.apache.blur.store.blockcache_v2; import java.io.IOException; import java.util.Collection; import java.util.Set; import org.apache.blur.store.blockcache.LastModified; import org.apache.blur.store.hdfs.DirectoryDecorator; 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; public class CacheDirectory extends Directory implements DirectoryDecorator, LastModified { private final Directory _internal; private final String _directoryName; private final Cache _cache; private final String _shard; private final String _table; private final Set<String> _tableBlockCacheFileTypes; public CacheDirectory(String table, String shard, Directory directory, Cache cache, Set<String> tableBlockCacheFileTypes) { if (!(directory instanceof LastModified)) { throw new RuntimeException("Directory [" + directory + "] does not implement '" + LastModified.class.toString() + "'"); } _table = table; _shard = shard; _directoryName = notNull(table + "_" + shard); _internal = notNull(directory); _cache = notNull(cache); _tableBlockCacheFileTypes = tableBlockCacheFileTypes; } public String getShard() { return _shard; } public String getTable() { return _table; } public IndexInput openInput(String name, IOContext context) throws IOException { IndexInput indexInput = _internal.openInput(name, context); if (_cache.cacheFileForReading(this, name, context) || (_tableBlockCacheFileTypes != null && isCachableFile(name))) { return new CacheIndexInput(this, name, indexInput, _cache); } return indexInput; } private boolean isCachableFile(String name) { if (_tableBlockCacheFileTypes == null) { return true; } else if (_tableBlockCacheFileTypes.isEmpty()) { return false; } for (String ext : _tableBlockCacheFileTypes) { if (name.endsWith(ext)) { return true; } } return false; } public IndexOutput createOutput(String name, IOContext context) throws IOException { if (_cache.cacheFileForWriting(this, name, context) || (_tableBlockCacheFileTypes != null && isCachableFile(name))) { return new CacheIndexOutput(this, name, _cache, _internal, context); } return _internal.createOutput(name, context); } public void deleteFile(String name) throws IOException { _cache.removeFile(this, name); _internal.deleteFile(name); } public String[] listAll() throws IOException { return _internal.listAll(); } public boolean fileExists(String name) throws IOException { return _internal.fileExists(name); } public long fileLength(String name) throws IOException { return _internal.fileLength(name); } public void sync(Collection<String> names) throws IOException { _internal.sync(names); } public Lock makeLock(String name) { return _internal.makeLock(name); } public void clearLock(String name) throws IOException { _internal.clearLock(name); } public void close() throws IOException { _cache.releaseDirectory(this); _internal.close(); } public void setLockFactory(LockFactory lockFactory) throws IOException { _internal.setLockFactory(lockFactory); } public LockFactory getLockFactory() { return _internal.getLockFactory(); } public String getLockID() { return _internal.getLockID(); } public String toString() { return _internal.toString(); } public void copy(Directory to, String src, String dest, IOContext context) throws IOException { _internal.copy(to, src, dest, context); } public IndexInputSlicer createSlicer(String name, IOContext context) throws IOException { return _internal.createSlicer(name, context); } public String getDirectoryName() { return _directoryName; } @Override public long getFileModified(String name) throws IOException { return ((LastModified) _internal).getFileModified(name); } @Override public Directory getOriginalDirectory() { return _internal; } private static <T> T notNull(T t) { if (t == null) { throw new IllegalArgumentException("Cannot be null"); } return t; } }