Add native GCJ Directory implementation.

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@150525 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Doug Cutting 2004-09-20 18:14:25 +00:00
parent 49d0e47491
commit ae6229c8cb
5 changed files with 280 additions and 0 deletions

View File

@ -65,6 +65,9 @@ $Id$
missing, others duplicated) if the sort keys were not unique and there missing, others duplicated) if the sort keys were not unique and there
were more than 100 matches. (Daniel Naber) were more than 100 matches. (Daniel Naber)
14. Add native Directory implementation that works under GCJ. (cutting)
1.4.1 1.4.1
1. Fixed a performance bug in hit sorting code, where values were not 1. Fixed a performance bug in hit sorting code, where values were not

74
src/gcj/Makefile Normal file
View File

@ -0,0 +1,74 @@
# Makefile for Lucene GCJ code
#
# Usually invoked by Ant. Requires that core classes & jars are already built.
BUILD=../../build
LUCENE_OBJ=$(subst .jar,.a,$(wildcard $(BUILD)/lucene-*.jar))
DEST=$(BUILD)/gcj
CORE=$(BUILD)/classes/java
SRC=.
CORE_HEADERS=$(CORE)/org/apache/lucene/store/IndexInput.h
GCJ_JAVA=$(wildcard $(SRC)/org/apache/lucene/store/*.java)
GCJ_OBJ=$(DEST)/lucene-gcj.a
CFLAGS ?= -O3 -ffast-math
GCJFLAGS ?= $(CFLAGS) -fno-bounds-check -fno-store-check
ifdef PROFILE_ARCS
CFLAGS += -fprofile-arcs
endif
ifdef BRANCH_PROBABILITIES
CFLAGS += -fbranch-probabilities
endif
LIBS = -lstdc++
# default rule build's command line executables
all: $(BUILD)/indexFiles $(BUILD)/searchFiles
# pattern rules to generate various things
%.a : %.jar
gcj $(GCJFLAGS) -c -I $(CORE) -o $@ $<
$(DEST)/%.class : $(SRC)/%.java
mkdir -p $(dir $@)
gcj -C -I $(CORE) -d $(DEST) $<
$(CORE)/%.h : $(CORE)/%.class
gcjh --classpath=$(CORE) -d $(CORE) \
$(subst /,.,$(subst .class,,$(subst $(CORE)/,,$<)))
$(DEST)/%.h : $(DEST)/%.class
gcjh --classpath=$(DEST) -d $(DEST) \
$(subst /,.,$(subst .class,,$(subst $(DEST)/,,$<)))
$(DEST)/%.o : $(SRC)/%.cc $(DEST)/%.h $(CORE_HEADERS)
g++ $(CFLAGS) -c -I $(CORE) -I $(DEST) -o $@ $<
$(GCJ_OBJ) : $(GCJ_JAVA)
mkdir -p $(dir $@)
gcj $(GCJFLAGS) -c -I $(CORE) -I $(DEST) -o $@ $^
# list of all object code to be linked
OBJ = $(LUCENE_OBJ) $(GCJ_OBJ) $(DEST)/org/apache/lucene/store/GCJIndexInput.o
USE_GCJ_DIRECTORY =\
-Dorg.apache.lucene.FSDirectory.class=org.apache.lucene.store.GCJDirectory
PROPS = $(USE_GCJ_DIRECTORY)
# link together various applications
$(BUILD)/indexFiles: $(OBJ)
gcj $(GCJFLAGS) $(PROPS) $(LIBS) $^ -o $@ \
--main=org.apache.lucene.demo.IndexFiles
$(BUILD)/searchFiles: $(OBJ)
gcj $(GCJFLAGS) $(PROPS) $(LIBS) $^ -o $@ \
--main=org.apache.lucene.demo.SearchFiles
# remove generated files
clean:
rm -rf $(DEST) $(BUILD)/{*.a,indexFiles,searchFiles}

View File

@ -0,0 +1,32 @@
package org.apache.lucene.store;
/**
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.io.File;
/** Native file-based {@link Directory} implementation, using GCJ.
*
* @author Doug Cutting
*/
public class GCJDirectory extends FSDirectory {
public IndexInput openInput(String name) throws IOException {
return new GCJIndexInput(new File(getFile(), name).getPath());
}
}

View File

@ -0,0 +1,102 @@
#include <org/apache/lucene/store/GCJIndexInput.h>
#include <gnu/gcj/RawData.h>
#include <java/io/IOException.h>
#include <gcj/cni.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <iostream>
using namespace ::std;
using namespace ::java::io;
using namespace ::gnu::gcj;
using namespace ::org::apache::lucene::store;
#define RAW(X) reinterpret_cast< RawData*>(X)
#define BYTES(X) reinterpret_cast< jbyte *>(X)
void GCJIndexInput::open() {
// convert the Java String file name to a char*
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (file) + 1);
jsize total = JvGetStringUTFRegion (file, 0, file->length(), buf);
buf[total] = '\0';
// open the file
fd = ::open (buf, O_RDONLY);
if (fd < 0)
throw new IOException(JvNewStringLatin1(strerror(errno)));
// stat it
struct stat sb;
if (::fstat (fd, &sb))
throw new IOException(JvNewStringLatin1(strerror(errno)));
// get length from stat
fileLength = sb.st_size;
// mmap the file
data = RAW(::mmap(0, fileLength, PROT_READ, MAP_SHARED, fd, 0));
if (data < 0)
throw new IOException(JvNewStringLatin1(strerror(errno)));
// initialize pointer to the start of the file
pointer = data;
}
jbyte GCJIndexInput::readByte() {
// if (getFilePointer() >= fileLength)
// throw new IOException(JvNewStringLatin1("EOF"));
//return *(BYTES(pointer)++);
jbyte* bytes = BYTES(pointer);
jbyte byte = *(bytes++);
pointer = RAW(bytes);
return byte;
}
void GCJIndexInput::readBytes(jbyteArray buffer, jint start, jint length) {
memcpy(elements(buffer)+start, pointer, length);
// BYTES(pointer) += length;
jbyte* bytes = BYTES(pointer);
bytes += length;
pointer = RAW(bytes);
}
jint GCJIndexInput::readVInt() {
// if (getFilePointer() >= fileLength)
// throw new IOException(JvNewStringLatin1("EOF"));
jbyte* bytes = BYTES(pointer);
jbyte b = *(bytes++);
jint i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = *(bytes++);
i |= (b & 0x7F) << shift;
}
pointer = RAW(bytes);
return i;
}
void GCJIndexInput::doClose() {
::munmap(data, fileLength);
::close(fd);
}
jlong GCJIndexInput::getFilePointer() {
return BYTES(pointer) - BYTES(data);
}
void GCJIndexInput::seek(jlong offset) {
pointer = RAW(BYTES(data) + offset);
}

View File

@ -0,0 +1,69 @@
package org.apache.lucene.store;
/**
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import gnu.gcj.RawData;
/** Native file-based {@link IndexInput} implementation, using GCJ.
*
* @author Doug Cutting
*/
public class GCJIndexInput extends IndexInput {
private String file;
private int fd;
private long fileLength;
private RawData data;
private RawData pointer;
private boolean isClone;
public GCJIndexInput(String file) throws IOException {
this.file = file;
open();
}
private native void open() throws IOException;
public native byte readByte() throws IOException;
public native void readBytes(byte[] b, int offset, int len)
throws IOException;
public native int readVInt() throws IOException;
public native long getFilePointer();
public native void seek(long pos) throws IOException;
public long length() { return fileLength; }
public Object clone() {
GCJIndexInput clone = (GCJIndexInput)super.clone();
clone.isClone = true;
return clone;
}
public void close() throws IOException {
if (!isClone)
doClose();
}
private native void doClose() throws IOException;
}