Skip to content

Commit

Permalink
Use AutoCloseable in some places where we previously used SafeCloseab…
Browse files Browse the repository at this point in the history
…le, and standardize some SafeCloseable utilities (#5274)
  • Loading branch information
rcaudy authored Mar 21, 2024
1 parent a6d33ce commit dd6ace7
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 58 deletions.
50 changes: 27 additions & 23 deletions Util/src/main/java/io/deephaven/util/SafeCloseable.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,43 @@
*/
public interface SafeCloseable extends AutoCloseable {

@Override
void close();

/**
* {@link #close() Close} all non-{@code null} SafeCloseable arguments.
* {@link #close() Close} all non-{@code null} {@link AutoCloseable} arguments.
*
* @param safeCloseables SafeCloseables to {@link #close() close}
* @param autoCloseables {@link AutoCloseable AutoCloseables} to {@link #close() close}
*/
static void closeAll(@NotNull final SafeCloseable... safeCloseables) {
closeAll(Arrays.asList(safeCloseables).iterator());
static void closeAll(@NotNull final AutoCloseable... autoCloseables) {
closeAll(Arrays.asList(autoCloseables).iterator());
}

/**
* {@link #close() Close} all non-{@code null} SafeCloseable elements. Terminates the {@code stream}.
* {@link #close() Close} all non-{@code null} {@link AutoCloseable} elements. Terminates the {@code stream}.
*
* @param stream the stream of SafeCloseables to {@link #close() close}
* @param <SCT> the safe closable type
* @param stream The stream of {@link AutoCloseable AutoCloseables} to {@link #close() close}
* @param <ACT> the auto closable type
*/
static <SCT extends SafeCloseable> void closeAll(@NotNull final Stream<SCT> stream) {
static <ACT extends AutoCloseable> void closeAll(@NotNull final Stream<ACT> stream) {
closeAll(stream.iterator());
}

/**
* {@link #close() Close} all non-{@code null} SafeCloseable elements. Consumes the {@code iterator}.
* {@link #close() Close} all non-{@code null} {@link AutoCloseable} elements. Consumes the {@code iterator}.
*
* @param iterator the iterator of SafeCloseables to {@link #close() close}
* @param <SCT> the safe closable type
* @param iterator The iterator of {@link AutoCloseable AutoCloseables} to {@link #close() close}
* @param <ACT> the auto closable type
*/
static <SCT extends SafeCloseable> void closeAll(@NotNull final Iterator<SCT> iterator) {
static <ACT extends AutoCloseable> void closeAll(@NotNull final Iterator<ACT> iterator) {
List<Exception> exceptions = null;
while (iterator.hasNext()) {
final SafeCloseable safeCloseable = iterator.next();
if (safeCloseable == null) {
final AutoCloseable autoCloseable = iterator.next();
if (autoCloseable == null) {
continue;
}
try {
safeCloseable.close();
autoCloseable.close();
} catch (Exception e) {
if (exceptions == null) {
exceptions = new ArrayList<>();
Expand All @@ -67,16 +70,17 @@ static <SCT extends SafeCloseable> void closeAll(@NotNull final Iterator<SCT> it
}

/**
* {@link #close() Close} a single SafeCloseable argument if it is non-{@code null}.
* {@link #close() Close} a single {@link AutoCloseable} argument if it is non-{@code null}.
*
* @param safeCloseable The SafeCloseable to {@link #close() close}
* @param autoCloseable The {@link AutoCloseable} to {@link #close() close}
*/
static void closeIfNonNull(@Nullable final SafeCloseable safeCloseable) {
if (safeCloseable != null) {
safeCloseable.close();
static void closeIfNonNull(@Nullable final AutoCloseable autoCloseable) {
if (autoCloseable != null) {
try {
autoCloseable.close();
} catch (Exception e) {
throw new UncheckedDeephavenException("Exception while closing resource", e);
}
}
}

@Override
void close();
}
20 changes: 10 additions & 10 deletions Util/src/main/java/io/deephaven/util/SafeCloseableArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@
import java.util.List;

/**
* {@link SafeCloseable} that will close non-null values inside of an array.
* {@link SafeCloseable} that will close non-null values inside an array.
* <p>
* The common use case is to create an array; use the SafeCloseableArray in an ignored try-with-resources variable, and
* then populate the array within the loop. If you fail before populating the array nothing is closed, if you fail
* during or after populating the array the created values are closed.
* then populate the array within the loop. If the operation fails before populating the array nothing is closed. If the
* operation fails during or after populating the array the populated values are closed.
*/
public class SafeCloseableArray<SCT extends SafeCloseable> implements SafeCloseable {
public class SafeCloseableArray<ACT extends AutoCloseable> implements SafeCloseable {

private final SCT[] array;
private final ACT[] array;

public SafeCloseableArray(SCT[] entries) {
public SafeCloseableArray(ACT[] entries) {
array = entries;
}

Expand All @@ -30,16 +30,16 @@ public final void close() {
}

/**
* Close an array of {@link SafeCloseable} entries, ignoring {@code null} elements and assigning elements to
* Close an array of {@link AutoCloseable} entries, ignoring {@code null} elements and assigning elements to
* {@code null} as they are cleared.
*
*
* @param array The array to operate one
*/
public static <SCT extends SafeCloseable> void close(@NotNull final SCT[] array) {
public static <ACT extends AutoCloseable> void close(final ACT @NotNull [] array) {
final int length = array.length;
List<Exception> exceptions = null;
for (int ii = 0; ii < length; ii++) {
try (final SafeCloseable ignored = array[ii]) {
try (final AutoCloseable ignored = array[ii]) {
array[ii] = null;
} catch (Exception e) {
if (exceptions == null) {
Expand Down
27 changes: 13 additions & 14 deletions Util/src/main/java/io/deephaven/util/SafeCloseableList.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,34 @@
import java.util.stream.Collector;

/**
* {@link SafeCloseable} that will close an internal list of other {@link SafeCloseable}s.
* {@link SafeCloseable} that will close an internal list of {@link AutoCloseable AutoCloseables}.
*/
public class SafeCloseableList implements SafeCloseable {

private final List<SafeCloseable> list = new ArrayList<>();
private final List<AutoCloseable> list = new ArrayList<>();

public SafeCloseableList() {}

public SafeCloseableList(SafeCloseable... entries) {
public SafeCloseableList(AutoCloseable... entries) {
this(Arrays.asList(entries));
}

public SafeCloseableList(Collection<SafeCloseable> entries) {
public SafeCloseableList(Collection<AutoCloseable> entries) {
list.addAll(entries);
}

public final void addAll(@NotNull final List<SafeCloseable> closeableList) {
public final void addAll(@NotNull final List<AutoCloseable> closeableList) {
list.addAll(closeableList);
}

public final <T extends SafeCloseable> T[] addArray(@Nullable final T[] closeables) {
public final <T extends AutoCloseable> T[] addArray(@Nullable final T[] closeables) {
if (closeables != null) {
list.add(new SafeCloseableArray<>(closeables));
}
return closeables;
}

public final <T extends SafeCloseable> T add(final T closeable) {
public final <T extends AutoCloseable> T add(final T closeable) {
list.add(closeable);
return closeable;
}
Expand All @@ -56,23 +56,22 @@ public final void clear() {

@Override
public final void close() {
for (final SafeCloseable closeable : list) {
if (closeable != null) {
closeable.close();
}
try {
SafeCloseable.closeAll(list.iterator());
} finally {
list.clear();
}
list.clear();
}

public static final Collector<SafeCloseable, SafeCloseableList, SafeCloseableList> COLLECTOR = new Collector<>() {
public static final Collector<AutoCloseable, SafeCloseableList, SafeCloseableList> COLLECTOR = new Collector<>() {

@Override
public Supplier<SafeCloseableList> supplier() {
return SafeCloseableList::new;
}

@Override
public BiConsumer<SafeCloseableList, SafeCloseable> accumulator() {
public BiConsumer<SafeCloseableList, AutoCloseable> accumulator() {
return SafeCloseableList::add;
}

Expand Down
10 changes: 3 additions & 7 deletions Util/src/main/java/io/deephaven/util/SafeCloseablePair.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import java.util.Objects;

public class SafeCloseablePair<A extends SafeCloseable, B extends SafeCloseable> implements SafeCloseable {
public class SafeCloseablePair<A extends AutoCloseable, B extends AutoCloseable> implements SafeCloseable {

public final A first;
public final B second;

Expand All @@ -32,12 +33,7 @@ public int hashCode() {

@Override
public void close() {
if (this.first != null) {
this.first.close();
}
if (this.second != null) {
this.second.close();
}
SafeCloseable.closeAll(first, second);
}

public static <AP extends SafeCloseable, BP extends SafeCloseable, A extends AP, B extends BP> SafeCloseablePair<AP, BP> downcast(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
package io.deephaven.engine.table.iterators;

import io.deephaven.engine.primitive.iterator.CloseableIterator;
import io.deephaven.util.SafeCloseable;

/**
* Iteration support for values supplied by a column.
*
* @apiNote ColumnIterators must be explicitly {@link #close() closed} or used until exhausted in order to avoid
* resource leaks.
*/
public interface ColumnIterator<DATA_TYPE> extends CloseableIterator<DATA_TYPE> {
public interface ColumnIterator<DATA_TYPE> extends CloseableIterator<DATA_TYPE>, SafeCloseable {

@Override
default void close() {}

/**
* @return The number of elements remaining in this ColumnIterator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//
package io.deephaven.engine.primitive.iterator;

import io.deephaven.util.SafeCloseable;
import io.deephaven.util.SafeCloseableArray;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -17,14 +16,14 @@
import java.util.stream.StreamSupport;

/**
* This interface extends {@link Iterator} and {@link SafeCloseable} in order to allow for iterators that acquire
* This interface extends {@link Iterator} and {@link AutoCloseable} in order to allow for iterators that acquire
* resources that must be released. Such iterators must document this need, and appropriate measures (e.g. a
* try-with-resources block) should be taken to ensure that they are {@link #close() closed}. Methods that return
* streams over CloseableIterator instances should ensure that closing the resulting {@link Stream},
* {@link java.util.stream.IntStream IntStream}, {@link java.util.stream.LongStream LongStream}, or
* {@link java.util.stream.DoubleStream DoubleStream} will also close the iterator.
*/
public interface CloseableIterator<TYPE> extends Iterator<TYPE>, SafeCloseable {
public interface CloseableIterator<TYPE> extends Iterator<TYPE>, AutoCloseable {

/**
* Create a {@link Stream} over the remaining elements of this CloseableIterator. Closing the result will close this
Expand Down

0 comments on commit dd6ace7

Please sign in to comment.