org.elasticsearch.index.store.FsDirectoryService Maven / Gradle / Ivy
The newest version!
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index.store;
import com.google.common.collect.Sets;
import org.apache.lucene.store.*;
import org.apache.lucene.util.Constants;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.metrics.CounterMetric;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.settings.IndexSettingsService;
import org.elasticsearch.index.shard.ShardPath;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Set;
public class FsDirectoryService extends DirectoryService implements StoreRateLimiting.Listener, StoreRateLimiting.Provider {
protected final IndexStore indexStore;
private final CounterMetric rateLimitingTimeInNanos = new CounterMetric();
private final ShardPath path;
@Inject
public FsDirectoryService(IndexSettingsService indexSettingsService, IndexStore indexStore, ShardPath path) {
this(indexSettingsService.getSettings(), indexStore, path);
}
public FsDirectoryService(Settings indexSettings, IndexStore indexStore, ShardPath path) {
super(path.getShardId(), indexSettings);
this.path = path;
this.indexStore = indexStore;
}
@Override
public long throttleTimeInNanos() {
return rateLimitingTimeInNanos.count();
}
@Override
public StoreRateLimiting rateLimiting() {
return indexStore.rateLimiting();
}
public static LockFactory buildLockFactory(Settings indexSettings) {
String fsLock = indexSettings.get("index.store.fs.lock", indexSettings.get("index.store.fs.fs_lock", "native"));
LockFactory lockFactory;
if (fsLock.equals("native")) {
lockFactory = NativeFSLockFactory.INSTANCE;
} else if (fsLock.equals("simple")) {
lockFactory = SimpleFSLockFactory.INSTANCE;
} else {
throw new IllegalArgumentException("unrecognized fs_lock \"" + fsLock + "\": must be native or simple");
}
return lockFactory;
}
protected final LockFactory buildLockFactory() throws IOException {
return buildLockFactory(indexSettings);
}
@Override
public Directory newDirectory() throws IOException {
final Path location = path.resolveIndex();
Files.createDirectories(location);
Directory wrapped = newFSDirectory(location, buildLockFactory());
return new RateLimitedFSDirectory(wrapped, this, this) ;
}
@Override
public void onPause(long nanos) {
rateLimitingTimeInNanos.inc(nanos);
}
/*
* We are mmapping norms, docvalues as well as term dictionaries, all other files are served through NIOFS
* this provides good random access performance while not creating unnecessary mmaps for files like stored
* fields etc.
*/
private static final Set PRIMARY_EXTENSIONS = Collections.unmodifiableSet(Sets.newHashSet("nvd", "dvd", "tim"));
protected Directory newFSDirectory(Path location, LockFactory lockFactory) throws IOException {
final String storeType = indexSettings.get(IndexStoreModule.STORE_TYPE, IndexStoreModule.Type.DEFAULT.getSettingsKey());
if (IndexStoreModule.Type.FS.match(storeType) || IndexStoreModule.Type.DEFAULT.match(storeType)) {
final FSDirectory open = FSDirectory.open(location, lockFactory); // use lucene defaults
if (open instanceof MMapDirectory && Constants.WINDOWS == false) {
return newDefaultDir(location, (MMapDirectory) open, lockFactory);
}
return open;
} else if (IndexStoreModule.Type.SIMPLEFS.match(storeType)) {
return new SimpleFSDirectory(location, lockFactory);
} else if (IndexStoreModule.Type.NIOFS.match(storeType)) {
return new NIOFSDirectory(location, lockFactory);
} else if (IndexStoreModule.Type.MMAPFS.match(storeType)) {
return new MMapDirectory(location, lockFactory);
}
throw new IllegalArgumentException("No directory found for type [" + storeType + "]");
}
private Directory newDefaultDir(Path location, final MMapDirectory mmapDir, LockFactory lockFactory) throws IOException {
return new FileSwitchDirectory(PRIMARY_EXTENSIONS, mmapDir, new NIOFSDirectory(location, lockFactory), true) {
@Override
public String[] listAll() throws IOException {
// Avoid doing listAll twice:
return mmapDir.listAll();
}
};
}
}