Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.elasticsearch.core.internal.io;

import org.elasticsearch.common.Nullable;

import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.FileChannel;
Expand Down Expand Up @@ -64,6 +66,15 @@ public static void close(final Closeable... objects) throws IOException {
close(null, Arrays.asList(objects));
}

/**
* @see #close(Closeable...)
*/
public static void close(@Nullable Closeable closeable) throws IOException {
if (closeable != null) {
closeable.close();
}
}

/**
* Closes all given {@link Closeable}s. Some of the {@linkplain Closeable}s may be null; they are
* ignored. After everything is closed, the method adds any exceptions as suppressed to the
Expand Down Expand Up @@ -102,9 +113,7 @@ public static void close(final Exception ex, final Iterable<? extends Closeable>
Exception firstException = ex;
for (final Closeable object : objects) {
try {
if (object != null) {
object.close();
}
close(object);
} catch (final IOException | RuntimeException e) {
if (firstException == null) {
firstException = e;
Expand Down Expand Up @@ -142,14 +151,18 @@ public static void closeWhileHandlingException(final Closeable... objects) {
*/
public static void closeWhileHandlingException(final Iterable<? extends Closeable> objects) {
for (final Closeable object : objects) {
// noinspection EmptyCatchBlock
try {
if (object != null) {
object.close();
}
} catch (final IOException | RuntimeException e) {
closeWhileHandlingException(object);
}
}

}
/**
* @see #closeWhileHandlingException(Closeable...)
*/
public static void closeWhileHandlingException(final Closeable closeable) {
// noinspection EmptyCatchBlock
try {
close(closeable);
} catch (final IOException | RuntimeException e) {
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@

import org.elasticsearch.common.bytes.ReleasableBytesReference;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.lease.Releasables;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.util.ByteArray;
import org.elasticsearch.common.util.PageCacheRecycler;

/**
Expand All @@ -35,42 +33,18 @@
* stream should only be closed after the bytes have been output or copied
* elsewhere.
*/
public class ReleasableBytesStreamOutput extends BytesStreamOutput
implements Releasable {

private Releasable releasable;
public class ReleasableBytesStreamOutput extends BytesStreamOutput implements Releasable {

public ReleasableBytesStreamOutput(BigArrays bigarrays) {
this(PageCacheRecycler.PAGE_SIZE_IN_BYTES, bigarrays);
}

public ReleasableBytesStreamOutput(int expectedSize, BigArrays bigArrays) {
super(expectedSize, bigArrays);
this.releasable = Releasables.releaseOnce(this.bytes);
}

@Override
public void close() {
Releasables.close(releasable);
}

@Override
void ensureCapacity(long offset) {
final ByteArray prevBytes = this.bytes;
super.ensureCapacity(offset);
if (prevBytes != this.bytes) {
// re-create the releasable with the new reference
releasable = Releasables.releaseOnce(this.bytes);
}
}

@Override
public void reset() {
final ByteArray prevBytes = this.bytes;
super.reset();
if (prevBytes != this.bytes) {
// re-create the releasable with the new reference
releasable = Releasables.releaseOnce(this.bytes);
}
bytes.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ public static Releasable wrap(final Releasable... releasables) {
}

/**
* Equivalent to {@link #wrap(Releasable...)} but can be called multiple times without double releasing.
* Wraps a {@link Releasable} such that its {@link Releasable#close()} method can be called multiple times without double releasing.
*/
public static Releasable releaseOnce(final Releasable... releasables) {
public static Releasable releaseOnce(final Releasable releasable) {
final AtomicBoolean released = new AtomicBoolean(false);
return () -> {
if (released.compareAndSet(false, true)) {
close(releasables);
releasable.close();
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public class ReleasablesTests extends ESTestCase {

public void testReleaseOnce() {
AtomicInteger count = new AtomicInteger(0);
Releasable releasable = Releasables.releaseOnce(count::incrementAndGet, count::incrementAndGet);
Releasable releasable = Releasables.releaseOnce(count::incrementAndGet);
assertEquals(0, count.get());
releasable.close();
assertEquals(2, count.get());
assertEquals(1, count.get());
releasable.close();
assertEquals(2, count.get());
assertEquals(1, count.get());
}
}