diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2012-03-10 07:48:48 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2012-03-10 07:48:48 -0800 |
commit | 351ecb6678ec3cbd469bfa8076dfdc7aad83e987 (patch) | |
tree | 83bfc6d5ff5cddf7144cc85de5b4df755753b724 /src/DotNetOpenAuth.Core/Messaging/EnumerableCache.cs | |
parent | 9615b7bd55edd2aac07a32a8f808c8fa2f5a6e85 (diff) | |
download | DotNetOpenAuth-351ecb6678ec3cbd469bfa8076dfdc7aad83e987.zip DotNetOpenAuth-351ecb6678ec3cbd469bfa8076dfdc7aad83e987.tar.gz DotNetOpenAuth-351ecb6678ec3cbd469bfa8076dfdc7aad83e987.tar.bz2 |
Applied all the StyleCop fixes necessary by the StyleCop 4.7 upgrade.
Diffstat (limited to 'src/DotNetOpenAuth.Core/Messaging/EnumerableCache.cs')
-rw-r--r-- | src/DotNetOpenAuth.Core/Messaging/EnumerableCache.cs | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/EnumerableCache.cs b/src/DotNetOpenAuth.Core/Messaging/EnumerableCache.cs deleted file mode 100644 index afbdf30..0000000 --- a/src/DotNetOpenAuth.Core/Messaging/EnumerableCache.cs +++ /dev/null @@ -1,243 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="EnumerableCache.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// This code is released under the Microsoft Public License (Ms-PL). -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Messaging { - using System; - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics.Contracts; - - /// <summary> - /// Extension methods for <see cref="IEnumerable<T>"/> types. - /// </summary> - public static class EnumerableCacheExtensions { - /// <summary> - /// Caches the results of enumerating over a given object so that subsequence enumerations - /// don't require interacting with the object a second time. - /// </summary> - /// <typeparam name="T">The type of element found in the enumeration.</typeparam> - /// <param name="sequence">The enumerable object.</param> - /// <returns> - /// Either a new enumerable object that caches enumerated results, or the original, <paramref name="sequence"/> - /// object if no caching is necessary to avoid additional CPU work. - /// </returns> - /// <remarks> - /// <para>This is designed for use on the results of generator methods (the ones with <c>yield return</c> in them) - /// so that only those elements in the sequence that are needed are ever generated, while not requiring - /// regeneration of elements that are enumerated over multiple times.</para> - /// <para>This can be a huge performance gain if enumerating multiple times over an expensive generator method.</para> - /// <para>Some enumerable types such as collections, lists, and already-cached generators do not require - /// any (additional) caching, and this method will simply return those objects rather than caching them - /// to avoid double-caching.</para> - /// </remarks> - public static IEnumerable<T> CacheGeneratedResults<T>(this IEnumerable<T> sequence) { - Requires.NotNull(sequence, "sequence"); - - // Don't create a cache for types that don't need it. - if (sequence is IList<T> || - sequence is ICollection<T> || - sequence is Array || - sequence is EnumerableCache<T>) { - return sequence; - } - - return new EnumerableCache<T>(sequence); - } - - /// <summary> - /// A wrapper for <see cref="IEnumerable<T>"/> types and returns a caching <see cref="IEnumerator<T>"/> - /// from its <see cref="IEnumerable<T>.GetEnumerator"/> method. - /// </summary> - /// <typeparam name="T">The type of element in the sequence.</typeparam> - private class EnumerableCache<T> : IEnumerable<T> { - /// <summary> - /// The results from enumeration of the live object that have been collected thus far. - /// </summary> - private List<T> cache; - - /// <summary> - /// The original generator method or other enumerable object whose contents should only be enumerated once. - /// </summary> - private IEnumerable<T> generator; - - /// <summary> - /// The enumerator we're using over the generator method's results. - /// </summary> - private IEnumerator<T> generatorEnumerator; - - /// <summary> - /// The sync object our caching enumerators use when adding a new live generator method result to the cache. - /// </summary> - /// <remarks> - /// Although individual enumerators are not thread-safe, this <see cref="IEnumerable<T>"/> should be - /// thread safe so that multiple enumerators can be created from it and used from different threads. - /// </remarks> - private object generatorLock = new object(); - - /// <summary> - /// Initializes a new instance of the EnumerableCache class. - /// </summary> - /// <param name="generator">The generator.</param> - internal EnumerableCache(IEnumerable<T> generator) { - Requires.NotNull(generator, "generator"); - - this.generator = generator; - } - - #region IEnumerable<T> Members - - /// <summary> - /// Returns an enumerator that iterates through the collection. - /// </summary> - /// <returns> - /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection. - /// </returns> - public IEnumerator<T> GetEnumerator() { - if (this.generatorEnumerator == null) { - this.cache = new List<T>(); - this.generatorEnumerator = this.generator.GetEnumerator(); - } - - return new EnumeratorCache(this); - } - - #endregion - - #region IEnumerable Members - - /// <summary> - /// Returns an enumerator that iterates through a collection. - /// </summary> - /// <returns> - /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection. - /// </returns> - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return this.GetEnumerator(); - } - - #endregion - - /// <summary> - /// An enumerator that uses cached enumeration results whenever they are available, - /// and caches whatever results it has to pull from the original <see cref="IEnumerable<T>"/> object. - /// </summary> - private class EnumeratorCache : IEnumerator<T> { - /// <summary> - /// The parent enumeration wrapper class that stores the cached results. - /// </summary> - private EnumerableCache<T> parent; - - /// <summary> - /// The position of this enumerator in the cached list. - /// </summary> - private int cachePosition = -1; - - /// <summary> - /// Initializes a new instance of the EnumeratorCache class. - /// </summary> - /// <param name="parent">The parent cached enumerable whose GetEnumerator method is calling this constructor.</param> - internal EnumeratorCache(EnumerableCache<T> parent) { - Requires.NotNull(parent, "parent"); - - this.parent = parent; - } - - #region IEnumerator<T> Members - - /// <summary> - /// Gets the element in the collection at the current position of the enumerator. - /// </summary> - /// <returns> - /// The element in the collection at the current position of the enumerator. - /// </returns> - public T Current { - get { - if (this.cachePosition < 0 || this.cachePosition >= this.parent.cache.Count) { - throw new InvalidOperationException(); - } - - return this.parent.cache[this.cachePosition]; - } - } - - #endregion - - #region IEnumerator Properties - - /// <summary> - /// Gets the element in the collection at the current position of the enumerator. - /// </summary> - /// <returns> - /// The element in the collection at the current position of the enumerator. - /// </returns> - object System.Collections.IEnumerator.Current { - get { return this.Current; } - } - - #endregion - - #region IDisposable Members - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region IEnumerator Methods - - /// <summary> - /// Advances the enumerator to the next element of the collection. - /// </summary> - /// <returns> - /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. - /// </returns> - /// <exception cref="T:System.InvalidOperationException"> - /// The collection was modified after the enumerator was created. - /// </exception> - public bool MoveNext() { - this.cachePosition++; - if (this.cachePosition >= this.parent.cache.Count) { - lock (this.parent.generatorLock) { - if (this.parent.generatorEnumerator.MoveNext()) { - this.parent.cache.Add(this.parent.generatorEnumerator.Current); - } else { - return false; - } - } - } - - return true; - } - - /// <summary> - /// Sets the enumerator to its initial position, which is before the first element in the collection. - /// </summary> - /// <exception cref="T:System.InvalidOperationException"> - /// The collection was modified after the enumerator was created. - /// </exception> - public void Reset() { - this.cachePosition = -1; - } - - #endregion - - /// <summary> - /// Releases unmanaged and - optionally - managed resources - /// </summary> - /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool disposing) { - // Nothing to do here. - } - } - } - } -} |