Skip to content

Commit

Permalink
Allow Lucene directory implementations to estimate their size
Browse files Browse the repository at this point in the history
Relates ES-5995
  • Loading branch information
tlrx committed Jul 19, 2023
1 parent 00b5050 commit d973c97
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
package org.elasticsearch.index.store;

import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FilterDirectory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexOutput;
import org.elasticsearch.common.lucene.store.FilterIndexOutput;
Expand All @@ -22,7 +21,7 @@
import java.nio.file.AccessDeniedException;
import java.nio.file.NoSuchFileException;

final class ByteSizeCachingDirectory extends FilterDirectory {
final class ByteSizeCachingDirectory extends ByteSizeDirectory {

private static class SizeAndModCount {
final long size;
Expand Down Expand Up @@ -57,7 +56,7 @@ private static long estimateSizeInBytes(Directory directory) throws IOException

ByteSizeCachingDirectory(Directory in, TimeValue refreshInterval) {
super(in);
size = new SingleObjectCache<SizeAndModCount>(refreshInterval, new SizeAndModCount(0L, -1L, true)) {
size = new SingleObjectCache<>(refreshInterval, new SizeAndModCount(0L, -1L, true)) {
@Override
protected SizeAndModCount refresh() {
// It is ok for the size of the directory to be more recent than
Expand Down Expand Up @@ -103,8 +102,8 @@ protected boolean needsRefresh() {
};
}

/** Return the cumulative size of all files in this directory. */
long estimateSizeInBytes() throws IOException {
@Override
public long estimateSizeInBytes() throws IOException {
try {
return size.getOrRefresh().size;
} catch (UncheckedIOException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.index.store;

import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FilterDirectory;

import java.io.IOException;

public abstract class ByteSizeDirectory extends FilterDirectory {

protected ByteSizeDirectory(Directory in) {
super(in);
}

/** Return the cumulative size of all files in this directory. */
public abstract long estimateSizeInBytes() throws IOException;
}
30 changes: 20 additions & 10 deletions server/src/main/java/org/elasticsearch/index/store/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ public Store(ShardId shardId, IndexSettings indexSettings, Directory directory,

public Store(ShardId shardId, IndexSettings indexSettings, Directory directory, ShardLock shardLock, OnClose onClose) {
super(shardId, indexSettings);
final TimeValue refreshInterval = indexSettings.getValue(INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING);
logger.debug("store stats are refreshed with refresh_interval [{}]", refreshInterval);
ByteSizeCachingDirectory sizeCachingDir = new ByteSizeCachingDirectory(directory, refreshInterval);
this.directory = new StoreDirectory(sizeCachingDir, Loggers.getLogger("index.store.deletes", shardId));
this.directory = new StoreDirectory(
byteSizeDirectory(directory, indexSettings, logger),
Loggers.getLogger("index.store.deletes", shardId)
);
this.shardLock = shardLock;
this.onClose = onClose;

Expand Down Expand Up @@ -355,7 +355,7 @@ public CheckIndex.Status checkIndex(PrintStream out) throws IOException {
*/
public StoreStats stats(long reservedBytes, LongUnaryOperator localSizeFunction) throws IOException {
ensureOpen();
long sizeInBytes = directory.estimateSize();
long sizeInBytes = directory.estimateSizeInBytes();
return new StoreStats(localSizeFunction.applyAsLong(sizeInBytes), sizeInBytes, reservedBytes);
}

Expand Down Expand Up @@ -443,6 +443,16 @@ private void closeInternal() {
}
}

private static ByteSizeDirectory byteSizeDirectory(Directory directory, IndexSettings indexSettings, Logger logger) {
if (directory instanceof ByteSizeDirectory byteSizeDirectory) {
return byteSizeDirectory;
} else {
final TimeValue refreshInterval = indexSettings.getValue(INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING);
logger.debug("store stats are refreshed with {} [{}]", INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING.getKey(), refreshInterval);
return new ByteSizeCachingDirectory(directory, refreshInterval);
}
}

/**
* Reads a MetadataSnapshot from the given index locations or returns an empty snapshot if it can't be read.
*
Expand Down Expand Up @@ -720,18 +730,18 @@ public void beforeClose() {
shardLock.setDetails("closing shard");
}

static final class StoreDirectory extends FilterDirectory {
static final class StoreDirectory extends ByteSizeDirectory {

private final Logger deletesLogger;

StoreDirectory(ByteSizeCachingDirectory delegateDirectory, Logger deletesLogger) {
StoreDirectory(ByteSizeDirectory delegateDirectory, Logger deletesLogger) {
super(delegateDirectory);
this.deletesLogger = deletesLogger;
}

/** Estimate the cumulative size of all files in this directory in bytes. */
long estimateSize() throws IOException {
return ((ByteSizeCachingDirectory) getDelegate()).estimateSizeInBytes();
@Override
public long estimateSizeInBytes() throws IOException {
return ((ByteSizeDirectory) getDelegate()).estimateSizeInBytes();
}

@Override
Expand Down

0 comments on commit d973c97

Please sign in to comment.