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 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 dirthrows IOException {
051     this(dir, false);
052   }
053 
054   private RAMDirectory(Directory dir, boolean closeDirthrows 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 = (intis.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 dirthrows 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 dirthrows 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 namethrows 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 namethrows 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(01);
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 }