/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */ using System; namespace Lucene.Net.Store { /// A memory-resident {@link Directory} implementation. /// /// /// $Id: RAMDirectory.java 351779 2005-12-02 17:37:50Z bmesser $ /// public sealed class RAMDirectory : Directory { private class AnonymousClassLock : Lock { public AnonymousClassLock(System.String name, RAMDirectory enclosingInstance) { InitBlock(name, enclosingInstance); } private void InitBlock(System.String name, RAMDirectory enclosingInstance) { this.name = name; this.enclosingInstance = enclosingInstance; } private System.String name; private RAMDirectory enclosingInstance; public RAMDirectory Enclosing_Instance { get { return enclosingInstance; } } public override bool Obtain() { lock (Enclosing_Instance.files.SyncRoot) { if (!Enclosing_Instance.FileExists(name)) { Enclosing_Instance.CreateOutput(name).Close(); return true; } return false; } } public override void Release() { Enclosing_Instance.DeleteFile(name); } public override bool IsLocked() { return Enclosing_Instance.FileExists(name); } } internal System.Collections.Hashtable files = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); /// Constructs an empty {@link Directory}. public RAMDirectory() { } /// Creates a new RAMDirectory instance from a different /// Directory implementation. This can be used to load /// a disk-based index into memory. ///

/// This should be used only with indices that can fit into memory. /// ///

/// a Directory value /// /// if an error occurs /// public RAMDirectory(Directory dir):this(dir, false) { } private RAMDirectory(Directory dir, bool closeDir) { System.String[] files = dir.List(); byte[] buf = new byte[BufferedIndexOutput.BUFFER_SIZE]; for (int i = 0; i < files.Length; i++) { // make place on ram disk IndexOutput os = CreateOutput(System.IO.Path.GetFileName(files[i])); // read current file IndexInput is_Renamed = dir.OpenInput(files[i]); // and copy to ram disk long len = (int) is_Renamed.Length(); long readCount = 0; while (readCount < len) { int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len ? (int) (len - readCount) : BufferedIndexOutput.BUFFER_SIZE; is_Renamed.ReadBytes(buf, 0, toRead); os.WriteBytes(buf, toRead); readCount += toRead; } // graceful cleanup is_Renamed.Close(); os.Close(); } if (closeDir) dir.Close(); } /// Creates a new RAMDirectory instance from the {@link FSDirectory}. /// /// /// a File specifying the index directory /// public RAMDirectory(System.IO.FileInfo dir) : this(FSDirectory.GetDirectory(dir, false), true) { } /// Creates a new RAMDirectory instance from the {@link FSDirectory}. /// /// /// a String specifying the full index directory path /// public RAMDirectory(System.String dir) : this(FSDirectory.GetDirectory(dir, false), true) { } /// Returns an array of strings, one for each file in the directory. public override System.String[] List() { System.String[] result = new System.String[files.Count]; int i = 0; System.Collections.IEnumerator names = files.Keys.GetEnumerator(); while (names.MoveNext()) { result[i++] = ((System.String) names.Current); } return result; } /// Returns true iff the named file exists in this directory. public override bool FileExists(System.String name) { RAMFile file = (RAMFile) files[name]; return file != null; } /// Returns the time the named file was last modified. public override long FileModified(System.String name) { RAMFile file = (RAMFile) files[name]; return file.lastModified; } /// Set the modified time of an existing file to now. public override void TouchFile(System.String name) { // final boolean MONITOR = false; RAMFile file = (RAMFile) files[name]; long ts2, ts1 = System.DateTime.Now.Ticks; do { try { System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * 0 + 100 * 1)); } catch (System.Threading.ThreadInterruptedException) { } ts2 = System.DateTime.Now.Ticks; // if (MONITOR) { // count++; // } } while (ts1 == ts2); file.lastModified = ts2; // if (MONITOR) // System.out.println("SLEEP COUNT: " + count); } /// Returns the length in bytes of a file in the directory. public override long FileLength(System.String name) { RAMFile file = (RAMFile) files[name]; return file.length; } /// Removes an existing file in the directory. public override void DeleteFile(System.String name) { files.Remove(name); } /// Removes an existing file in the directory. public override void RenameFile(System.String from, System.String to) { RAMFile file = (RAMFile) files[from]; files.Remove(from); files[to] = file; } /// Creates a new, empty file in the directory with the given name. /// Returns a stream writing this file. /// public override IndexOutput CreateOutput(System.String name) { RAMFile file = new RAMFile(); files[name] = file; return new RAMOutputStream(file); } /// Returns a stream reading an existing file. public override IndexInput OpenInput(System.String name) { RAMFile file = (RAMFile) files[name]; return new RAMInputStream(file); } /// Construct a {@link Lock}. /// the name of the lock file /// public override Lock MakeLock(System.String name) { return new AnonymousClassLock(name, this); } /// Closes the store to future operations. public override void Close() { } } }