You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by pn...@apache.org on 2011/11/13 02:57:24 UTC

[Lucene.Net] svn commit: r1201389 - in /incubator/lucene.net/trunk: src/core/Store/SimpleFSDirectory.cs src/core/SupportClass.cs src/core/Util/AttributeSource.cs test/core/Analysis/TestAnalyzers.cs

Author: pnasser
Date: Sun Nov 13 01:57:23 2011
New Revision: 1201389

URL: http://svn.apache.org/viewvc?rev=1201389&view=rev
Log:
[LUCENENET-433] AttributeSource can have an invalid computed state 

Modified:
    incubator/lucene.net/trunk/src/core/Store/SimpleFSDirectory.cs
    incubator/lucene.net/trunk/src/core/SupportClass.cs
    incubator/lucene.net/trunk/src/core/Util/AttributeSource.cs
    incubator/lucene.net/trunk/test/core/Analysis/TestAnalyzers.cs

Modified: incubator/lucene.net/trunk/src/core/Store/SimpleFSDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Store/SimpleFSDirectory.cs?rev=1201389&r1=1201388&r2=1201389&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Store/SimpleFSDirectory.cs (original)
+++ incubator/lucene.net/trunk/src/core/Store/SimpleFSDirectory.cs Sun Nov 13 01:57:23 2011
@@ -95,7 +95,22 @@ namespace Lucene.Net.Store
 		public override IndexInput OpenInput(System.String name, int bufferSize)
 		{
 			EnsureOpen();
-			return new SimpleFSIndexInput(new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name)), bufferSize, GetReadChunkSize());
+
+		    Exception e = null;
+		    for (int i = 0; i < 10; i++)
+		    {
+		        try
+		        {
+                    return new SimpleFSIndexInput(new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name)), bufferSize, GetReadChunkSize());
+		        }
+		        catch (System.UnauthorizedAccessException ex)
+		        {
+		            e = ex;
+                    System.Threading.Thread.Sleep(1);
+		        }
+		    }
+
+		    throw e;
 		}
 		
 		public /*protected internal*/class SimpleFSIndexInput:BufferedIndexInput, System.ICloneable

Modified: incubator/lucene.net/trunk/src/core/SupportClass.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/SupportClass.cs?rev=1201389&r1=1201388&r2=1201389&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/SupportClass.cs (original)
+++ incubator/lucene.net/trunk/src/core/SupportClass.cs Sun Nov 13 01:57:23 2011
@@ -1795,6 +1795,11 @@ public class SupportClass
                 return false;
             }
         }
+
+        public System.Collections.Generic.IList<TItem> Values()
+        {
+            return base.Items;
+        }
     }
 
     /// <summary>Represents a strongly typed list of objects that can be accessed by index.

Modified: incubator/lucene.net/trunk/src/core/Util/AttributeSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Util/AttributeSource.cs?rev=1201389&r1=1201388&r2=1201389&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Util/AttributeSource.cs (original)
+++ incubator/lucene.net/trunk/src/core/Util/AttributeSource.cs Sun Nov 13 01:57:23 2011
@@ -16,7 +16,7 @@
  */
 
 using System;
-
+using System.Collections.Generic;
 using TokenStream = Lucene.Net.Analysis.TokenStream;
 
 namespace Lucene.Net.Util
@@ -93,11 +93,12 @@ namespace Lucene.Net.Util
 			}
 		}
 		
-		// These two maps must always be in sync!!!
+        // These two maps must always be in sync!!!
 		// So they are private, final and read-only from the outside (read-only iterators)
 		private SupportClass.GeneralKeyedCollection<Type, SupportClass.AttributeImplItem> attributes;
 		private SupportClass.GeneralKeyedCollection<Type, SupportClass.AttributeImplItem> attributeImpls;
-		
+	    private State[] currentState = null;
+
 		private AttributeFactory factory;
 		
 		/// <summary> An AttributeSource using the default attribute factory <see cref="AttributeSource.AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY" />.</summary>
@@ -114,15 +115,17 @@ namespace Lucene.Net.Util
 			}
 			this.attributes = input.attributes;
 			this.attributeImpls = input.attributeImpls;
+		    this.currentState = input.currentState;
 			this.factory = input.factory;
 		}
 		
 		/// <summary> An AttributeSource using the supplied <see cref="AttributeFactory" /> for creating new <see cref="Attribute" /> instances.</summary>
 		public AttributeSource(AttributeFactory factory)
 		{
-            this.attributes = new SupportClass.GeneralKeyedCollection<Type, SupportClass.AttributeImplItem>(delegate(SupportClass.AttributeImplItem att) { return att.Key; });
-            this.attributeImpls = new SupportClass.GeneralKeyedCollection<Type, SupportClass.AttributeImplItem>(delegate(SupportClass.AttributeImplItem att) { return att.Key; });
-			this.factory = factory;
+            this.attributes = new SupportClass.GeneralKeyedCollection<Type, SupportClass.AttributeImplItem>(att => att.Key);
+            this.attributeImpls = new SupportClass.GeneralKeyedCollection<Type, SupportClass.AttributeImplItem>(att => att.Key);
+			this.currentState = new State[1];
+            this.factory = factory;
 		}
 		
 		/// <summary> returns the used AttributeFactory.</summary>
@@ -138,7 +141,7 @@ namespace Lucene.Net.Util
 		/// Note that this return value is different from Java in that it enumerates over the values
 		/// and not the keys
 		/// </summary>
-		public virtual System.Collections.Generic.IEnumerable<Type> GetAttributeClassesIterator()
+		public virtual IEnumerable<Type> GetAttributeClassesIterator()
 		{
             foreach (SupportClass.AttributeImplItem item in this.attributes)
             {
@@ -151,24 +154,82 @@ namespace Lucene.Net.Util
 		/// if one instance implements more than one Attribute interface.
 		/// Signature for Java 1.5: <c>public Iterator&lt;AttributeImpl&gt; getAttributeImplsIterator()</c>
 		/// </summary>
-		public virtual System.Collections.Generic.IEnumerable<AttributeImpl> GetAttributeImplsIterator()
+		public virtual IEnumerable<AttributeImpl> GetAttributeImplsIterator()
 		{
-			if (HasAttributes())
-			{
-				if (currentState == null)
-				{
-					ComputeCurrentState();
-				}
-                while (currentState != null)
-                {
-                    AttributeImpl att = currentState.attribute;
-                    currentState = currentState.next;
-                    yield return att;
-                }
-			}
+		    State initState = GetCurrentState();
+            if (initState != null)
+            {
+                return new AnonymousEnumerable(initState);
+            }
+            else
+            {
+                return new List<AttributeImpl>();
+            }
 		}
 		
-		/// <summary>a cache that stores all interfaces for known implementation classes for performance (slow reflection) </summary>
+        class AnonymousEnumerable : IEnumerable<AttributeImpl>
+        {
+            State state;
+            public AnonymousEnumerable(State state)
+            {
+                this.state = state;
+            }
+            public IEnumerator<AttributeImpl> GetEnumerator()
+            {
+                return new AnonymousEnumerator(state);
+            }
+            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+            {
+                return new AnonymousEnumerator(state);
+            }
+        }
+		
+        class AnonymousEnumerator : IEnumerator<AttributeImpl>
+        {
+            State state;
+            public AnonymousEnumerator(State state)
+            {
+                this.state = state;
+            }
+
+            AttributeImpl InternalCurrent
+            {
+                get
+                {
+                    if (state == null)
+                        throw new KeyNotFoundException();
+
+                    AttributeImpl att = state.attribute;
+                    state = state.next;
+                    return att;
+                }
+            }
+ 
+            public AttributeImpl Current
+            {
+                get { return InternalCurrent; }
+            }
+
+            public void Dispose()
+            {}
+
+            object System.Collections.IEnumerator.Current
+            {
+                get { return InternalCurrent; }
+            }
+
+            public bool MoveNext()
+            {
+                return state != null;
+            }
+
+            public void Reset()
+            {
+                
+            }
+        }
+
+        /// <summary>a cache that stores all interfaces for known implementation classes for performance (slow reflection) </summary>
 		private static readonly SupportClass.WeakHashTable knownImplClasses = new SupportClass.WeakHashTable();
 
         // {{Aroush-2.9 Port issue, need to mimic java's IdentityHashMap
@@ -228,7 +289,7 @@ namespace Lucene.Net.Util
 				if (!attributes.ContainsKey(curInterface))
 				{
 					// invalidate state to force recomputation in captureState()
-					this.currentState = null;
+					this.currentState[0] = null;
                     attributes.Add(new SupportClass.AttributeImplItem(curInterface, att));
                     if (!attributeImpls.ContainsKey(clazz))
                     {
@@ -269,7 +330,7 @@ namespace Lucene.Net.Util
 		/// <summary>Returns true, iff this AttributeSource has any attributes </summary>
 		public virtual bool HasAttributes()
 		{
-			return !(this.attributes.Count == 0);
+			return this.attributes.Count != 0;
 		}
 		
 		/// <summary> The caller must pass in a Class&lt;? extends Attribute&gt; value. 
@@ -328,57 +389,49 @@ namespace Lucene.Net.Util
 				return clone;
 			}
 		}
-		
-		private State currentState = null;
-		
-		private void  ComputeCurrentState()
-		{
-			currentState = new State();
-			State c = currentState;
-            System.Collections.Generic.IEnumerator<SupportClass.AttributeImplItem> it = attributeImpls.GetEnumerator();
-			if (it.MoveNext())
-				c.attribute = it.Current.Value;
-			while (it.MoveNext())
-			{
-				c.next = new State();
-				c = c.next;
-				c.attribute = it.Current.Value;
-			}
-		}
-		
-		/// <summary> Resets all Attributes in this AttributeSource by calling
+
+        private State GetCurrentState()
+        {
+            State s = currentState[0];
+            if (s != null || !HasAttributes())
+            {
+                return s;
+            }
+
+            State c = s = currentState[0] = new State();
+            var it = attributeImpls.Values().GetEnumerator();
+            it.MoveNext();
+            c.attribute = it.Current.Value;
+
+            while (it.MoveNext())
+            {
+                c.next = new State();
+                c = c.next;
+                c.attribute = it.Current.Value;
+            }
+
+            return s;
+
+        }
+
+	    /// <summary> Resets all Attributes in this AttributeSource by calling
 		/// <see cref="AttributeImpl.Clear()" /> on each Attribute implementation.
 		/// </summary>
 		public virtual void  ClearAttributes()
 		{
-			if (HasAttributes())
+			for (State state = GetCurrentState(); state != null; state = state.next)
 			{
-				if (currentState == null)
-				{
-					ComputeCurrentState();
-				}
-				for (State state = currentState; state != null; state = state.next)
-				{
-					state.attribute.Clear();
-				}
+				state.attribute.Clear();
 			}
-		}
+	    }
 		
 		/// <summary> Captures the state of all Attributes. The return value can be passed to
 		/// <see cref="RestoreState" /> to restore the state of this or another AttributeSource.
 		/// </summary>
 		public virtual State CaptureState()
 		{
-			if (!HasAttributes())
-			{
-				return null;
-			}
-			
-			if (currentState == null)
-			{
-				ComputeCurrentState();
-			}
-			return (State) this.currentState.Clone();
+		    State state = this.GetCurrentState();
+		    return (state == null) ? null : (State) state.Clone();
 		}
 		
 		/// <summary> Restores this state by copying the values of all attribute implementations
@@ -415,20 +468,13 @@ namespace Lucene.Net.Util
 		public override int GetHashCode()
 		{
 			int code = 0;
-			if (HasAttributes())
-			{
-				if (currentState == null)
-				{
-					ComputeCurrentState();
-				}
-				for (State state = currentState; state != null; state = state.next)
-				{
-					code = code * 31 + state.attribute.GetHashCode();
-				}
-			}
-			
-			return code;
-		}
+            for (State state = GetCurrentState(); state != null; state = state.next)
+            {
+                code = code*31 + state.attribute.GetHashCode();
+            }
+
+		    return code;
+        }
 		
 		public  override bool Equals(System.Object obj)
 		{
@@ -454,16 +500,8 @@ namespace Lucene.Net.Util
 					}
 					
 					// it is only equal if all attribute impls are the same in the same order
-					if (this.currentState == null)
-					{
-						this.ComputeCurrentState();
-					}
-					State thisState = this.currentState;
-					if (other.currentState == null)
-					{
-						other.ComputeCurrentState();
-					}
-					State otherState = other.currentState;
+					State thisState = this.GetCurrentState();
+					State otherState = other.GetCurrentState();
 					while (thisState != null && otherState != null)
 					{
 						if (otherState.attribute.GetType() != thisState.attribute.GetType() || !otherState.attribute.Equals(thisState.attribute))
@@ -491,13 +529,13 @@ namespace Lucene.Net.Util
 			
 			if (HasAttributes())
 			{
-				if (currentState == null)
+				if (currentState[0] == null)
 				{
-					ComputeCurrentState();
+				    currentState[0] = GetCurrentState();
 				}
-				for (State state = currentState; state != null; state = state.next)
+				for (State state = currentState[0]; state != null; state = state.next)
 				{
-					if (state != currentState)
+					if (state != currentState[0])
 						sb.Append(',');
 					sb.Append(state.attribute.ToString());
 				}
@@ -517,15 +555,15 @@ namespace Lucene.Net.Util
 			// first clone the impls
 			if (HasAttributes())
 			{
-				if (currentState == null)
-				{
-					ComputeCurrentState();
-				}
-				for (State state = currentState; state != null; state = state.next)
+				for (State state = GetCurrentState() ; state != null; state = state.next)
 				{
 					AttributeImpl impl = (AttributeImpl) state.attribute.Clone();
-                    clone.attributeImpls.Add(new SupportClass.AttributeImplItem(impl.GetType(), impl));
-				}
+
+                    if (!clone.attributeImpls.ContainsKey(impl.GetType()))
+                    {
+                        clone.attributeImpls.Add(new SupportClass.AttributeImplItem(impl.GetType(), impl));
+                    }
+                }
 			}
 			
 			// now the interfaces

Modified: incubator/lucene.net/trunk/test/core/Analysis/TestAnalyzers.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/core/Analysis/TestAnalyzers.cs?rev=1201389&r1=1201388&r2=1201389&view=diff
==============================================================================
--- incubator/lucene.net/trunk/test/core/Analysis/TestAnalyzers.cs (original)
+++ incubator/lucene.net/trunk/test/core/Analysis/TestAnalyzers.cs Sun Nov 13 01:57:23 2011
@@ -134,6 +134,25 @@ namespace Lucene.Net.Analysis
 			Assert.IsTrue(ts.IncrementToken());
 			Assert.IsFalse(ts.IncrementToken());
 		}
+
+        [Test]
+        public void Test_LUCENE_3042_LUCENENET_433()
+        {
+            String testString = "t";
+
+            Analyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer();
+            TokenStream stream = analyzer.ReusableTokenStream("dummy", new System.IO.StringReader(testString));
+            stream.Reset();
+            while (stream.IncrementToken())
+            {
+                // consume
+            }
+            stream.End();
+            stream.Close();
+
+            AssertAnalyzesToReuse(analyzer, testString, new String[] { "t" });
+        }
+
 	}
 	
 	class PayloadSetter:TokenFilter