/* * 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. Locking /// implementation is by default the {@link SingleInstanceLockFactory} /// but can be changed with {@link #setLockFactory}. /// /// /// $Id: RAMDirectory.java 781333 2009-06-03 10:38:57Z mikemccand $ /// [Serializable] public class RAMDirectory:Directory { private const long serialVersionUID = 1L; internal protected Support.Dictionary fileMap = new Support.Dictionary(); internal protected long sizeInBytes = 0; // ***** // Lock acquisition sequence: RAMDirectory, then RAMFile // ***** /// Constructs an empty {@link Directory}. public RAMDirectory() { SetLockFactory(new SingleInstanceLockFactory()); } /// 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. ///

/// Note that the resulting RAMDirectory instance is fully /// independent from the original Directory (it is a /// complete copy). Any subsequent changes to the /// original Directory will not be visible in the /// RAMDirectory instance. /// ///

/// a Directory value /// /// if an error occurs /// public RAMDirectory(Directory dir):this(dir, false) { } private RAMDirectory(Directory dir, bool closeDir):this() { Directory.Copy(dir, this, closeDir); } /// Creates a new RAMDirectory instance from the {@link FSDirectory}. /// /// /// a File specifying the index directory /// /// /// /// /// Use {@link #RAMDirectory(Directory)} instead /// [Obsolete("Use RAMDirectory(Directory) instead")] public RAMDirectory(System.IO.FileInfo dir):this(FSDirectory.GetDirectory(dir), true) { } /// Creates a new RAMDirectory instance from the {@link FSDirectory}. /// /// /// a String specifying the full index directory path /// /// /// /// /// Use {@link #RAMDirectory(Directory)} instead /// [Obsolete("Use RAMDirectory(Directory) instead")] public RAMDirectory(System.String dir):this(FSDirectory.GetDirectory(dir), true) { } //https://issues.apache.org/jira/browse/LUCENENET-174 [System.Runtime.Serialization.OnDeserialized] void OnDeserialized(System.Runtime.Serialization.StreamingContext context) { if (lockFactory == null) { SetLockFactory(new SingleInstanceLockFactory()); } } [Obsolete("Lucene.Net-2.9.1. This method overrides obsolete member Lucene.Net.Store.Directory.List()")] public override System.String[] List() { lock (this) { return ListAll(); } } public override System.String[] ListAll() { lock (this) { EnsureOpen(); System.String[] result = new System.String[fileMap.Count]; int i = 0; foreach(string key in fileMap.Keys) { result[i++] = key; } return result; } } /// Returns true iff the named file exists in this directory. public override bool FileExists(System.String name) { EnsureOpen(); RAMFile file; lock (this) { file = (RAMFile) fileMap[name]; } return file != null; } /// Returns the time the named file was last modified. /// IOException if the file does not exist public override long FileModified(System.String name) { EnsureOpen(); RAMFile file; lock (this) { file = (RAMFile) fileMap[name]; } if (file == null) throw new System.IO.FileNotFoundException(name); return file.GetLastModified(); } /// Set the modified time of an existing file to now. /// IOException if the file does not exist public override void TouchFile(System.String name) { EnsureOpen(); RAMFile file; lock (this) { file = (RAMFile) fileMap[name]; } if (file == null) throw new System.IO.FileNotFoundException(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 ie) { // In 3.0 we will change this to throw // InterruptedException instead Support.ThreadClass.Current().Interrupt(); throw new System.SystemException(ie.Message, ie); } ts2 = System.DateTime.Now.Ticks; } while (ts1 == ts2); file.SetLastModified(ts2); } /// Returns the length in bytes of a file in the directory. /// IOException if the file does not exist public override long FileLength(System.String name) { EnsureOpen(); RAMFile file; lock (this) { file = (RAMFile) fileMap[name]; } if (file == null) throw new System.IO.FileNotFoundException(name); return file.GetLength(); } /// Return total size in bytes of all files in this /// directory. This is currently quantized to /// RAMOutputStream.BUFFER_SIZE. /// public long SizeInBytes() { lock (this) { EnsureOpen(); return sizeInBytes; } } /// Removes an existing file in the directory. /// IOException if the file does not exist public override void DeleteFile(System.String name) { lock (this) { EnsureOpen(); RAMFile file = (RAMFile) fileMap[name]; if (file != null) { fileMap.Remove(name); file.directory = null; sizeInBytes -= file.sizeInBytes; } else throw new System.IO.FileNotFoundException(name); } } /// Renames an existing file in the directory. /// FileNotFoundException if from does not exist /// /// [Obsolete] public override void RenameFile(System.String from, System.String to) { lock (this) { EnsureOpen(); RAMFile fromFile = (RAMFile) fileMap[from]; if (fromFile == null) throw new System.IO.FileNotFoundException(from); RAMFile toFile = (RAMFile) fileMap[to]; if (toFile != null) { sizeInBytes -= toFile.sizeInBytes; // updates to RAMFile.sizeInBytes synchronized on directory toFile.directory = null; } fileMap.Remove(from); fileMap[to] = fromFile; } } /// 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) { EnsureOpen(); RAMFile file = new RAMFile(this); lock (this) { RAMFile existing = (RAMFile) fileMap[name]; if (existing != null) { sizeInBytes -= existing.sizeInBytes; existing.directory = null; } fileMap[name] = file; } return new RAMOutputStream(file); } /// Returns a stream reading an existing file. public override IndexInput OpenInput(System.String name) { EnsureOpen(); RAMFile file; lock (this) { file = (RAMFile) fileMap[name]; } if (file == null) throw new System.IO.FileNotFoundException(name); return new RAMInputStream(file); } /// Closes the store to future operations, releasing associated memory. public override void Close() { isOpen = false; fileMap = null; } /// /// .NET /// public override void Dispose() { Close(); } public long sizeInBytes_ForNUnitTest { get { return sizeInBytes; } set { sizeInBytes = value; } } } }