001: package org.apache.lucene.store.je;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.DataInputStream;
022: import java.io.IOException;
023: import java.util.ArrayList;
024: import java.util.Collections;
025: import java.util.HashSet;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.Set;
029:
030: import org.apache.lucene.store.Directory;
031: import org.apache.lucene.store.IndexInput;
032: import org.apache.lucene.store.IndexOutput;
033: import org.apache.lucene.store.Lock;
034:
035: import com.sleepycat.je.Cursor;
036: import com.sleepycat.je.Database;
037: import com.sleepycat.je.DatabaseEntry;
038: import com.sleepycat.je.DatabaseException;
039: import com.sleepycat.je.OperationStatus;
040: import com.sleepycat.je.Transaction;
041:
042: /**
043: * Port of Andi Vajda's DbDirectory to to Java Edition of Berkeley Database
044: *
045: * A JEDirectory is a Berkeley DB JE based implementation of
046: * {@link org.apache.lucene.store.Directory Directory}. It uses two
047: * {@link com.sleepycat.je.Database Db} database handles, one for storing file
048: * records and another for storing file data blocks.
049: *
050: * @author Aaron Donovan
051: */
052:
053: public class JEDirectory extends Directory {
054:
055: protected Set openFiles = Collections
056: .synchronizedSet(new HashSet());
057:
058: protected Database files, blocks;
059:
060: protected Transaction txn;
061:
062: protected int flags;
063:
064: /**
065: * Instantiate a DbDirectory. The same threading rules that apply to
066: * Berkeley DB handles apply to instances of DbDirectory.
067: *
068: * @param txn
069: * a transaction handle that is going to be used for all db
070: * operations done by this instance. This parameter may be
071: * <code>null</code>.
072: * @param files
073: * a db handle to store file records.
074: * @param blocks
075: * a db handle to store file data blocks.
076: * @param flags
077: * flags used for db read operations.
078: */
079:
080: public JEDirectory(Transaction txn, Database files,
081: Database blocks, int flags) {
082: super ();
083:
084: this .txn = txn;
085: this .files = files;
086: this .blocks = blocks;
087: this .flags = flags;
088: }
089:
090: public JEDirectory(Transaction txn, Database files, Database blocks) {
091: this (txn, files, blocks, 0);
092: }
093:
094: public void close() throws IOException {
095: flush();
096: }
097:
098: /**
099: * Flush the currently open files. After they have been flushed it is safe
100: * to commit the transaction without closing this DbDirectory instance
101: * first.
102: *
103: * @see #setTransaction
104: */
105: public void flush() throws IOException {
106: Iterator iterator = openFiles.iterator();
107:
108: while (iterator.hasNext()) {
109: System.out.println(((JEIndexOutput) iterator.next()).file
110: .getName());
111: // ((IndexOutput) iterator.next()).flush();
112: }
113: }
114:
115: public IndexOutput createOutput(String name) throws IOException {
116: return new JEIndexOutput(this , name, true);
117: }
118:
119: public void deleteFile(String name) throws IOException {
120: new File(name).delete(this );
121: }
122:
123: public boolean fileExists(String name) throws IOException {
124: return new File(name).exists(this );
125: }
126:
127: public long fileLength(String name) throws IOException {
128: File file = new File(name);
129:
130: if (file.exists(this ))
131: return file.getLength();
132:
133: throw new IOException("File does not exist: " + name);
134: }
135:
136: public long fileModified(String name) throws IOException {
137: File file = new File(name);
138:
139: if (file.exists(this ))
140: return file.getTimeModified();
141:
142: throw new IOException("File does not exist: " + name);
143: }
144:
145: public String[] list() throws IOException {
146: Cursor cursor = null;
147: List list = new ArrayList();
148:
149: try {
150: try {
151: DatabaseEntry key = new DatabaseEntry(new byte[0]);
152: DatabaseEntry data = new DatabaseEntry(null);
153:
154: data.setPartial(true);
155: // TODO see if cursor needs configuration
156: cursor = files.openCursor(txn, null);
157: // TODO see if LockMode should be set
158: if (cursor.getNext(key, data, null) != OperationStatus.NOTFOUND) {
159: ByteArrayInputStream buffer = new ByteArrayInputStream(
160: key.getData());
161: DataInputStream in = new DataInputStream(buffer);
162: String name = in.readUTF();
163:
164: in.close();
165: list.add(name);
166:
167: while (cursor.getNext(key, data, null) != OperationStatus.NOTFOUND) {
168: buffer = new ByteArrayInputStream(key.getData());
169: in = new DataInputStream(buffer);
170: name = in.readUTF();
171: in.close();
172:
173: list.add(name);
174: }
175: }
176: } finally {
177: if (cursor != null)
178: cursor.close();
179: }
180: } catch (DatabaseException e) {
181: throw new IOException(e.getMessage());
182: }
183:
184: return (String[]) list.toArray(new String[list.size()]);
185: }
186:
187: public IndexInput openInput(String name) throws IOException {
188: return new JEIndexInput(this , name);
189: }
190:
191: public Lock makeLock(String name) {
192: return new JELock();
193: }
194:
195: public void renameFile(String from, String to) throws IOException {
196: new File(from).rename(this , to);
197: }
198:
199: public void touchFile(String name) throws IOException {
200: File file = new File(name);
201: long length = 0L;
202:
203: if (file.exists(this ))
204: length = file.getLength();
205:
206: file.modify(this , length, System.currentTimeMillis());
207: }
208:
209: /**
210: * Once a transaction handle was committed it is no longer valid. In order
211: * to continue using this JEDirectory instance after a commit, the
212: * transaction handle has to be replaced.
213: *
214: * @param txn
215: * the new transaction handle to use
216: */
217: public void setTransaction(Transaction txn) {
218: this.txn = txn;
219: }
220: }
|