001 package gate.creole.annic.apache.lucene.store;
002
003 /**
004 * Copyright 2004 The Apache Software Foundation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.IOException;
020 import java.io.File;
021 import java.util.Hashtable;
022 import java.util.Enumeration;
023
024 import gate.creole.annic.apache.lucene.store.Directory;
025 import gate.creole.annic.apache.lucene.store.InputStream;
026 import gate.creole.annic.apache.lucene.store.OutputStream;
027
028 /**
029 * A memory-resident {@link Directory} implementation.
030 *
031 * @version $Id: RAMDirectory.java 529 2004-10-05 11:55:26Z niraj $
032 */
033 public final class RAMDirectory extends Directory {
034 Hashtable files = new Hashtable();
035
036 /** Constructs an empty {@link Directory}. */
037 public RAMDirectory() {
038 }
039
040 /**
041 * Creates a new <code>RAMDirectory</code> instance from a different
042 * <code>Directory</code> implementation. This can be used to load
043 * a disk-based index into memory.
044 * <P>
045 * This should be used only with indices that can fit into memory.
046 *
047 * @param dir a <code>Directory</code> value
048 * @exception IOException if an error occurs
049 */
050 public RAMDirectory(Directory dir) throws IOException {
051 this(dir, false);
052 }
053
054 private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
055 final String[] files = dir.list();
056 for (int i = 0; i < files.length; i++) {
057 // make place on ram disk
058 OutputStream os = createFile(files[i]);
059 // read current file
060 InputStream is = dir.openFile(files[i]);
061 // and copy to ram disk
062 int len = (int) is.length();
063 byte[] buf = new byte[len];
064 is.readBytes(buf, 0, len);
065 os.writeBytes(buf, len);
066 // graceful cleanup
067 is.close();
068 os.close();
069 }
070 if(closeDir)
071 dir.close();
072 }
073
074 /**
075 * Creates a new <code>RAMDirectory</code> instance from the {@link FSDirectory}.
076 *
077 * @param dir a <code>File</code> specifying the index directory
078 */
079 public RAMDirectory(File dir) throws IOException {
080 this(FSDirectory.getDirectory(dir, false), true);
081 }
082
083 /**
084 * Creates a new <code>RAMDirectory</code> instance from the {@link FSDirectory}.
085 *
086 * @param dir a <code>String</code> specifying the full index directory path
087 */
088 public RAMDirectory(String dir) throws IOException {
089 this(FSDirectory.getDirectory(dir, false), true);
090 }
091
092 /** Returns an array of strings, one for each file in the directory. */
093 public final String[] list() {
094 String[] result = new String[files.size()];
095 int i = 0;
096 Enumeration names = files.keys();
097 while (names.hasMoreElements())
098 result[i++] = (String)names.nextElement();
099 return result;
100 }
101
102 /** Returns true iff the named file exists in this directory. */
103 public final boolean fileExists(String name) {
104 RAMFile file = (RAMFile)files.get(name);
105 return file != null;
106 }
107
108 /** Returns the time the named file was last modified. */
109 public final long fileModified(String name) throws IOException {
110 RAMFile file = (RAMFile)files.get(name);
111 return file.lastModified;
112 }
113
114 /** Set the modified time of an existing file to now. */
115 public void touchFile(String name) throws IOException {
116 // final boolean MONITOR = false;
117
118 RAMFile file = (RAMFile)files.get(name);
119 long ts2, ts1 = System.currentTimeMillis();
120 do {
121 try {
122 Thread.sleep(0, 1);
123 } catch (InterruptedException e) {}
124 ts2 = System.currentTimeMillis();
125 // if (MONITOR) {
126 // count++;
127 // }
128 } while(ts1 == ts2);
129
130 file.lastModified = ts2;
131
132 // if (MONITOR)
133 // System.out.println("SLEEP COUNT: " + count);
134 }
135
136 /** Returns the length in bytes of a file in the directory. */
137 public final long fileLength(String name) {
138 RAMFile file = (RAMFile)files.get(name);
139 return file.length;
140 }
141
142 /** Removes an existing file in the directory. */
143 public final void deleteFile(String name) {
144 files.remove(name);
145 }
146
147 /** Removes an existing file in the directory. */
148 public final void renameFile(String from, String to) {
149 RAMFile file = (RAMFile)files.get(from);
150 files.remove(from);
151 files.put(to, file);
152 }
153
154 /** Creates a new, empty file in the directory with the given name.
155 Returns a stream writing this file. */
156 public final OutputStream createFile(String name) {
157 RAMFile file = new RAMFile();
158 files.put(name, file);
159 return new RAMOutputStream(file);
160 }
161
162 /** Returns a stream reading an existing file. */
163 public final InputStream openFile(String name) {
164 RAMFile file = (RAMFile)files.get(name);
165 return new RAMInputStream(file);
166 }
167
168 /** Construct a {@link Lock}.
169 * @param name the name of the lock file
170 */
171 public final Lock makeLock(final String name) {
172 return new Lock() {
173 public boolean obtain() throws IOException {
174 synchronized (files) {
175 if (!fileExists(name)) {
176 createFile(name).close();
177 return true;
178 }
179 return false;
180 }
181 }
182 public void release() {
183 deleteFile(name);
184 }
185 public boolean isLocked() {
186 return fileExists(name);
187 }
188 };
189 }
190
191 /** Closes the store to future operations. */
192 public final void close() {
193 }
194 }
|