You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by do...@apache.org on 2009/07/29 20:04:24 UTC

svn commit: r798995 [20/35] - in /incubator/lucene.net/trunk/C#/src: Lucene.Net/ Lucene.Net/Analysis/ Lucene.Net/Analysis/Standard/ Lucene.Net/Document/ Lucene.Net/Index/ Lucene.Net/QueryParser/ Lucene.Net/Search/ Lucene.Net/Search/Function/ Lucene.Net...

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/NearSpansOrdered.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/NearSpansOrdered.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/NearSpansOrdered.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/NearSpansOrdered.cs Wed Jul 29 18:04:12 2009
@@ -15,13 +15,12 @@
  * limitations under the License.
  */
 
-using System;
-
 using IndexReader = Lucene.Net.Index.IndexReader;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
-	
 	/// <summary>A Spans that is formed from the ordered subspans of a SpanNearQuery
 	/// where the subspans do not overlap and have a maximum slop between them.
 	/// <p>
@@ -40,7 +39,7 @@
 	/// <pre>t1 t2 .. t3      </pre>
 	/// <pre>      t1 .. t2 t3</pre>
 	/// </summary>
-	class NearSpansOrdered : Spans
+	class NearSpansOrdered : PayloadSpans
 	{
 		internal class AnonymousClassComparator : System.Collections.IComparer
 		{
@@ -61,7 +60,7 @@
 				}
 				
 			}
-			public virtual int Compare(System.Object o1, System.Object o2)
+			public virtual int Compare(object o1, object o2)
 			{
 				return ((Spans) o1).Doc() - ((Spans) o2).Doc();
 			}
@@ -70,12 +69,13 @@
 		{
 			spanDocComparator = new AnonymousClassComparator(this);
 		}
+
 		private int allowedSlop;
 		private bool firstTime = true;
 		private bool more = false;
 		
 		/// <summary>The spans in the same order as the SpanNearQuery </summary>
-		private Spans[] subSpans;
+		private PayloadSpans[] subSpans;
 		
 		/// <summary>Indicates that all subSpans have same doc() </summary>
 		private bool inSameDoc = false;
@@ -83,8 +83,10 @@
 		private int matchDoc = - 1;
 		private int matchStart = - 1;
 		private int matchEnd = - 1;
-		
-		private Spans[] subSpansByDoc;
+        private List<byte[]> matchPayload;
+
+		private PayloadSpans[] subSpansByDoc;
+
 		private System.Collections.IComparer spanDocComparator;
 		
 		private SpanNearQuery query;
@@ -98,11 +100,12 @@
 			}
 			allowedSlop = spanNearQuery.GetSlop();
 			SpanQuery[] clauses = spanNearQuery.GetClauses();
-			subSpans = new Spans[clauses.Length];
-			subSpansByDoc = new Spans[clauses.Length];
+			subSpans = new PayloadSpans[clauses.Length];
+            matchPayload = new List<byte[]>();
+			subSpansByDoc = new PayloadSpans[clauses.Length];
 			for (int i = 0; i < clauses.Length; i++)
 			{
-				subSpans[i] = clauses[i].GetSpans(reader);
+				subSpans[i] = clauses[i].GetPayloadSpans(reader);
 				subSpansByDoc[i] = subSpans[i]; // used in toSameDoc()
 			}
 			query = spanNearQuery; // kept for toString() only.
@@ -125,7 +128,17 @@
 		{
 			return matchEnd;
 		}
-		
+
+        public ICollection<byte[]> GetPayload()
+        {
+            return matchPayload;
+        }
+
+        public bool IsPayloadAvailable()
+        {
+            return matchPayload.Count > 0;
+        }
+
 		// inherit javadocs
 		public virtual bool Next()
 		{
@@ -142,6 +155,7 @@
 				}
 				more = true;
 			}
+            matchPayload.Clear();
 			return AdvanceAfterOrdered();
 		}
 		
@@ -173,6 +187,7 @@
 					return false;
 				}
 			}
+            matchPayload.Clear();
 			return AdvanceAfterOrdered();
 		}
 		
@@ -286,12 +301,18 @@
 		{
 			matchStart = subSpans[subSpans.Length - 1].Start();
 			matchEnd = subSpans[subSpans.Length - 1].End();
+            if (subSpans[subSpans.Length - 1].IsPayloadAvailable())
+                SupportClass.CollectionsSupport.AddAll(subSpans[subSpans.Length - 1].GetPayload(), matchPayload);
 			int matchSlop = 0;
 			int lastStart = matchStart;
 			int lastEnd = matchEnd;
 			for (int i = subSpans.Length - 2; i >= 0; i--)
 			{
-				Spans prevSpans = subSpans[i];
+				PayloadSpans prevSpans = subSpans[i];
+
+                if (subSpans[i].IsPayloadAvailable())
+                    matchPayload.InsertRange(0, subSpans[i].GetPayload());
+
 				int prevStart = prevSpans.Start();
 				int prevEnd = prevSpans.End();
 				while (true)

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/NearSpansUnordered.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/NearSpansUnordered.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/NearSpansUnordered.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/NearSpansUnordered.cs Wed Jul 29 18:04:12 2009
@@ -15,15 +15,14 @@
  * limitations under the License.
  */
 
-using System;
-
 using IndexReader = Lucene.Net.Index.IndexReader;
 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
-	
-	class NearSpansUnordered : Spans
+	internal class NearSpansUnordered : PayloadSpans
 	{
 		private SpanNearQuery query;
 		
@@ -62,7 +61,7 @@
 				Initialize(size);
 			}
 			
-			public override bool LessThan(System.Object o1, System.Object o2)
+			public override bool LessThan(object o1, object o2)
 			{
 				SpansCell spans1 = (SpansCell) o1;
 				SpansCell spans2 = (SpansCell) o2;
@@ -79,7 +78,7 @@
 		
 		
 		/// <summary>Wraps a Spans, and can be used to form a linked list. </summary>
-		private class SpansCell : Spans
+		private class SpansCell : PayloadSpans
 		{
 			private void  InitBlock(NearSpansUnordered enclosingInstance)
 			{
@@ -94,12 +93,12 @@
 				}
 				
 			}
-			private Spans spans;
+			private PayloadSpans spans;
 			internal SpansCell next;
 			private int length = - 1;
 			private int index;
 			
-			public SpansCell(NearSpansUnordered enclosingInstance, Spans spans, int index)
+			public SpansCell(NearSpansUnordered enclosingInstance, PayloadSpans spans, int index)
 			{
 				InitBlock(enclosingInstance);
 				this.spans = spans;
@@ -148,7 +147,17 @@
 			{
 				return spans.End();
 			}
-			
+
+            public ICollection<byte[]> GetPayload()
+            {
+                return new List<byte[]>(spans.GetPayload());
+            }
+
+            public bool IsPayloadAvailable()
+            {
+                return spans.IsPayloadAvailable();
+            }
+
 			public override System.String ToString()
 			{
 				return spans.ToString() + "#" + index;
@@ -165,7 +174,7 @@
 			queue = new CellQueue(this, clauses.Length);
 			for (int i = 0; i < clauses.Length; i++)
 			{
-				SpansCell cell = new SpansCell(this, clauses[i].GetSpans(reader), i);
+				SpansCell cell = new SpansCell(this, clauses[i].GetPayloadSpans(reader), i);
 				ordered.Add(cell);
 			}
 		}
@@ -290,7 +299,28 @@
 		{
 			return max.End();
 		}
-		
+
+        public ICollection<byte[]> GetPayload()
+        {
+            Dictionary<byte[], byte[]> matchPayload = new Dictionary<byte[], byte[]>();
+            for (SpansCell cell = first; cell != null; cell = cell.next)
+                if (cell.IsPayloadAvailable())
+                    for (IEnumerator<byte[]> e = cell.GetPayload().GetEnumerator(); e.MoveNext(); )
+                        matchPayload[e.Current] = e.Current;
+            return matchPayload.Keys;
+        }
+
+        public bool IsPayloadAvailable()
+        {
+            SpansCell pointer = Min();
+            while (pointer != null)
+            {
+                if (pointer.IsPayloadAvailable())
+                    return true;
+                pointer = pointer.next;
+            }
+            return false;
+        }
 		
 		public override System.String ToString()
 		{

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/PayloadSpans.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/PayloadSpans.cs?rev=798995&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/PayloadSpans.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/PayloadSpans.cs Wed Jul 29 18:04:12 2009
@@ -0,0 +1,69 @@
+/**
+ * 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.Collections.Generic;
+
+namespace Lucene.Net.Search.Spans
+{
+    /// <summary>
+    ///   <font color="#FF0000">
+    /// WARNING: The status of the <b>Payloads</b> feature is experimental.
+    /// The APIs introduced here might change in the future and will not be
+    /// supported anymore in such a case.</font>
+    ///
+    /// </summary>
+    public interface PayloadSpans : Spans
+    {
+        /// <summary>
+        /// Returns the payload data for the current span.
+        /// This is invalid until {@link #next()} is called for
+        /// the first time.
+        /// This method must not be called more than once after each call
+        /// of {@link #next()}. However, payloads are loaded lazily,
+        /// so if the payload data for the current position is not needed,
+        /// this method may not be called at all for performance reasons.<br>
+        /// <br>
+        /// Note that the return type is a collection, thus the ordering should not be relied upon.
+        /// <br/>
+        /// <p><font color="#FF0000">
+        /// WARNING: The status of the <b>Payloads</b> feature is experimental.
+        /// The APIs introduced here might change in the future and will not be
+        /// supported anymore in such a case.</font>
+        ///
+        /// @return a List of byte arrays containing the data of this payload, otherwise null if isPayloadAvailable is false
+        /// @throws java.io.IOException
+        /// </summary>
+        // TODO: Remove warning after API has been finalized
+        ICollection<byte[]> GetPayload();
+
+        /// <summary>
+        /// Checks if a payload can be loaded at this position.
+        /// <p/>
+        /// Payloads can only be loaded once per call to
+        /// {@link #next()}.
+        /// <p/>
+        /// <p><font color="#FF0000">
+        /// WARNING: The status of the <b>Payloads</b> feature is experimental.
+        /// The APIs introduced here might change in the future and will not be
+        /// supported anymore in such a case.</font>
+        ///
+        /// @return true if there is a payload available at this position that can be loaded
+        /// </summary>
+        // TODO: Remove warning after API has been finalized
+        bool IsPayloadAvailable();
+    }
+}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanFirstQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanFirstQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanFirstQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanFirstQuery.cs Wed Jul 29 18:04:12 2009
@@ -15,84 +15,19 @@
  * limitations under the License.
  */
 
-using System;
-
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Query = Lucene.Net.Search.Query;
 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
 	
 	/// <summary>Matches spans near the beginning of a field. </summary>
-	[Serializable]
+	[System.Serializable]
 	public class SpanFirstQuery : SpanQuery
 	{
-		private class AnonymousClassSpans : Spans
-		{
-			public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanFirstQuery enclosingInstance)
-			{
-				InitBlock(reader, enclosingInstance);
-			}
-			private void  InitBlock(Lucene.Net.Index.IndexReader reader, SpanFirstQuery enclosingInstance)
-			{
-				this.reader = reader;
-				this.enclosingInstance = enclosingInstance;
-				spans = Enclosing_Instance.match.GetSpans(reader);
-			}
-			private Lucene.Net.Index.IndexReader reader;
-			private SpanFirstQuery enclosingInstance;
-			public SpanFirstQuery Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-			private Spans spans;
-			
-			public virtual bool Next()
-			{
-				while (spans.Next())
-				{
-					// scan to next match
-					if (End() <= Enclosing_Instance.end)
-						return true;
-				}
-				return false;
-			}
-			
-			public virtual bool SkipTo(int target)
-			{
-				if (!spans.SkipTo(target))
-					return false;
-				
-				if (spans.End() <= Enclosing_Instance.end)
-				// there is a match
-					return true;
-				
-				return Next(); // scan to next match
-			}
-			
-			public virtual int Doc()
-			{
-				return spans.Doc();
-			}
-			public virtual int Start()
-			{
-				return spans.Start();
-			}
-			public virtual int End()
-			{
-				return spans.End();
-			}
-			
-			public override System.String ToString()
-			{
-				return "spans(" + Enclosing_Instance.ToString() + ")";
-			}
-		}
 		private SpanQuery match;
 		private int end;
 		
@@ -148,13 +83,95 @@
 		{
 			match.ExtractTerms(terms);
 		}
-		
+
+        public override PayloadSpans GetPayloadSpans(IndexReader reader)
+        {
+            return (PayloadSpans)GetSpans(reader);
+        }
+
 		public override Spans GetSpans(IndexReader reader)
 		{
-			return new AnonymousClassSpans(reader, this);
+			return new AnonymousClassPayloadSpans(reader, this);
 		}
-		
-		public override Query Rewrite(IndexReader reader)
+
+        private class AnonymousClassPayloadSpans : PayloadSpans
+        {
+            private PayloadSpans spans;
+            private Lucene.Net.Index.IndexReader reader;
+            private SpanFirstQuery enclosingInstance;
+
+            private void InitBlock(Lucene.Net.Index.IndexReader reader, SpanFirstQuery enclosingInstance)
+            {
+                this.reader = reader;
+                this.enclosingInstance = enclosingInstance;
+                spans = Enclosing_Instance.match.GetPayloadSpans(reader);
+            }
+
+            public AnonymousClassPayloadSpans(Lucene.Net.Index.IndexReader reader, SpanFirstQuery enclosingInstance)
+            {
+                InitBlock(reader, enclosingInstance);
+            }
+
+            public SpanFirstQuery Enclosing_Instance
+            {
+                get
+                {
+                    return enclosingInstance;
+                }
+            }
+
+            public virtual bool Next()
+            {
+                while (spans.Next())
+                {
+                    // scan to next match
+                    if (End() <= Enclosing_Instance.end)
+                        return true;
+                }
+                return false;
+            }
+
+            public virtual bool SkipTo(int target)
+            {
+                if (!spans.SkipTo(target))
+                    return false;
+
+                return (spans.End() <= Enclosing_Instance.end) || Next();
+            }
+
+            public virtual int Doc()
+            {
+                return spans.Doc();
+            }
+            public virtual int Start()
+            {
+                return spans.Start();
+            }
+            public virtual int End()
+            {
+                return spans.End();
+            }
+
+            public ICollection<byte[]> GetPayload()
+            {
+                List<byte[]> result = null;
+                if (spans.IsPayloadAvailable())
+                    result = new List<byte[]>(spans.GetPayload());
+                return result;
+            }
+
+            public bool IsPayloadAvailable()
+            {
+                return spans.IsPayloadAvailable();
+            }
+
+            public override System.String ToString()
+            {
+                return "spans(" + Enclosing_Instance.ToString() + ")";
+            }
+        }
+
+        public override Query Rewrite(IndexReader reader)
 		{
 			SpanFirstQuery clone = null;
 			
@@ -175,7 +192,7 @@
 			}
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanNearQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanNearQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanNearQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanNearQuery.cs Wed Jul 29 18:04:12 2009
@@ -126,9 +126,11 @@
 			{
 				SpanQuery clause = (SpanQuery) i.Current;
 				buffer.Append(clause.ToString(field));
-				buffer.Append(", ");
+				if (i.MoveNext())
+				{
+					buffer.Append(", ");
+				}
 			}
-            if (clauses.Count > 0) buffer.Length -= 2;
 			buffer.Append("], ");
 			buffer.Append(slop);
 			buffer.Append(", ");
@@ -142,15 +144,20 @@
 		{
 			if (clauses.Count == 0)
 			// optimize 0-clause case
-				return new SpanOrQuery(GetClauses()).GetSpans(reader);
+				return new SpanOrQuery(GetClauses()).GetPayloadSpans(reader);
 			
 			if (clauses.Count == 1)
 			// optimize 1-clause case
-				return ((SpanQuery) clauses[0]).GetSpans(reader);
+				return ((SpanQuery) clauses[0]).GetPayloadSpans(reader);
 			
-			return inOrder ? (Spans) new NearSpansOrdered(this, reader) : (Spans) new NearSpansUnordered(this, reader);
+			return inOrder ? (PayloadSpans) new NearSpansOrdered(this, reader) : (PayloadSpans) new NearSpansUnordered(this, reader);
 		}
 		
+        public override PayloadSpans GetPayloadSpans(IndexReader reader)
+        {
+            return (PayloadSpans) GetSpans(reader);
+        }
+
 		public override Query Rewrite(IndexReader reader)
 		{
 			SpanNearQuery clone = null;
@@ -177,7 +184,7 @@
 		}
 		
 		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;
@@ -219,4 +226,4 @@
 			return (int) result;
 		}
 	}
-}
+}
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanNotQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanNotQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanNotQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanNotQuery.cs Wed Jul 29 18:04:12 2009
@@ -15,22 +15,22 @@
  * limitations under the License.
  */
 
-using System;
-
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Query = Lucene.Net.Search.Query;
 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
 	
 	/// <summary>Removes matches which overlap with another SpanQuery. </summary>
-	[Serializable]
+	[System.Serializable]
 	public class SpanNotQuery : SpanQuery
 	{
-		private class AnonymousClassSpans : Spans
+		private class AnonymousClassPayloadSpans : PayloadSpans
 		{
-			public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanNotQuery enclosingInstance)
+			public AnonymousClassPayloadSpans(Lucene.Net.Index.IndexReader reader, SpanNotQuery enclosingInstance)
 			{
 				InitBlock(reader, enclosingInstance);
 			}
@@ -38,7 +38,7 @@
 			{
 				this.reader = reader;
 				this.enclosingInstance = enclosingInstance;
-				includeSpans = Enclosing_Instance.include.GetSpans(reader);
+				includeSpans = Enclosing_Instance.include.GetPayloadSpans(reader);
 				excludeSpans = Enclosing_Instance.exclude.GetSpans(reader);
 				moreExclude = excludeSpans.Next();
 			}
@@ -52,7 +52,7 @@
 				}
 				
 			}
-			private Spans includeSpans;
+			private PayloadSpans includeSpans;
 			private bool moreInclude = true;
 			
 			private Spans excludeSpans;
@@ -119,7 +119,20 @@
 			{
 				return includeSpans.End();
 			}
-			
+
+            public ICollection<byte[]> GetPayload()
+            {
+                List<byte[]> result = null;
+                if (includeSpans.IsPayloadAvailable())
+                    result = new List<byte[]>(includeSpans.GetPayload());
+                return result;
+            }
+
+            public bool IsPayloadAvailable()
+            {
+                return includeSpans.IsPayloadAvailable();
+            }
+
 			public override System.String ToString()
 			{
 				return "spans(" + Enclosing_Instance.ToString() + ")";
@@ -187,9 +200,14 @@
 		
 		public override Spans GetSpans(IndexReader reader)
 		{
-			return new AnonymousClassSpans(reader, this);
+			return new AnonymousClassPayloadSpans(reader, this);
 		}
-		
+
+        public override PayloadSpans GetPayloadSpans(IndexReader reader)
+        {
+            return (PayloadSpans)GetSpans(reader);
+        }
+
 		public override Query Rewrite(IndexReader reader)
 		{
 			SpanNotQuery clone = null;
@@ -219,7 +237,7 @@
 		}
 		
 		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanOrQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanOrQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanOrQuery.cs Wed Jul 29 18:04:12 2009
@@ -15,23 +15,23 @@
  * limitations under the License.
  */
 
-using System;
-
 using IndexReader = Lucene.Net.Index.IndexReader;
 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
 using Query = Lucene.Net.Search.Query;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
 	
 	/// <summary>Matches the union of its clauses.</summary>
-	[Serializable]
+	[System.Serializable]
 	public class SpanOrQuery : SpanQuery
 	{
-		private class AnonymousClassSpans : Spans
+		private class AnonymousClassPayloadSpans : PayloadSpans
 		{
-			public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
+			public AnonymousClassPayloadSpans(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
 			{
 				InitBlock(reader, enclosingInstance);
 			}
@@ -58,7 +58,7 @@
 				System.Collections.IEnumerator i = Enclosing_Instance.clauses.GetEnumerator();
 				while (i.MoveNext())
 				{
-					Spans spans = ((SpanQuery) i.Current).GetSpans(reader);
+					PayloadSpans spans = ((SpanQuery) i.Current).GetPayloadSpans(reader);
 					if (((target == - 1) && spans.Next()) || ((target != - 1) && spans.SkipTo(target)))
 					{
 						queue.Put(spans);
@@ -91,9 +91,9 @@
 				return queue.Size() != 0;
 			}
 			
-			private Spans Top()
+			private PayloadSpans Top()
 			{
-				return (Spans) queue.Top();
+				return (PayloadSpans) queue.Top();
 			}
 			
 			public virtual bool SkipTo(int target)
@@ -130,7 +130,22 @@
 			{
 				return Top().End();
 			}
-			
+
+            public ICollection<byte[]> GetPayload()
+            {
+                List<byte[]> result = null;
+                PayloadSpans theTop = (PayloadSpans)Top();
+                if (theTop != null && theTop.IsPayloadAvailable())
+                    result = new List<byte[]>(theTop.GetPayload());
+                return result;
+            }
+
+            public bool IsPayloadAvailable()
+            {
+                PayloadSpans top = Top();
+                return top != null && top.IsPayloadAvailable();
+            }
+
 			public override System.String ToString()
 			{
 				return "spans(" + Enclosing_Instance + ")@" + ((queue == null) ? "START" : (queue.Size() > 0 ? (Doc() + ":" + Start() + "-" + End()) : "END"));
@@ -233,15 +248,17 @@
 			{
 				SpanQuery clause = (SpanQuery) i.Current;
 				buffer.Append(clause.ToString(field));
-				buffer.Append(", ");
+				if (i.MoveNext())
+				{
+					buffer.Append(", ");
+				}
 			}
-            if(clauses.Count>0) buffer.Length -= 2;
 			buffer.Append("])");
 			buffer.Append(ToStringUtils.Boost(GetBoost()));
 			return buffer.ToString();
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;
@@ -287,7 +304,7 @@
 				Initialize(size);
 			}
 			
-			public override bool LessThan(System.Object o1, System.Object o2)
+			public override bool LessThan(object o1, object o2)
 			{
 				Spans spans1 = (Spans) o1;
 				Spans spans2 = (Spans) o2;
@@ -308,15 +325,19 @@
 				}
 			}
 		}
-		
-		
+
+        public override PayloadSpans GetPayloadSpans(IndexReader reader)
+        {
+            return (PayloadSpans)GetSpans(reader);
+        }
+
 		public override Spans GetSpans(IndexReader reader)
 		{
 			if (clauses.Count == 1)
 				// optimize 1-clause case
-				return ((SpanQuery) clauses[0]).GetSpans(reader);
+				return ((SpanQuery) clauses[0]).GetPayloadSpans(reader);
 			
-			return new AnonymousClassSpans(reader, this);
+			return new AnonymousClassPayloadSpans(reader, this);
 		}
 	}
-}
+}
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanQuery.cs Wed Jul 29 18:04:12 2009
@@ -15,25 +15,42 @@
  * limitations under the License.
  */
 
-using System;
-
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Query = Lucene.Net.Search.Query;
 using Weight = Lucene.Net.Search.Weight;
 using Searcher = Lucene.Net.Search.Searcher;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
 	
 	/// <summary>Base class for span-based queries. </summary>
-	[Serializable]
+	[System.Serializable]
 	public abstract class SpanQuery : Query
 	{
 		/// <summary>Expert: Returns the matches for this query in an index.  Used internally
 		/// to search for spans. 
 		/// </summary>
 		public abstract Spans GetSpans(IndexReader reader);
-		
+
+        /// <summary>
+        /// Returns the matches for this query in an index, including access to any payloads
+        /// at thos positions.  Implementin classes that want access to the payloads will need
+        /// to implement this.
+        /// <para>
+        /// WARNING: The status of the Payloads feature is experimental.
+        /// The APIs introduced here might change in the future and will not be
+        /// supported anymore in such a cse.
+        /// </para>
+        /// </summary>
+        /// <param name="reader">the reader to use to access spans/payloads</param>
+        /// <returns>null</returns>
+        public virtual PayloadSpans GetPayloadSpans(IndexReader reader)
+        {
+            return null;
+        }
+
 		/// <summary>Returns the name of the field matched by this query.</summary>
 		public abstract System.String GetField();
 		

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanScorer.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanScorer.cs Wed Jul 29 18:04:12 2009
@@ -26,7 +26,7 @@
 {
 	
 	/// <summary> Public for extension only.</summary>
-	class SpanScorer : Scorer
+	public class SpanScorer : Scorer
 	{
 		protected internal Spans spans;
 		protected internal Weight weight;
@@ -85,13 +85,13 @@
 			}
 			doc = spans.Doc();
 			freq = 0.0f;
-			while (more && doc == spans.Doc())
-			{
-				int matchLength = spans.End() - spans.Start();
-				freq += GetSimilarity().SloppyFreq(matchLength);
-				more = spans.Next();
-			}
-			return more || (freq != 0);
+            do
+            {
+                int matchLength = spans.End() - spans.Start();
+                freq += GetSimilarity().SloppyFreq(matchLength);
+                more = spans.Next();
+            } while (more && doc == spans.Doc());
+			return true;
 		}
 		
 		public override int Doc()

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanTermQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/SpanTermQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanTermQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/SpanTermQuery.cs Wed Jul 29 18:04:12 2009
@@ -79,7 +79,7 @@
 		}
 		
 		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is SpanTermQuery))
 				return false;
@@ -97,5 +97,10 @@
 		{
 			return new TermSpans(reader.TermPositions(term), term);
 		}
+
+        public override PayloadSpans GetPayloadSpans(IndexReader reader)
+        {
+            return (PayloadSpans)GetSpans(reader);
+        }
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/TermSpans.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Spans/TermSpans.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/TermSpans.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Spans/TermSpans.cs Wed Jul 29 18:04:12 2009
@@ -15,18 +15,18 @@
  * limitations under the License.
  */
 
-using System;
-
 using Term = Lucene.Net.Index.Term;
 using TermPositions = Lucene.Net.Index.TermPositions;
 
+using System.Collections.Generic;
+
 namespace Lucene.Net.Search.Spans
 {
 	
 	/// <summary> Expert:
 	/// Public for extension only
 	/// </summary>
-	public class TermSpans : Spans
+	public class TermSpans : PayloadSpans
 	{
 		protected internal TermPositions positions;
 		protected internal Term term;
@@ -100,7 +100,21 @@
 		{
 			return position + 1;
 		}
-		
+
+        public ICollection<byte[]> GetPayload()
+        {
+            byte[] bytes = new byte[positions.GetPayloadLength()];
+            bytes = positions.GetPayload(bytes, 0);
+            List<byte[]> result = new List<byte[]>(1);
+            result.Add(bytes);
+            return result;
+        }
+
+        public bool IsPayloadAvailable()
+        {
+            return positions.IsPayloadAvailable();
+        }
+
 		public override System.String ToString()
 		{
 			return "spans(" + term.ToString() + ")@" + (doc == - 1 ? "START" : ((doc == System.Int32.MaxValue) ? "END" : doc + "-" + position));

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TermQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/TermQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TermQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TermQuery.cs Wed Jul 29 18:04:12 2009
@@ -197,7 +197,7 @@
 		}
 		
 		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is TermQuery))
 				return false;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopDocCollector.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/TopDocCollector.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopDocCollector.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopDocCollector.cs Wed Jul 29 18:04:12 2009
@@ -29,29 +29,45 @@
 	/// <p>This may be extended, overriding the collect method to, e.g.,
 	/// conditionally invoke <code>super()</code> in order to filter which
 	/// documents are collected.
-	/// 
 	/// </summary>
 	public class TopDocCollector : HitCollector
 	{
 		
 		private ScoreDoc reusableSD;
 		
-		internal int totalHits;
-		internal PriorityQueue hq;
+        /// <summary>
+        /// The total number of hits the collector encountered.
+        /// </summary>
+		protected internal int totalHits;
+
+        /// <summary>
+        /// The priority queue which holds the top-scoring document.
+        /// </summary>
+		protected internal PriorityQueue hq;
 		
 		/// <summary>Construct to collect a given number of hits.</summary>
 		/// <param name="numHits">the maximum number of hits to collect
 		/// </param>
-		public TopDocCollector(int numHits) : this(numHits, new HitQueue(numHits))
+		public TopDocCollector(int numHits) : this(new HitQueue(numHits))
 		{
 		}
 		
+        [System.Obsolete("Use TopDocCollector(PriorityQueue) instead.  numHits is not used by this constructor.")]
 		internal TopDocCollector(int numHits, PriorityQueue hq)
 		{
 			this.hq = hq;
 		}
-		
-		// javadoc inherited
+
+        /// <summary>
+        /// Constructor to collect the top-scoring documents by using the given PriorityQueue.
+        /// </summary>
+        /// <param name="hq"></param>
+        internal TopDocCollector(PriorityQueue hq)
+        {
+            this.hq = hq;
+        }
+
+        // javadoc inherited
 		public override void  Collect(int doc, float score)
 		{
 			if (score > 0.0f)

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopFieldDocCollector.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/TopFieldDocCollector.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopFieldDocCollector.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopFieldDocCollector.cs Wed Jul 29 18:04:12 2009
@@ -43,7 +43,7 @@
 		/// </param>
 		/// <param name="numHits">the maximum number of hits to collect
 		/// </param>
-		public TopFieldDocCollector(IndexReader reader, Sort sort, int numHits) : base(numHits, new FieldSortedHitQueue(reader, sort.fields, numHits))
+		public TopFieldDocCollector(IndexReader reader, Sort sort, int numHits) : base(new FieldSortedHitQueue(reader, sort.fields, numHits))
 		{
 		}
 		

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopFieldDocs.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/TopFieldDocs.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopFieldDocs.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/TopFieldDocs.cs Wed Jul 29 18:04:12 2009
@@ -19,15 +19,8 @@
 
 namespace Lucene.Net.Search
 {
-	
-	
 	/// <summary> Expert: Returned by low-level sorted search implementations.
-	/// 
-	/// <p>Created: Feb 12, 2004 8:58:46 AM 
-	/// 
 	/// </summary>
-	/// <author>   Tim Jones (Nacimiento Software)
-	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
 	/// <version>  $Id: TopFieldDocs.java 472959 2006-11-09 16:21:50Z yonik $

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/WildcardQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/WildcardQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/WildcardQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/WildcardQuery.cs Wed Jul 29 18:04:12 2009
@@ -48,7 +48,7 @@
 			return new WildcardTermEnum(reader, GetTerm());
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (o is WildcardQuery)
 				return base.Equals(o);

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/SharpZipLibAdapter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/SharpZipLibAdapter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/SharpZipLibAdapter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/SharpZipLibAdapter.cs Wed Jul 29 18:04:12 2009
@@ -36,14 +36,14 @@
 {
     public class SharpZipLibAdapter : SupportClass.CompressionSupport.ICompressionAdapter
     {
-        public byte[] Compress(byte[] input)
+        public byte[] Compress(byte[] input, int offset, int length)
         {
             // Create the compressor with highest level of compression
             Deflater compressor = new Deflater();
             compressor.SetLevel(Deflater.BEST_COMPRESSION);
 
             // Give the compressor the data to compress
-            compressor.SetInput(input);
+            compressor.SetInput(input, offset, length);
             compressor.Finish();
 
             /*

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/BufferedIndexInput.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs Wed Jul 29 18:04:12 2009
@@ -29,7 +29,7 @@
 		
 		private int bufferSize = BUFFER_SIZE;
 		
-		private byte[] buffer;
+		protected internal byte[] buffer;
 		
 		private long bufferStart = 0; // position in file of buffer
 		private int bufferLength = 0; // end of valid bytes
@@ -56,7 +56,7 @@
 		/// <summary>Change the buffer size used by this IndexInput </summary>
 		public virtual void  SetBufferSize(int newSize)
 		{
-			System.Diagnostics.Debug.Assert(buffer == null || bufferSize == buffer.Length);
+			System.Diagnostics.Debug.Assert(buffer == null || bufferSize == buffer.Length, "buffer=" + buffer + " bufferSize=" + bufferSize + " buffer.length=" + (buffer != null ? buffer.Length : 0));
 			if (newSize != bufferSize)
 			{
 				CheckBufferSize(newSize);
@@ -77,11 +77,16 @@
 					bufferStart += bufferPosition;
 					bufferPosition = 0;
 					bufferLength = numToCopy;
-					buffer = newBuffer;
+					NewBuffer(newBuffer);
 				}
 			}
 		}
-		
+
+        protected internal virtual void NewBuffer(byte[] newBuffer)
+        {
+            buffer = newBuffer;
+        }
+
 		/// <seealso cref="setBufferSize">
 		/// </seealso>
 		public virtual int GetBufferSize()
@@ -173,7 +178,7 @@
 			
 			if (buffer == null)
 			{
-				buffer = new byte[bufferSize]; // allocate buffer lazily
+				NewBuffer(new byte[bufferSize]); // allocate buffer lazily
 				SeekInternal(bufferStart);
 			}
 
@@ -220,7 +225,7 @@
 		/// </seealso>
 		protected internal abstract void  SeekInternal(long pos);
 		
-		public override System.Object Clone()
+		public override object Clone()
 		{
 			BufferedIndexInput clone = (BufferedIndexInput) base.Clone();
 			

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/CheckSumIndexInput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/CheckSumIndexInput.cs?rev=798995&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/CheckSumIndexInput.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/CheckSumIndexInput.cs Wed Jul 29 18:04:12 2009
@@ -0,0 +1,73 @@
+/**
+ * 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.
+ */
+
+namespace Lucene.Net.Store
+{
+
+    /** Writes bytes through to a primary IndexOutput, computing
+     *  checksum as it goes. Note that you cannot use seek(). */
+    public class ChecksumIndexInput : IndexInput
+    {
+        IndexInput main;
+        //Checksum digest;
+
+        public ChecksumIndexInput(IndexInput main)
+        {
+            this.main = main;
+            //digest = new CRC32();
+        }
+
+        public override byte ReadByte()
+        {
+            byte b = main.ReadByte();
+            //digest.update(b);
+            return b;
+        }
+
+        public override void ReadBytes(byte[] b, int offset, int len)
+        {
+            main.ReadBytes(b, offset, len);
+            //digest.update(b, offset, len);
+        }
+
+        public long GetChecksum()
+        {
+            return 0;
+            //return digest.getValue();
+        }
+
+        public override void Close()
+        {
+            main.Close();
+        }
+
+        public override long GetFilePointer()
+        {
+            return main.GetFilePointer();
+        }
+
+        public override void Seek(long pos)
+        {
+            throw new System.SystemException("not allowed");
+        }
+
+        public override long Length()
+        {
+            return main.Length();
+        }
+    }
+}

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/CheckSumIndexOutput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/CheckSumIndexOutput.cs?rev=798995&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/CheckSumIndexOutput.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/CheckSumIndexOutput.cs Wed Jul 29 18:04:12 2009
@@ -0,0 +1,103 @@
+/**
+ * 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.
+ */
+
+namespace Lucene.Net.Store
+{
+
+    /** Writes bytes through to a primary IndexOutput, computing
+     *  checksum.  Note that you cannot use seek().*/
+    public class ChecksumIndexOutput : IndexOutput
+    {
+        IndexOutput main;
+        //Checksum digest;
+
+        public ChecksumIndexOutput(IndexOutput main)
+        {
+            this.main = main;
+            //digest = new CRC32();
+        }
+
+        public override void WriteByte(byte b)
+        {
+            //digest.update(b);
+            main.WriteByte(b);
+        }
+
+        public override void WriteBytes(byte[] b, int offset, int length)
+        {
+            //digest.update(b, offset, length);
+            main.WriteBytes(b, offset, length);
+        }
+
+        public long GetChecksum()
+        {
+            return 0;
+            //return digest.getValue();
+        }
+
+        public override void Flush()
+        {
+            main.Flush();
+        }
+
+        public override void Close()
+        {
+            main.Close();
+        }
+
+        public override long GetFilePointer()
+        {
+            return main.GetFilePointer();
+        }
+
+        public override void Seek(long pos)
+        {
+            throw new System.SystemException("not allowed");
+        }
+
+        /**
+         * Starts but does not complete the commit of this file (=
+         * writing of the final checksum at the end).  After this
+         * is called must call {@link #finishCommit} and the
+         * {@link #close} to complete the commit.
+         */
+        public void PrepareCommit()
+        {
+            long checksum = GetChecksum();
+            // Intentionally write a mismatched checksum.  This is
+            // because we want to 1) test, as best we can, that we
+            // are able to write a long to the file, but 2) not
+            // actually "commit" the file yet.  This (prepare
+            // commit) is phase 1 of a two-phase commit.
+            long pos = main.GetFilePointer();
+            main.WriteLong(checksum - 1);
+            main.Flush();
+            main.Seek(pos);
+        }
+
+        /** See {@link #prepareCommit} */
+        public void FinishCommit()
+        {
+            main.WriteLong(GetChecksum());
+        }
+
+        public override long Length()
+        {
+            return main.Length();
+        }
+    }
+}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/Directory.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs Wed Jul 29 18:04:12 2009
@@ -41,7 +41,8 @@
 	[Serializable]
 	public abstract class Directory
 	{
-		
+        protected internal volatile bool isOpen = true;
+
 		/// <summary>Holds the LockFactory instance (implements locking for
 		/// this Directory instance). 
 		/// </summary>
@@ -84,8 +85,18 @@
 		/// Returns a stream writing this file. 
 		/// </summary>
 		public abstract IndexOutput CreateOutput(System.String name);
-		
-		
+
+        /// <summary>
+        /// Ensure that any writes to the file are moved to
+        /// stable storage.  Lucene uses this to properly commit
+        /// chages to the index, to prevent a machine/OS crash
+        /// from corrupting the index.
+        /// </summary>
+        /// <param name="name"></param>
+        public virtual void Sync(String name)
+        {
+        }
+
 		/// <summary>Returns a stream reading an existing file. </summary>
 		public abstract IndexInput OpenInput(System.String name);
 		
@@ -223,5 +234,14 @@
 			if (closeDirSrc)
 				src.Close();
 		}
+
+        /// <summary>
+        /// Throws AlreadyClosedException if this Directory is closed.
+        /// </summary>
+        protected internal virtual void EnsureOpen()
+        {
+            if (!isOpen)
+                throw new AlreadyClosedException("this Directory is closed");
+        }
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/FSDirectory.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs Wed Jul 29 18:04:12 2009
@@ -39,8 +39,6 @@
 	/// </summary>
 	/// <seealso cref="Directory">
 	/// </seealso>
-	/// <author>  Doug Cutting
-	/// </author>
 	public class FSDirectory : Directory
 	{
 		
@@ -89,16 +87,12 @@
 		/// the <code>getDirectory</code> methods that take a
 		/// <code>lockFactory</code> (for example, {@link #GetDirectory(String, LockFactory)}).
 		/// </deprecated>
-        
-        //Deprecated. As of 2.1, LOCK_DIR is unused because the write.lock is now stored by default in the index directory. 
-        //If you really want to store locks elsewhere you can create your own SimpleFSLockFactory (or NativeFSLockFactory, etc.) passing in your preferred lock directory. 
-        //Then, pass this LockFactory instance to one of the getDirectory methods that take a lockFactory (for example, getDirectory(String, LockFactory)).
-		//public static readonly System.String LOCK_DIR = SupportClass.AppSettings.Get("Lucene.Net.lockDir", System.IO.Path.GetTempPath());
+		public static readonly System.String LOCK_DIR = SupportClass.AppSettings.Get("Lucene.Net.lockDir", System.IO.Path.GetTempPath());
 		
 		/// <summary>The default class which implements filesystem-based directories. </summary>
 		private static System.Type IMPL;
 		
-        private static System.Security.Cryptography.HashAlgorithm DIGESTER;
+		private static System.Security.Cryptography.MD5 DIGESTER;
 		
 		/// <summary>A buffer optionally used in renameTo method </summary>
 		private byte[] buffer = null;
@@ -338,7 +332,7 @@
 						{
 							lockFactory = (LockFactory) System.Activator.CreateInstance(c, true);
 						}
-						catch (System.UnauthorizedAccessException e)
+						catch (System.UnauthorizedAccessException)
 						{
 							throw new System.IO.IOException("IllegalAccessException when instantiating LockClass " + lockClassName);
 						}
@@ -383,13 +377,21 @@
 		/// <summary>Returns an array of strings, one for each Lucene index file in the directory. </summary>
 		public override System.String[] List()
 		{
-            return SupportClass.FileSupport.GetLuceneIndexFiles(directory.FullName, IndexFileNameFilter.GetFilter());
+            EnsureOpen();
+            System.String[] files = SupportClass.FileSupport.GetLuceneIndexFiles(directory.FullName, IndexFileNameFilter.GetFilter());
+            for (int i = 0; i < files.Length; i++)
+            {
+                System.IO.FileInfo fi = new System.IO.FileInfo(files[i]);
+                files[i] = fi.Name;
+            }
+			return files;
 		}
 		
 		/// <summary>Returns true iff a file with the given name exists. </summary>
 		public override bool FileExists(System.String name)
 		{
-			System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
+            EnsureOpen();
+            System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
 			bool tmpBool;
 			if (System.IO.File.Exists(file.FullName))
 				tmpBool = true;
@@ -401,7 +403,8 @@
 		/// <summary>Returns the time the named file was last modified. </summary>
 		public override long FileModified(System.String name)
 		{
-			System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
+            EnsureOpen();
+            System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
 			return (file.LastWriteTime.Ticks);
 		}
 		
@@ -415,26 +418,36 @@
 		/// <summary>Set the modified time of an existing file to now. </summary>
 		public override void  TouchFile(System.String name)
 		{
-			System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
+            EnsureOpen();
+            System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
 			file.LastWriteTime = System.DateTime.Now;
 		}
 		
 		/// <summary>Returns the length in bytes of a file in the directory. </summary>
 		public override long FileLength(System.String name)
 		{
-			System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
+            EnsureOpen();
+            System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
 			return file.Exists ? file.Length : 0;
 		}
 		
 		/// <summary>Removes an existing file in the directory. </summary>
 		public override void  DeleteFile(System.String name)
 		{
-			System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
+            EnsureOpen();
+            System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
 			bool tmpBool;
 			if (System.IO.File.Exists(file.FullName))
 			{
-				System.IO.File.Delete(file.FullName);
-				tmpBool = true;
+                try
+                {
+                    System.IO.File.Delete(file.FullName);
+                }
+                catch (System.UnauthorizedAccessException e)
+                {
+                    throw new System.IO.IOException(e.Message, e);
+                }
+                tmpBool = true;
 			}
 			else if (System.IO.Directory.Exists(file.FullName))
 			{
@@ -454,9 +467,10 @@
 		/// </deprecated>
 		public override void  RenameFile(System.String from, System.String to)
 		{
-			lock (this)
+            lock (this)
 			{
-				System.IO.FileInfo old = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, from));
+                EnsureOpen();
+                System.IO.FileInfo old = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, from));
 				System.IO.FileInfo nu = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, to));
 				
 				/* This is not atomic.  If the program crashes between the call to
@@ -576,6 +590,7 @@
 		/// </summary>
 		public override IndexOutput CreateOutput(System.String name)
 		{
+            EnsureOpen();
 			
 			System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
 			bool tmpBool;
@@ -603,25 +618,87 @@
 			return new FSIndexOutput(file);
 		}
 
+        public override void Sync(string name)
+        {
+            EnsureOpen();
+
+            string fullName = System.IO.Path.Combine(directory.FullName, name);
+            bool success = false;
+            int retryCount = 0;
+            UnauthorizedAccessException exc = null;
+
+            while (!success && retryCount < 5)
+            {
+                retryCount++;
+                System.IO.FileStream file = null;
+
+                try
+                {
+                    try
+                    {
+                        file = new System.IO.FileStream(fullName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
+                        
+                        //TODO
+                        // {{dougsale-2.4}}:
+                        // 
+                        // in Lucene (Java):
+                        // file.getFD().sync();
+                        // file is a java.io.RandomAccessFile
+                        // getFD() returns java.io.FileDescriptor
+                        // sync() documentation states: "Force all system buffers to synchronize with the underlying device."
+                        //
+                        // what they try to do here is get ahold of the underlying file descriptor
+                        // for the given file name and make sure all (downstream) associated system buffers are
+                        // flushed to disk
+                        // 
+                        // how do i do that in .Net?  flushing the created stream might inadvertently do it, or it
+                        // may do nothing at all.  I can find references to the file HANDLE, but it's not really
+                        // a type, simply an int pointer.
+                        //
+                        // where is FSDirectory.Sync(string name) called from - if this isn't a new feature but rather a refactor, maybe
+                        // i can snip the old code from where it was re-factored...
+
+                        success = true;
+                    }
+                    finally
+                    {
+                        if (file != null)
+                            file.Close();
+                    }
+                }
+                catch (UnauthorizedAccessException e)
+                {
+                    exc = e;
+                    System.Threading.Thread.Sleep(5);
+                }
+            }
+            if (!success)
+                // throw original exception
+                throw exc;
+        }
+
         // Inherit javadoc
         public override IndexInput OpenInput(System.String name)
         {
+            EnsureOpen();
             return OpenInput(name, BufferedIndexInput.BUFFER_SIZE);
         }
 
         // Inherit javadoc
         public override IndexInput OpenInput(System.String name, int bufferSize)
         {
+            EnsureOpen();
             return new FSIndexInput(new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name)), bufferSize);
         }
-
+ 
 		/// <summary> So we can do some byte-to-hexchar conversion below</summary>
 		private static readonly char[] HEX_DIGITS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
 		
 		
 		public override System.String GetLockID()
 		{
-			System.String dirName; // name to be hashed
+            EnsureOpen();
+            System.String dirName; // name to be hashed
 			try
 			{
 				dirName = directory.FullName;
@@ -653,8 +730,9 @@
 		{
 			lock (this)
 			{
-				if (--refCount <= 0)
+				if (isOpen && --refCount <= 0)
 				{
+                    isOpen = false;
 					lock (DIRECTORIES.SyncRoot)
 					{
 						DIRECTORIES.Remove(directory.FullName);
@@ -665,7 +743,8 @@
 		
 		public virtual System.IO.FileInfo GetFile()
 		{
-			return directory;
+            EnsureOpen();
+            return directory;
 		}
 		
 		/// <summary>For debug output. </summary>
@@ -677,11 +756,11 @@
 		public /*protected internal*/ class FSIndexInput : BufferedIndexInput, System.ICloneable
 		{
 		
-			private class Descriptor : System.IO.BinaryReader
+			protected internal class Descriptor : System.IO.BinaryReader
 			{
 				// remember if the file is open, so that we don't try to close it
 				// more than once
-				private bool isOpen;
+				protected internal volatile bool isOpen;
 				internal long position;
 				internal long length;
 			
@@ -713,7 +792,7 @@
 				}
 			}
 		
-			private Descriptor file;
+			protected internal Descriptor file;
 			internal bool isClone;
 			
 	        public bool isClone_ForNUnitTest
@@ -786,7 +865,7 @@
 				return file.length;
 			}
 			
-			public override System.Object Clone()
+			public override object Clone()
 			{
 				FSIndexInput clone = (FSIndexInput) base.Clone();
 				clone.isClone = true;
@@ -808,7 +887,7 @@
 		
 			// remember if the file is open, so that we don't try to close it
 			// more than once
-			private bool isOpen;
+			private volatile bool isOpen;
 		
 			public FSIndexOutput(System.IO.FileInfo path)
 			{
@@ -835,6 +914,13 @@
 			public override void  FlushBuffer(byte[] b, int offset, int size)
 			{
 				file.Write(b, offset, size);
+                // {{dougsale-2.4.0}}
+                // When writing frequently with small amounts of data, the data isn't flushed to disk.
+                // Thus, attempting to read the data soon after this method is invoked leads to
+                // BufferedIndexInput.Refill() throwing an IOException for reading past EOF.
+                // Test\Index\TestDoc.cs demonstrates such a situation.
+                // Forcing a flush here prevents said issue.
+                file.Flush();
 			}
 			public override void  Close()
 			{
@@ -858,7 +944,13 @@
 			{
 				return file.BaseStream.Length;
 			}
+            public override void SetLength(long length)
+            {
+                System.IO.FileStream fs = (System.IO.FileStream)file.BaseStream;
+                fs.SetLength(length);
+            }
 		}
+
 		static FSDirectory()
 		{
 			{
@@ -886,7 +978,7 @@
 			{
 				try
 				{
-                    DIGESTER = SupportClass.Cryptography.GetHashAlgorithm();
+					DIGESTER = System.Security.Cryptography.MD5.Create();
 				}
 				catch (System.Exception e)
 				{

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/IndexInput.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs Wed Jul 29 18:04:12 2009
@@ -27,7 +27,14 @@
 	/// </seealso>
 	public abstract class IndexInput : System.ICloneable
 	{
-		private char[] chars; // used by readString()
+        // used by ReadString()
+        private byte[] bytes;
+        
+        // used by ReadModifiedUTF8String()
+        private char[] chars;
+
+        // true if using modified UTF-8 strings
+        private bool preUTF8Strings;
 		
 		/// <summary>Reads and returns a single byte.</summary>
 		/// <seealso cref="IndexOutput.WriteByte(byte)">
@@ -117,20 +124,41 @@
 			}
 			return i;
 		}
-		
+
+        /// <summary>
+        /// Set to read strings in the deprecated modified UTF-8 format
+        /// (length in Java chars and Java's modified UTF-8 encoding).
+        /// Used for pre-2.4.0 indexes.  See JIRA LUCENE-510 for details.
+        /// </summary>
+        public void SetModifiedUTF8StringsMode()
+        {
+            preUTF8Strings = true;
+        }
+
 		/// <summary>Reads a string.</summary>
 		/// <seealso cref="IndexOutput.WriteString(String)">
 		/// </seealso>
-		public virtual System.String ReadString()
+		public virtual string ReadString()
 		{
+            if (preUTF8Strings)
+                return ReadModifiedUTF8String();
+            int length = ReadVInt();
+            if (bytes == null || length > bytes.Length)
+                bytes = new byte[(int) (length*1.25)];
+            ReadBytes(bytes, 0, length);
+            return System.Text.Encoding.UTF8.GetString(bytes, 0, length);
+        }
+
+        public virtual string ReadModifiedUTF8String()
+        {
 			int length = ReadVInt();
 			if (chars == null || length > chars.Length)
 				chars = new char[length];
 			ReadChars(chars, 0, length);
-			return new System.String(chars, 0, length);
+			return new String(chars, 0, length);
 		}
 		
-		/// <summary>Reads UTF-8 encoded characters into an array.</summary>
+		/// <summary>Reads Lucene's old "modified UTF-8" encoded characters into an array.</summary>
 		/// <param name="buffer">the array to read characters into
 		/// </param>
 		/// <param name="start">the offset in the array to start storing characters
@@ -139,6 +167,7 @@
 		/// </param>
 		/// <seealso cref="IndexOutput.WriteChars(String,int,int)">
 		/// </seealso>
+        [Obsolete("please use ReadString() or ReadBytes() instead")] 
 		public virtual void  ReadChars(char[] buffer, int start, int length)
 		{
 			int end = start + length;
@@ -165,6 +194,7 @@
 		/// </summary>
 		/// <param name="length">The number of chars to read
 		/// </param>
+        [Obsolete("this method operates on old \"modified UTF-8\" encoded strings")]
 		public virtual void  SkipChars(int length)
 		{
 			for (int i = 0; i < length; i++)
@@ -215,7 +245,7 @@
 		/// different points in the input from each other and from the stream they
 		/// were cloned from.
 		/// </summary>
-		public virtual System.Object Clone()
+		public virtual object Clone()
 		{
 			IndexInput clone = null;
 			try
@@ -225,7 +255,8 @@
 			catch (System.Exception)
 			{
 			}
-			
+
+            clone.bytes = null;
 			clone.chars = null;
 			
 			return clone;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/IndexOutput.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs Wed Jul 29 18:04:12 2009
@@ -16,6 +16,7 @@
  */
 
 using System;
+using UnicodeUtil = Lucene.Net.Util.UnicodeUtil;
 
 namespace Lucene.Net.Store
 {
@@ -29,6 +30,7 @@
 	/// </seealso>
 	public abstract class IndexOutput
 	{
+        private UnicodeUtil.UTF8Result utf8Result = new UnicodeUtil.UTF8Result();
 		
 		/// <summary>Writes a single byte.</summary>
 		/// <seealso cref="IndexInput.ReadByte()">
@@ -113,23 +115,19 @@
 		/// <summary>Writes a string.</summary>
 		/// <seealso cref="IndexInput.ReadString()">
 		/// </seealso>
-		public virtual void  WriteString(System.String s)
+		public virtual void  WriteString(string s)
 		{
-			int length = s.Length;
-			WriteVInt(length);
-			WriteChars(s, 0, length);
+            UnicodeUtil.UTF16toUTF8(s, 0, s.Length, utf8Result);
+			WriteVInt(utf8Result.length);
+			WriteBytes(utf8Result.result, 0, utf8Result.length);
 		}
 		
-		/// <summary>Writes a sequence of UTF-8 encoded characters from a string.</summary>
-		/// <param name="s">the source of the characters
-		/// </param>
-		/// <param name="start">the first character in the sequence
-		/// </param>
-		/// <param name="length">the number of characters in the sequence
-		/// </param>
-		/// <seealso cref="IndexInput.ReadChars(char[],int,int)">
-		/// </seealso>
-		public virtual void  WriteChars(System.String s, int start, int length)
+		/// <summary>Writes a sub sequence of chars from s as "modified UTF-8" encoded bytes.</summary>
+		/// <param name="s">the source of the characters</param>
+		/// <param name="start">the first character in the sequence</param>
+		/// <param name="length">the number of characters in the sequence</param>
+        [Obsolete("please pre-convert to UTF-8 bytes or use WriteString()")]
+		public virtual void  WriteChars(string s, int start, int length)
 		{
 			int end = start + length;
 			for (int i = start; i < end; i++)
@@ -151,16 +149,12 @@
 			}
 		}
 		
-		/// <summary>Writes a sequence of UTF-8 encoded characters from a char[].</summary>
-		/// <param name="s">the source of the characters
-		/// </param>
-		/// <param name="start">the first character in the sequence
-		/// </param>
-		/// <param name="length">the number of characters in the sequence
-		/// </param>
-		/// <seealso cref="IndexInput.ReadChars(char[],int,int)">
-		/// </seealso>
-		public virtual void  WriteChars(char[] s, int start, int length)
+		/// <summary>Writes a sub sequence of chars from s as "modified UTF-8" encoded bytes.</summary>
+		/// <param name="s">the source of the characters</param>
+		/// <param name="start">the first character in the sequence</param>
+		/// <param name="length">the number of characters in the sequence</param>
+        [Obsolete("please pre-convert to UTF-8 bytes or use WriteString()")]
+        public virtual void  WriteChars(char[] s, int start, int length)
 		{
 			int end = start + length;
 			for (int i = start; i < end; i++)
@@ -224,5 +218,20 @@
 		
 		/// <summary>The number of bytes in the file. </summary>
 		public abstract long Length();
+
+        /// <summary>
+        /// Set the file length. By default, this method does
+        /// nothing (it's optional for a Directory to implement
+        /// it).  But, certain Directory implementations (for
+        /// example @see FSDirectory) can use this to inform the
+        /// underlying IO system to pre-allocate the file to the
+        /// specified size.  If the length is longer than the
+        /// current file length, the bytes added to the file are
+        /// undefined.  Otherwise the file is truncated.
+        /// <param name="length">file length</param>
+        /// </summary>
+        public virtual void SetLength(long length)
+        {
+        }
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/Lock.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs Wed Jul 29 18:04:12 2009
@@ -23,7 +23,7 @@
 	/// <summary>An interprocess mutex lock.
 	/// <p>Typical use might look like:<pre>
 	/// new Lock.With(directory.makeLock("my.lock")) {
-	/// public Object doBody() {
+	/// public object doBody() {
 	/// <i>... code to execute while locked ...</i>
 	/// }
 	/// }.run();
@@ -143,7 +143,7 @@
 			}
 			
 			/// <summary>Code to execute with exclusive access. </summary>
-			protected internal abstract System.Object DoBody();
+			protected internal abstract object DoBody();
 			
 			/// <summary>Calls {@link #doBody} while <i>lock</i> is obtained.  Blocks if lock
 			/// cannot be obtained immediately.  Retries to obtain lock once per second
@@ -154,7 +154,7 @@
 			/// <summary> be obtained
 			/// </summary>
 			/// <throws>  IOException if {@link Lock#obtain} throws IOException </throws>
-			public virtual System.Object Run()
+			public virtual object Run()
 			{
 				bool locked = false;
 				try

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/LockStressTest.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs Wed Jul 29 18:04:12 2009
@@ -62,7 +62,7 @@
 			{
 				c = System.Type.GetType(lockFactoryClassName);
 			}
-			catch (System.Exception e)
+			catch (System.Exception)
 			{
 				throw new System.IO.IOException("unable to find LockClass " + lockFactoryClassName);
 			}
@@ -72,15 +72,15 @@
 			{
 				lockFactory = (LockFactory) System.Activator.CreateInstance(c);
 			}
-			catch (System.UnauthorizedAccessException e)
+			catch (System.UnauthorizedAccessException)
 			{
 				throw new System.IO.IOException("IllegalAccessException when instantiating LockClass " + lockFactoryClassName);
 			}
-			catch (System.InvalidCastException e)
+			catch (System.InvalidCastException)
 			{
 				throw new System.IO.IOException("unable to cast LockClass " + lockFactoryClassName + " instance to a LockFactory");
 			}
-			catch (System.Exception e)
+			catch (System.Exception)
 			{
 				throw new System.IO.IOException("InstantiationException when instantiating LockClass " + lockFactoryClassName);
 			}
@@ -111,7 +111,7 @@
 				{
 					obtained = l.Obtain(10);
 				}
-				catch (LockObtainFailedException e)
+				catch (LockObtainFailedException)
 				{
 					System.Console.Out.Write("x");
 				}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/MMapDirectory.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs Wed Jul 29 18:04:12 2009
@@ -69,7 +69,7 @@
 				return length;
 			}
 			
-			public override System.Object Clone()
+			public override object Clone()
 			{
 				MMapIndexInput clone = (MMapIndexInput) base.Clone();
 				// clone.buffer = buffer.duplicate();   // {{Aroush-1.9}}
@@ -181,7 +181,7 @@
 				return length;
 			}
 			
-			public override System.Object Clone()
+			public override object Clone()
 			{
 				MultiMMapIndexInput clone = (MultiMMapIndexInput) base.Clone();
 				clone.buffers = new System.IO.MemoryStream[buffers.Length];

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMDirectory.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs Wed Jul 29 18:04:12 2009
@@ -25,8 +25,6 @@
 	/// but can be changed with {@link #setLockFactory}.
 	/// 
 	/// </summary>
-	/// <version>  $Id: RAMDirectory.java 581625 2007-10-03 15:24:12Z mikemccand $
-	/// </version>
     [Serializable]
     public class RAMDirectory : Directory
     {
@@ -47,16 +45,6 @@
             set { sizeInBytes = value; }
         }
 
-        //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());
-            }
-        }
-
 		// *****
 		// Lock acquisition sequence:  RAMDirectory, then RAMFile
 		// *****
@@ -296,11 +284,12 @@
 		/// <summary>Closes the store to future operations, releasing associated memory. </summary>
 		public override void  Close()
 		{
+            isOpen = false;
 			fileMap = null;
 		}
 		
 		/// <throws>  AlreadyClosedException if this IndexReader is closed </throws>
-		protected internal void  EnsureOpen()
+		protected internal override void  EnsureOpen()
 		{
 			if (fileMap == null)
 			{

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMFile.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs Wed Jul 29 18:04:12 2009
@@ -60,8 +60,24 @@
 				this.length = length;
 			}
 		}
-		
-		// For non-stream access from thread that might be concurrent with writing
+
+        public virtual long GetLength_ForNUnitTest()
+        {
+            lock (this)
+            {
+                return length;
+            }
+        }
+
+        public virtual void SetLength_ForNUnitTest(long length)
+        {
+            lock (this)
+            {
+                this.length = length;
+            }
+        }
+
+        // For non-stream access from thread that might be concurrent with writing
 		internal virtual long GetLastModified()
 		{
 			lock (this)
@@ -112,8 +128,24 @@
 				return buffers.Count;
 			}
 		}
-		
-		/// <summary> Expert: allocate a new buffer. 
+
+        public byte[] GetBuffer_ForNUnitTest(int index)
+        {
+            lock (this)
+            {
+                return (byte[])buffers[index];
+            }
+        }
+
+        public int NumBuffers_ForNUnitTest()
+        {
+            lock (this)
+            {
+                return buffers.Count;
+            }
+        }
+        
+        /// <summary> Expert: allocate a new buffer. 
 		/// Subclasses can allocate differently. 
 		/// </summary>
 		/// <param name="size">size of allocated buffer.

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMInputStream.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs Wed Jul 29 18:04:12 2009
@@ -23,9 +23,6 @@
 	/// <summary> A memory-resident {@link IndexInput} implementation.
 	/// 
 	/// </summary>
-	/// <version>  $Id: RAMInputStream.java 598693 2007-11-27 17:01:21Z mikemccand $
-	/// </version>
-	
 	public class RAMInputStream : IndexInput, System.ICloneable
 	{
 		internal static readonly int BUFFER_SIZE;
@@ -76,7 +73,7 @@
 			if (bufferPosition >= bufferLength)
 			{
 				currentBufferIndex++;
-				SwitchCurrentBuffer();
+				SwitchCurrentBuffer(true);
 			}
 			return currentBuffer[bufferPosition++];
 		}
@@ -88,7 +85,7 @@
 				if (bufferPosition >= bufferLength)
 				{
 					currentBufferIndex++;
-					SwitchCurrentBuffer();
+					SwitchCurrentBuffer(true);
 				}
 				
 				int remainInBuffer = bufferLength - bufferPosition;
@@ -100,12 +97,19 @@
 			}
 		}
 		
-		private void  SwitchCurrentBuffer()
+		private void  SwitchCurrentBuffer(bool enforceEOF)
 		{
 			if (currentBufferIndex >= file.NumBuffers())
 			{
 				// end of file reached, no more buffers left
-				throw new System.IO.IOException("Read past EOF");
+                if (enforceEOF)
+                    throw new System.IO.IOException("Read past EOF");
+                else
+                {
+                    // Force EOF if a read takes place at this position
+                    currentBufferIndex--;
+                    bufferPosition = BUFFER_SIZE;
+                }
 			}
 			else
 			{
@@ -127,13 +131,13 @@
 			if (currentBuffer == null || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE)
 			{
 				currentBufferIndex = (int) (pos / BUFFER_SIZE);
-				SwitchCurrentBuffer();
+				SwitchCurrentBuffer(false);
 			}
 			bufferPosition = (int) (pos % BUFFER_SIZE);
 		}
 
         // {{Aroush-1.9}} Do we need this Clone()?!
-        /* override public System.Object Clone()
+        /* override public object Clone()
         {
             return null;
         }

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMOutputStream.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs Wed Jul 29 18:04:12 2009
@@ -23,9 +23,6 @@
 	/// <summary> A memory-resident {@link IndexOutput} implementation.
 	/// 
 	/// </summary>
-	/// <version>  $Id: RAMOutputStream.java 598693 2007-11-27 17:01:21Z mikemccand $
-	/// </version>
-	
 	public class RAMOutputStream:IndexOutput
 	{
 		internal const int BUFFER_SIZE = 1024;
@@ -128,6 +125,8 @@
 		
 		public override void  WriteBytes(byte[] b, int offset, int len)
 		{
+            System.Diagnostics.Debug.Assert(b != null);
+
 			while (len > 0)
 			{
 				if (bufferPosition == bufferLength)
@@ -179,5 +178,14 @@
 		{
 			return currentBufferIndex < 0?0:bufferStart + bufferPosition;
 		}
+
+        /// <summary>
+        /// Returns the byte usage of all buffers.
+        /// </summary>
+        /// <returns></returns>
+        public long SizeInBytes()
+        {
+            return file.NumBuffers() * BUFFER_SIZE;
+        }
 	}
 }
\ No newline at end of file