/*
* Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.HashMap;
import org.h2.engine.SysProperties;
import org.h2.message.DbException;
import org.h2.store.fs.FileUtils;
This class deletes temporary files when they are not used any longer.
/**
* This class deletes temporary files when they are not used any longer.
*/
public class TempFileDeleter {
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private final HashMap<PhantomReference<?>, Object> refMap = new HashMap<>();
private TempFileDeleter() {
// utility class
}
public static TempFileDeleter getInstance() {
return new TempFileDeleter();
}
Add a file or a closeable to the list of temporary objects to delete. The
file is deleted once the file object is garbage collected.
Params: - resource – the file name or the closeable
- monitor – the object to monitor
Returns: the reference that can be used to stop deleting the file or closing the closeable
/**
* Add a file or a closeable to the list of temporary objects to delete. The
* file is deleted once the file object is garbage collected.
*
* @param resource the file name or the closeable
* @param monitor the object to monitor
* @return the reference that can be used to stop deleting the file or closing the closeable
*/
public synchronized Reference<?> addFile(Object resource, Object monitor) {
if (!(resource instanceof String) && !(resource instanceof AutoCloseable)) {
throw DbException.getUnsupportedException("Unsupported resource " + resource);
}
IOUtils.trace("TempFileDeleter.addFile",
resource instanceof String ? (String) resource : "-", monitor);
PhantomReference<?> ref = new PhantomReference<>(monitor, queue);
refMap.put(ref, resource);
deleteUnused();
return ref;
}
Delete the given file or close the closeable now. This will remove the
reference from the list.
Params: - ref – the reference as returned by addFile
- resource – the file name or closeable
/**
* Delete the given file or close the closeable now. This will remove the
* reference from the list.
*
* @param ref the reference as returned by addFile
* @param resource the file name or closeable
*/
public synchronized void deleteFile(Reference<?> ref, Object resource) {
if (ref != null) {
Object f2 = refMap.remove(ref);
if (f2 != null) {
if (SysProperties.CHECK) {
if (resource != null && !f2.equals(resource)) {
DbException.throwInternalError("f2:" + f2 + " f:" + resource);
}
}
resource = f2;
}
}
if (resource instanceof String) {
String fileName = (String) resource;
if (FileUtils.exists(fileName)) {
try {
IOUtils.trace("TempFileDeleter.deleteFile", fileName, null);
FileUtils.tryDelete(fileName);
} catch (Exception e) {
// TODO log such errors?
}
}
} else if (resource instanceof AutoCloseable) {
AutoCloseable closeable = (AutoCloseable) resource;
try {
IOUtils.trace("TempFileDeleter.deleteCloseable", "-", null);
closeable.close();
} catch (Exception e) {
// TODO log such errors?
}
}
}
Delete all registered temp resources.
/**
* Delete all registered temp resources.
*/
public void deleteAll() {
for (Object resource : new ArrayList<>(refMap.values())) {
deleteFile(null, resource);
}
deleteUnused();
}
Delete all unused resources now.
/**
* Delete all unused resources now.
*/
public void deleteUnused() {
while (queue != null) {
Reference<?> ref = queue.poll();
if (ref == null) {
break;
}
deleteFile(ref, null);
}
}
This method is called if a file should no longer be deleted or a resource
should no longer be closed if the object is garbage collected.
Params: - ref – the reference as returned by addFile
- resource – file name or closeable
/**
* This method is called if a file should no longer be deleted or a resource
* should no longer be closed if the object is garbage collected.
*
* @param ref the reference as returned by addFile
* @param resource file name or closeable
*/
public void stopAutoDelete(Reference<?> ref, Object resource) {
IOUtils.trace("TempFileDeleter.stopAutoDelete",
resource instanceof String ? (String) resource : "-", ref);
if (ref != null) {
Object f2 = refMap.remove(ref);
if (SysProperties.CHECK) {
if (f2 == null || !f2.equals(resource)) {
DbException.throwInternalError("f2:" + f2 +
" " + (f2 == null ? "" : f2) + " f:" + resource);
}
}
}
deleteUnused();
}
}