You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by cc...@apache.org on 2012/02/28 23:43:28 UTC

[Lucene.Net] svn commit: r1294875 [18/45] - in /incubator/lucene.net/trunk: ./ build/ build/vs2010/contrib/ build/vs2010/test/ doc/ src/ src/contrib/Analyzers/ src/contrib/Analyzers/AR/ src/contrib/Analyzers/BR/ src/contrib/Analyzers/CJK/ src/contrib/Analyzers/Cn/ ...

Modified: incubator/lucene.net/trunk/src/core/Index/InvertedDocConsumer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/InvertedDocConsumer.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/InvertedDocConsumer.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/InvertedDocConsumer.cs Tue Feb 28 22:43:08 2012
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 
 namespace Lucene.Net.Index
 {
@@ -28,9 +29,11 @@ namespace Lucene.Net.Index
 		
 		/// <summary>Abort (called after hitting AbortException) </summary>
 		public abstract void  Abort();
-		
-		/// <summary>Flush a new segment </summary>
-		internal abstract void  Flush(System.Collections.IDictionary threadsAndFields, SegmentWriteState state);
+
+	    /// <summary>Flush a new segment </summary>
+	    internal abstract void Flush(
+	        IDictionary<InvertedDocConsumerPerThread, ICollection<InvertedDocConsumerPerField>> threadsAndFields,
+	        SegmentWriteState state);
 		
 		/// <summary>Close doc stores </summary>
 		internal abstract void  CloseDocStore(SegmentWriteState state);

Modified: incubator/lucene.net/trunk/src/core/Index/InvertedDocEndConsumer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/InvertedDocEndConsumer.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/InvertedDocEndConsumer.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/InvertedDocEndConsumer.cs Tue Feb 28 22:43:08 2012
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 
 namespace Lucene.Net.Index
 {
@@ -23,7 +24,7 @@ namespace Lucene.Net.Index
 	abstract class InvertedDocEndConsumer
 	{
 		public abstract InvertedDocEndConsumerPerThread AddThread(DocInverterPerThread docInverterPerThread);
-		public abstract void  Flush(System.Collections.IDictionary threadsAndFields, SegmentWriteState state);
+        public abstract void Flush(IDictionary<InvertedDocEndConsumerPerThread, ICollection<InvertedDocEndConsumerPerField>> threadsAndFields, SegmentWriteState state);
 		internal abstract void  CloseDocStore(SegmentWriteState state);
 		public abstract void  Abort();
 		internal abstract void  SetFieldInfos(FieldInfos fieldInfos);

Modified: incubator/lucene.net/trunk/src/core/Index/KeepOnlyLastCommitDeletionPolicy.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/KeepOnlyLastCommitDeletionPolicy.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/KeepOnlyLastCommitDeletionPolicy.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/KeepOnlyLastCommitDeletionPolicy.cs Tue Feb 28 22:43:08 2012
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 
 namespace Lucene.Net.Index
 {
@@ -30,21 +31,21 @@ namespace Lucene.Net.Index
 	{
 		
 		/// <summary> Deletes all commits except the most recent one.</summary>
-		public void  OnInit(System.Collections.IList commits)
+		public void  OnInit<T>(IList<T> commits) where T : IndexCommit
 		{
 			// Note that commits.size() should normally be 1:
 			OnCommit(commits);
 		}
 		
 		/// <summary> Deletes all commits except the most recent one.</summary>
-		public void  OnCommit(System.Collections.IList commits)
+		public void  OnCommit<T>(IList<T> commits) where T : IndexCommit
 		{
 			// Note that commits.size() should normally be 2 (if not
 			// called by onInit above):
 			int size = commits.Count;
 			for (int i = 0; i < size - 1; i++)
 			{
-				((IndexCommit) commits[i]).Delete();
+				commits[i].Delete();
 			}
 		}
 	}

Modified: incubator/lucene.net/trunk/src/core/Index/LogByteSizeMergePolicy.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/LogByteSizeMergePolicy.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/LogByteSizeMergePolicy.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/LogByteSizeMergePolicy.cs Tue Feb 28 22:43:08 2012
@@ -23,7 +23,7 @@ namespace Lucene.Net.Index
 	/// <summary>This is a <see cref="LogMergePolicy" /> that measures size of a
 	/// segment as the total byte size of the segment's files. 
 	/// </summary>
-	public class LogByteSizeMergePolicy:LogMergePolicy
+	public class LogByteSizeMergePolicy : LogMergePolicy
 	{
 		
 		/// <seealso cref="SetMinMergeMB">
@@ -33,9 +33,10 @@ namespace Lucene.Net.Index
 		/// <summary>Default maximum segment size.  A segment of this size</summary>
 		/// <seealso cref="SetMaxMergeMB">
 		/// </seealso>
-		public static readonly long DEFAULT_MAX_MERGE_MB = System.Int64.MaxValue;
+		public static readonly long DEFAULT_MAX_MERGE_MB = long.MaxValue;
 		
-		public LogByteSizeMergePolicy(IndexWriter writer):base(writer)
+		public LogByteSizeMergePolicy(IndexWriter writer)
+            : base(writer)
 		{
 			minMergeSize = (long) (DEFAULT_MIN_MERGE_MB * 1024 * 1024);
             //mgarski - the line below causes an overflow in .NET, resulting in a negative number...
@@ -46,6 +47,11 @@ namespace Lucene.Net.Index
 		{
 			return SizeBytes(info);
 		}
+
+        protected override void Dispose(bool disposing)
+        {
+            // Do nothing.
+        }
 		
 		/// <summary><p/>Determines the largest segment (measured by total
 		/// byte size of the segment's files, in MB) that may be

Modified: incubator/lucene.net/trunk/src/core/Index/LogDocMergePolicy.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/LogDocMergePolicy.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/LogDocMergePolicy.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/LogDocMergePolicy.cs Tue Feb 28 22:43:08 2012
@@ -25,7 +25,7 @@ namespace Lucene.Net.Index
 	/// into account). 
 	/// </summary>
 	
-	public class LogDocMergePolicy:LogMergePolicy
+	public class LogDocMergePolicy : LogMergePolicy
 	{
 		
 		/// <seealso cref="SetMinMergeDocs">
@@ -59,7 +59,12 @@ namespace Lucene.Net.Index
 		{
 			minMergeSize = minMergeDocs;
 		}
-		
+
+        protected override void Dispose(bool disposing)
+        {
+            // Do nothing.
+        }
+
 		/// <summary>Get the minimum size for a segment to remain
 		/// un-merged.
 		/// </summary>

Modified: incubator/lucene.net/trunk/src/core/Index/LogMergePolicy.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/LogMergePolicy.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/LogMergePolicy.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/LogMergePolicy.cs Tue Feb 28 22:43:08 2012
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 
 namespace Lucene.Net.Index
 {
@@ -38,7 +39,7 @@ namespace Lucene.Net.Index
 	/// file(s) for the segment.<p/>
 	/// </summary>
 	
-	public abstract class LogMergePolicy:MergePolicy
+	public abstract class LogMergePolicy : MergePolicy
 	{
 		
 		/// <summary>Defines the allowed range of log(size) for each
@@ -77,8 +78,8 @@ namespace Lucene.Net.Index
 		
 		private bool useCompoundFile = true;
 		private bool useCompoundDocStore = true;
-		
-		public LogMergePolicy(IndexWriter writer):base(writer)
+
+	    protected LogMergePolicy(IndexWriter writer):base(writer)
 		{
 		}
 		
@@ -205,10 +206,6 @@ namespace Lucene.Net.Index
 			return calibrateSizeByDeletes;
 		}
 		
-		public override void  Close()
-		{
-		}
-		
 		abstract protected internal long Size(SegmentInfo info);
 		
 		protected internal virtual long SizeDocs(SegmentInfo info)
@@ -239,7 +236,7 @@ namespace Lucene.Net.Index
 			}
 		}
 		
-		private bool IsOptimized(SegmentInfos infos, int maxNumSegments, System.Collections.Hashtable segmentsToOptimize)
+		private bool IsOptimized(SegmentInfos infos, int maxNumSegments, ISet<SegmentInfo> segmentsToOptimize)
 		{
 			int numSegments = infos.Count;
 			int numToOptimize = 0;
@@ -277,7 +274,7 @@ namespace Lucene.Net.Index
 		/// (mergeFactor at a time) so the <see cref="MergeScheduler" />
 		/// in use may make use of concurrency. 
 		/// </summary>
-		public override MergeSpecification FindMergesForOptimize(SegmentInfos infos, int maxNumSegments, System.Collections.Hashtable segmentsToOptimize)
+		public override MergeSpecification FindMergesForOptimize(SegmentInfos infos, int maxNumSegments, ISet<SegmentInfo> segmentsToOptimize)
 		{
 			MergeSpecification spec;
 			
@@ -558,14 +555,14 @@ namespace Lucene.Net.Index
             else
             {
                 long totSize = 0;
-                for (int i = 0; i < infos.Count; i++)
+                foreach(SegmentInfo info in infos)
                 {
-                    totSize += Size(infos.Info(i));
+                    totSize += Size(info);
                 }
                 long mergeSize = 0;
-                for (int i = 0; i < infosToMerge.Count; i++)
+                foreach(SegmentInfo info in infosToMerge)
                 {
-                    mergeSize += Size(infosToMerge.Info(i));
+                    mergeSize += Size(info);
                 }
 
                 doCFS = mergeSize <= noCFSRatio * totSize;

Modified: incubator/lucene.net/trunk/src/core/Index/MergeDocIDRemapper.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/MergeDocIDRemapper.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/MergeDocIDRemapper.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/MergeDocIDRemapper.cs Tue Feb 28 22:43:08 2012
@@ -16,6 +16,7 @@
  */
 
 using System;
+using Lucene.Net.Support;
 
 namespace Lucene.Net.Index
 {
@@ -97,7 +98,7 @@ namespace Lucene.Net.Index
 				
 				while (hi >= lo)
 				{
-					int mid = SupportClass.Number.URShift((lo + hi), 1);
+					int mid = Number.URShift((lo + hi), 1);
 					int midValue = starts[mid];
 					if (oldDocID < midValue)
 						hi = mid - 1;

Modified: incubator/lucene.net/trunk/src/core/Index/MergePolicy.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/MergePolicy.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/MergePolicy.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/MergePolicy.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,7 @@
  */
 
 using System;
-
+using System.Collections.Generic;
 using Directory = Lucene.Net.Store.Directory;
 
 namespace Lucene.Net.Index
@@ -58,7 +58,7 @@ namespace Lucene.Net.Index
 	/// these APIs.
 	/// </summary>
 	
-	public abstract class MergePolicy
+	public abstract class MergePolicy : IDisposable
 	{
 		
 		/// <summary>OneMerge provides the information necessary to perform
@@ -71,21 +71,19 @@ namespace Lucene.Net.Index
 		public class OneMerge
 		{
 			
-			internal SegmentInfo info; // used by IndexWriter
-			internal bool mergeDocStores; // used by IndexWriter
-			internal bool optimize; // used by IndexWriter
-			internal bool registerDone; // used by IndexWriter
-			internal long mergeGen; // used by IndexWriter
-			internal bool isExternal; // used by IndexWriter
-			internal int maxNumSegmentsOptimize; // used by IndexWriter
-			internal SegmentReader[] readers; // used by IndexWriter
-			internal SegmentReader[] readersClone; // used by IndexWriter
+			internal SegmentInfo info;              // used by IndexWriter
+			internal bool mergeDocStores;           // used by IndexWriter
+			internal bool optimize;                 // used by IndexWriter
+			internal bool registerDone;             // used by IndexWriter
+			internal long mergeGen;                 // used by IndexWriter
+			internal bool isExternal;               // used by IndexWriter
+			internal int maxNumSegmentsOptimize;    // used by IndexWriter
+			internal SegmentReader[] readers;       // used by IndexWriter
+			internal SegmentReader[] readersClone;  // used by IndexWriter
 			internal SegmentInfos segments;
 			internal bool useCompoundFile;
 			internal bool aborted;
 			internal System.Exception error;
-
-            internal volatile bool mergeDone;     // used by IndexWriter
 			
 			public OneMerge(SegmentInfos segments, bool useCompoundFile)
 			{
@@ -184,7 +182,7 @@ namespace Lucene.Net.Index
 			
 			/// <summary> The subset of segments to be included in the primitive merge.</summary>
 			
-			public System.Collections.IList merges = new System.Collections.ArrayList();
+			public IList<OneMerge> merges = new List<OneMerge>();
 			
 			public virtual void  Add(OneMerge merge)
 			{
@@ -197,7 +195,7 @@ namespace Lucene.Net.Index
 				b.Append("MergeSpec:\n");
 				int count = merges.Count;
 				for (int i = 0; i < count; i++)
-					b.Append("  ").Append(1 + i).Append(": ").Append(((OneMerge) merges[i]).SegString(dir));
+					b.Append("  ").Append(1 + i).Append(": ").Append(merges[i].SegString(dir));
 				return b.ToString();
 			}
 		}
@@ -209,24 +207,12 @@ namespace Lucene.Net.Index
 		public class MergeException:System.SystemException
 		{
 			private Directory dir;
-			/// <deprecated>
-			/// Use <see cref="MergePolicy.MergeException(String,Directory)" /> instead 
-			/// </deprecated>
-            [Obsolete("Use MergePolicy.MergeException(String,Directory) instead ")]
-			public MergeException(System.String message):base(message)
-			{
-			}
+
 			public MergeException(System.String message, Directory dir):base(message)
 			{
 				this.dir = dir;
 			}
-			/// <deprecated>
-			/// Use <see cref="MergePolicy.MergeException(Exception,Directory)" /> instead 
-			/// </deprecated>
-            [Obsolete("Use MergePolicy.MergeException(Throwable,Directory) instead ")]
-			public MergeException(System.Exception exc):base(null, exc)
-			{
-			}
+
 			public MergeException(System.Exception exc, Directory dir):base(null, exc)
 			{
 				this.dir = dir;
@@ -252,8 +238,8 @@ namespace Lucene.Net.Index
 		}
 		
 		protected internal IndexWriter writer;
-		
-		public MergePolicy(IndexWriter writer)
+
+	    protected MergePolicy(IndexWriter writer)
 		{
 			this.writer = writer;
 		}
@@ -267,23 +253,24 @@ namespace Lucene.Net.Index
 		/// <param name="segmentInfos">the total set of segments in the index
 		/// </param>
 		public abstract MergeSpecification FindMerges(SegmentInfos segmentInfos);
-		
-		/// <summary> Determine what set of merge operations is necessary in order to optimize
-		/// the index. <see cref="IndexWriter" /> calls this when its
-		/// <see cref="IndexWriter.Optimize()" /> method is called. This call is always
-		/// synchronized on the <see cref="IndexWriter" /> instance so only one thread at a
-		/// time will call this method.
-		/// 
-		/// </summary>
-		/// <param name="segmentInfos">the total set of segments in the index
-		/// </param>
-		/// <param name="maxSegmentCount">requested maximum number of segments in the index (currently this
-		/// is always 1)
-		/// </param>
-		/// <param name="segmentsToOptimize">contains the specific SegmentInfo instances that must be merged
-		/// away. This may be a subset of all SegmentInfos.
-		/// </param>
-		public abstract MergeSpecification FindMergesForOptimize(SegmentInfos segmentInfos, int maxSegmentCount, System.Collections.Hashtable segmentsToOptimize);
+
+	    /// <summary> Determine what set of merge operations is necessary in order to optimize
+	    /// the index. <see cref="IndexWriter" /> calls this when its
+	    /// <see cref="IndexWriter.Optimize()" /> method is called. This call is always
+	    /// synchronized on the <see cref="IndexWriter" /> instance so only one thread at a
+	    /// time will call this method.
+	    /// 
+	    /// </summary>
+	    /// <param name="segmentInfos">the total set of segments in the index
+	    /// </param>
+	    /// <param name="maxSegmentCount">requested maximum number of segments in the index (currently this
+	    /// is always 1)
+	    /// </param>
+	    /// <param name="segmentsToOptimize">contains the specific SegmentInfo instances that must be merged
+	    /// away. This may be a subset of all SegmentInfos.
+	    /// </param>
+	    public abstract MergeSpecification FindMergesForOptimize(SegmentInfos segmentInfos, int maxSegmentCount,
+	                                                             ISet<SegmentInfo> segmentsToOptimize);
 		
 		/// <summary> Determine what set of merge operations is necessary in order to expunge all
 		/// deletes from the index.
@@ -292,9 +279,21 @@ namespace Lucene.Net.Index
 		/// <param name="segmentInfos">the total set of segments in the index
 		/// </param>
 		public abstract MergeSpecification FindMergesToExpungeDeletes(SegmentInfos segmentInfos);
-		
-		/// <summary> Release all resources for the policy.</summary>
-		public abstract void  Close();
+
+        /// <summary> Release all resources for the policy.</summary>
+        [Obsolete("Use Dispose() instead")]
+		public void Close()
+        {
+            Dispose();
+        }
+
+        /// <summary> Release all resources for the policy.</summary>
+	    public void Dispose()
+	    {
+	        Dispose(true);
+	    }
+
+	    protected abstract void Dispose(bool disposing);
 		
 		/// <summary> Returns true if a newly flushed (not from merge)
 		/// segment should use the compound file format.

Modified: incubator/lucene.net/trunk/src/core/Index/MergeScheduler.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/MergeScheduler.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/MergeScheduler.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/MergeScheduler.cs Tue Feb 28 22:43:08 2012
@@ -35,13 +35,24 @@ namespace Lucene.Net.Index
 	/// these APIs.
 	/// </summary>
 	
-	public abstract class MergeScheduler
+	public abstract class MergeScheduler : IDisposable
 	{
 		
 		/// <summary>Run the merges provided by <see cref="IndexWriter.GetNextMerge()" />. </summary>
 		public abstract void  Merge(IndexWriter writer);
 		
-		/// <summary>Close this MergeScheduler. </summary>
-		public abstract void  Close();
+        [Obsolete("Use Dispose() instead")]
+		public void Close()
+        {
+            Dispose();
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+	    /// <summary>Close this MergeScheduler. </summary>
+	    protected abstract void Dispose(bool disposing);
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/src/core/Index/MultiLevelSkipListReader.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/MultiLevelSkipListReader.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/MultiLevelSkipListReader.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/MultiLevelSkipListReader.cs Tue Feb 28 22:43:08 2012
@@ -31,7 +31,7 @@ namespace Lucene.Net.Index
 	/// Subclasses must implement the abstract method <see cref="ReadSkipData(int, IndexInput)" />
 	/// which defines the actual format of the skip data.
 	/// </summary>
-	abstract class MultiLevelSkipListReader
+	abstract class MultiLevelSkipListReader : IDisposable
 	{
 		// the maximum number of skip levels possible for this index
 		private int maxNumberOfSkipLevels;
@@ -50,6 +50,8 @@ namespace Lucene.Net.Index
 		
 		private int docCount;
 		private bool haveSkipped;
+
+	    private bool isDisposed;
 		
 		private IndexInput[] skipStream; // skipStream for each level
 		private long[] skipPointer; // the start pointer of each skip level
@@ -175,17 +177,29 @@ namespace Lucene.Net.Index
 				childPointer[level] = skipStream[level].ReadVLong() + skipPointer[level - 1];
 			}
 		}
-		
-		internal virtual void  Close()
-		{
-			for (int i = 1; i < skipStream.Length; i++)
-			{
-				if (skipStream[i] != null)
-				{
-					skipStream[i].Close();
-				}
-			}
-		}
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (isDisposed) return;
+
+            if (disposing)
+            {
+                for (int i = 1; i < skipStream.Length; i++)
+                {
+                    if (skipStream[i] != null)
+                    {
+                        skipStream[i].Close();
+                    }
+                }
+            }
+
+            isDisposed = true;
+        }
 		
 		/// <summary>initializes the reader </summary>
 		internal virtual void  Init(long skipPointer, int df)
@@ -265,11 +279,13 @@ namespace Lucene.Net.Index
 		
 		
 		/// <summary>used to buffer the top skip levels </summary>
-		private sealed class SkipBuffer:IndexInput
+		private sealed class SkipBuffer : IndexInput
 		{
 			private byte[] data;
 			private long pointer;
 			private int pos;
+
+		    private bool isDisposed;
 			
 			internal SkipBuffer(IndexInput input, int length)
 			{
@@ -277,11 +293,17 @@ namespace Lucene.Net.Index
 				pointer = input.GetFilePointer();
 				input.ReadBytes(data, 0, length);
 			}
-			
-			public override void  Close()
-			{
-				data = null;
-			}
+
+            protected override void Dispose(bool disposing)
+            {
+                if (isDisposed) return;
+                if (disposing)
+                {
+                    data = null;
+                }
+
+                isDisposed = true;
+            }
 			
 			public override long GetFilePointer()
 			{

Modified: incubator/lucene.net/trunk/src/core/Index/MultiReader.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/MultiReader.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/MultiReader.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/MultiReader.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,8 @@
  */
 
 using System;
-
+using System.Linq;
+using Lucene.Net.Support;
 using Document = Lucene.Net.Documents.Document;
 using FieldSelector = Lucene.Net.Documents.FieldSelector;
 using MultiTermDocs = Lucene.Net.Index.DirectoryReader.MultiTermDocs;
@@ -26,481 +27,462 @@ using DefaultSimilarity = Lucene.Net.Sea
 
 namespace Lucene.Net.Index
 {
-	
-	/// <summary>An IndexReader which reads multiple indexes, appending their content.
-	/// 
-	/// </summary>
-	/// <version>  $Id: MultiReader.java 782406 2009-06-07 16:31:18Z mikemccand $
-	/// </version>
-	public class MultiReader:IndexReader, System.ICloneable
-	{
-		protected internal IndexReader[] subReaders;
-		private int[] starts; // 1st docno for each segment
-		private bool[] decrefOnClose; // remember which subreaders to decRef on close
-		private System.Collections.IDictionary normsCache = new System.Collections.Hashtable();
-		private int maxDoc = 0;
-		private int numDocs = - 1;
-		private bool hasDeletions = false;
-		
-		/// <summary> <p/>Construct a MultiReader aggregating the named set of (sub)readers.
-		/// Directory locking for delete, undeleteAll, and setNorm operations is
-		/// left to the subreaders. <p/>
-		/// <p/>Note that all subreaders are closed if this Multireader is closed.<p/>
-		/// </summary>
-		/// <param name="subReaders">set of (sub)readers
-		/// </param>
-		/// <throws>  IOException </throws>
-		public MultiReader(IndexReader[] subReaders)
-		{
-			Initialize(subReaders, true);
-		}
-		
-		/// <summary> <p/>Construct a MultiReader aggregating the named set of (sub)readers.
-		/// Directory locking for delete, undeleteAll, and setNorm operations is
-		/// left to the subreaders. <p/>
-		/// </summary>
-		/// <param name="closeSubReaders">indicates whether the subreaders should be closed
-		/// when this MultiReader is closed
-		/// </param>
-		/// <param name="subReaders">set of (sub)readers
-		/// </param>
-		/// <throws>  IOException </throws>
-		public MultiReader(IndexReader[] subReaders, bool closeSubReaders)
-		{
-			Initialize(subReaders, closeSubReaders);
-		}
-		
-		private void  Initialize(IndexReader[] subReaders, bool closeSubReaders)
-		{
-			this.subReaders = new IndexReader[subReaders.Length];
-			subReaders.CopyTo(this.subReaders, 0);
-			starts = new int[subReaders.Length + 1]; // build starts array
-			decrefOnClose = new bool[subReaders.Length];
-			for (int i = 0; i < subReaders.Length; i++)
-			{
-				starts[i] = maxDoc;
-				maxDoc += subReaders[i].MaxDoc(); // compute maxDocs
-				
-				if (!closeSubReaders)
-				{
-					subReaders[i].IncRef();
-					decrefOnClose[i] = true;
-				}
-				else
-				{
-					decrefOnClose[i] = false;
-				}
-				
-				if (subReaders[i].HasDeletions())
-					hasDeletions = true;
-			}
-			starts[subReaders.Length] = maxDoc;
-		}
-		
-		/// <summary> Tries to reopen the subreaders.
-		/// <br/>
-		/// If one or more subreaders could be re-opened (i. e. subReader.reopen() 
-		/// returned a new instance != subReader), then a new MultiReader instance 
-		/// is returned, otherwise this instance is returned.
-		/// <p/>
-		/// A re-opened instance might share one or more subreaders with the old 
-		/// instance. Index modification operations result in undefined behavior
-		/// when performed before the old instance is closed.
-		/// (see <see cref="IndexReader.Reopen()" />).
-		/// <p/>
-		/// If subreaders are shared, then the reference count of those
-		/// readers is increased to ensure that the subreaders remain open
-		/// until the last referring reader is closed.
-		/// 
-		/// </summary>
-		/// <throws>  CorruptIndexException if the index is corrupt </throws>
-		/// <throws>  IOException if there is a low-level IO error  </throws>
-		public override IndexReader Reopen()
-		{
-			lock (this)
-			{
-				return DoReopen(false);
-			}
-		}
-		
-		/// <summary> Clones the subreaders.
-		/// (see <see cref="IndexReader.Clone()" />).
-		/// <br/>
-		/// <p/>
-		/// If subreaders are shared, then the reference count of those
-		/// readers is increased to ensure that the subreaders remain open
-		/// until the last referring reader is closed.
-		/// </summary>
-		public override System.Object Clone()
-		{
-			try
-			{
-				return DoReopen(true);
-			}
-			catch (System.Exception ex)
-			{
-				throw new System.SystemException(ex.Message, ex);
-			}
-		}
-		
-		/// <summary> If clone is true then we clone each of the subreaders</summary>
-		/// <param name="doClone">
-		/// </param>
-		/// <returns> New IndexReader, or same one (this) if
-		/// reopen/clone is not necessary
-		/// </returns>
-		/// <throws>  CorruptIndexException </throws>
-		/// <throws>  IOException </throws>
-		protected internal virtual IndexReader DoReopen(bool doClone)
-		{
-			EnsureOpen();
-			
-			bool reopened = false;
-			IndexReader[] newSubReaders = new IndexReader[subReaders.Length];
-			
-			bool success = false;
-			try
-			{
-				for (int i = 0; i < subReaders.Length; i++)
-				{
-					if (doClone)
-						newSubReaders[i] = (IndexReader) subReaders[i].Clone();
-					else
-						newSubReaders[i] = subReaders[i].Reopen();
-					// if at least one of the subreaders was updated we remember that
-					// and return a new MultiReader
-					if (newSubReaders[i] != subReaders[i])
-					{
-						reopened = true;
-					}
-				}
-				success = true;
-			}
-			finally
-			{
-				if (!success && reopened)
-				{
-					for (int i = 0; i < newSubReaders.Length; i++)
-					{
-						if (newSubReaders[i] != subReaders[i])
-						{
-							try
-							{
-								newSubReaders[i].Close();
-							}
-							catch (System.IO.IOException ignore)
-							{
-								// keep going - we want to clean up as much as possible
-							}
-						}
-					}
-				}
-			}
-			
-			if (reopened)
-			{
-				bool[] newDecrefOnClose = new bool[subReaders.Length];
-				for (int i = 0; i < subReaders.Length; i++)
-				{
-					if (newSubReaders[i] == subReaders[i])
-					{
-						newSubReaders[i].IncRef();
-						newDecrefOnClose[i] = true;
-					}
-				}
-				MultiReader mr = new MultiReader(newSubReaders);
-				mr.decrefOnClose = newDecrefOnClose;
-				mr.SetDisableFakeNorms(GetDisableFakeNorms());
-				return mr;
-			}
-			else
-			{
-				return this;
-			}
-		}
-		
-		public override TermFreqVector[] GetTermFreqVectors(int n)
-		{
-			EnsureOpen();
-			int i = ReaderIndex(n); // find segment num
-			return subReaders[i].GetTermFreqVectors(n - starts[i]); // dispatch to segment
-		}
-		
-		public override TermFreqVector GetTermFreqVector(int n, System.String field)
-		{
-			EnsureOpen();
-			int i = ReaderIndex(n); // find segment num
-			return subReaders[i].GetTermFreqVector(n - starts[i], field);
-		}
-		
-		
-		public override void  GetTermFreqVector(int docNumber, System.String field, TermVectorMapper mapper)
-		{
-			EnsureOpen();
-			int i = ReaderIndex(docNumber); // find segment num
-			subReaders[i].GetTermFreqVector(docNumber - starts[i], field, mapper);
-		}
-		
-		public override void  GetTermFreqVector(int docNumber, TermVectorMapper mapper)
-		{
-			EnsureOpen();
-			int i = ReaderIndex(docNumber); // find segment num
-			subReaders[i].GetTermFreqVector(docNumber - starts[i], mapper);
-		}
-		
-		public override bool IsOptimized()
-		{
-			return false;
-		}
-		
-		public override int NumDocs()
-		{
-			// Don't call ensureOpen() here (it could affect performance)
+    
+    /// <summary>An IndexReader which reads multiple indexes, appending 
+    /// their content.
+    /// </summary>
+    public class MultiReader:IndexReader, System.ICloneable
+    {
+        protected internal IndexReader[] subReaders;
+        private int[] starts; // 1st docno for each segment
+        private bool[] decrefOnClose; // remember which subreaders to decRef on close
+        private System.Collections.Generic.IDictionary<string, byte[]> normsCache = new HashMap<string,byte[]>();
+        private int maxDoc = 0;
+        private int numDocs = - 1;
+        private bool hasDeletions = false;
+        
+        /// <summary> <p/>Construct a MultiReader aggregating the named set of (sub)readers.
+        /// Directory locking for delete, undeleteAll, and setNorm operations is
+        /// left to the subreaders. <p/>
+        /// <p/>Note that all subreaders are closed if this Multireader is closed.<p/>
+        /// </summary>
+        /// <param name="subReaders">set of (sub)readers
+        /// </param>
+        /// <throws>  IOException </throws>
+        public MultiReader(params IndexReader[] subReaders)
+        {
+            Initialize(subReaders, true);
+        }
+        
+        /// <summary> <p/>Construct a MultiReader aggregating the named set of (sub)readers.
+        /// Directory locking for delete, undeleteAll, and setNorm operations is
+        /// left to the subreaders. <p/>
+        /// </summary>
+        /// <param name="closeSubReaders">indicates whether the subreaders should be closed
+        /// when this MultiReader is closed
+        /// </param>
+        /// <param name="subReaders">set of (sub)readers
+        /// </param>
+        /// <throws>  IOException </throws>
+        public MultiReader(IndexReader[] subReaders, bool closeSubReaders)
+        {
+            Initialize(subReaders, closeSubReaders);
+        }
+        
+        private void  Initialize(IndexReader[] subReaders, bool closeSubReaders)
+        {
+            // Deep copy
+            this.subReaders = subReaders.ToArray();
+            starts = new int[subReaders.Length + 1]; // build starts array
+            decrefOnClose = new bool[subReaders.Length];
+            for (int i = 0; i < subReaders.Length; i++)
+            {
+                starts[i] = maxDoc;
+                maxDoc += subReaders[i].MaxDoc(); // compute maxDocs
+                
+                if (!closeSubReaders)
+                {
+                    subReaders[i].IncRef();
+                    decrefOnClose[i] = true;
+                }
+                else
+                {
+                    decrefOnClose[i] = false;
+                }
+                
+                if (subReaders[i].HasDeletions())
+                    hasDeletions = true;
+            }
+            starts[subReaders.Length] = maxDoc;
+        }
+        
+        /// <summary> Tries to reopen the subreaders.
+        /// <br/>
+        /// If one or more subreaders could be re-opened (i. e. subReader.reopen() 
+        /// returned a new instance != subReader), then a new MultiReader instance 
+        /// is returned, otherwise this instance is returned.
+        /// <p/>
+        /// A re-opened instance might share one or more subreaders with the old 
+        /// instance. Index modification operations result in undefined behavior
+        /// when performed before the old instance is closed.
+        /// (see <see cref="IndexReader.Reopen()" />).
+        /// <p/>
+        /// If subreaders are shared, then the reference count of those
+        /// readers is increased to ensure that the subreaders remain open
+        /// until the last referring reader is closed.
+        /// 
+        /// </summary>
+        /// <throws>  CorruptIndexException if the index is corrupt </throws>
+        /// <throws>  IOException if there is a low-level IO error  </throws>
+        public override IndexReader Reopen()
+        {
+            lock (this)
+            {
+                return DoReopen(false);
+            }
+        }
+        
+        /// <summary> Clones the subreaders.
+        /// (see <see cref="IndexReader.Clone()" />).
+        /// <br/>
+        /// <p/>
+        /// If subreaders are shared, then the reference count of those
+        /// readers is increased to ensure that the subreaders remain open
+        /// until the last referring reader is closed.
+        /// </summary>
+        public override System.Object Clone()
+        {
+            try
+            {
+                return DoReopen(true);
+            }
+            catch (System.Exception ex)
+            {
+                throw new System.SystemException(ex.Message, ex);
+            }
+        }
+        
+        /// <summary> If clone is true then we clone each of the subreaders</summary>
+        /// <param name="doClone">
+        /// </param>
+        /// <returns> New IndexReader, or same one (this) if
+        /// reopen/clone is not necessary
+        /// </returns>
+        /// <throws>  CorruptIndexException </throws>
+        /// <throws>  IOException </throws>
+        protected internal virtual IndexReader DoReopen(bool doClone)
+        {
+            EnsureOpen();
+            
+            bool reopened = false;
+            IndexReader[] newSubReaders = new IndexReader[subReaders.Length];
+            
+            bool success = false;
+            try
+            {
+                for (int i = 0; i < subReaders.Length; i++)
+                {
+                    if (doClone)
+                        newSubReaders[i] = (IndexReader) subReaders[i].Clone();
+                    else
+                        newSubReaders[i] = subReaders[i].Reopen();
+                    // if at least one of the subreaders was updated we remember that
+                    // and return a new MultiReader
+                    if (newSubReaders[i] != subReaders[i])
+                    {
+                        reopened = true;
+                    }
+                }
+                success = true;
+            }
+            finally
+            {
+                if (!success && reopened)
+                {
+                    for (int i = 0; i < newSubReaders.Length; i++)
+                    {
+                        if (newSubReaders[i] != subReaders[i])
+                        {
+                            try
+                            {
+                                newSubReaders[i].Close();
+                            }
+                            catch (System.IO.IOException ignore)
+                            {
+                                // keep going - we want to clean up as much as possible
+                            }
+                        }
+                    }
+                }
+            }
+            
+            if (reopened)
+            {
+                bool[] newDecrefOnClose = new bool[subReaders.Length];
+                for (int i = 0; i < subReaders.Length; i++)
+                {
+                    if (newSubReaders[i] == subReaders[i])
+                    {
+                        newSubReaders[i].IncRef();
+                        newDecrefOnClose[i] = true;
+                    }
+                }
+                MultiReader mr = new MultiReader(newSubReaders);
+                mr.decrefOnClose = newDecrefOnClose;
+                return mr;
+            }
+            else
+            {
+                return this;
+            }
+        }
+        
+        public override TermFreqVector[] GetTermFreqVectors(int n)
+        {
+            EnsureOpen();
+            int i = ReaderIndex(n); // find segment num
+            return subReaders[i].GetTermFreqVectors(n - starts[i]); // dispatch to segment
+        }
+        
+        public override TermFreqVector GetTermFreqVector(int n, System.String field)
+        {
+            EnsureOpen();
+            int i = ReaderIndex(n); // find segment num
+            return subReaders[i].GetTermFreqVector(n - starts[i], field);
+        }
+        
+        
+        public override void  GetTermFreqVector(int docNumber, System.String field, TermVectorMapper mapper)
+        {
+            EnsureOpen();
+            int i = ReaderIndex(docNumber); // find segment num
+            subReaders[i].GetTermFreqVector(docNumber - starts[i], field, mapper);
+        }
+        
+        public override void  GetTermFreqVector(int docNumber, TermVectorMapper mapper)
+        {
+            EnsureOpen();
+            int i = ReaderIndex(docNumber); // find segment num
+            subReaders[i].GetTermFreqVector(docNumber - starts[i], mapper);
+        }
+        
+        public override bool IsOptimized()
+        {
+            return false;
+        }
+        
+        public override int NumDocs()
+        {
+            // Don't call ensureOpen() here (it could affect performance)
             // NOTE: multiple threads may wind up init'ing
             // numDocs... but that's harmless
-			if (numDocs == - 1)
-			{
-				// check cache
-				int n = 0; // cache miss--recompute
-				for (int i = 0; i < subReaders.Length; i++)
-					n += subReaders[i].NumDocs(); // sum from readers
-				numDocs = n;
-			}
-			return numDocs;
-		}
-		
-		public override int MaxDoc()
-		{
-			// Don't call ensureOpen() here (it could affect performance)
-			return maxDoc;
-		}
-		
-		// inherit javadoc
-		public override Document Document(int n, FieldSelector fieldSelector)
-		{
-			EnsureOpen();
-			int i = ReaderIndex(n); // find segment num
-			return subReaders[i].Document(n - starts[i], fieldSelector); // dispatch to segment reader
-		}
-		
-		public override bool IsDeleted(int n)
-		{
-			// Don't call ensureOpen() here (it could affect performance)
-			int i = ReaderIndex(n); // find segment num
-			return subReaders[i].IsDeleted(n - starts[i]); // dispatch to segment reader
-		}
-		
-		public override bool HasDeletions()
-		{
-			// Don't call ensureOpen() here (it could affect performance)
-			return hasDeletions;
-		}
-		
-		protected internal override void  DoDelete(int n)
-		{
-			numDocs = - 1; // invalidate cache
-			int i = ReaderIndex(n); // find segment num
-			subReaders[i].DeleteDocument(n - starts[i]); // dispatch to segment reader
-			hasDeletions = true;
-		}
-		
-		protected internal override void  DoUndeleteAll()
-		{
-			for (int i = 0; i < subReaders.Length; i++)
-				subReaders[i].UndeleteAll();
-			
-			hasDeletions = false;
-			numDocs = - 1; // invalidate cache
-		}
-		
-		private int ReaderIndex(int n)
-		{
-			// find reader for doc n:
-			return DirectoryReader.ReaderIndex(n, this.starts, this.subReaders.Length);
-		}
-		
-		public override bool HasNorms(System.String field)
-		{
-			EnsureOpen();
-			for (int i = 0; i < subReaders.Length; i++)
-			{
-				if (subReaders[i].HasNorms(field))
-					return true;
-			}
-			return false;
-		}
-		
-		private byte[] ones;
-		private byte[] FakeNorms()
-		{
-			if (ones == null)
-				ones = SegmentReader.CreateFakeNorms(MaxDoc());
-			return ones;
-		}
-		
-		public override byte[] Norms(System.String field)
-		{
-			lock (this)
-			{
-				EnsureOpen();
-				byte[] bytes = (byte[]) normsCache[field];
-				if (bytes != null)
-					return bytes; // cache hit
-				if (!HasNorms(field))
-					return GetDisableFakeNorms()?null:FakeNorms();
-				
-				bytes = new byte[MaxDoc()];
-				for (int i = 0; i < subReaders.Length; i++)
-					subReaders[i].Norms(field, bytes, starts[i]);
-				normsCache[field] = bytes; // update cache
-				return bytes;
-			}
-		}
-		
-		public override void  Norms(System.String field, byte[] result, int offset)
-		{
-			lock (this)
-			{
-				EnsureOpen();
-				byte[] bytes = (byte[]) normsCache[field];
-				for (int i = 0; i < subReaders.Length; i++)
-				// read from segments
-					subReaders[i].Norms(field, result, offset + starts[i]);
-				
-				if (bytes == null && !HasNorms(field))
-				{
+            if (numDocs == - 1)
+            {
+                // check cache
+                int n = 0; // cache miss--recompute
+                for (int i = 0; i < subReaders.Length; i++)
+                    n += subReaders[i].NumDocs(); // sum from readers
+                numDocs = n;
+            }
+            return numDocs;
+        }
+        
+        public override int MaxDoc()
+        {
+            // Don't call ensureOpen() here (it could affect performance)
+            return maxDoc;
+        }
+        
+        // inherit javadoc
+        public override Document Document(int n, FieldSelector fieldSelector)
+        {
+            EnsureOpen();
+            int i = ReaderIndex(n); // find segment num
+            return subReaders[i].Document(n - starts[i], fieldSelector); // dispatch to segment reader
+        }
+        
+        public override bool IsDeleted(int n)
+        {
+            // Don't call ensureOpen() here (it could affect performance)
+            int i = ReaderIndex(n); // find segment num
+            return subReaders[i].IsDeleted(n - starts[i]); // dispatch to segment reader
+        }
+        
+        public override bool HasDeletions()
+        {
+            // Don't call ensureOpen() here (it could affect performance)
+            return hasDeletions;
+        }
+        
+        protected internal override void  DoDelete(int n)
+        {
+            numDocs = - 1; // invalidate cache
+            int i = ReaderIndex(n); // find segment num
+            subReaders[i].DeleteDocument(n - starts[i]); // dispatch to segment reader
+            hasDeletions = true;
+        }
+        
+        protected internal override void  DoUndeleteAll()
+        {
+            for (int i = 0; i < subReaders.Length; i++)
+                subReaders[i].UndeleteAll();
+            
+            hasDeletions = false;
+            numDocs = - 1; // invalidate cache
+        }
+        
+        private int ReaderIndex(int n)
+        {
+            // find reader for doc n:
+            return DirectoryReader.ReaderIndex(n, this.starts, this.subReaders.Length);
+        }
+        
+        public override bool HasNorms(System.String field)
+        {
+            EnsureOpen();
+            for (int i = 0; i < subReaders.Length; i++)
+            {
+                if (subReaders[i].HasNorms(field))
+                    return true;
+            }
+            return false;
+        }
+        
+        public override byte[] Norms(System.String field)
+        {
+            lock (this)
+            {
+                EnsureOpen();
+                byte[] bytes = normsCache[field];
+                if (bytes != null)
+                    return bytes; // cache hit
+                if (!HasNorms(field))
+                    return null;
+                
+                bytes = new byte[MaxDoc()];
+                for (int i = 0; i < subReaders.Length; i++)
+                    subReaders[i].Norms(field, bytes, starts[i]);
+                normsCache[field] = bytes; // update cache
+                return bytes;
+            }
+        }
+        
+        public override void  Norms(System.String field, byte[] result, int offset)
+        {
+            lock (this)
+            {
+                EnsureOpen();
+                byte[] bytes = normsCache[field];
+                for (int i = 0; i < subReaders.Length; i++)
+                // read from segments
+                    subReaders[i].Norms(field, result, offset + starts[i]);
+                
+                if (bytes == null && !HasNorms(field))
+                {
                     for (int i = offset; i < result.Length; i++)
                     {
                         result[i] = (byte) DefaultSimilarity.EncodeNorm(1.0f);
                     }
-				}
-				else if (bytes != null)
-				{
-					// cache hit
-					Array.Copy(bytes, 0, result, offset, MaxDoc());
-				}
-				else
-				{
-					for (int i = 0; i < subReaders.Length; i++)
-					{
-						// read from segments
-						subReaders[i].Norms(field, result, offset + starts[i]);
-					}
-				}
-			}
-		}
-		
-		protected internal override void  DoSetNorm(int n, System.String field, byte value_Renamed)
-		{
-			lock (normsCache.SyncRoot)
-			{
-				normsCache.Remove(field); // clear cache
-			}
-			int i = ReaderIndex(n); // find segment num
-			subReaders[i].SetNorm(n - starts[i], field, value_Renamed); // dispatch
-		}
-		
-		public override TermEnum Terms()
-		{
-			EnsureOpen();
-			return new MultiTermEnum(this, subReaders, starts, null);
-		}
-		
-		public override TermEnum Terms(Term term)
-		{
-			EnsureOpen();
-			return new MultiTermEnum(this, subReaders, starts, term);
-		}
-		
-		public override int DocFreq(Term t)
-		{
-			EnsureOpen();
-			int total = 0; // sum freqs in segments
-			for (int i = 0; i < subReaders.Length; i++)
-				total += subReaders[i].DocFreq(t);
-			return total;
-		}
-		
-		public override TermDocs TermDocs()
-		{
-			EnsureOpen();
-			return new MultiTermDocs(this, subReaders, starts);
-		}
-		
-		public override TermPositions TermPositions()
-		{
-			EnsureOpen();
-			return new MultiTermPositions(this, subReaders, starts);
-		}
-		
-		/// <deprecated> 
-		/// </deprecated>
-        [Obsolete]
-		protected internal override void  DoCommit()
-		{
-			DoCommit(null);
-		}
+                }
+                else if (bytes != null)
+                {
+                    // cache hit
+                    Array.Copy(bytes, 0, result, offset, MaxDoc());
+                }
+                else
+                {
+                    for (int i = 0; i < subReaders.Length; i++)
+                    {
+                        // read from segments
+                        subReaders[i].Norms(field, result, offset + starts[i]);
+                    }
+                }
+            }
+        }
+        
+        protected internal override void  DoSetNorm(int n, System.String field, byte value_Renamed)
+        {
+            lock (normsCache)
+            {
+                normsCache.Remove(field); // clear cache
+            }
+            int i = ReaderIndex(n); // find segment num
+            subReaders[i].SetNorm(n - starts[i], field, value_Renamed); // dispatch
+        }
+        
+        public override TermEnum Terms()
+        {
+            EnsureOpen();
+            return new MultiTermEnum(this, subReaders, starts, null);
+        }
+        
+        public override TermEnum Terms(Term term)
+        {
+            EnsureOpen();
+            return new MultiTermEnum(this, subReaders, starts, term);
+        }
+        
+        public override int DocFreq(Term t)
+        {
+            EnsureOpen();
+            int total = 0; // sum freqs in segments
+            for (int i = 0; i < subReaders.Length; i++)
+                total += subReaders[i].DocFreq(t);
+            return total;
+        }
+        
+        public override TermDocs TermDocs()
+        {
+            EnsureOpen();
+            return new MultiTermDocs(this, subReaders, starts);
+        }
+        
+        public override TermPositions TermPositions()
+        {
+            EnsureOpen();
+            return new MultiTermPositions(this, subReaders, starts);
+        }
 
         protected internal override void DoCommit(System.Collections.Generic.IDictionary<string, string> commitUserData)
-		{
-			for (int i = 0; i < subReaders.Length; i++)
-				subReaders[i].Commit(commitUserData);
-		}
-		
-		protected internal override void  DoClose()
-		{
-			lock (this)
-			{
-				for (int i = 0; i < subReaders.Length; i++)
-				{
-					if (decrefOnClose[i])
-					{
-						subReaders[i].DecRef();
-					}
-					else
-					{
-						subReaders[i].Close();
-					}
-				}
-			}
+        {
+            for (int i = 0; i < subReaders.Length; i++)
+                subReaders[i].Commit(commitUserData);
+        }
+        
+        protected internal override void  DoClose()
+        {
+            lock (this)
+            {
+                for (int i = 0; i < subReaders.Length; i++)
+                {
+                    if (decrefOnClose[i])
+                    {
+                        subReaders[i].DecRef();
+                    }
+                    else
+                    {
+                        subReaders[i].Close();
+                    }
+                }
+            }
 
             // NOTE: only needed in case someone had asked for
             // FieldCache for top-level reader (which is generally
             // not a good idea):
             Lucene.Net.Search.FieldCache_Fields.DEFAULT.Purge(this);
-		}
+        }
 
         public override System.Collections.Generic.ICollection<string> GetFieldNames(IndexReader.FieldOption fieldNames)
-		{
-			EnsureOpen();
-			return DirectoryReader.GetFieldNames(fieldNames, this.subReaders);
-		}
-		
-		/// <summary> Checks recursively if all subreaders are up to date. </summary>
-		public override bool IsCurrent()
-		{
-			for (int i = 0; i < subReaders.Length; i++)
-			{
-				if (!subReaders[i].IsCurrent())
-				{
-					return false;
-				}
-			}
-			
-			// all subreaders are up to date
-			return true;
-		}
-		
-		/// <summary>Not implemented.</summary>
-		/// <throws>  UnsupportedOperationException </throws>
-		public override long GetVersion()
-		{
-			throw new System.NotSupportedException("MultiReader does not support this method.");
-		}
-		
-		public override IndexReader[] GetSequentialSubReaders()
-		{
-			return subReaders;
-		}
-	}
+        {
+            EnsureOpen();
+            return DirectoryReader.GetFieldNames(fieldNames, this.subReaders);
+        }
+        
+        /// <summary> Checks recursively if all subreaders are up to date. </summary>
+        public override bool IsCurrent()
+        {
+            for (int i = 0; i < subReaders.Length; i++)
+            {
+                if (!subReaders[i].IsCurrent())
+                {
+                    return false;
+                }
+            }
+            
+            // all subreaders are up to date
+            return true;
+        }
+        
+        /// <summary>Not implemented.</summary>
+        /// <throws>  UnsupportedOperationException </throws>
+        public override long GetVersion()
+        {
+            throw new System.NotSupportedException("MultiReader does not support this method.");
+        }
+        
+        public override IndexReader[] GetSequentialSubReaders()
+        {
+            return subReaders;
+        }
+    }
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/src/core/Index/MultipleTermPositions.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/MultipleTermPositions.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/MultipleTermPositions.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/MultipleTermPositions.cs Tue Feb 28 22:43:08 2012
@@ -16,8 +16,8 @@
  */
 
 using System;
-
-using PriorityQueue = Lucene.Net.Util.PriorityQueue;
+using System.Collections.Generic;
+using Lucene.Net.Util;
 
 namespace Lucene.Net.Index
 {
@@ -28,30 +28,25 @@ namespace Lucene.Net.Index
 	/// </summary>
 	public class MultipleTermPositions : TermPositions
 	{
-		
-		private sealed class TermPositionsQueue:PriorityQueue
+		private sealed class TermPositionsQueue : PriorityQueue<TermPositions>
 		{
-			internal TermPositionsQueue(System.Collections.IList termPositions)
+			internal TermPositionsQueue(LinkedList<TermPositions> termPositions)
 			{
 				Initialize(termPositions.Count);
 				
-				System.Collections.IEnumerator i = termPositions.GetEnumerator();
-				while (i.MoveNext())
-				{
-					TermPositions tp = (TermPositions) i.Current;
+				foreach(TermPositions tp in termPositions)
 					if (tp.Next())
-						Put(tp);
-				}
+						Add(tp);
 			}
 			
 			internal TermPositions Peek()
 			{
-				return (TermPositions) Top();
+				return Top();
 			}
 			
-			public override bool LessThan(System.Object a, System.Object b)
+			public override bool LessThan(TermPositions a, TermPositions b)
 			{
-				return ((TermPositions) a).Doc() < ((TermPositions) b).Doc();
+				return a.Doc() < b.Doc();
 			}
 		}
 		
@@ -112,7 +107,8 @@ namespace Lucene.Net.Index
 		private int _freq;
 		private TermPositionsQueue _termPositionsQueue;
 		private IntQueue _posList;
-		
+
+	    private bool isDisposed;
 		/// <summary> Creates a new <c>MultipleTermPositions</c> instance.
 		/// 
 		/// </summary>
@@ -120,10 +116,10 @@ namespace Lucene.Net.Index
 		/// </exception>
 		public MultipleTermPositions(IndexReader indexReader, Term[] terms)
 		{
-			System.Collections.IList termPositions = new System.Collections.ArrayList();
+			var termPositions = new System.Collections.Generic.LinkedList<TermPositions>();
 			
 			for (int i = 0; i < terms.Length; i++)
-				termPositions.Add(indexReader.TermPositions(terms[i]));
+				termPositions.AddLast(indexReader.TermPositions(terms[i]));
 			
 			_termPositionsQueue = new TermPositionsQueue(termPositions);
 			_posList = new IntQueue();
@@ -146,7 +142,7 @@ namespace Lucene.Net.Index
 					_posList.add(tp.NextPosition());
 				
 				if (tp.Next())
-					_termPositionsQueue.AdjustTop();
+					_termPositionsQueue.UpdateTop();
 				else
 				{
 					_termPositionsQueue.Pop();
@@ -170,9 +166,9 @@ namespace Lucene.Net.Index
 		{
 			while (_termPositionsQueue.Peek() != null && target > _termPositionsQueue.Peek().Doc())
 			{
-				TermPositions tp = (TermPositions) _termPositionsQueue.Pop();
+				TermPositions tp = _termPositionsQueue.Pop();
 				if (tp.SkipTo(target))
-					_termPositionsQueue.Put(tp);
+					_termPositionsQueue.Add(tp);
 				else
 					tp.Close();
 			}
@@ -189,22 +185,40 @@ namespace Lucene.Net.Index
 			return _freq;
 		}
 		
+        [Obsolete("Use Dispose() instead")]
 		public void  Close()
 		{
-			while (_termPositionsQueue.Size() > 0)
-				((TermPositions) _termPositionsQueue.Pop()).Close();
+		    Dispose();
 		}
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (isDisposed) return;
+            
+            if (disposing)
+            {
+                while (_termPositionsQueue.Size() > 0)
+                    _termPositionsQueue.Pop().Close();
+            }
+
+            isDisposed = true;
+        }
 		
 		/// <summary> Not implemented.</summary>
 		/// <throws>  UnsupportedOperationException </throws>
-		public virtual void  Seek(Term arg0)
+		public virtual void Seek(Term arg0)
 		{
 			throw new System.NotSupportedException();
 		}
 		
 		/// <summary> Not implemented.</summary>
 		/// <throws>  UnsupportedOperationException </throws>
-		public virtual void  Seek(TermEnum termEnum)
+		public virtual void Seek(TermEnum termEnum)
 		{
 			throw new System.NotSupportedException();
 		}

Modified: incubator/lucene.net/trunk/src/core/Index/NormsWriter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/NormsWriter.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/NormsWriter.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/NormsWriter.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,8 @@
  */
 
 using System;
-
+using System.Collections.Generic;
+using Lucene.Net.Support;
 using IndexOutput = Lucene.Net.Store.IndexOutput;
 using Similarity = Lucene.Net.Search.Similarity;
 
@@ -30,7 +31,7 @@ namespace Lucene.Net.Index
 	/// merges all of these together into a single _X.nrm file.
 	/// </summary>
 	
-	sealed class NormsWriter:InvertedDocEndConsumer
+	sealed class NormsWriter : InvertedDocEndConsumer
 	{
 		
 		private static readonly byte defaultNorm;
@@ -45,7 +46,7 @@ namespace Lucene.Net.Index
 		}
 		
 		// We only write the _X.nrm file at flush
-		internal void  Files(System.Collections.ICollection files)
+		internal void  Files(ICollection<string> files)
 		{
 		}
 		
@@ -57,35 +58,31 @@ namespace Lucene.Net.Index
 		/// <summary>Produce _X.nrm if any document had a field with norms
 		/// not disabled 
 		/// </summary>
-		public override void  Flush(System.Collections.IDictionary threadsAndFields, SegmentWriteState state)
+        public override void Flush(IDictionary<InvertedDocEndConsumerPerThread,ICollection<InvertedDocEndConsumerPerField>> threadsAndFields, SegmentWriteState state)
 		{
-			
-			System.Collections.IDictionary byField = new System.Collections.Hashtable();
+
+            IDictionary<FieldInfo, IList<NormsWriterPerField>> byField = new HashMap<FieldInfo, IList<NormsWriterPerField>>();
 			
 			// Typically, each thread will have encountered the same
 			// field.  So first we collate by field, ie, all
 			// per-thread field instances that correspond to the
 			// same FieldInfo
-			System.Collections.IEnumerator it = new System.Collections.Hashtable(threadsAndFields).GetEnumerator();
-			while (it.MoveNext())
+			foreach(var entry in threadsAndFields)
 			{
-				System.Collections.DictionaryEntry entry = (System.Collections.DictionaryEntry) it.Current;
-				
-				System.Collections.ICollection fields = (System.Collections.ICollection) entry.Value;
-				System.Collections.IEnumerator fieldsIt = fields.GetEnumerator();
-                System.Collections.ArrayList fieldsToRemove = new System.Collections.ArrayList();
-				
+				ICollection<InvertedDocEndConsumerPerField> fields = entry.Value;
+				IEnumerator<InvertedDocEndConsumerPerField> fieldsIt = fields.GetEnumerator();
+			    var fieldsToRemove = new HashSet<NormsWriterPerField>();
 				while (fieldsIt.MoveNext())
 				{
-					NormsWriterPerField perField = (NormsWriterPerField) ((System.Collections.DictionaryEntry) fieldsIt.Current).Key;
+					NormsWriterPerField perField = (NormsWriterPerField) fieldsIt.Current;
 					
 					if (perField.upto > 0)
 					{
 						// It has some norms
-						System.Collections.IList l = (System.Collections.IList) byField[perField.fieldInfo];
+						IList<NormsWriterPerField> l = byField[perField.fieldInfo];
 						if (l == null)
 						{
-							l = new System.Collections.ArrayList();
+							l = new List<NormsWriterPerField>();
 							byField[perField.fieldInfo] = l;
 						}
 						l.Add(perField);
@@ -97,16 +94,14 @@ namespace Lucene.Net.Index
                         fieldsToRemove.Add(perField);
 					}
 				}
-
-                System.Collections.Hashtable fieldsHT = (System.Collections.Hashtable)fields;
-                for (int i = 0; i < fieldsToRemove.Count; i++)
+                foreach (var field in fieldsToRemove)
                 {
-                    fieldsHT.Remove(fieldsToRemove[i]);    
+                    fields.Remove(field);
                 }
 			}
 			
 			System.String normsFileName = state.segmentName + "." + IndexFileNames.NORMS_EXTENSION;
-			state.flushedFiles[normsFileName] = normsFileName;
+			state.flushedFiles.Add(normsFileName);
 			IndexOutput normsOut = state.directory.CreateOutput(normsFileName);
 			
 			try
@@ -122,7 +117,7 @@ namespace Lucene.Net.Index
 					
 					FieldInfo fieldInfo = fieldInfos.FieldInfo(fieldNumber);
 					
-					System.Collections.IList toMerge = (System.Collections.IList) byField[fieldInfo];
+					IList<NormsWriterPerField> toMerge = byField[fieldInfo];
 					int upto = 0;
 					if (toMerge != null)
 					{
@@ -135,7 +130,7 @@ namespace Lucene.Net.Index
 						int[] uptos = new int[numFields];
 						
 						for (int j = 0; j < numFields; j++)
-							fields[j] = (NormsWriterPerField) toMerge[j];
+							fields[j] = toMerge[j];
 						
 						int numLeft = numFields;
 						

Modified: incubator/lucene.net/trunk/src/core/Index/NormsWriterPerField.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/NormsWriterPerField.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/NormsWriterPerField.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/NormsWriterPerField.cs Tue Feb 28 22:43:08 2012
@@ -29,7 +29,7 @@ namespace Lucene.Net.Index
 	/// and record the norm. 
 	/// </summary>
 	
-	sealed class NormsWriterPerField:InvertedDocEndConsumerPerField, System.IComparable
+	sealed class NormsWriterPerField:InvertedDocEndConsumerPerField, System.IComparable<NormsWriterPerField>
 	{
 		
 		internal NormsWriterPerThread perThread;
@@ -64,9 +64,9 @@ namespace Lucene.Net.Index
 			upto = 0;
 		}
 		
-		public int CompareTo(System.Object other)
+		public int CompareTo(NormsWriterPerField other)
 		{
-			return String.CompareOrdinal(fieldInfo.name, ((NormsWriterPerField) other).fieldInfo.name);
+			return String.CompareOrdinal(fieldInfo.name, other.fieldInfo.name);
 		}
 		
 		internal override void  Finish()

Modified: incubator/lucene.net/trunk/src/core/Index/ParallelReader.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/ParallelReader.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/ParallelReader.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/ParallelReader.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,9 @@
  */
 
 using System;
-
+using System.Collections.Generic;
+using System.Linq;
+using Lucene.Net.Support;
 using Document = Lucene.Net.Documents.Document;
 using FieldSelector = Lucene.Net.Documents.FieldSelector;
 using FieldSelectorResult = Lucene.Net.Documents.FieldSelectorResult;
@@ -24,8 +26,6 @@ using Fieldable = Lucene.Net.Documents.F
 
 namespace Lucene.Net.Index
 {
-	
-	
 	/// <summary>An IndexReader which reads multiple, parallel indexes.  Each index added
 	/// must have the same number of documents, but typically each contains
 	/// different fields.  Each document contains the union of the fields of all
@@ -45,12 +45,12 @@ namespace Lucene.Net.Index
 	/// </summary>
 	public class ParallelReader:IndexReader, System.ICloneable
 	{
-		private System.Collections.ArrayList readers = new System.Collections.ArrayList();
-		private System.Collections.IList decrefOnClose = new System.Collections.ArrayList(); // remember which subreaders to decRef on close
+        private List<IndexReader> readers = new List<IndexReader>();
+        private List<bool> decrefOnClose = new List<bool>(); // remember which subreaders to decRef on close
 		internal bool incRefReaders = false;
-		private System.Collections.SortedList fieldToReader = new System.Collections.SortedList();
-		private System.Collections.IDictionary readerToFields = new System.Collections.Hashtable();
-		private System.Collections.IList storedFieldReaders = new System.Collections.ArrayList();
+		private SortedDictionary<string, IndexReader> fieldToReader = new SortedDictionary<string, IndexReader>();
+		private IDictionary<IndexReader, ICollection<string>> readerToFields = new HashMap<IndexReader, ICollection<string>>();
+        private List<IndexReader> storedFieldReaders = new List<IndexReader>();
 		
 		private int maxDoc;
 		private int numDocs;
@@ -109,14 +109,13 @@ namespace Lucene.Net.Index
 			if (reader.NumDocs() != numDocs)
 				throw new System.ArgumentException("All readers must have same numDocs: " + numDocs + "!=" + reader.NumDocs());
 			
-			System.Collections.Generic.ICollection<string> fields = reader.GetFieldNames(IndexReader.FieldOption.ALL);
+			ICollection<string> fields = reader.GetFieldNames(IndexReader.FieldOption.ALL);
 			readerToFields[reader] = fields;
-			System.Collections.IEnumerator i = fields.GetEnumerator();
-			while (i.MoveNext())
+			foreach(var field in fields)
 			{
 				// update fieldToReader map
-				System.String field = (System.String) i.Current;
-				if (fieldToReader[field] == null)
+                // Do a containskey firt to mimic java behavior
+				if (!fieldToReader.ContainsKey(field) || fieldToReader[field] == null)
 					fieldToReader[field] = reader;
 			}
 			
@@ -174,15 +173,14 @@ namespace Lucene.Net.Index
 			EnsureOpen();
 			
 			bool reopened = false;
-			System.Collections.IList newReaders = new System.Collections.ArrayList();
+            IList<IndexReader> newReaders = new List<IndexReader>();
 			
 			bool success = false;
 			
 			try
 			{
-				for (int i = 0; i < readers.Count; i++)
+				foreach(var oldReader in readers)
 				{
-					IndexReader oldReader = (IndexReader) readers[i];
 					IndexReader newReader = null;
 					if (doClone)
 					{
@@ -208,7 +206,7 @@ namespace Lucene.Net.Index
 				{
 					for (int i = 0; i < newReaders.Count; i++)
 					{
-						IndexReader r = (IndexReader) newReaders[i];
+						IndexReader r = newReaders[i];
 						if (r != readers[i])
 						{
 							try
@@ -226,12 +224,12 @@ namespace Lucene.Net.Index
 			
 			if (reopened)
 			{
-				System.Collections.IList newDecrefOnClose = new System.Collections.ArrayList();
+                List<bool> newDecrefOnClose = new List<bool>();
 				ParallelReader pr = new ParallelReader();
 				for (int i = 0; i < readers.Count; i++)
 				{
-					IndexReader oldReader = (IndexReader) readers[i];
-					IndexReader newReader = (IndexReader) newReaders[i];
+					IndexReader oldReader = readers[i];
+					IndexReader newReader = newReaders[i];
 					if (newReader == oldReader)
 					{
 						newDecrefOnClose.Add(true);
@@ -280,16 +278,16 @@ namespace Lucene.Net.Index
 		{
 			// Don't call ensureOpen() here (it could affect performance)
 			if (readers.Count > 0)
-				return ((IndexReader) readers[0]).IsDeleted(n);
+				return readers[0].IsDeleted(n);
 			return false;
 		}
 		
 		// delete in all readers
 		protected internal override void  DoDelete(int n)
 		{
-			for (int i = 0; i < readers.Count; i++)
+			foreach(var reader in readers)
 			{
-				((IndexReader) readers[i]).DeleteDocument(n);
+				reader.DeleteDocument(n);
 			}
 			hasDeletions = true;
 		}
@@ -297,9 +295,9 @@ namespace Lucene.Net.Index
 		// undeleteAll in all readers
 		protected internal override void  DoUndeleteAll()
 		{
-			for (int i = 0; i < readers.Count; i++)
+			foreach(var reader in readers)
 			{
-				((IndexReader) readers[i]).UndeleteAll();
+				reader.UndeleteAll();
 			}
 			hasDeletions = false;
 		}
@@ -309,17 +307,15 @@ namespace Lucene.Net.Index
 		{
 			EnsureOpen();
 			Document result = new Document();
-			for (int i = 0; i < storedFieldReaders.Count; i++)
+			foreach(IndexReader reader in storedFieldReaders)
 			{
-				IndexReader reader = (IndexReader) storedFieldReaders[i];
-				
 				bool include = (fieldSelector == null);
 				if (!include)
 				{
-					System.Collections.IEnumerator it = ((System.Collections.ICollection) readerToFields[reader]).GetEnumerator();
-					while (it.MoveNext())
+				    var fields = readerToFields[reader];
+					foreach(var field in fields)
 					{
-						if (fieldSelector.Accept((System.String) it.Current) != FieldSelectorResult.NO_LOAD)
+                        if (fieldSelector.Accept(field) != FieldSelectorResult.NO_LOAD)
 						{
 							include = true;
 							break;
@@ -328,10 +324,10 @@ namespace Lucene.Net.Index
 				}
 				if (include)
 				{
-					System.Collections.IEnumerator fieldIterator = reader.Document(n, fieldSelector).GetFields().GetEnumerator();
-					while (fieldIterator.MoveNext())
+				    var fields = reader.Document(n, fieldSelector).GetFields();
+					foreach(var field in fields)
 					{
-						result.Add((Fieldable) fieldIterator.Current);
+                        result.Add(field);
 					}
 				}
 			}
@@ -342,24 +338,23 @@ namespace Lucene.Net.Index
 		public override TermFreqVector[] GetTermFreqVectors(int n)
 		{
 			EnsureOpen();
-			System.Collections.ArrayList results = new System.Collections.ArrayList();
-            System.Collections.IEnumerator i = new System.Collections.Hashtable(fieldToReader).GetEnumerator();
-			while (i.MoveNext())
-			{
-				System.Collections.DictionaryEntry e = (System.Collections.DictionaryEntry) i.Current;
-				System.String field = (System.String) e.Key;
-				IndexReader reader = (IndexReader) e.Value;
+			IList<TermFreqVector> results = new List<TermFreqVector>();
+            foreach(var e in fieldToReader)
+			{
+				System.String field = e.Key;
+				IndexReader reader = e.Value;
+
 				TermFreqVector vector = reader.GetTermFreqVector(n, field);
 				if (vector != null)
 					results.Add(vector);
 			}
-			return (TermFreqVector[]) results.ToArray(typeof(TermFreqVector));
+			return results.ToArray();
 		}
 		
 		public override TermFreqVector GetTermFreqVector(int n, System.String field)
 		{
 			EnsureOpen();
-			IndexReader reader = ((IndexReader) fieldToReader[field]);
+			IndexReader reader = (fieldToReader[field]);
 			return reader == null?null:reader.GetTermFreqVector(n, field);
 		}
 		
@@ -367,7 +362,7 @@ namespace Lucene.Net.Index
 		public override void  GetTermFreqVector(int docNumber, System.String field, TermVectorMapper mapper)
 		{
 			EnsureOpen();
-			IndexReader reader = ((IndexReader) fieldToReader[field]);
+			IndexReader reader = (fieldToReader[field]);
 			if (reader != null)
 			{
 				reader.GetTermFreqVector(docNumber, field, mapper);
@@ -378,12 +373,10 @@ namespace Lucene.Net.Index
 		{
 			EnsureOpen();
 
-            System.Collections.IEnumerator i = new System.Collections.Hashtable(fieldToReader).GetEnumerator();
-			while (i.MoveNext())
+            foreach(var e in fieldToReader)
 			{
-				System.Collections.DictionaryEntry e = (System.Collections.DictionaryEntry) i.Current;
-				System.String field = (System.String) e.Key;
-				IndexReader reader = (IndexReader) e.Value;
+				System.String field = e.Key;
+				IndexReader reader = e.Value;
 				reader.GetTermFreqVector(docNumber, field, mapper);
 			}
 		}
@@ -391,28 +384,28 @@ namespace Lucene.Net.Index
 		public override bool HasNorms(System.String field)
 		{
 			EnsureOpen();
-			IndexReader reader = ((IndexReader) fieldToReader[field]);
-			return reader == null?false:reader.HasNorms(field);
+			IndexReader reader = fieldToReader[field];
+		    return reader != null && reader.HasNorms(field);
 		}
 		
 		public override byte[] Norms(System.String field)
 		{
 			EnsureOpen();
-			IndexReader reader = ((IndexReader) fieldToReader[field]);
+			IndexReader reader = fieldToReader[field];
 			return reader == null?null:reader.Norms(field);
 		}
 		
 		public override void  Norms(System.String field, byte[] result, int offset)
 		{
 			EnsureOpen();
-			IndexReader reader = ((IndexReader) fieldToReader[field]);
+			IndexReader reader = fieldToReader[field];
 			if (reader != null)
 				reader.Norms(field, result, offset);
 		}
 		
 		protected internal override void  DoSetNorm(int n, System.String field, byte value_Renamed)
 		{
-			IndexReader reader = ((IndexReader) fieldToReader[field]);
+			IndexReader reader = fieldToReader[field];
 			if (reader != null)
 				reader.DoSetNorm(n, field, value_Renamed);
 		}
@@ -432,7 +425,7 @@ namespace Lucene.Net.Index
 		public override int DocFreq(Term term)
 		{
 			EnsureOpen();
-			IndexReader reader = ((IndexReader) fieldToReader[term.Field()]);
+			IndexReader reader = fieldToReader[term.Field()];
 			return reader == null?0:reader.DocFreq(term);
 		}
 		
@@ -463,9 +456,9 @@ namespace Lucene.Net.Index
 		/// <summary> Checks recursively if all subreaders are up to date. </summary>
 		public override bool IsCurrent()
 		{
-			for (int i = 0; i < readers.Count; i++)
-			{
-				if (!((IndexReader) readers[i]).IsCurrent())
+			foreach(var reader in readers)
+            {
+				if (!reader.IsCurrent())
 				{
 					return false;
 				}
@@ -478,16 +471,16 @@ namespace Lucene.Net.Index
 		/// <summary> Checks recursively if all subindexes are optimized </summary>
 		public override bool IsOptimized()
 		{
-			for (int i = 0; i < readers.Count; i++)
-			{
-				if (!((IndexReader) readers[i]).IsOptimized())
-				{
-					return false;
-				}
-			}
-			
-			// all subindexes are optimized
-			return true;
+            foreach (var reader in readers)
+            {
+                if (!reader.IsOptimized())
+                {
+                    return false;
+                }
+            }
+
+            // all subindexes are optimized
+            return true;
 		}
 		
 		
@@ -501,21 +494,13 @@ namespace Lucene.Net.Index
 		// for testing
 		public /*internal*/ virtual IndexReader[] GetSubReaders()
 		{
-			return (IndexReader[]) readers.ToArray(typeof(IndexReader));
-		}
-		
-		/// <deprecated> 
-		/// </deprecated>
-        [Obsolete]
-		protected internal override void  DoCommit()
-		{
-			DoCommit(null);
+			return readers.ToArray();
 		}
 
-        protected internal override void DoCommit(System.Collections.Generic.IDictionary<string, string> commitUserData)
+        protected internal override void DoCommit(IDictionary<string, string> commitUserData)
 		{
-			for (int i = 0; i < readers.Count; i++)
-				((IndexReader) readers[i]).Commit(commitUserData);
+			foreach(var reader in readers)
+				reader.Commit(commitUserData);
 		}
 		
 		protected internal override void  DoClose()
@@ -524,13 +509,13 @@ namespace Lucene.Net.Index
 			{
 				for (int i = 0; i < readers.Count; i++)
 				{
-					if (((System.Boolean) decrefOnClose[i]))
+					if (decrefOnClose[i])
 					{
-						((IndexReader) readers[i]).DecRef();
+						readers[i].DecRef();
 					}
 					else
 					{
-						((IndexReader) readers[i]).Close();
+						readers[i].Close();
 					}
 				}
 			}
@@ -541,17 +526,16 @@ namespace Lucene.Net.Index
         public override System.Collections.Generic.ICollection<string> GetFieldNames(IndexReader.FieldOption fieldNames)
 		{
 			EnsureOpen();
-            System.Collections.Generic.List<string> fieldSet = new System.Collections.Generic.List<string>();
-			for (int i = 0; i < readers.Count; i++)
+            ISet<string> fieldSet = new HashSet<string>();
+			foreach(var reader in readers)
 			{
-				IndexReader reader = ((IndexReader) readers[i]);
-				System.Collections.Generic.ICollection<string> names = reader.GetFieldNames(fieldNames);
-                fieldSet.AddRange(names);
+				ICollection<string> names = reader.GetFieldNames(fieldNames);
+                fieldSet.UnionWith(names);
 			}
 			return fieldSet;
 		}
 		
-		private class ParallelTermEnum:TermEnum
+		private class ParallelTermEnum : TermEnum
 		{
 			private void  InitBlock(ParallelReader enclosingInstance)
 			{
@@ -567,15 +551,17 @@ namespace Lucene.Net.Index
 				
 			}
 			private System.String field;
-			private System.Collections.IEnumerator fieldIterator;
+			private IEnumerator<string> fieldIterator;
 			private TermEnum termEnum;
+
+		    private bool isDisposed;
 			
 			public ParallelTermEnum(ParallelReader enclosingInstance)
 			{
 				InitBlock(enclosingInstance);
 				try
 				{
-					field = ((System.String) Enclosing_Instance.fieldToReader.GetKey(0));
+					field = Enclosing_Instance.fieldToReader.Keys.First();
 				}
 				catch (ArgumentOutOfRangeException e)
 				{
@@ -583,14 +569,14 @@ namespace Lucene.Net.Index
 					return;
 				}
 				if (field != null)
-					termEnum = ((IndexReader) Enclosing_Instance.fieldToReader[field]).Terms();
+					termEnum = Enclosing_Instance.fieldToReader[field].Terms();
 			}
 			
 			public ParallelTermEnum(ParallelReader enclosingInstance, Term term)
 			{
 				InitBlock(enclosingInstance);
 				field = term.Field();
-				IndexReader reader = ((IndexReader) Enclosing_Instance.fieldToReader[field]);
+				IndexReader reader = Enclosing_Instance.fieldToReader[field];
 				if (reader != null)
 					termEnum = reader.Terms(term);
 			}
@@ -609,30 +595,20 @@ namespace Lucene.Net.Index
 				// find the next field with terms, if any
 				if (fieldIterator == null)
 				{
-                    System.Collections.Comparer comparer = System.Collections.Comparer.Default;
-                    System.Collections.SortedList newList = new System.Collections.SortedList();
-                    if (Enclosing_Instance.fieldToReader != null)
+                    var newList = new List<string>();  
+                    if (Enclosing_Instance.fieldToReader != null && Enclosing_Instance.fieldToReader.Count > 0)
                     {
-                        if (Enclosing_Instance.fieldToReader.Count > 0)
-                        {
-                            int index = 0;
-                            while (comparer.Compare(Enclosing_Instance.fieldToReader.GetKey(index), field) < 0)
-                                index++;
-                            for (; index < Enclosing_Instance.fieldToReader.Count; index++)
-                            {
-                                newList.Add(Enclosing_Instance.fieldToReader.GetKey(index), Enclosing_Instance.fieldToReader[Enclosing_Instance.fieldToReader.GetKey(index)]);
-                            }
-                        }
+                        var comparer = Enclosing_Instance.fieldToReader.Comparer;
+                        foreach(var entry in Enclosing_Instance.fieldToReader.Keys.Where(x => comparer.Compare(x, field) >= 0))
+                            newList.Add(entry);
                     }
 
-                    fieldIterator = newList.Keys.GetEnumerator();
-                    fieldIterator.MoveNext();
-					System.Object generatedAux = fieldIterator.Current; // Skip field to get next one
+                    fieldIterator = newList.Skip(1).GetEnumerator(); // Skip field to get next one
 				}
 				while (fieldIterator.MoveNext())
 				{
-					field = ((System.String) fieldIterator.Current);
-					termEnum = ((IndexReader) Enclosing_Instance.fieldToReader[field]).Terms(new Term(field));
+					field = fieldIterator.Current;
+					termEnum = Enclosing_Instance.fieldToReader[field].Terms(new Term(field));
 					Term term = termEnum.Term();
 					if (term != null && (System.Object) term.Field() == (System.Object) field)
 						return true;
@@ -658,12 +634,19 @@ namespace Lucene.Net.Index
 				
 				return termEnum.DocFreq();
 			}
-			
-			public override void  Close()
-			{
-				if (termEnum != null)
-					termEnum.Close();
-			}
+
+            protected override void Dispose(bool disposing)
+            {
+                if (isDisposed) return;
+
+                if (disposing)
+                {
+                    if (termEnum != null)
+                        termEnum.Close();
+                }
+
+                isDisposed = true;
+            }
 		}
 		
 		// wrap a TermDocs in order to support seek(Term)
@@ -683,6 +666,8 @@ namespace Lucene.Net.Index
 				
 			}
 			protected internal TermDocs termDocs;
+
+		    private bool isDisposed;
 			
 			public ParallelTermDocs(ParallelReader enclosingInstance)
 			{
@@ -691,10 +676,12 @@ namespace Lucene.Net.Index
 			public ParallelTermDocs(ParallelReader enclosingInstance, Term term)
 			{
 				InitBlock(enclosingInstance);
-				if (term == null)
-					termDocs = (Enclosing_Instance.readers.Count == 0)?null:((IndexReader) Enclosing_Instance.readers[0]).TermDocs(null);
-				else
-					Seek(term);
+                if (term == null)
+                    termDocs = (Enclosing_Instance.readers.Count == 0)
+                                   ? null
+                                   : Enclosing_Instance.readers[0].TermDocs(null);
+                else
+                    Seek(term);
 			}
 			
 			public virtual int Doc()
@@ -708,7 +695,7 @@ namespace Lucene.Net.Index
 			
 			public virtual void  Seek(Term term)
 			{
-				IndexReader reader = ((IndexReader) Enclosing_Instance.fieldToReader[term.Field()]);
+				IndexReader reader = Enclosing_Instance.fieldToReader[term.Field()];
 				termDocs = reader != null?reader.TermDocs(term):null;
 			}
 			
@@ -740,12 +727,30 @@ namespace Lucene.Net.Index
 				
 				return termDocs.SkipTo(target);
 			}
-			
-			public virtual void  Close()
-			{
-				if (termDocs != null)
-					termDocs.Close();
-			}
+
+            [Obsolete("Use Dispose() instead")]
+            public virtual void Close()
+            {
+                Dispose();
+            }
+
+		    public void Dispose()
+		    {
+		        Dispose(true);
+		    }
+
+            protected virtual void Dispose(bool disposing)
+            {
+                if (isDisposed) return;
+
+                if (disposing)
+                {
+                    if (termDocs != null)
+                        termDocs.Close();
+                }
+
+                isDisposed = true;
+            }
 		}
 		
 		private class ParallelTermPositions:ParallelTermDocs, TermPositions
@@ -776,7 +781,7 @@ namespace Lucene.Net.Index
 			
 			public override void  Seek(Term term)
 			{
-				IndexReader reader = ((IndexReader) Enclosing_Instance.fieldToReader[term.Field()]);
+				IndexReader reader = Enclosing_Instance.fieldToReader[term.Field()];
 				termDocs = reader != null?reader.TermPositions(term):null;
 			}
 			

Modified: incubator/lucene.net/trunk/src/core/Index/PositionBasedTermVectorMapper.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Index/PositionBasedTermVectorMapper.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Index/PositionBasedTermVectorMapper.cs (original)
+++ incubator/lucene.net/trunk/src/core/Index/PositionBasedTermVectorMapper.cs Tue Feb 28 22:43:08 2012
@@ -16,6 +16,8 @@
  */
 
 using System;
+using System.Collections.Generic;
+using Lucene.Net.Support;
 
 namespace Lucene.Net.Index
 {
@@ -26,19 +28,13 @@ namespace Lucene.Net.Index
 	/// </summary>
 	public class PositionBasedTermVectorMapper:TermVectorMapper
 	{
-		private System.Collections.IDictionary fieldToTerms;
+		private IDictionary<string, IDictionary<int, TVPositionInfo>> fieldToTerms;
 		
 		private System.String currentField;
 		/// <summary> A Map of Integer and TVPositionInfo</summary>
-		private System.Collections.IDictionary currentPositions;
+        private IDictionary<int, TVPositionInfo> currentPositions;
 		private bool storeOffsets;
 		
-		
-		
-		
-		/// <summary> 
-		/// 
-		/// </summary>
 		public PositionBasedTermVectorMapper():base(false, false)
 		{
 		}
@@ -68,8 +64,8 @@ namespace Lucene.Net.Index
 		{
 			for (int i = 0; i < positions.Length; i++)
 			{
-				System.Int32 posVal = (System.Int32) positions[i];
-				TVPositionInfo pos = (TVPositionInfo) currentPositions[posVal];
+				System.Int32 posVal =  positions[i];
+				TVPositionInfo pos = currentPositions[posVal];
 				if (pos == null)
 				{
 					pos = new TVPositionInfo(positions[i], storeOffsets);
@@ -98,10 +94,10 @@ namespace Lucene.Net.Index
 			{
 				//ignoring offsets
 			}
-			fieldToTerms = new System.Collections.Hashtable(numTerms);
+			fieldToTerms = new HashMap<string, IDictionary<int, TVPositionInfo>>(numTerms);
 			this.storeOffsets = storeOffsets;
 			currentField = field;
-			currentPositions = new System.Collections.Hashtable();
+			currentPositions = new HashMap<int, TVPositionInfo>();
 			fieldToTerms[currentField] = currentPositions;
 		}
 		
@@ -110,7 +106,7 @@ namespace Lucene.Net.Index
 		/// </summary>
 		/// <returns> A map between field names and a Map.  The sub-Map key is the position as the integer, the value is <see cref="Lucene.Net.Index.PositionBasedTermVectorMapper.TVPositionInfo" />.
 		/// </returns>
-		public virtual System.Collections.IDictionary GetFieldToTerms()
+        public virtual IDictionary<string, IDictionary<int, TVPositionInfo>> GetFieldToTerms()
 		{
 			return fieldToTerms;
 		}
@@ -132,7 +128,7 @@ namespace Lucene.Net.Index
 			/// <summary> Note, there may be multiple terms at the same position</summary>
 			/// <returns> A List of Strings
 			/// </returns>
-			virtual public System.Collections.IList Terms
+			virtual public IList<String> Terms
 			{
 				get
 				{
@@ -144,7 +140,7 @@ namespace Lucene.Net.Index
 			/// There may be multiple entries since there may be multiple terms at a position</summary>
 			/// <returns> A List of TermVectorOffsetInfo objects, if offsets are store.
 			/// </returns>
-			virtual public System.Collections.IList Offsets
+			virtual public IList<TermVectorOffsetInfo> Offsets
 			{
 				get
 				{
@@ -154,18 +150,18 @@ namespace Lucene.Net.Index
 			}
 			private int position;
 			//a list of Strings
-			private System.Collections.IList terms;
+			private IList<string> terms;
 			//A list of TermVectorOffsetInfo
-			private System.Collections.IList offsets;
+			private IList<TermVectorOffsetInfo> offsets;
 			
 			
 			public TVPositionInfo(int position, bool storeOffsets)
 			{
 				this.position = position;
-				terms = new System.Collections.ArrayList();
+				terms = new List<string>();
 				if (storeOffsets)
 				{
-					offsets = new System.Collections.ArrayList();
+					offsets = new List<TermVectorOffsetInfo>();
 				}
 			}