summaryrefslogtreecommitdiffstats
path: root/vespajlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2018-09-26 10:55:46 +0200
committerHenning Baldersheim <balder@yahoo-inc.com>2018-09-26 10:55:46 +0200
commit115a99c2af52187838223286a44a14b21d3439ba (patch)
tree505a2b5a393ecceeb2cc2394645298e76592a1a1 /vespajlib
parent281866759742475d8c82b258270383f5bf24501b (diff)
USE jna to provide access to native fadvise system call
Diffstat (limited to 'vespajlib')
-rw-r--r--vespajlib/src/main/java/com/yahoo/io/NativeIO.java83
-rw-r--r--vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java35
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());
+ }
+ }
+ }
+}