diff options
Diffstat (limited to 'vespajlib')
-rw-r--r-- | vespajlib/src/main/java/com/yahoo/io/NativeIO.java | 83 | ||||
-rw-r--r-- | vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java | 35 |
2 files changed, 118 insertions, 0 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/io/NativeIO.java b/vespajlib/src/main/java/com/yahoo/io/NativeIO.java new file mode 100644 index 00000000000..5adb509ac3b --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/io/NativeIO.java @@ -0,0 +1,83 @@ +package com.yahoo.io; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.logging.Logger; + +import com.sun.jna.LastErrorException; +import com.sun.jna.Native; +import com.sun.jna.Platform; + +public class NativeIO { + private final Logger logger = Logger.getLogger(getClass().getName()); + private static final int POSIX_FADV_DONTNEED = 4; // See /usr/include/linux/fadvise.h + private static boolean initialized = false; + private static Throwable initError = null; + static { + try { + if (Platform.isLinux()) { + Native.register(Platform.C_LIBRARY_NAME); + initialized = true; + } + } catch (Throwable throwable) { + initError = throwable; + } + } + + private final Field fieldFD; + + private static native int posix_fadvise(int fd, long offset, long len, int flag) throws LastErrorException; + + public NativeIO() { + if (!initialized) { + logger.warning("native IO not possible due to " + initError); + if (initError != null) { + throw new RuntimeException(initError); + } else { + throw new RuntimeException("Platform is unsúpported. Only supported on linux."); + } + } + fieldFD = getField(FileDescriptor.class, "fd"); + } + + public void dropFileFromCache(FileDescriptor fd) { + if (initialized) { + posix_fadvise(getfh(fd), 0, 0, POSIX_FADV_DONTNEED); + } + } + + public void dropFileFromCache(File file) { + try { + dropFileFromCache(new FileInputStream(file).getFD()); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + + private static Field getField(Class<?> clazz, String fieldName) { + Field field; + try { + field = clazz.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + field.setAccessible(true); + return field; + } + + private int getfh(FileDescriptor fd) { + try { + return fieldFD.getInt(fd); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java b/vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java new file mode 100644 index 00000000000..91144d5999f --- /dev/null +++ b/vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java @@ -0,0 +1,35 @@ +package com.yahoo.io; + +import com.sun.jna.Platform; +import org.junit.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +public class NativeIOTestCase { + + @Test + public void requireThatDropFileFromCacheDoesNotThrow() throws IOException { + File testFile = new File("testfile"); + FileOutputStream output = new FileOutputStream(testFile); + output.write('t'); + output.flush(); + output.close(); + try { + NativeIO nativeIO = new NativeIO(); + nativeIO.dropFileFromCache(output.getFD()); + nativeIO.dropFileFromCache(testFile); + } catch (Throwable e) { + if (Platform.isLinux()) { + assertTrue(false); + } else { + assertEquals("Platform is unsúpported. Only supported on linux.", e.getMessage()); + } + } + } +} |