- integrated Aaron Donovan's port to Berkeley DB Java Edition

- reorganized directory tree to accomodate multiple implementations


git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@366041 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Vajda 2006-01-05 01:04:17 +00:00
parent 2d85b34db8
commit c312ac9d52
18 changed files with 1360 additions and 31 deletions

View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<project name="bdb-je" default="default">
<description>
Lucene Berkeley DB Java Edition integration
</description>
<property name="je.version" value="2.0.90" />
<path id="je.jar">
<pathelement location="lib/je-${je.version}/lib/je.jar" />
</path>
<available classname="com.sleepycat.je.Database" property="je.jar.exists">
<classpath refid="je.jar" />
</available>
<pathconvert property="project.classpath" targetos="unix" refid="je.jar" />
<property name="build.dir" location="../../../build/contrib/db/bdb-je" />
<property name="dist.dir" location="../../../dist/contrib/db/bdb-je" />
<import file="../../contrib-build.xml" />
<target name="get-je-jar" unless="je.jar.exists">
<mkdir dir="lib" />
<get src="http://downloads.sleepycat.com/je-${je.version}.zip"
dest="lib/je-${je.version}.zip" />
<unzip src="lib/je-${je.version}.zip" dest="lib">
<patternset>
<include name="je-${je.version}/lib/je.jar" />
</patternset>
</unzip>
</target>
<target name="check-and-get-je-jar" depends="get-je-jar" />
<target name="init" depends="common.init,check-and-get-je-jar" />
</project>

View File

@ -0,0 +1,83 @@
package org.apache.lucene.store.je;
/**
* Copyright 2002-2006 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 com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
/**
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
*
* @author Aaron Donovan
*/
public class Block extends Object {
protected DatabaseEntry key, data;
protected Block(File file) throws IOException {
byte[] fileKey = file.getKey();
key = new DatabaseEntry(new byte[fileKey.length + 8]);
data = new DatabaseEntry(new byte[JEIndexOutput.BLOCK_LEN]);
System.arraycopy(fileKey, 0, key.getData(), 0, fileKey.length);
seek(0L);
}
protected byte[] getKey() {
return key.getData();
}
protected byte[] getData() {
return data.getData();
}
protected void seek(long position) throws IOException {
byte[] data = key.getData();
int index = data.length - 8;
position >>>= JEIndexOutput.BLOCK_SHIFT;
data[index + 0] = (byte) (0xff & (position >>> 56));
data[index + 1] = (byte) (0xff & (position >>> 48));
data[index + 2] = (byte) (0xff & (position >>> 40));
data[index + 3] = (byte) (0xff & (position >>> 32));
data[index + 4] = (byte) (0xff & (position >>> 24));
data[index + 5] = (byte) (0xff & (position >>> 16));
data[index + 6] = (byte) (0xff & (position >>> 8));
data[index + 7] = (byte) (0xff & (position >>> 0));
}
protected void get(JEDirectory directory) throws IOException {
try {
// TODO check LockMode
directory.blocks.get(directory.txn, key, data, null);
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
}
protected void put(JEDirectory directory) throws IOException {
try {
directory.blocks.put(directory.txn, key, data);
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
}
}

View File

@ -0,0 +1,233 @@
package org.apache.lucene.store.je;
/**
* Copyright 2002-2006 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
/**
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
*
* @author Aaron Donovan
*/
public class File extends Object {
static protected Random random = new Random();
protected DatabaseEntry key, data;
protected long length, timeModified;
protected String name;
protected byte[] uuid;
protected File(String name) throws IOException {
setName(name);
data = new DatabaseEntry(new byte[32]);
}
protected File(JEDirectory directory, String name, boolean create)
throws IOException {
this(name);
if (!exists(directory)) {
if (!create)
throw new IOException("File does not exist: " + name);
else {
DatabaseEntry key = new DatabaseEntry(new byte[24]);
DatabaseEntry data = new DatabaseEntry(null);
Database blocks = directory.blocks;
Transaction txn = directory.txn;
data.setPartial(true);
uuid = new byte[16];
try {
do {
/* generate a v.4 random-uuid unique to this db */
random.nextBytes(uuid);
uuid[6] = (byte) ((byte) 0x40 | (uuid[6] & (byte) 0x0f));
uuid[8] = (byte) ((byte) 0x80 | (uuid[8] & (byte) 0x3f));
System.arraycopy(uuid, 0, key.getData(), 0, 16);
// TODO check LockMode
} while (blocks.get(txn, key, data, null) != OperationStatus.NOTFOUND);
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
}
} else if (create)
length = 0L;
}
protected String getName() {
return name;
}
private void setName(String name) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(128);
DataOutputStream out = new DataOutputStream(buffer);
out.writeUTF(name);
out.close();
key = new DatabaseEntry(buffer.toByteArray());
this.name = name;
}
protected byte[] getKey() throws IOException {
if (uuid == null)
throw new IOException("Uninitialized file");
return uuid;
}
protected long getLength() {
return length;
}
protected long getTimeModified() {
return timeModified;
}
protected boolean exists(JEDirectory directory) throws IOException {
Database files = directory.files;
Transaction txn = directory.txn;
try {
// TODO check LockMode
if (files.get(txn, key, data, null) == OperationStatus.NOTFOUND)
return false;
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
byte[] bytes = data.getData();
ByteArrayInputStream buffer = new ByteArrayInputStream(bytes);
DataInputStream in = new DataInputStream(buffer);
length = in.readLong();
timeModified = in.readLong();
in.close();
uuid = new byte[16];
System.arraycopy(bytes, 16, uuid, 0, 16);
return true;
}
protected void modify(JEDirectory directory, long length, long timeModified)
throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(32);
DataOutputStream out = new DataOutputStream(buffer);
Database files = directory.files;
Transaction txn = directory.txn;
out.writeLong(length);
out.writeLong(timeModified);
out.write(getKey());
out.close();
System.arraycopy(buffer.toByteArray(), 0, data.getData(), 0, 32);
try {
files.put(txn, key, data);
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
this.length = length;
this.timeModified = timeModified;
}
protected void delete(JEDirectory directory) throws IOException {
if (!exists(directory))
throw new IOException("File does not exist: " + getName());
Cursor cursor = null;
try {
try {
byte[] bytes = getKey();
int ulen = bytes.length + 8;
byte[] cursorBytes = new byte[ulen];
DatabaseEntry cursorKey = new DatabaseEntry(cursorBytes);
DatabaseEntry cursorData = new DatabaseEntry(null);
Database files = directory.files;
Database blocks = directory.blocks;
Transaction txn = directory.txn;
System.arraycopy(bytes, 0, cursorBytes, 0, bytes.length);
cursorData.setPartial(true);
cursor = blocks.openCursor(txn, null);
if (cursor.getSearchKey(cursorKey, cursorData, null) != OperationStatus.NOTFOUND) {
cursor.delete();
while (cursor.getNextDup(cursorKey, cursorData, null) != OperationStatus.NOTFOUND) {
cursor.delete();
}
}
files.delete(txn, key);
} finally {
if (cursor != null)
cursor.close();
}
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
}
protected void rename(JEDirectory directory, String name)
throws IOException {
if (!exists(directory))
throw new IOException("File does not exist: " + getName());
File newFile = new File(name);
if (newFile.exists(directory))
newFile.delete(directory);
try {
Database files = directory.files;
Transaction txn = directory.txn;
files.delete(txn, key);
setName(name);
files.put(txn, key, data);
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
}
}

View File

@ -0,0 +1,218 @@
package org.apache.lucene.store.je;
/**
* Copyright 2002-2006 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.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.Lock;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
/**
* Port of Andi Vajda's DbDirectory to to Java Edition of Berkeley Database
*
* A JEDirectory is a Berkeley DB JE based implementation of
* {@link org.apache.lucene.store.Directory Directory}. It uses two
* {@link com.sleepycat.je.Database Db} database handles, one for storing file
* records and another for storing file data blocks.
*
* @author Aaron Donovan
*/
public class JEDirectory extends Directory {
protected Set openFiles = Collections.synchronizedSet(new HashSet());
protected Database files, blocks;
protected Transaction txn;
protected int flags;
/**
* Instantiate a DbDirectory. The same threading rules that apply to
* Berkeley DB handles apply to instances of DbDirectory.
*
* @param txn
* a transaction handle that is going to be used for all db
* operations done by this instance. This parameter may be
* <code>null</code>.
* @param files
* a db handle to store file records.
* @param blocks
* a db handle to store file data blocks.
* @param flags
* flags used for db read operations.
*/
public JEDirectory(Transaction txn, Database files, Database blocks,
int flags) {
super();
this.txn = txn;
this.files = files;
this.blocks = blocks;
this.flags = flags;
}
public JEDirectory(Transaction txn, Database files, Database blocks) {
this(txn, files, blocks, 0);
}
public void close() throws IOException {
flush();
}
/**
* Flush the currently open files. After they have been flushed it is safe
* to commit the transaction without closing this DbDirectory instance
* first.
*
* @see setTransaction
*/
public void flush() throws IOException {
Iterator iterator = openFiles.iterator();
while (iterator.hasNext()) {
System.out
.println(((JEIndexOutput) iterator.next()).file.getName());
// ((IndexOutput) iterator.next()).flush();
}
}
public IndexOutput createOutput(String name) throws IOException {
return new JEIndexOutput(this, name, true);
}
public void deleteFile(String name) throws IOException {
new File(name).delete(this);
}
public boolean fileExists(String name) throws IOException {
return new File(name).exists(this);
}
public long fileLength(String name) throws IOException {
File file = new File(name);
if (file.exists(this))
return file.getLength();
throw new IOException("File does not exist: " + name);
}
public long fileModified(String name) throws IOException {
File file = new File(name);
if (file.exists(this))
return file.getTimeModified();
throw new IOException("File does not exist: " + name);
}
public String[] list() throws IOException {
Cursor cursor = null;
List list = new ArrayList();
try {
try {
DatabaseEntry key = new DatabaseEntry(new byte[0]);
DatabaseEntry data = new DatabaseEntry(null);
data.setPartial(true);
// TODO see if cursor needs configuration
cursor = files.openCursor(txn, null);
// TODO see if LockMode should be set
if (cursor.getNext(key, data, null) != OperationStatus.NOTFOUND) {
ByteArrayInputStream buffer = new ByteArrayInputStream(key
.getData());
DataInputStream in = new DataInputStream(buffer);
String name = in.readUTF();
in.close();
list.add(name);
while (cursor.getNext(key, data, null) != OperationStatus.NOTFOUND) {
buffer = new ByteArrayInputStream(key.getData());
in = new DataInputStream(buffer);
name = in.readUTF();
in.close();
list.add(name);
}
}
} finally {
if (cursor != null)
cursor.close();
}
} catch (DatabaseException e) {
throw new IOException(e.getMessage());
}
return (String[]) list.toArray(new String[list.size()]);
}
public IndexInput openInput(String name) throws IOException {
return new JEIndexInput(this, name);
}
public Lock makeLock(String name) {
return new JELock();
}
public void renameFile(String from, String to) throws IOException {
new File(from).rename(this, to);
}
public void touchFile(String name) throws IOException {
File file = new File(name);
long length = 0L;
if (file.exists(this))
length = file.getLength();
file.modify(this, length, System.currentTimeMillis());
}
/**
* Once a transaction handle was committed it is no longer valid. In order
* to continue using this JEDirectory instance after a commit, the
* transaction handle has to be replaced.
*
* @param txn
* the new transaction handle to use
*/
public void setTransaction(Transaction txn) {
this.txn = txn;
}
}

View File

@ -0,0 +1,134 @@
package org.apache.lucene.store.je;
/**
* Copyright 2002-2006 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 org.apache.lucene.store.IndexInput;
/**
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
*
* @author Aaron Donovan
*/
public class JEIndexInput extends IndexInput {
protected long position = 0L, length = 0L;
protected JEDirectory directory;
protected Block block;
protected File file;
protected JEIndexInput(JEDirectory directory, String name)
throws IOException {
super();
this.directory = directory;
this.file = new File(name);
if (!file.exists(directory))
throw new IOException("File does not exist: " + name);
length = file.getLength();
block = new Block(file);
block.get(directory);
}
public Object clone() {
try {
JEIndexInput clone = (JEIndexInput) super.clone();
clone.block = new Block(file);
clone.block.seek(position);
clone.block.get(directory);
return clone;
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
public void close() throws IOException {
}
public long length() {
return length;
}
public byte readByte() throws IOException {
if (position + 1 > length)
throw new IOException(file.getName() + ": Reading past end of file");
int blockPos = (int) (position++ & JEIndexOutput.BLOCK_MASK);
byte b = block.getData()[blockPos];
if (blockPos + 1 == JEIndexOutput.BLOCK_LEN) {
block.seek(position);
block.get(directory);
}
return b;
}
public void readBytes(byte[] b, int offset, int len) throws IOException {
if (position + len > length)
throw new IOException("Reading past end of file");
else {
int blockPos = (int) (position & JEIndexOutput.BLOCK_MASK);
while (blockPos + len >= JEIndexOutput.BLOCK_LEN) {
int blockLen = JEIndexOutput.BLOCK_LEN - blockPos;
System
.arraycopy(block.getData(), blockPos, b, offset,
blockLen);
len -= blockLen;
offset += blockLen;
position += blockLen;
block.seek(position);
block.get(directory);
blockPos = 0;
}
if (len > 0) {
System.arraycopy(block.getData(), blockPos, b, offset, len);
position += len;
}
}
}
public void seek(long pos) throws IOException {
if (pos > length)
throw new IOException("seeking past end of file");
if ((pos >>> JEIndexOutput.BLOCK_SHIFT) != (position >>> JEIndexOutput.BLOCK_SHIFT)) {
block.seek(pos);
block.get(directory);
}
position = pos;
}
public long getFilePointer() {
return position;
}
}

View File

@ -0,0 +1,141 @@
package org.apache.lucene.store.je;
/**
* Copyright 2002-2006 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 org.apache.lucene.store.IndexOutput;
/**
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
*
* @author Aaron Donovan
*/
public class JEIndexOutput extends IndexOutput {
/**
* The size of data blocks, currently 16k (2^14), is determined by this
* constant.
*/
static public final int BLOCK_SHIFT = 14;
static public final int BLOCK_LEN = 1 << BLOCK_SHIFT;
static public final int BLOCK_MASK = BLOCK_LEN - 1;
protected long position = 0L, length = 0L;
protected JEDirectory directory;
protected Block block;
protected File file;
protected JEIndexOutput(JEDirectory directory, String name, boolean create)
throws IOException {
super();
this.directory = directory;
file = new File(directory, name, create);
block = new Block(file);
length = file.getLength();
seek(length);
block.get(directory);
directory.openFiles.add(this);
}
public void close() throws IOException {
flush();
file.modify(directory, length, System.currentTimeMillis());
directory.openFiles.remove(this);
}
public void flush() throws IOException {
if (length > 0)
block.put(directory);
}
public void writeByte(byte b) throws IOException {
int blockPos = (int) (position++ & BLOCK_MASK);
block.getData()[blockPos] = b;
if (blockPos + 1 == BLOCK_LEN) {
block.put(directory);
block.seek(position);
block.get(directory);
}
if (position > length)
length = position;
}
public void writeBytes(byte[] b, int len) throws IOException {
int blockPos = (int) (position & BLOCK_MASK);
int offset = 0;
while (blockPos + len >= BLOCK_LEN) {
int blockLen = BLOCK_LEN - blockPos;
System.arraycopy(b, offset, block.getData(), blockPos, blockLen);
block.put(directory);
len -= blockLen;
offset += blockLen;
position += blockLen;
block.seek(position);
block.get(directory);
blockPos = 0;
}
if (len > 0) {
System.arraycopy(b, offset, block.getData(), blockPos, len);
position += len;
}
if (position > length)
length = position;
}
public long length() throws IOException {
return length;
}
public void seek(long pos) throws IOException {
if (pos > length)
throw new IOException("seeking past end of file");
if ((pos >>> BLOCK_SHIFT) == (position >>> BLOCK_SHIFT))
position = pos;
else {
block.put(directory);
block.seek(pos);
block.get(directory);
position = pos;
}
}
public long getFilePointer() {
return position;
}
}

View File

@ -0,0 +1,50 @@
package org.apache.lucene.store.je;
/**
* Copyright 2002-2006 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 org.apache.lucene.store.Lock;
/**
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
*
* @author Aaron Donovan
*/
public class JELock extends Lock {
boolean isLocked = false;
public JELock()
{
}
public boolean obtain()
{
return (isLocked = true);
}
public void release()
{
isLocked = false;
}
public boolean isLocked()
{
return isLocked;
}
}

View File

@ -0,0 +1,407 @@
package org.apache.lucene.store.je;
/**
* Copyright 2005 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.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;
import junit.framework.TestCase;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.je.JEDirectory;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.Transaction;
/**
* Tests {@link JEDirectory}.
*
* Adapted from Andi Vajda's org.apache.lucene.db.DbStoreTest.
* @author Aaron Donovan
*/
public class JEStoreTest extends TestCase {
protected File dbHome = new File("index");
protected Environment env;
protected Database index, blocks;
public void setUp()
throws Exception
{
if (!dbHome.exists())
dbHome.mkdir();
else {
File[] files = dbHome.listFiles();
for (int i = 0; i < files.length; i++) {
String name = files[i].getName();
if (name.endsWith("jdb") || name.equals("je.lck"))
files[i].delete();
}
}
EnvironmentConfig envConfig = new EnvironmentConfig();
DatabaseConfig dbConfig = new DatabaseConfig();
envConfig.setTransactional(true);
envConfig.setAllowCreate(true);
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
env = new Environment(dbHome, envConfig);
Transaction txn = null;
try {
txn = env.beginTransaction(null, null);
index = env.openDatabase(txn, "__index__", dbConfig);
blocks = env.openDatabase(txn, "__blocks__", dbConfig);
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
index = null;
blocks = null;
throw e;
} finally {
if (txn != null)
txn.commit();
txn = null;
}
}
public void tearDown()
throws Exception
{
if (index != null)
index.close();
if (blocks != null)
blocks.close();
if (env != null)
env.close();
}
public void testBytes()
throws Exception
{
final int count = 250;
final int LENGTH_MASK = 0xffff;
Random gen = new Random(1251971);
int totalLength = 0;
int duration;
Date end;
Date veryStart = new Date();
Date start = new Date();
Transaction txn = null;
Directory store = null;
System.out.println("Writing files byte by byte");
try {
txn = env.beginTransaction(null, null);
store = new JEDirectory(txn, index, blocks);
for (int i = 0; i < count; i++) {
String name = i + ".dat";
int length = gen.nextInt() & LENGTH_MASK;
IndexOutput file = store.createOutput(name);
totalLength += length;
for (int j = 0; j < length; j++) {
byte b = (byte)(gen.nextInt() & 0x7F);
file.writeByte(b);
}
file.close();
}
} catch (IOException e) {
txn.abort();
txn = null;
throw e;
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
throw e;
} finally {
if (txn != null)
txn.commit();
store.close();
}
end = new Date();
duration = (int) (end.getTime() - start.getTime());
System.out.print(duration);
System.out.print(" total milliseconds to create, ");
System.out.print(totalLength / duration);
System.out.println(" kb/s");
try {
txn = env.beginTransaction(null, null);
store = new JEDirectory(txn, index, blocks);
gen = new Random(1251971);
start = new Date();
for (int i = 0; i < count; i++) {
String name = i + ".dat";
int length = gen.nextInt() & LENGTH_MASK;
IndexInput file = store.openInput(name);
if (file.length() != length)
throw new Exception("length incorrect");
for (int j = 0; j < length; j++) {
byte b = (byte)(gen.nextInt() & 0x7F);
if (file.readByte() != b)
throw new Exception("contents incorrect");
}
file.close();
}
} catch (IOException e) {
txn.abort();
txn = null;
throw e;
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
throw e;
} finally {
if (txn != null)
txn.commit();
store.close();
}
end = new Date();
duration = (int) (end.getTime() - start.getTime());
System.out.print(duration);
System.out.print(" total milliseconds to read, ");
System.out.print(totalLength / duration);
System.out.println(" kb/s");
try {
txn = env.beginTransaction(null, null);
store = new JEDirectory(txn, index, blocks);
gen = new Random(1251971);
start = new Date();
for (int i = 0; i < count; i++) {
String name = i + ".dat";
store.deleteFile(name);
}
} catch (IOException e) {
txn.abort();
txn = null;
throw e;
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
throw e;
} finally {
if (txn != null)
txn.commit();
store.close();
}
end = new Date();
System.out.print(end.getTime() - start.getTime());
System.out.println(" total milliseconds to delete");
System.out.print(end.getTime() - veryStart.getTime());
System.out.println(" total milliseconds");
}
public void testArrays()
throws Exception
{
final int count = 250;
final int LENGTH_MASK = 0xffff;
Random gen = new Random(1251971);
int totalLength = 0;
int duration;
Date end;
Date veryStart = new Date();
Date start = new Date();
Transaction txn = null;
Directory store = null;
System.out.println("Writing files as one byte array");
try {
txn = env.beginTransaction(null, null);
store = new JEDirectory(txn, index, blocks);
for (int i = 0; i < count; i++) {
String name = i + ".dat";
int length = gen.nextInt() & LENGTH_MASK;
IndexOutput file = store.createOutput(name);
byte[] data = new byte[length];
totalLength += length;
gen.nextBytes(data);
file.writeBytes(data, length);
file.close();
}
} catch (IOException e) {
txn.abort();
txn = null;
throw e;
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
throw e;
} finally {
if (txn != null)
txn.commit();
store.close();
}
end = new Date();
duration = (int) (end.getTime() - start.getTime());
System.out.print(duration);
System.out.print(" total milliseconds to create, ");
System.out.print(totalLength / duration);
System.out.println(" kb/s");
try {
txn = env.beginTransaction(null, null);
store = new JEDirectory(txn, index, blocks);
gen = new Random(1251971);
start = new Date();
for (int i = 0; i < count; i++) {
String name = i + ".dat";
int length = gen.nextInt() & LENGTH_MASK;
IndexInput file = store.openInput(name);
if (file.length() != length)
throw new Exception("length incorrect");
byte[] data = new byte[length];
byte[] read = new byte[length];
gen.nextBytes(data);
file.readBytes(read, 0, length);
if (!Arrays.equals(data, read))
throw new Exception("contents incorrect");
file.close();
}
} catch (IOException e) {
txn.abort();
txn = null;
throw e;
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
throw e;
} finally {
if (txn != null)
txn.commit();
store.close();
}
end = new Date();
duration = (int) (end.getTime() - start.getTime());
System.out.print(duration);
System.out.print(" total milliseconds to read, ");
System.out.print(totalLength / duration);
System.out.println(" kb/s");
try {
txn = env.beginTransaction(null, null);
store = new JEDirectory(txn, index, blocks);
gen = new Random(1251971);
start = new Date();
for (int i = 0; i < count; i++) {
String name = i + ".dat";
store.deleteFile(name);
}
} catch (IOException e) {
txn.abort();
txn = null;
throw e;
} catch (DatabaseException e) {
if (txn != null)
{
txn.abort();
txn = null;
}
throw e;
} finally {
if (txn != null)
txn.commit();
store.close();
}
end = new Date();
System.out.print(end.getTime() - start.getTime());
System.out.println(" total milliseconds to delete");
System.out.print(end.getTime() - veryStart.getTime());
System.out.println(" total milliseconds");
}
}

33
contrib/db/bdb/build.xml Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<project name="bdb" default="default">
<description>
Lucene Berkeley DB integration
</description>
<property name="db.version" value="4.3.29" />
<path id="db.jar">
<pathelement location="lib/db-${db.version}.jar" />
</path>
<available classname="com.sleepycat.db.internal.Db" property="db.jar.exists">
<classpath refid="db.jar" />
</available>
<pathconvert property="project.classpath" targetos="unix" refid="db.jar" />
<property name="build.dir" location="../../../build/contrib/db/bdb" />
<property name="dist.dir" location="../../../dist/contrib/db/bdb" />
<import file="../../contrib-build.xml" />
<target name="get-db-jar" unless="db.jar.exists">
<mkdir dir="lib" />
<get src="http://downloads.osafoundation.org/db/db-${db.version}.jar"
dest="lib/db-${db.version}.jar" />
</target>
<target name="check-and-get-db-jar" depends="get-db-jar" />
<target name="init" depends="common.init,check-and-get-db-jar" />
</project>

View File

@ -1,7 +1,7 @@
package org.apache.lucene.store.db; package org.apache.lucene.store.db;
/** /**
* Copyright 2002-2005 The Apache Software Foundation * Copyright 2002-2006 The Apache Software Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
package org.apache.lucene.store.db; package org.apache.lucene.store.db;
/** /**
* Copyright 2002-2005 The Apache Software Foundation * Copyright 2002-2006 The Apache Software Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
package org.apache.lucene.store.db; package org.apache.lucene.store.db;
/** /**
* Copyright 2002-2005 The Apache Software Foundation * Copyright 2002-2006 The Apache Software Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
package org.apache.lucene.store.db; package org.apache.lucene.store.db;
/** /**
* Copyright 2002-2005 The Apache Software Foundation * Copyright 2002-2006 The Apache Software Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
package org.apache.lucene.store.db; package org.apache.lucene.store.db;
/** /**
* Copyright 2002-2005 The Apache Software Foundation * Copyright 2002-2006 The Apache Software Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
package org.apache.lucene.store.db; package org.apache.lucene.store.db;
/** /**
* Copyright 2002-2005 The Apache Software Foundation * Copyright 2002-2006 The Apache Software Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -3,36 +3,28 @@
<description> <description>
Lucene DB integration Lucene DB integration
- bdb: using the Java interface of C Berkeley DB
- bdb-je: using Berkeley DB Java Edition
</description> </description>
<property name="db.version" value="4.3.29"/> <target name="bdb">
<ant dir="bdb" />
<path id="db.jar">
<pathelement location="lib/db-${db.version}.jar"/>
</path>
<available classname="com.sleepycat.db.internal.Db" property="db.jar.exists">
<classpath refid="db.jar"/>
</available>
<pathconvert property="project.classpath"
targetos="unix"
refid="db.jar"
/>
<import file="../contrib-build.xml"/>
<target name="get-db-jar" unless="db.jar.exists">
<mkdir dir="lib"/>
<get src="http://downloads.osafoundation.org/db/db-${db.version}.jar"
dest="lib/db-${db.version}.jar"
/>
</target> </target>
<target name="check-and-get-db-jar" depends="get-db-jar"> <target name="bdb-je">
<ant dir="bdb-je" />
</target> </target>
<target name="init" depends="common.init,check-and-get-db-jar"> <target name="default" depends="bdb,bdb-je" />
<target name="clean">
<ant dir="bdb" target="clean" />
<ant dir="bdb-je" target="clean" />
</target> </target>
<target name="test">
<ant dir="bdb" target="test" />
<ant dir="bdb-je" target="test" />
</target>
</project> </project>