RAMDirectory.java
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 @SuppressWarnings({"rawtypes","unchecked"})
034 public final class RAMDirectory extends Directory {
035   Hashtable files = new Hashtable();
036 
037   /** Constructs an empty {@link Directory}. */
038   public RAMDirectory() {
039   }
040 
041   /**
042    * Creates a new <code>RAMDirectory</code> instance from a different
043    <code>Directory</code> implementation.  This can be used to load
044    * a disk-based index into memory.
045    <P>
046    * This should be used only with indices that can fit into memory.
047    *
048    @param dir a <code>Directory</code> value
049    @exception IOException if an error occurs
050    */
051   public RAMDirectory(Directory dirthrows IOException {
052     this(dir, false);
053   }
054 
055   private RAMDirectory(Directory dir, boolean closeDirthrows IOException {
056     final String[] files = dir.list();
057     for (int i = 0; i < files.length; i++) {
058       // make place on ram disk
059       OutputStream os = createFile(files[i]);
060       // read current file
061       InputStream is = dir.openFile(files[i]);
062       // and copy to ram disk
063       int len = (intis.length();
064       byte[] buf = new byte[len];
065       is.readBytes(buf, 0, len);
066       os.writeBytes(buf, len);
067       // graceful cleanup
068       is.close();
069       os.close();
070     }
071     if(closeDir)
072       dir.close();
073   }
074 
075   /**
076    * Creates a new <code>RAMDirectory</code> instance from the {@link FSDirectory}.
077    *
078    @param dir a <code>File</code> specifying the index directory
079    */
080   public RAMDirectory(File dirthrows IOException {
081     this(FSDirectory.getDirectory(dir, false)true);
082   }
083 
084   /**
085    * Creates a new <code>RAMDirectory</code> instance from the {@link FSDirectory}.
086    *
087    @param dir a <code>String</code> specifying the full index directory path
088    */
089   public RAMDirectory(String dirthrows IOException {
090     this(FSDirectory.getDirectory(dir, false)true);
091   }
092 
093   /** Returns an array of strings, one for each file in the directory. */
094   @Override
095   public final String[] list() {
096     String[] result = new String[files.size()];
097     int i = 0;
098     Enumeration names = files.keys();
099     while (names.hasMoreElements())
100       result[i++(String)names.nextElement();
101     return result;
102   }
103 
104   /** Returns true iff the named file exists in this directory. */
105   @Override
106   public final boolean fileExists(String name) {
107     RAMFile file = (RAMFile)files.get(name);
108     return file != null;
109   }
110 
111   /** Returns the time the named file was last modified. */
112   @Override
113   public final long fileModified(String namethrows IOException {
114     RAMFile file = (RAMFile)files.get(name);
115     return file.lastModified;
116   }
117 
118   /** Set the modified time of an existing file to now. */
119   @Override
120   public void touchFile(String namethrows IOException {
121 //     final boolean MONITOR = false;
122 
123     RAMFile file = (RAMFile)files.get(name);
124     long ts2, ts1 = System.currentTimeMillis();
125     do {
126       try {
127         Thread.sleep(01);
128       catch (InterruptedException e) {}
129       ts2 = System.currentTimeMillis();
130 //       if (MONITOR) {
131 //         count++;
132 //       }
133     while(ts1 == ts2);
134 
135     file.lastModified = ts2;
136 
137 //     if (MONITOR)
138 //         System.out.println("SLEEP COUNT: " + count);
139   }
140 
141   /** Returns the length in bytes of a file in the directory. */
142   @Override
143   public final long fileLength(String name) {
144     RAMFile file = (RAMFile)files.get(name);
145     return file.length;
146   }
147 
148   /** Removes an existing file in the directory. */
149   @Override
150   public final void deleteFile(String name) {
151     files.remove(name);
152   }
153 
154   /** Removes an existing file in the directory. */
155   @Override
156   public final void renameFile(String from, String to) {
157     RAMFile file = (RAMFile)files.get(from);
158     files.remove(from);
159     files.put(to, file);
160   }
161 
162   /** Creates a new, empty file in the directory with the given name.
163       Returns a stream writing this file. */
164   @Override
165   public final OutputStream createFile(String name) {
166     RAMFile file = new RAMFile();
167     files.put(name, file);
168     return new RAMOutputStream(file);
169   }
170 
171   /** Returns a stream reading an existing file. */
172   @Override
173   public final InputStream openFile(String name) {
174     RAMFile file = (RAMFile)files.get(name);
175     return new RAMInputStream(file);
176   }
177 
178   /** Construct a {@link Lock}.
179    @param name the name of the lock file
180    */
181   @Override
182   public final Lock makeLock(final String name) {
183     return new Lock() {
184       @Override
185       public boolean obtain() throws IOException {
186         synchronized (files) {
187           if (!fileExists(name)) {
188             createFile(name).close();
189             return true;
190           }
191           return false;
192         }
193       }
194       @Override
195       public void release() {
196         deleteFile(name);
197       }
198       @Override
199       public boolean isLocked() {
200         return fileExists(name);
201       }
202     };
203   }
204 
205   /** Closes the store to future operations. */
206   @Override
207   public final void close() {
208   }
209 }