2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with this
4 * work for additional information regarding copyright ownership. The ASF
5 * licenses this file to You under the Apache License, Version 2.0 (the
6 * "License"); you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
19 #include <fcntl.h> // posix_fadvise, constants for open
20 #include <string.h> // strerror
21 #include <errno.h> // errno
22 #include <unistd.h> // pread
23 #include <sys/mman.h> // posix_madvise, madvise
24 #include <sys/types.h> // constants for open
25 #include <sys/stat.h> // constants for open
27 // java -cp .:lib/junit-4.7.jar:./build/classes/test:./build/classes/java:./build/classes/demo -Dlucene.version=2.9-dev -DtempDir=build -ea org.junit.runner.JUnitCore org.apache.lucene.index.TestDoc
30 * Class: org_apache_lucene_store_NativePosixUtil
31 * Method: posix_fadvise
32 * Signature: (Ljava/io/FileDescriptor;JJI)V
35 JNIEXPORT jint JNICALL Java_org_apache_lucene_store_NativePosixUtil_posix_1fadvise(JNIEnv *env, jclass _ignore, jobject fileDescriptor, jlong offset, jlong len, jint advice)
38 jmethodID const_fdesc;
40 jclass ioex = env->FindClass("java/io/IOException");
45 jclass fdesc = env->FindClass("java/io/FileDescriptor");
50 // read the int fd field
51 jfieldID fdField = env->GetFieldID(fdesc, "fd", "I");
52 if (fdField == NULL) {
56 int fd = env->GetIntField(fileDescriptor, fdField);
57 //printf("fd=%d\n", fd); fflush(stdout);
63 osAdvice = POSIX_FADV_NORMAL;
66 osAdvice = POSIX_FADV_SEQUENTIAL;
69 osAdvice = POSIX_FADV_RANDOM;
72 osAdvice = POSIX_FADV_WILLNEED;
75 osAdvice = POSIX_FADV_DONTNEED;
78 osAdvice = POSIX_FADV_NOREUSE;
82 int result = posix_fadvise(fd, (off_t) offset, (off_t) len, osAdvice);
86 env->ThrowNew(ioex, strerror(errno));
95 * Class: org_apache_lucene_store_NativePosixUtil
97 * Signature: (Ljava/lang/String;Z)Ljava/io/FileDescriptor;
100 JNIEXPORT jobject JNICALL Java_org_apache_lucene_store_NativePosixUtil_open_1direct(JNIEnv *env, jclass _ignore, jstring filename, jboolean readOnly)
103 jmethodID const_fdesc;
104 jclass class_fdesc, class_ioex;
109 class_ioex = env->FindClass("java/io/IOException");
110 if (class_ioex == NULL) return NULL;
111 class_fdesc = env->FindClass("java/io/FileDescriptor");
112 if (class_fdesc == NULL) return NULL;
114 fname = (char *) env->GetStringUTFChars(filename, NULL);
117 fd = open(fname, O_RDONLY | O_DIRECT | O_NOATIME);
119 fd = open(fname, O_RDWR | O_CREAT | O_DIRECT | O_NOATIME, 0666);
122 //printf("open %s -> %d; ro %d\n", fname, fd, readOnly); fflush(stdout);
124 env->ReleaseStringUTFChars(filename, fname);
127 // open returned an error. Throw an IOException with the error string
128 env->ThrowNew(class_ioex, strerror(errno));
132 // construct a new FileDescriptor
133 const_fdesc = env->GetMethodID(class_fdesc, "<init>", "()V");
134 if (const_fdesc == NULL) return NULL;
135 ret = env->NewObject(class_fdesc, const_fdesc);
137 // poke the "fd" field with the file descriptor
138 field_fd = env->GetFieldID(class_fdesc, "fd", "I");
139 if (field_fd == NULL) return NULL;
140 env->SetIntField(ret, field_fd, fd);
148 * Class: org_apache_lucene_store_NativePosixUtil
150 * Signature: (Ljava/io/FileDescriptor;JLjava/nio/ByteBuffer;)I
153 JNIEXPORT jlong JNICALL Java_org_apache_lucene_store_NativePosixUtil_pread(JNIEnv *env, jclass _ignore, jobject jfd, jlong pos, jobject byteBuf)
156 jclass class_fdesc = env->FindClass("java/io/FileDescriptor");
157 if (class_fdesc == NULL) {
161 jfieldID field_fd = env->GetFieldID(class_fdesc, "fd", "I");
162 if (field_fd == NULL) {
166 const int fd = env->GetIntField(jfd, field_fd);
168 void *p = env->GetDirectBufferAddress(byteBuf);
173 size_t size = (size_t) env->GetDirectBufferCapacity(byteBuf);
178 size_t numBytesRead = pread(fd, p, (size_t) size, (off_t) pos);
179 if (numBytesRead == -1) {
180 jclass class_ioex = env->FindClass("java/io/IOException");
181 if (class_ioex == NULL) {
185 env->ThrowNew(class_ioex, strerror(errno));
189 return (jlong) numBytesRead;
193 * Class: org_apache_lucene_store_NativePosixUtil
194 * Method: posix_madvise
195 * Signature: (Ljava/nio/ByteBuffer;I)I
198 JNIEXPORT jint JNICALL Java_org_apache_lucene_store_NativePosixUtil_posix_1madvise(JNIEnv *env, jclass _ignore, jobject buffer, jint advice) {
199 void *p = env->GetDirectBufferAddress(buffer);
204 size_t size = (size_t) env->GetDirectBufferCapacity(buffer);
209 int page = getpagesize();
211 // round start down to start of page
212 long long start = (long long) p;
213 start = start & (~(page-1));
215 // round end up to start of page
216 long long end = start + size;
217 end = (end + page-1)&(~(page-1));
223 osAdvice = POSIX_MADV_NORMAL;
226 osAdvice = POSIX_MADV_SEQUENTIAL;
229 osAdvice = POSIX_MADV_RANDOM;
232 osAdvice = POSIX_MADV_WILLNEED;
235 osAdvice = POSIX_MADV_DONTNEED;
242 //printf("DO posix_madvise: %lx %d\n", p, size);fflush(stdout);
244 if (posix_madvise((void *) start, size, osAdvice) != 0) {
245 jclass class_ioex = env->FindClass("java/io/IOException");
246 if (class_ioex == NULL) {
250 env->ThrowNew(class_ioex, strerror(errno));
259 * Class: org_apache_lucene_store_NativePosixUtil
261 * Signature: (Ljava/nio/ByteBuffer;I)I
264 JNIEXPORT jint JNICALL Java_org_apache_lucene_store_NativePosixUtil_madvise(JNIEnv *env, jclass _ignore, jobject buffer, jint advice) {
265 void *p = env->GetDirectBufferAddress(buffer);
270 size_t size = (size_t) env->GetDirectBufferCapacity(buffer);
275 int page = getpagesize();
277 // round start down to start of page
278 long long start = (long long) p;
279 start = start & (~(page-1));
281 // round end up to start of page
282 long long end = start + size;
283 end = (end + page-1)&(~(page-1));
289 osAdvice = MADV_NORMAL;
292 osAdvice = MADV_SEQUENTIAL;
295 osAdvice = MADV_RANDOM;
298 osAdvice = MADV_WILLNEED;
301 osAdvice = MADV_DONTNEED;
309 //printf("DO madvise: page=%d p=0x%lx 0x%lx size=0x%lx\n", page, p, start, size);fflush(stdout);
311 if (madvise((void *) start, size, osAdvice) != 0) {
312 jclass class_ioex = env->FindClass("java/io/IOException");
313 if (class_ioex == NULL) {
317 env->ThrowNew(class_ioex, strerror(errno));