You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by di...@apache.org on 2011/07/07 15:44:48 UTC
[Lucene.Net] svn commit: r1143825 - in /incubator/lucene.net/branches/Lucene.Net_2_9_4g:
src/core/Store/SimpleFSDirectory.cs
src/core/Support/GeneralKeyedCollection.cs src/core/Util/AttributeSource.cs
test/core/Analysis/TestAnalyzers.cs
Author: digy
Date: Thu Jul 7 13:44:47 2011
New Revision: 1143825
URL: http://svn.apache.org/viewvc?rev=1143825&view=rev
Log:
[LUCENENET-433] AttributeSource can have an invalid computed state.
For 2.9.4g branch
Modified:
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Store/SimpleFSDirectory.cs
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Support/GeneralKeyedCollection.cs
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Util/AttributeSource.cs
incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/core/Analysis/TestAnalyzers.cs
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Store/SimpleFSDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Store/SimpleFSDirectory.cs?rev=1143825&r1=1143824&r2=1143825&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Store/SimpleFSDirectory.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Store/SimpleFSDirectory.cs Thu Jul 7 13:44:47 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());
+ //return new SimpleFSIndexInput(new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name)), bufferSize, GetReadChunkSize());
+ //{{DIGY}}
+ 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) //Give another chance {{DIGY}}
+ {
+ e = ex;
+ System.Threading.Thread.Sleep(1);
+ }
+ }
+ throw e;
}
public /*protected internal*/class SimpleFSIndexInput:BufferedIndexInput, System.ICloneable
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Support/GeneralKeyedCollection.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Support/GeneralKeyedCollection.cs?rev=1143825&r1=1143824&r2=1143825&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Support/GeneralKeyedCollection.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Support/GeneralKeyedCollection.cs Thu Jul 7 13:44:47 2011
@@ -81,5 +81,10 @@ namespace Lucene.Net.Support
return false;
}
}
+
+ public System.Collections.Generic.IList<TItem> Values()
+ {
+ return base.Items;
+ }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Util/AttributeSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Util/AttributeSource.cs?rev=1143825&r1=1143824&r2=1143825&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Util/AttributeSource.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/core/Util/AttributeSource.cs Thu Jul 7 13:44:47 2011
@@ -22,155 +22,249 @@ using TokenStream = Lucene.Net.Analysis.
namespace Lucene.Net.Util
{
-
- /// <summary> An AttributeSource contains a list of different {@link AttributeImpl}s,
- /// and methods to add and get them. There can only be a single instance
- /// of an attribute in the same AttributeSource instance. This is ensured
- /// by passing in the actual type of the Attribute (Class<Attribute>) to
- /// the {@link #AddAttribute(Class)}, which then checks if an instance of
- /// that type is already present. If yes, it returns the instance, otherwise
- /// it creates a new instance and returns it.
- /// </summary>
- public class AttributeSource
- {
- /// <summary> An AttributeFactory creates instances of {@link AttributeImpl}s.</summary>
- public abstract class AttributeFactory
- {
- /// <summary> returns an {@link AttributeImpl} for the supplied {@link Attribute} interface class.
- /// <p/>Signature for Java 1.5: <code>public AttributeImpl createAttributeInstance(Class%lt;? extends Attribute> attClass)</code>
- /// </summary>
- public abstract AttributeImpl CreateAttributeInstance(System.Type attClass);
-
- /// <summary> This is the default factory that creates {@link AttributeImpl}s using the
- /// class name of the supplied {@link Attribute} interface class by appending <code>Impl</code> to it.
- /// </summary>
- public static readonly AttributeFactory DEFAULT_ATTRIBUTE_FACTORY = new DefaultAttributeFactory();
-
- private sealed class DefaultAttributeFactory:AttributeFactory
- {
+
+ /// <summary> An AttributeSource contains a list of different {@link AttributeImpl}s,
+ /// and methods to add and get them. There can only be a single instance
+ /// of an attribute in the same AttributeSource instance. This is ensured
+ /// by passing in the actual type of the Attribute (Class<Attribute>) to
+ /// the {@link #AddAttribute(Class)}, which then checks if an instance of
+ /// that type is already present. If yes, it returns the instance, otherwise
+ /// it creates a new instance and returns it.
+ /// </summary>
+ public class AttributeSource
+ {
+ /// <summary> An AttributeFactory creates instances of {@link AttributeImpl}s.</summary>
+ public abstract class AttributeFactory
+ {
+ /// <summary> returns an {@link AttributeImpl} for the supplied {@link Attribute} interface class.
+ /// <p/>Signature for Java 1.5: <code>public AttributeImpl createAttributeInstance(Class%lt;? extends Attribute> attClass)</code>
+ /// </summary>
+ public abstract AttributeImpl CreateAttributeInstance(System.Type attClass);
+
+ /// <summary> This is the default factory that creates {@link AttributeImpl}s using the
+ /// class name of the supplied {@link Attribute} interface class by appending <code>Impl</code> to it.
+ /// </summary>
+ public static readonly AttributeFactory DEFAULT_ATTRIBUTE_FACTORY = new DefaultAttributeFactory();
+
+ private sealed class DefaultAttributeFactory : AttributeFactory
+ {
private static readonly Support.WeakDictionary<Type, WeakReference> attClassImplMap = new Support.WeakDictionary<Type, WeakReference>();
-
- internal DefaultAttributeFactory()
- {
- }
-
- public override AttributeImpl CreateAttributeInstance(System.Type attClass)
- {
- try
- {
- return (AttributeImpl) System.Activator.CreateInstance(GetClassForInterface(attClass));
- }
- catch (System.UnauthorizedAccessException e)
+
+ internal DefaultAttributeFactory()
+ {
+ }
+
+ public override AttributeImpl CreateAttributeInstance(System.Type attClass)
+ {
+ try
+ {
+ return (AttributeImpl)System.Activator.CreateInstance(GetClassForInterface(attClass));
+ }
+ catch (System.UnauthorizedAccessException e)
{
throw new System.ArgumentException("Could not instantiate implementing class for " + attClass.FullName);
- }
- catch (System.Exception e)
- {
+ }
+ catch (System.Exception e)
+ {
throw new System.ArgumentException("Could not instantiate implementing class for " + attClass.FullName);
- }
- }
-
- private static System.Type GetClassForInterface(System.Type attClass)
- {
- lock (attClassImplMap)
- {
+ }
+ }
+
+ private static System.Type GetClassForInterface(System.Type attClass)
+ {
+ lock (attClassImplMap)
+ {
WeakReference refz = attClassImplMap[attClass];
- System.Type clazz = (refz == null) ? null : ((System.Type) refz.Target);
- if (clazz == null)
- {
- try
- {
+ System.Type clazz = (refz == null) ? null : ((System.Type)refz.Target);
+ if (clazz == null)
+ {
+ try
+ {
string name = attClass.FullName + "Impl," + attClass.Assembly.FullName;
- attClassImplMap.Add(attClass, new WeakReference( clazz = System.Type.GetType(name, true))); //OK
- }
- catch (System.Exception e)
- {
- throw new System.ArgumentException("Could not find implementing class for " + attClass.FullName);
- }
- }
- return clazz;
- }
- }
- }
- }
-
- // These two maps must always be in sync!!!
- // So they are private, final and read-only from the outside (read-only iterators)
- private Support.GeneralKeyedCollection<Type, Support.AttributeImplItem> attributes;
- private Support.GeneralKeyedCollection<Type, Support.AttributeImplItem> attributeImpls;
-
- private AttributeFactory factory;
-
- /// <summary> An AttributeSource using the default attribute factory {@link AttributeSource.AttributeFactory#DEFAULT_ATTRIBUTE_FACTORY}.</summary>
- public AttributeSource():this(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY)
- {
- }
-
- /// <summary> An AttributeSource that uses the same attributes as the supplied one.</summary>
- public AttributeSource(AttributeSource input)
- {
- if (input == null)
- {
- throw new System.ArgumentException("input AttributeSource must not be null");
- }
- this.attributes = input.attributes;
- this.attributeImpls = input.attributeImpls;
- this.factory = input.factory;
- }
-
- /// <summary> An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} instances.</summary>
- public AttributeSource(AttributeFactory factory)
- {
+ attClassImplMap.Add(attClass, new WeakReference(clazz = System.Type.GetType(name, true))); //OK
+ }
+ catch (System.Exception e)
+ {
+ throw new System.ArgumentException("Could not find implementing class for " + attClass.FullName);
+ }
+ }
+ return clazz;
+ }
+ }
+ }
+ }
+
+ /// <summary> This class holds the state of an AttributeSource.</summary>
+ /// <seealso cref="captureState">
+ /// </seealso>
+ /// <seealso cref="restoreState">
+ /// </seealso>
+ public sealed class State : System.ICloneable
+ {
+ internal /*private*/ AttributeImpl attribute;
+ internal /*private*/ State next;
+
+ public System.Object Clone()
+ {
+ State clone = new State();
+ clone.attribute = (AttributeImpl)attribute.Clone();
+
+ if (next != null)
+ {
+ clone.next = (State)next.Clone();
+ }
+
+ return clone;
+ }
+ }
+
+
+ // These two maps must always be in sync!!!
+ // So they are private, final and read-only from the outside (read-only iterators)
+ private Support.GeneralKeyedCollection<Type, Support.AttributeImplItem> attributes;
+ private Support.GeneralKeyedCollection<Type, Support.AttributeImplItem> attributeImpls;
+ private State[] currentState = null;
+
+ private AttributeFactory factory;
+
+ /// <summary> An AttributeSource using the default attribute factory {@link AttributeSource.AttributeFactory#DEFAULT_ATTRIBUTE_FACTORY}.</summary>
+ public AttributeSource()
+ : this(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY)
+ {
+ }
+
+ /// <summary> An AttributeSource that uses the same attributes as the supplied one.</summary>
+ public AttributeSource(AttributeSource input)
+ {
+ if (input == null)
+ {
+ throw new System.ArgumentException("input AttributeSource must not be null");
+ }
+ this.attributes = input.attributes;
+ this.attributeImpls = input.attributeImpls;
+ this.currentState = input.currentState;
+ this.factory = input.factory;
+ }
+
+ /// <summary> An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} instances.</summary>
+ public AttributeSource(AttributeFactory factory)
+ {
this.attributes = new Support.GeneralKeyedCollection<Type, Support.AttributeImplItem>(delegate(Support.AttributeImplItem att) { return att.Key; });
this.attributeImpls = new Support.GeneralKeyedCollection<Type, Support.AttributeImplItem>(delegate(Support.AttributeImplItem att) { return att.Key; });
- this.factory = factory;
- }
-
- /// <summary> returns the used AttributeFactory.</summary>
- public virtual AttributeFactory GetAttributeFactory()
- {
- return this.factory;
- }
-
- /// <summary>Returns a new iterator that iterates the attribute classes
- /// in the same order they were added in.
- /// Signature for Java 1.5: <code>public Iterator<Class<? extends Attribute>> getAttributeClassesIterator()</code>
- ///
- /// Note that this return value is different from Java in that it enumerates over the values
- /// and not the keys
- /// </summary>
- public virtual IEnumerable<Type> GetAttributeClassesIterator()
- {
+ this.currentState = new State[1];
+ this.factory = factory;
+ }
+
+ /// <summary> returns the used AttributeFactory.</summary>
+ public virtual AttributeFactory GetAttributeFactory()
+ {
+ return this.factory;
+ }
+
+ /// <summary>Returns a new iterator that iterates the attribute classes
+ /// in the same order they were added in.
+ /// Signature for Java 1.5: <code>public Iterator<Class<? extends Attribute>> getAttributeClassesIterator()</code>
+ ///
+ /// Note that this return value is different from Java in that it enumerates over the values
+ /// and not the keys
+ /// </summary>
+ public virtual IEnumerable<Type> GetAttributeClassesIterator()
+ {
foreach (Support.AttributeImplItem item in this.attributes)
{
yield return item.Key;
}
- }
-
- /// <summary>Returns a new iterator that iterates all unique Attribute implementations.
- /// This iterator may contain less entries that {@link #getAttributeClassesIterator},
- /// if one instance implements more than one Attribute interface.
- /// Signature for Java 1.5: <code>public Iterator<AttributeImpl> getAttributeImplsIterator()</code>
- /// </summary>
- public virtual IEnumerable<AttributeImpl> GetAttributeImplsIterator()
- {
- if (HasAttributes())
- {
- if (currentState == null)
- {
- ComputeCurrentState();
- }
- while (currentState != null)
- {
- AttributeImpl att = currentState.attribute;
- currentState = currentState.next;
- yield return att;
- }
- }
- }
-
- /// <summary>a cache that stores all interfaces for known implementation classes for performance (slow reflection) </summary>
- private static readonly Support.WeakDictionary<Type,List<WeakReference>> knownImplClasses = new Support.WeakDictionary<Type,List<WeakReference>>();
+ }
+
+ /// <summary>Returns a new iterator that iterates all unique Attribute implementations.
+ /// This iterator may contain less entries that {@link #getAttributeClassesIterator},
+ /// if one instance implements more than one Attribute interface.
+ /// Signature for Java 1.5: <code>public Iterator<AttributeImpl> getAttributeImplsIterator()</code>
+ /// </summary>
+ public virtual IEnumerable<AttributeImpl> GetAttributeImplsIterator()
+ {
+ State initState = GetCurrentState();
+ if (initState != null)
+ {
+ return new AnonymousEnumerable(initState);
+ }
+ else
+ {
+ return new List<AttributeImpl>();
+ }
+ }
+
+ 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 Support.WeakDictionary<Type, List<WeakReference>> knownImplClasses = new Support.WeakDictionary<Type, List<WeakReference>>();
// {{Aroush-2.9 Port issue, need to mimic java's IdentityHashMap
/*
@@ -183,72 +277,72 @@ namespace Lucene.Net.Util
* equal if and only if (k1==null ? k2==null : k1.equals(k2)).)
*/
// Aroush-2.9}}
-
- /// <summary>Adds a custom AttributeImpl instance with one or more Attribute interfaces. </summary>
- public virtual void AddAttributeImpl(AttributeImpl att)
- {
- System.Type clazz = att.GetType();
- if (attributeImpls.Contains(clazz))
- return ;
+
+ /// <summary>Adds a custom AttributeImpl instance with one or more Attribute interfaces. </summary>
+ public virtual void AddAttributeImpl(AttributeImpl att)
+ {
+ System.Type clazz = att.GetType();
+ if (attributeImpls.Contains(clazz))
+ return;
List<WeakReference> foundInterfaces;
- lock (knownImplClasses)
- {
+ lock (knownImplClasses)
+ {
foundInterfaces = knownImplClasses[clazz];
- if (foundInterfaces == null)
- {
+ if (foundInterfaces == null)
+ {
// we have a strong reference to the class instance holding all interfaces in the list (parameter "att"),
// so all WeakReferences are never evicted by GC
knownImplClasses.Add(clazz, foundInterfaces = new List<WeakReference>());
- // find all interfaces that this attribute instance implements
- // and that extend the Attribute interface
- System.Type actClazz = clazz;
- do
- {
- System.Type[] interfaces = actClazz.GetInterfaces();
- for (int i = 0; i < interfaces.Length; i++)
- {
- System.Type curInterface = interfaces[i];
- if (curInterface != typeof(Attribute) && typeof(Attribute).IsAssignableFrom(curInterface))
- {
- foundInterfaces.Add(new WeakReference(curInterface));
- }
- }
- actClazz = actClazz.BaseType;
- }
- while (actClazz != null);
- }
- }
-
- // add all interfaces of this AttributeImpl to the maps
- foreach(WeakReference curInterfaceRef in foundInterfaces)
- {
- System.Type curInterface = (System.Type) curInterfaceRef.Target;
- System.Diagnostics.Debug.Assert(curInterface != null,"We have a strong reference on the class holding the interfaces, so they should never get evicted");
- // Attribute is a superclass of this interface
- if (!attributes.ContainsKey(curInterface))
- {
- // invalidate state to force recomputation in captureState()
- this.currentState = null;
+ // find all interfaces that this attribute instance implements
+ // and that extend the Attribute interface
+ System.Type actClazz = clazz;
+ do
+ {
+ System.Type[] interfaces = actClazz.GetInterfaces();
+ for (int i = 0; i < interfaces.Length; i++)
+ {
+ System.Type curInterface = interfaces[i];
+ if (curInterface != typeof(Attribute) && typeof(Attribute).IsAssignableFrom(curInterface))
+ {
+ foundInterfaces.Add(new WeakReference(curInterface));
+ }
+ }
+ actClazz = actClazz.BaseType;
+ }
+ while (actClazz != null);
+ }
+ }
+
+ // add all interfaces of this AttributeImpl to the maps
+ foreach (WeakReference curInterfaceRef in foundInterfaces)
+ {
+ System.Type curInterface = (System.Type)curInterfaceRef.Target;
+ System.Diagnostics.Debug.Assert(curInterface != null, "We have a strong reference on the class holding the interfaces, so they should never get evicted");
+ // Attribute is a superclass of this interface
+ if (!attributes.ContainsKey(curInterface))
+ {
+ // invalidate state to force recomputation in captureState()
+ this.currentState[0] = null;
attributes.Add(new Support.AttributeImplItem(curInterface, att));
if (!attributeImpls.ContainsKey(clazz))
{
attributeImpls.Add(new Support.AttributeImplItem(clazz, att));
}
- }
- }
- }
-
- /// <summary> The caller must pass in a Class<? extends Attribute> value.
- /// This method first checks if an instance of that class is
- /// already in this AttributeSource and returns it. Otherwise a
- /// new instance is created, added to this AttributeSource and returned.
- /// Signature for Java 1.5: <code>public <T extends Attribute> T addAttribute(Class<T>)</code>
- /// </summary>
- public virtual Attribute AddAttribute(System.Type attClass)
- {
- if (!attributes.ContainsKey(attClass))
- {
- if (!(attClass.IsInterface && typeof(Attribute).IsAssignableFrom(attClass)))
+ }
+ }
+ }
+
+ /// <summary> The caller must pass in a Class<? extends Attribute> value.
+ /// This method first checks if an instance of that class is
+ /// already in this AttributeSource and returns it. Otherwise a
+ /// new instance is created, added to this AttributeSource and returned.
+ /// Signature for Java 1.5: <code>public <T extends Attribute> T addAttribute(Class<T>)</code>
+ /// </summary>
+ public virtual Attribute AddAttribute(System.Type attClass)
+ {
+ if (!attributes.ContainsKey(attClass))
+ {
+ if (!(attClass.IsInterface && typeof(Attribute).IsAssignableFrom(attClass)))
{
throw new ArgumentException(
"AddAttribute() only accepts an interface that extends Attribute, but " +
@@ -256,45 +350,45 @@ namespace Lucene.Net.Util
);
}
- AttributeImpl attImpl = this.factory.CreateAttributeInstance(attClass);
- AddAttributeImpl(attImpl);
- return attImpl;
- }
- else
- {
- return attributes[attClass].Value;
- }
- }
-
- /// <summary>Returns true, iff this AttributeSource has any attributes </summary>
- public virtual bool HasAttributes()
- {
- return !(this.attributes.Count == 0);
- }
-
- /// <summary> The caller must pass in a Class<? extends Attribute> value.
- /// Returns true, iff this AttributeSource contains the passed-in Attribute.
- /// Signature for Java 1.5: <code>public boolean hasAttribute(Class<? extends Attribute>)</code>
- /// </summary>
- public virtual bool HasAttribute(System.Type attClass)
- {
- return this.attributes.Contains(attClass);
- }
-
- /// <summary> The caller must pass in a Class<? extends Attribute> value.
- /// Returns the instance of the passed in Attribute contained in this AttributeSource
- /// Signature for Java 1.5: <code>public <T extends Attribute> T getAttribute(Class<T>)</code>
- ///
- /// </summary>
- /// <throws> IllegalArgumentException if this AttributeSource does not contain the </throws>
- /// <summary> Attribute. It is recommended to always use {@link #addAttribute} even in consumers
- /// of TokenStreams, because you cannot know if a specific TokenStream really uses
- /// a specific Attribute. {@link #addAttribute} will automatically make the attribute
- /// available. If you want to only use the attribute, if it is available (to optimize
- /// consuming), use {@link #hasAttribute}.
- /// </summary>
- public virtual Attribute GetAttribute(System.Type attClass)
- {
+ AttributeImpl attImpl = this.factory.CreateAttributeInstance(attClass);
+ AddAttributeImpl(attImpl);
+ return attImpl;
+ }
+ else
+ {
+ return attributes[attClass].Value;
+ }
+ }
+
+ /// <summary>Returns true, iff this AttributeSource has any attributes </summary>
+ public virtual bool HasAttributes()
+ {
+ return !(this.attributes.Count == 0);
+ }
+
+ /// <summary> The caller must pass in a Class<? extends Attribute> value.
+ /// Returns true, iff this AttributeSource contains the passed-in Attribute.
+ /// Signature for Java 1.5: <code>public boolean hasAttribute(Class<? extends Attribute>)</code>
+ /// </summary>
+ public virtual bool HasAttribute(System.Type attClass)
+ {
+ return this.attributes.Contains(attClass);
+ }
+
+ /// <summary> The caller must pass in a Class<? extends Attribute> value.
+ /// Returns the instance of the passed in Attribute contained in this AttributeSource
+ /// Signature for Java 1.5: <code>public <T extends Attribute> T getAttribute(Class<T>)</code>
+ ///
+ /// </summary>
+ /// <throws> IllegalArgumentException if this AttributeSource does not contain the </throws>
+ /// <summary> Attribute. It is recommended to always use {@link #addAttribute} even in consumers
+ /// of TokenStreams, because you cannot know if a specific TokenStream really uses
+ /// a specific Attribute. {@link #addAttribute} will automatically make the attribute
+ /// available. If you want to only use the attribute, if it is available (to optimize
+ /// consuming), use {@link #hasAttribute}.
+ /// </summary>
+ public virtual Attribute GetAttribute(System.Type attClass)
+ {
if (!this.attributes.ContainsKey(attClass))
{
throw new System.ArgumentException("This AttributeSource does not have the attribute '" + attClass.FullName + "'.");
@@ -303,238 +397,202 @@ namespace Lucene.Net.Util
{
return this.attributes[attClass].Value;
}
- }
-
- /// <summary> This class holds the state of an AttributeSource.</summary>
- /// <seealso cref="captureState">
- /// </seealso>
- /// <seealso cref="restoreState">
- /// </seealso>
- public sealed class State : System.ICloneable
- {
- internal /*private*/ AttributeImpl attribute;
- internal /*private*/ State next;
-
- public System.Object Clone()
- {
- State clone = new State();
- clone.attribute = (AttributeImpl) attribute.Clone();
-
- if (next != null)
- {
- clone.next = (State) next.Clone();
- }
-
- return clone;
- }
- }
-
- private State currentState = null;
-
- private void ComputeCurrentState()
- {
- currentState = new State();
- State c = currentState;
- IEnumerator<Support.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
- /// {@link AttributeImpl#Clear()} on each Attribute implementation.
- /// </summary>
- public virtual void ClearAttributes()
- {
- if (HasAttributes())
- {
- if (currentState == null)
- {
- ComputeCurrentState();
- }
- for (State state = currentState; state != null; state = state.next)
- {
- state.attribute.Clear();
- }
- }
- }
-
- /// <summary> Captures the state of all Attributes. The return value can be passed to
- /// {@link #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();
- }
-
- /// <summary> Restores this state by copying the values of all attribute implementations
- /// that this state contains into the attributes implementations of the targetStream.
- /// The targetStream must contain a corresponding instance for each argument
- /// contained in this state (e.g. it is not possible to restore the state of
- /// an AttributeSource containing a TermAttribute into a AttributeSource using
- /// a Token instance as implementation).
- ///
- /// Note that this method does not affect attributes of the targetStream
- /// that are not contained in this state. In other words, if for example
- /// the targetStream contains an OffsetAttribute, but this state doesn't, then
- /// the value of the OffsetAttribute remains unchanged. It might be desirable to
- /// reset its value to the default, in which case the caller should first
- /// call {@link TokenStream#ClearAttributes()} on the targetStream.
- /// </summary>
- public virtual void RestoreState(State state)
- {
- if (state == null)
- return ;
-
- do
- {
- if (!attributeImpls.ContainsKey(state.attribute.GetType()))
- {
- throw new System.ArgumentException("State contains an AttributeImpl that is not in this AttributeSource");
- }
- state.attribute.CopyTo(attributeImpls[state.attribute.GetType()].Value);
- state = state.next;
- }
- while (state != null);
- }
-
- 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;
- }
-
- public override bool Equals(System.Object obj)
- {
- if (obj == this)
- {
- return true;
- }
-
- if (obj is AttributeSource)
- {
- AttributeSource other = (AttributeSource) obj;
-
- if (HasAttributes())
- {
- if (!other.HasAttributes())
- {
- return false;
- }
-
- if (this.attributeImpls.Count != other.attributeImpls.Count)
- {
- return false;
- }
-
- // 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;
- while (thisState != null && otherState != null)
- {
- if (otherState.attribute.GetType() != thisState.attribute.GetType() || !otherState.attribute.Equals(thisState.attribute))
- {
- return false;
- }
- thisState = thisState.next;
- otherState = otherState.next;
- }
- return true;
- }
- else
- {
- return !other.HasAttributes();
- }
- }
- else
- return false;
- }
-
- public override System.String ToString()
- {
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- sb.Append('(');
-
- if (HasAttributes())
- {
- if (currentState == null)
- {
- ComputeCurrentState();
- }
- for (State state = currentState; state != null; state = state.next)
- {
- if (state != currentState)
- sb.Append(',');
- sb.Append(state.attribute.ToString());
- }
- }
- sb.Append(')');
- return sb.ToString();
- }
-
- /// <summary> Performs a clone of all {@link AttributeImpl} instances returned in a new
- /// AttributeSource instance. This method can be used to e.g. create another TokenStream
- /// with exactly the same attributes (using {@link #AttributeSource(AttributeSource)})
- /// </summary>
- public virtual AttributeSource CloneAttributes()
- {
- AttributeSource clone = new AttributeSource(this.factory);
-
- // first clone the impls
- if (HasAttributes())
- {
- if (currentState == null)
- {
- ComputeCurrentState();
- }
- for (State state = currentState; state != null; state = state.next)
- {
- AttributeImpl impl = (AttributeImpl) state.attribute.Clone();
- clone.attributeImpls.Add(new Support.AttributeImplItem(impl.GetType(), impl));
- }
- }
-
- // now the interfaces
+ }
+
+ //private void ComputeCurrentState()
+ //{
+ // currentState = new State();
+ // State c = s = currentState[0] = new State();
+ // IEnumerator<Support.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;
+ // }
+ //}
+
+ 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
+ /// {@link AttributeImpl#Clear()} on each Attribute implementation.
+ /// </summary>
+ public virtual void ClearAttributes()
+ {
+ for (State state = GetCurrentState(); state != null; state = state.next)
+ {
+ state.attribute.Clear();
+ }
+ }
+
+ /// <summary> Captures the state of all Attributes. The return value can be passed to
+ /// {@link #restoreState} to restore the state of this or another AttributeSource.
+ /// </summary>
+ public virtual State CaptureState()
+ {
+ State state = this.GetCurrentState();
+ return (state == null) ? null : (State)state.Clone();
+ }
+
+ /// <summary> Restores this state by copying the values of all attribute implementations
+ /// that this state contains into the attributes implementations of the targetStream.
+ /// The targetStream must contain a corresponding instance for each argument
+ /// contained in this state (e.g. it is not possible to restore the state of
+ /// an AttributeSource containing a TermAttribute into a AttributeSource using
+ /// a Token instance as implementation).
+ ///
+ /// Note that this method does not affect attributes of the targetStream
+ /// that are not contained in this state. In other words, if for example
+ /// the targetStream contains an OffsetAttribute, but this state doesn't, then
+ /// the value of the OffsetAttribute remains unchanged. It might be desirable to
+ /// reset its value to the default, in which case the caller should first
+ /// call {@link TokenStream#ClearAttributes()} on the targetStream.
+ /// </summary>
+ public virtual void RestoreState(State state)
+ {
+ if (state == null)
+ return;
+
+ do
+ {
+ if (!attributeImpls.ContainsKey(state.attribute.GetType()))
+ {
+ throw new System.ArgumentException("State contains an AttributeImpl that is not in this AttributeSource");
+ }
+ state.attribute.CopyTo(attributeImpls[state.attribute.GetType()].Value);
+ state = state.next;
+ }
+ while (state != null);
+ }
+
+ public override int GetHashCode()
+ {
+ int code = 0;
+ for (State state = GetCurrentState(); state != null; state = state.next)
+ {
+ code = code * 31 + state.attribute.GetHashCode();
+ }
+ return code;
+ }
+
+ public override bool Equals(System.Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj is AttributeSource)
+ {
+ AttributeSource other = (AttributeSource)obj;
+
+ if (HasAttributes())
+ {
+ if (!other.HasAttributes())
+ {
+ return false;
+ }
+
+ if (this.attributeImpls.Count != other.attributeImpls.Count)
+ {
+ return false;
+ }
+
+ // it is only equal if all attribute impls are the same in the same order
+ 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))
+ {
+ return false;
+ }
+ thisState = thisState.next;
+ otherState = otherState.next;
+ }
+ return true;
+ }
+ else
+ {
+ return !other.HasAttributes();
+ }
+ }
+ else
+ return false;
+ }
+
+ public override System.String ToString()
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ sb.Append('(');
+
+ if (HasAttributes())
+ {
+ if (currentState[0] == null)
+ {
+ currentState[0] = GetCurrentState();
+ }
+ for (State state = currentState[0]; state != null; state = state.next)
+ {
+ if (state != currentState[0])
+ sb.Append(',');
+ sb.Append(state.attribute.ToString());
+ }
+ }
+ sb.Append(')');
+ return sb.ToString();
+ }
+
+ /// <summary> Performs a clone of all {@link AttributeImpl} instances returned in a new
+ /// AttributeSource instance. This method can be used to e.g. create another TokenStream
+ /// with exactly the same attributes (using {@link #AttributeSource(AttributeSource)})
+ /// </summary>
+ public virtual AttributeSource CloneAttributes()
+ {
+ AttributeSource clone = new AttributeSource(this.factory);
+
+ // first clone the impls
+ if (HasAttributes())
+ {
+ for (State state = GetCurrentState(); state != null; state = state.next)
+ {
+ AttributeImpl impl = (AttributeImpl)state.attribute.Clone();
+
+ if (!clone.attributeImpls.ContainsKey(impl.GetType()))
+ {
+ clone.attributeImpls.Add(new Support.AttributeImplItem(impl.GetType(), impl));
+ }
+ }
+ }
+
+ // now the interfaces
foreach (Support.AttributeImplItem att in this.attributes)
- {
+ {
clone.attributes.Add(new Support.AttributeImplItem(att.Key, clone.attributeImpls[att.Value.GetType()].Value));
- }
-
- return clone;
- }
- }
+ }
+
+ return clone;
+ }
+ }
}
\ No newline at end of file
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/core/Analysis/TestAnalyzers.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/core/Analysis/TestAnalyzers.cs?rev=1143825&r1=1143824&r2=1143825&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/core/Analysis/TestAnalyzers.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/core/Analysis/TestAnalyzers.cs Thu Jul 7 13:44:47 2011
@@ -134,6 +134,24 @@ 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