package gw.lang.tidb.database;
import sun.nio.ch.DirectBuffer;
import sun.misc.Cleaner;
import java.util.Collection;
import java.util.List;
import java.nio.ByteBuffer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
/**
* Copyright 2010 Guidewire Software, Inc.
*
* @deprecated all files under gw.lang.tidb.* will be removed in a future release
*/
public interface IDataFile
{
void open();
void close();
void create(int rowSize);
void drop();
int getRowSize();
int getCapacityInRows();
Collection<Integer> allocate(int numRows);
ByteBuffer getBufferForRow(int row);
void delete(int rowToDelete);
void tableScan(DataRowVisitor vistor);
void scanRows( List<Integer> rowNums, DataRowVisitor vistor);
class Util
{
public static void freeMemoryMappedFile(ByteBuffer byteBuffer) {
if (byteBuffer instanceof DirectBuffer ) {
/**
* AHK - 3/22/2010
*
* This is a vicious, eggregious hack. We've got two problems to deal with. First of all, there's no Java
* API for unmapping a memory mapped file. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038
* They haven't put one in for 8 years, so don't hold your breath. So to get around that, we call directly
* into one of their cleaner classes. That *almost* works.
*
* Unfortunately, the Cleaner class, when you call clean(), simply calls System.exit(1) if anything goes wrong.
* Occassionally in our test harness the cleaner fails due to what looks like some OS-level race condition
* that temporarily leaves the file locked. We'd like to retry in that case, rather than, you know, killing
* the *entire* VM with a system.exit() call. So we pull the thunk out of the cleaner and run it ourselves
* if it fails. Doing that involves all sorts of reflective fun.
*/
try {
Cleaner cleaner = ((DirectBuffer) byteBuffer).cleaner();
Field thunkField = Cleaner.class.getDeclaredField("thunk");
thunkField.setAccessible(true);
Runnable thunk = (Runnable) thunkField.get(cleaner);
Method removeMethod = Cleaner.class.getDeclaredMethod("remove", Cleaner.class);
removeMethod.setAccessible(true);
if (!((Boolean) removeMethod.invoke(null, cleaner))) {
return;
}
for (int i = 0; i < 10; i++) {
try {
thunk.run();
return;
} catch (Throwable t) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// Ignore
}
}
}
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
}