You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2016/11/10 11:33:16 UTC
[05/58] [abbrv] lucenenet git commit: Added TreeSet and
TreeDictionary from C5 to the Support namespace
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5f198526/src/Lucene.Net.Tests/core/Support/C5/Events.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/core/Support/C5/Events.cs b/src/Lucene.Net.Tests/core/Support/C5/Events.cs
new file mode 100644
index 0000000..f0f5082
--- /dev/null
+++ b/src/Lucene.Net.Tests/core/Support/C5/Events.cs
@@ -0,0 +1,893 @@
+\ufeff/*
+ Copyright (c) 2003-2016 Niels Kokholm, Peter Sestoft, and Rasmus Lystr�m
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+using System;
+using Lucene.Net.Support.C5;
+using NUnit.Framework;
+using SCG = System.Collections.Generic;
+
+namespace Lucene.Net.Support.Templates.Events
+{
+ public abstract class CollectionValueTester<TCollection, TItem> : GenericCollectionTester<TCollection, EventTypeEnum>
+ where TCollection : ICollectionValue<TItem>
+ {
+ protected TCollection collection;
+ protected CollectionEventList<TItem> seen;
+ protected EventTypeEnum listenTo;
+ protected void listen() { seen.Listen(collection, listenTo); }
+
+ public override void SetUp(TCollection list, EventTypeEnum testSpec, MemoryType memoryType)
+ {
+ this.collection = list;
+ listenTo = testSpec;
+ seen = new CollectionEventList<TItem>(EqualityComparer<TItem>.Default, memoryType);
+ }
+
+ public SCG.IEnumerable<EventTypeEnum> SpecsBasic
+ {
+ get
+ {
+ CircularQueue<EventTypeEnum> specs = new CircularQueue<EventTypeEnum>();
+ //foreach (EventTypeEnum listenTo in Enum.GetValues(typeof(EventTypeEnum)))
+ // if ((listenTo & ~EventTypeEnum.Basic) == 0)
+ // specs.Enqueue(listenTo);
+ //specs.Enqueue(EventTypeEnum.Added | EventTypeEnum.Removed);
+ for (int spec = 0; spec <= (int)EventTypeEnum.Basic; spec++)
+ specs.Enqueue((EventTypeEnum)spec);
+ return specs;
+ }
+ }
+ public SCG.IEnumerable<EventTypeEnum> SpecsAll
+ {
+ get
+ {
+ CircularQueue<EventTypeEnum> specs = new CircularQueue<EventTypeEnum>();
+ //foreach (EventTypeEnum listenTo in Enum.GetValues(typeof(EventTypeEnum)))
+ // specs.Enqueue(listenTo);
+ //specs.Enqueue(EventTypeEnum.Added | EventTypeEnum.Removed);
+
+ for (int spec = 0; spec <= (int)EventTypeEnum.All; spec++)
+ specs.Enqueue((EventTypeEnum)spec);
+ return specs;
+ }
+ }
+ }
+ public abstract class CollectionValueTester<U> : CollectionValueTester<U, int> where U : ICollectionValue<int>
+ {
+ }
+
+ public class ExtensibleTester<U> : CollectionValueTester<U> where U : IExtensible<int>
+ {
+ public override SCG.IEnumerable<EventTypeEnum> GetSpecs()
+ {
+ return SpecsBasic;
+ }
+ public virtual void Listenable()
+ {
+ Assert.AreEqual(EventTypeEnum.Basic, collection.ListenableEvents);
+ Assert.AreEqual(EventTypeEnum.None, collection.ActiveEvents);
+ listen();
+ Assert.AreEqual(listenTo, collection.ActiveEvents);
+ }
+
+ public void Add()
+ {
+ listen();
+ seen.Check(new CollectionEvent<int>[0]);
+ collection.Add(23);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ public void AddAll()
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ collection.Add(10 * i + 5);
+ }
+ listen();
+ collection.AddAll(new int[] { 45, 200, 56, 67 });
+ seen.Check(collection.AllowsDuplicates ?
+ collection.DuplicatesByCounting ?
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(200, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(55, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(65, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}
+ :
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(200, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}
+ :
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(200, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.AddAll(new int[] { });
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ }
+
+ public class CollectionTester<U> : ExtensibleTester<U> where U : ICollection<int>
+ {
+ public void Update()
+ {
+ collection.Add(4); collection.Add(54); collection.Add(56); collection.Add(8);
+ listen();
+ collection.Update(53);
+ seen.Check(
+ collection.AllowsDuplicates ?
+ collection.DuplicatesByCounting ?
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(54, 2), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 2), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ }
+ : new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(54, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ }
+ : new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(54, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.Update(67);
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void FindOrAdd()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ int val = 53;
+ collection.FindOrAdd(ref val);
+ seen.Check(new CollectionEvent<int>[] { });
+ val = 67;
+ collection.FindOrAdd(ref val);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ }
+
+ public void UpdateOrAdd()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ int val = 53;
+ collection.UpdateOrAdd(val);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ val = 67;
+ collection.UpdateOrAdd(val);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.UpdateOrAdd(51, out val);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(53, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(51, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ val = 67;
+ collection.UpdateOrAdd(81, out val);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(81, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ }
+
+ public void RemoveItem()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.Remove(53);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Remove(11);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ public void RemoveAll()
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ collection.Add(10 * i + 5);
+ }
+ listen();
+ collection.RemoveAll(new int[] { 32, 187, 45 });
+ //TODO: the order depends on internals of the HashSet
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(35, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(45, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.RemoveAll(new int[] { 200, 300 });
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void RetainAll()
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ collection.Add(10 * i + 5);
+ }
+ listen();
+ collection.RetainAll(new int[] { 32, 187, 45, 62, 75, 82, 95, 2 });
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(55, 1), collection),
+ //new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(75, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.RetainAll(new int[] { 32, 187, 45, 62, 75, 82, 95, 2 });
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void RemoveAllCopies()
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ collection.Add(3 * i + 5);
+ }
+ listen();
+ collection.RemoveAllCopies(14);
+ seen.Check(
+ collection.AllowsDuplicates ?
+ collection.DuplicatesByCounting ?
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 3), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}
+ :
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(14, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(17, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}
+ :
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.RemoveAllCopies(14);
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public virtual void Clear()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection.Clear();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedEventArgs(true, collection.AllowsDuplicates ? 3 : 2), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.Clear();
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ }
+
+ public class IndexedTester<U> : CollectionTester<U> where U : IIndexed<int>
+ {
+ public void RemoveAt()
+ {
+ collection.Add(4); collection.Add(16); collection.Add(28);
+ listen();
+ collection.RemoveAt(1);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(16,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(16, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ public void RemoveInterval()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.RemoveInterval(1, 2);
+ seen.Check(new CollectionEvent<int>[] {
+ collection is IList<int> ?
+ new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,2,1), collection):
+ new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedEventArgs(false,2), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.RemoveInterval(1, 0);
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+ }
+
+ public class SortedIndexedTester<U> : IndexedTester<U> where U : IIndexedSorted<int>
+ {
+ public void DeleteMinMax()
+ {
+ collection.Add(34);
+ collection.Add(56);
+ collection.Add(34);
+ collection.Add(12);
+ listen();
+ collection.DeleteMax();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.DeleteMin();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ }
+
+ public void AddSorted()
+ {
+ listen();
+ collection.AddSorted(collection.AllowsDuplicates ? new int[] { 31, 62, 63, 93 } : new int[] { 31, 62, 93 });
+ seen.Check(collection.AllowsDuplicates ?
+ collection.DuplicatesByCounting ?
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(31, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(93, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}
+ :
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(31, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(63, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(93, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}
+ :
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(31, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(93, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.AddSorted(new int[] { });
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void RemoveRange()
+ {
+ for (int i = 0; i < 20; i++)
+ collection.Add(i * 10 + 5);
+ listen();
+ collection.RemoveRangeFrom(173);
+ //TODO: fix order to remove in:
+ seen.Check(
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(195, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(185, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(175, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.RemoveRangeFromTo(83, 113);
+ seen.Check(
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(105, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(95, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(85, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.RemoveRangeTo(33);
+ seen.Check(
+ new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(5, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.RemoveRangeFrom(173);
+ seen.Check(new CollectionEvent<int>[] { });
+ collection.RemoveRangeFromTo(83, 113);
+ seen.Check(new CollectionEvent<int>[] { });
+ collection.RemoveRangeTo(33);
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+ }
+
+ public class ListTester<U> : IndexedTester<U> where U : IList<int>
+ {
+ public override SCG.IEnumerable<EventTypeEnum> GetSpecs()
+ {
+ return SpecsAll;
+ }
+
+ public override void Listenable()
+ {
+ Assert.AreEqual(EventTypeEnum.All, collection.ListenableEvents);
+ Assert.AreEqual(EventTypeEnum.None, collection.ActiveEvents);
+ listen();
+ Assert.AreEqual(listenTo, collection.ActiveEvents);
+ }
+ public void SetThis()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection[1] = 45;
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ }
+
+ public void Insert()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection.Insert(1, 45);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ }
+
+ public void InsertAll()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection.InsertAll(1, new int[] { 666, 777, 888 });
+ //seen.Print(Console.Error);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(666,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(666, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(777,2), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(777, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(888,3), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(888, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.InsertAll(1, new int[] { });
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void InsertFirstLast()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.InsertFirst(45);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.InsertLast(88);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(88,4), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(88, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ }
+
+ public void Remove()
+ {
+ collection.FIFO = false;
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.Remove();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.FIFO = true;
+ collection.Remove();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ public void RemoveFirst()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.RemoveFirst();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(4,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ public void RemoveLast()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.RemoveLast();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(18,2), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ public void Reverse()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection.Reverse();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.View(1, 0).Reverse();
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+
+ public void Sort()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection.Sort();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.View(1, 0).Sort();
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void Shuffle()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(8);
+ listen();
+ collection.Shuffle();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.View(1, 0).Shuffle();
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public override void Clear()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.View(1, 1).Clear();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,1,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.Clear();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,2,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.Clear();
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ public void ListDispose()
+ {
+ collection.Add(4); collection.Add(56); collection.Add(18);
+ listen();
+ collection.View(1, 1).Dispose();
+ seen.Check(new CollectionEvent<int>[] { });
+ collection.Dispose();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,3,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ collection.Dispose();
+ seen.Check(new CollectionEvent<int>[] { });
+ }
+
+ /*
+
+ * /
+ //[TearDown]
+ //public void Dispose() { list = null; seen = null; }
+ /*
+ [Test]
+ [ExpectedException(typeof(UnlistenableEventException))]
+ public void ViewChanged()
+ {
+ IList<int> w = collection.View(0, 0);
+ w.CollectionChanged += new CollectionChangedHandler<int>(w_CollectionChanged);
+ }
+
+ [Test]
+ [ExpectedException(typeof(UnlistenableEventException))]
+ public void ViewCleared()
+ {
+ IList<int> w = collection.View(0, 0);
+ w.CollectionCleared += new CollectionClearedHandler<int>(w_CollectionCleared);
+ }
+
+ [Test]
+ [ExpectedException(typeof(UnlistenableEventException))]
+ public void ViewAdded()
+ {
+ IList<int> w = collection.View(0, 0);
+ w.ItemsAdded += new ItemsAddedHandler<int>(w_ItemAdded);
+ }
+
+ [Test]
+ [ExpectedException(typeof(UnlistenableEventException))]
+ public void ViewInserted()
+ {
+ IList<int> w = collection.View(0, 0);
+ w.ItemInserted += new ItemInsertedHandler<int>(w_ItemInserted);
+ }
+
+ [Test]
+ [ExpectedException(typeof(UnlistenableEventException))]
+ public void ViewRemoved()
+ {
+ IList<int> w = collection.View(0, 0);
+ w.ItemsRemoved += new ItemsRemovedHandler<int>(w_ItemRemoved);
+ }
+
+ [Test]
+ [ExpectedException(typeof(UnlistenableEventException))]
+ public void ViewRemovedAt()
+ {
+ IList<int> w = collection.View(0, 0);
+ w.ItemRemovedAt += new ItemRemovedAtHandler<int>(w_ItemRemovedAt);
+ }
+
+ void w_CollectionChanged(object sender)
+ {
+ throw new NotImplementedException();
+ }
+
+ void w_CollectionCleared(object sender, ClearedEventArgs eventArgs)
+ {
+ throw new NotImplementedException();
+ }
+
+ void w_ItemAdded(object sender, ItemCountEventArgs<int> eventArgs)
+ {
+ throw new NotImplementedException();
+ }
+
+ void w_ItemInserted(object sender, ItemAtEventArgs<int> eventArgs)
+ {
+ throw new NotImplementedException();
+ }
+
+ void w_ItemRemoved(object sender, ItemCountEventArgs<int> eventArgs)
+ {
+ throw new NotImplementedException();
+ }
+
+ void w_ItemRemovedAt(object sender, ItemAtEventArgs<int> eventArgs)
+ {
+ throw new NotImplementedException();
+ }*/
+ }
+
+ public class StackTester<U> : CollectionValueTester<U> where U : IStack<int>
+ {
+ public override SCG.IEnumerable<EventTypeEnum> GetSpecs()
+ {
+ return SpecsBasic;
+ }
+
+ public void PushPop()
+ {
+ listen();
+ seen.Check(new CollectionEvent<int>[0]);
+ collection.Push(23);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(23,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Push(-12);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(-12,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(-12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Pop();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(-12,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(-12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Pop();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(23,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(23, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+ }
+
+ public class QueueTester<U> : CollectionValueTester<U> where U : IQueue<int>
+ {
+ public override SCG.IEnumerable<EventTypeEnum> GetSpecs()
+ {
+ return SpecsBasic;
+ }
+
+ public void EnqueueDequeue()
+ {
+ listen();
+ collection.Enqueue(67);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(67,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Enqueue(2);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(2,1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Dequeue();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(67,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(67, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Dequeue();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(2,0), collection),
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(2, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+ }
+
+ public class PriorityQueueTester<U> : ExtensibleTester<U> where U : IPriorityQueue<int>
+ {
+ public override System.Collections.Generic.IEnumerable<EventTypeEnum> GetSpecs()
+ {
+ return SpecsBasic;
+ }
+
+ public void Direct()
+ {
+ listen();
+ collection.Add(34);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.Add(56);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.AddAll(new int[] { });
+ seen.Check(new CollectionEvent<int>[] {
+ });
+ collection.Add(34);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.Add(12);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.DeleteMax();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.DeleteMin();
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.AddAll(new int[] { 4, 5, 6, 2 });
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(4, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(5, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(6, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)
+ });
+ }
+
+ public void WithHandles()
+ {
+ listen();
+ IPriorityQueueHandle<int> handle = null, handle2;
+ collection.Add(34);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.Add(56);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.Add(ref handle, 34);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.Add(12);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.DeleteMax(out handle2);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ collection.DeleteMin(out handle2);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(12, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+
+ collection.Replace(handle, 117);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(34, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(117, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+
+ collection.Delete(handle);
+ seen.Check(new CollectionEvent<int>[] {
+ new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(117, 1), collection),
+ new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection),
+ });
+ }
+ }
+
+ public class DictionaryTester<U> : CollectionValueTester<U, KeyValuePair<int, int>> where U : IDictionary<int, int>
+ {
+ public override SCG.IEnumerable<EventTypeEnum> GetSpecs()
+ {
+ return SpecsBasic;
+ }
+
+ public virtual void Listenable()
+ {
+ Assert.AreEqual(EventTypeEnum.Basic, collection.ListenableEvents);
+ Assert.AreEqual(EventTypeEnum.None, collection.ActiveEvents);
+ listen();
+ Assert.AreEqual(listenTo, collection.ActiveEvents);
+ }
+
+ public void AddAndREmove()
+ {
+ listen();
+ seen.Check(new CollectionEvent<KeyValuePair<int, int>>[0]);
+ collection.Add(23, 45);
+ seen.Check(new CollectionEvent<KeyValuePair<int, int>>[] {
+ new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Added, new ItemCountEventArgs<KeyValuePair<int,int>>(new KeyValuePair<int,int>(23,45), 1), collection),
+ new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ collection.Remove(25);
+ seen.Check(new CollectionEvent<KeyValuePair<int, int>>[] {
+ new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Removed, new ItemCountEventArgs<KeyValuePair<int,int>>(new KeyValuePair<int,int>(23,45), 1), collection),
+ new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Changed, new EventArgs(), collection)});
+ }
+
+
+
+ }
+
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5f198526/src/Lucene.Net.Tests/core/Support/C5/GenericCollectionTester.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/core/Support/C5/GenericCollectionTester.cs b/src/Lucene.Net.Tests/core/Support/C5/GenericCollectionTester.cs
new file mode 100644
index 0000000..12b4360
--- /dev/null
+++ b/src/Lucene.Net.Tests/core/Support/C5/GenericCollectionTester.cs
@@ -0,0 +1,87 @@
+\ufeff/*
+ Copyright (c) 2003-2016 Niels Kokholm, Peter Sestoft, and Rasmus Lystr�m
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+using System;
+using System.Reflection;
+using Lucene.Net.Support.C5;
+using NUnit.Framework;
+using SCG = System.Collections.Generic;
+
+namespace Lucene.Net.Support.Templates
+{
+ public abstract class GenericCollectionTester<U, W>
+ {
+ protected CircularQueue<MethodInfo> testMethods;
+ public GenericCollectionTester()
+ {
+ testMethods = new CircularQueue<MethodInfo>();
+ foreach (MethodInfo minfo in this.GetType().GetMethods())
+ {
+ if (minfo.GetParameters().Length == 0 &&
+ minfo.GetCustomAttributes(typeof(TestAttribute), false).Length > 0)
+ testMethods.Enqueue(minfo);
+ }
+ }
+
+ public virtual void Test(Func<U> factory, MemoryType memoryType = MemoryType.Normal)
+ {
+ foreach (MethodInfo minfo in testMethods)
+ {
+ foreach (W testSpec in GetSpecs())
+ {
+ SetUp(factory(), testSpec, memoryType);
+ //Console.WriteLine("Testing {0}, with method {1} and testSpec {{{2}}}", typeof(U), minfo.Name, testSpec);
+ try
+ {
+ minfo.Invoke(this, null);
+ }
+ catch (TargetInvocationException)
+ {
+ //if (e.InnerException is ExpectedExceptionAttribute)
+ //{
+ //}
+ //else
+ throw;
+ }
+ //tearDown
+ }
+ }
+ }
+
+ public abstract void SetUp(U collection, W testSpec, MemoryType memoryType);
+ public abstract SCG.IEnumerable<W> GetSpecs();
+ }
+
+ public abstract class GenericCollectionTester<U> : GenericCollectionTester<U, int>
+ {
+ public override System.Collections.Generic.IEnumerable<int> GetSpecs()
+ {
+ return new int[] { 0 };
+ }
+
+ public override void SetUp(U collection, int testSpec, MemoryType memoryType)
+ {
+ SetUp(collection, memoryType);
+ }
+
+ public abstract void SetUp(object collection, MemoryType memoryType);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5f198526/src/Lucene.Net.Tests/core/Support/C5/HashBag.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/core/Support/C5/HashBag.cs b/src/Lucene.Net.Tests/core/Support/C5/HashBag.cs
new file mode 100644
index 0000000..dbfec88
--- /dev/null
+++ b/src/Lucene.Net.Tests/core/Support/C5/HashBag.cs
@@ -0,0 +1,658 @@
+\ufeff/*
+ Copyright (c) 2003-2016 Niels Kokholm, Peter Sestoft, and Rasmus Lystr�m
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+using System;
+using SCG = System.Collections.Generic;
+
+namespace Lucene.Net.Support.C5
+{
+ /// <summary>
+ /// A bag collection based on a hash table of (item,count) pairs.
+ /// </summary>
+ [Serializable]
+ public class HashBag<T> : CollectionBase<T>, ICollection<T>
+ {
+ #region Fields
+ HashSet<KeyValuePair<T, int>> dict;
+ #endregion
+
+ #region Events
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <value></value>
+ public override EventTypeEnum ListenableEvents { get { return EventTypeEnum.Basic; } }
+
+ #endregion
+
+ #region Constructors
+ /// <summary>
+ /// Create a hash bag with the default item equalityComparer.
+ /// </summary>
+ public HashBag(MemoryType memoryType = MemoryType.Normal) : this(EqualityComparer<T>.Default, memoryType) { }
+
+ /// <summary>
+ /// Create a hash bag with an external item equalityComparer.
+ /// </summary>
+ /// <param name="itemequalityComparer">The external item equalityComparer.</param>
+ /// <param name = "memoryType"></param>
+ public HashBag(SCG.IEqualityComparer<T> itemequalityComparer, MemoryType memoryType = MemoryType.Normal)
+ : base(itemequalityComparer, memoryType)
+ {
+ if (memoryType != MemoryType.Normal)
+ throw new Exception("HashBag doesn't still support Safe and Strict memory type.");
+
+ dict = new HashSet<KeyValuePair<T, int>>(new KeyValuePairEqualityComparer<T, int>(itemequalityComparer), memoryType);
+ }
+
+ /// <summary>
+ /// Create a hash bag with external item equalityComparer, prescribed initial table size and default fill threshold (66%)
+ /// </summary>
+ /// <param name="capacity">Initial table size (rounded to power of 2, at least 16)</param>
+ /// <param name="itemequalityComparer">The external item equalitySCG.Comparer</param>
+ /// <param name = "memoryType"></param>
+ public HashBag(int capacity, SCG.IEqualityComparer<T> itemequalityComparer, MemoryType memoryType = MemoryType.Normal)
+ : base(itemequalityComparer, memoryType)
+ {
+ if (memoryType != MemoryType.Normal)
+ throw new Exception("HashBag doesn't still support Safe and Strict memory type.");
+
+ dict = new HashSet<KeyValuePair<T, int>>(capacity, new KeyValuePairEqualityComparer<T, int>(itemequalityComparer), memoryType);
+ }
+
+
+ /// <summary>
+ /// Create a hash bag with external item equalityComparer, prescribed initial table size and fill threshold.
+ /// </summary>
+ /// <param name="capacity">Initial table size (rounded to power of 2, at least 16)</param>
+ /// <param name="fill">Fill threshold (valid range 10% to 90%)</param>
+ /// <param name="itemequalityComparer">The external item equalitySCG.Comparer</param>
+ /// <param name = "memoryType"></param>
+ public HashBag(int capacity, double fill, SCG.IEqualityComparer<T> itemequalityComparer, MemoryType memoryType = MemoryType.Normal)
+ : base(itemequalityComparer, memoryType)
+ {
+ if (memoryType != MemoryType.Normal)
+ throw new Exception("HashBag doesn't still support Safe and Strict memory type.");
+
+ dict = new HashSet<KeyValuePair<T, int>>(capacity, fill, new KeyValuePairEqualityComparer<T, int>(itemequalityComparer), memoryType);
+ }
+
+ #endregion
+
+ #region IEditableCollection<T> Members
+
+ /// <summary>
+ /// The complexity of the Contains operation
+ /// </summary>
+ /// <value>Always returns Speed.Constant</value>
+ public virtual Speed ContainsSpeed { get { return Speed.Constant; } }
+
+ /// <summary>
+ /// Check if an item is in the bag
+ /// </summary>
+ /// <param name="item">The item to look for</param>
+ /// <returns>True if bag contains item</returns>
+ public virtual bool Contains(T item)
+ {
+ return dict.Contains(new KeyValuePair<T, int>(item, 0));
+ }
+
+
+ /// <summary>
+ /// Check if an item (collection equal to a given one) is in the bag and
+ /// if so report the actual item object found.
+ /// </summary>
+ /// <param name="item">On entry, the item to look for.
+ /// On exit the item found, if any</param>
+ /// <returns>True if bag contains item</returns>
+ public virtual bool Find(ref T item)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+
+ if (dict.Find(ref p))
+ {
+ item = p.Key;
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /// <summary>
+ /// Check if an item (collection equal to a given one) is in the bag and
+ /// if so replace the item object in the bag with the supplied one.
+ /// </summary>
+ /// <param name="item">The item object to update with</param>
+ /// <returns>True if item was found (and updated)</returns>
+ public virtual bool Update(T item)
+ { T olditem = default(T); return Update(item, out olditem); }
+
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="item"></param>
+ /// <param name="olditem"></param>
+ /// <returns></returns>
+ public virtual bool Update(T item, out T olditem)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+
+ updatecheck();
+
+ //Note: we cannot just do dict.Update: we have to lookup the count before we
+ //know what to update with. There is of course a way around if we use the
+ //implementation of hashset -which we do not want to do.
+ //The hashbag is moreover mainly a proof of concept
+ if (dict.Find(ref p))
+ {
+ olditem = p.Key;
+ p.Key = item;
+ dict.Update(p);
+ if (ActiveEvents != 0)
+ raiseForUpdate(item, olditem, p.Value);
+ return true;
+ }
+
+ olditem = default(T);
+ return false;
+ }
+
+
+ /// <summary>
+ /// Check if an item (collection equal to a given one) is in the bag.
+ /// If found, report the actual item object in the bag,
+ /// else add the supplied one.
+ /// </summary>
+ /// <param name="item">On entry, the item to look for or add.
+ /// On exit the actual object found, if any.</param>
+ /// <returns>True if item was found</returns>
+ public virtual bool FindOrAdd(ref T item)
+ {
+ updatecheck();
+ if (Find(ref item))
+ return true;
+
+ Add(item);
+ return false;
+ }
+
+
+ /// <summary>
+ /// Check if an item (collection equal to a supplied one) is in the bag and
+ /// if so replace the item object in the set with the supplied one; else
+ /// add the supplied one.
+ /// </summary>
+ /// <param name="item">The item to look for and update or add</param>
+ /// <returns>True if item was updated</returns>
+ public virtual bool UpdateOrAdd(T item)
+ {
+ updatecheck();
+ if (Update(item))
+ return true;
+
+ Add(item);
+ return false;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="item"></param>
+ /// <param name="olditem"></param>
+ /// <returns></returns>
+ public virtual bool UpdateOrAdd(T item, out T olditem)
+ {
+ updatecheck();
+ if (Update(item, out olditem))
+ return true;
+
+ Add(item);
+ return false;
+ }
+
+ /// <summary>
+ /// Remove one copy of an item from the bag
+ /// </summary>
+ /// <param name="item">The item to remove</param>
+ /// <returns>True if item was (found and) removed </returns>
+ public virtual bool Remove(T item)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+
+ updatecheck();
+ if (dict.Find(ref p))
+ {
+ size--;
+ if (p.Value == 1)
+ dict.Remove(p);
+ else
+ {
+ p.Value--;
+ dict.Update(p);
+ }
+ if (ActiveEvents != 0)
+ raiseForRemove(p.Key);
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /// <summary>
+ /// Remove one copy of an item from the bag, reporting the actual matching item object.
+ /// </summary>
+ /// <param name="item">The value to remove.</param>
+ /// <param name="removeditem">The removed value.</param>
+ /// <returns>True if item was found.</returns>
+ public virtual bool Remove(T item, out T removeditem)
+ {
+ updatecheck();
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+ if (dict.Find(ref p))
+ {
+ removeditem = p.Key;
+ size--;
+ if (p.Value == 1)
+ dict.Remove(p);
+ else
+ {
+ p.Value--;
+ dict.Update(p);
+ }
+ if (ActiveEvents != 0)
+ raiseForRemove(removeditem);
+
+ return true;
+ }
+
+ removeditem = default(T);
+ return false;
+ }
+
+ /// <summary>
+ /// Remove all items in a supplied collection from this bag, counting multiplicities.
+ /// </summary>
+ /// <param name="items">The items to remove.</param>
+ public virtual void RemoveAll(SCG.IEnumerable<T> items)
+ {
+#warning Improve if items is a counting bag
+ updatecheck();
+ bool mustRaise = (ActiveEvents & (EventTypeEnum.Changed | EventTypeEnum.Removed)) != 0;
+ RaiseForRemoveAllHandler raiseHandler = mustRaise ? new RaiseForRemoveAllHandler(this) : null;
+ foreach (T item in items)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+ if (dict.Find(ref p))
+ {
+ size--;
+ if (p.Value == 1)
+ dict.Remove(p);
+ else
+ {
+ p.Value--;
+ dict.Update(p);
+ }
+ if (mustRaise)
+ raiseHandler.Remove(p.Key);
+ }
+ }
+ if (mustRaise)
+ raiseHandler.Raise();
+ }
+
+ /// <summary>
+ /// Remove all items from the bag, resetting internal table to initial size.
+ /// </summary>
+ public virtual void Clear()
+ {
+ updatecheck();
+ if (size == 0)
+ return;
+ dict.Clear();
+ int oldsize = size;
+ size = 0;
+ if ((ActiveEvents & EventTypeEnum.Cleared) != 0)
+ raiseCollectionCleared(true, oldsize);
+ if ((ActiveEvents & EventTypeEnum.Changed) != 0)
+ raiseCollectionChanged();
+ }
+
+
+ /// <summary>
+ /// Remove all items *not* in a supplied collection from this bag,
+ /// counting multiplicities.
+ /// </summary>
+ /// <param name="items">The items to retain</param>
+ public virtual void RetainAll(SCG.IEnumerable<T> items)
+ {
+ updatecheck();
+
+ HashBag<T> res = new HashBag<T>(itemequalityComparer);
+
+ foreach (T item in items)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item);
+ if (dict.Find(ref p))
+ {
+ KeyValuePair<T, int> q = p;
+ if (res.dict.Find(ref q))
+ {
+ if (q.Value < p.Value)
+ {
+ q.Value++;
+ res.dict.Update(q);
+ res.size++;
+ }
+ }
+ else
+ {
+ q.Value = 1;
+ res.dict.Add(q);
+ res.size++;
+ }
+ }
+ }
+
+ if (size == res.size)
+ return;
+
+ CircularQueue<T> wasRemoved = null;
+ if ((ActiveEvents & EventTypeEnum.Removed) != 0)
+ {
+ wasRemoved = new CircularQueue<T>();
+ foreach (KeyValuePair<T, int> p in dict)
+ {
+ int removed = p.Value - res.ContainsCount(p.Key);
+ if (removed > 0)
+#warning We could send bag events here easily using a CircularQueue of (should?)
+ for (int i = 0; i < removed; i++)
+ wasRemoved.Enqueue(p.Key);
+ }
+ }
+ dict = res.dict;
+ size = res.size;
+
+ if ((ActiveEvents & EventTypeEnum.Removed) != 0)
+ raiseForRemoveAll(wasRemoved);
+ else if ((ActiveEvents & EventTypeEnum.Changed) != 0)
+ raiseCollectionChanged();
+ }
+
+ /// <summary>
+ /// Check if all items in a supplied collection is in this bag
+ /// (counting multiplicities).
+ /// </summary>
+ /// <param name="items">The items to look for.</param>
+ /// <returns>True if all items are found.</returns>
+ public virtual bool ContainsAll(SCG.IEnumerable<T> items)
+ {
+ HashBag<T> res = new HashBag<T>(itemequalityComparer);
+
+ foreach (T item in items)
+ if (res.ContainsCount(item) < ContainsCount(item))
+ res.Add(item);
+ else
+ return false;
+
+ return true;
+ }
+
+
+ /// <summary>
+ /// Create an array containing all items in this bag (in enumeration order).
+ /// </summary>
+ /// <returns>The array</returns>
+ public override T[] ToArray()
+ {
+ T[] res = new T[size];
+ int ind = 0;
+
+ foreach (KeyValuePair<T, int> p in dict)
+ for (int i = 0; i < p.Value; i++)
+ res[ind++] = p.Key;
+
+ return res;
+ }
+
+
+ /// <summary>
+ /// Count the number of times an item is in this set.
+ /// </summary>
+ /// <param name="item">The item to look for.</param>
+ /// <returns>The count</returns>
+ public virtual int ContainsCount(T item)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+
+ if (dict.Find(ref p))
+ return p.Value;
+
+ return 0;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public virtual ICollectionValue<T> UniqueItems() { return new DropMultiplicity<T>(dict); }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()
+ {
+ return new GuardedCollectionValue<KeyValuePair<T, int>>(dict);
+ }
+
+ /// <summary>
+ /// Remove all copies of item from this set.
+ /// </summary>
+ /// <param name="item">The item to remove</param>
+ public virtual void RemoveAllCopies(T item)
+ {
+ updatecheck();
+
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);
+
+ if (dict.Find(ref p))
+ {
+ size -= p.Value;
+ dict.Remove(p);
+ if ((ActiveEvents & EventTypeEnum.Removed) != 0)
+ raiseItemsRemoved(p.Key, p.Value);
+ if ((ActiveEvents & EventTypeEnum.Changed) != 0)
+ raiseCollectionChanged();
+ }
+ }
+
+ #endregion
+
+ #region ICollection<T> Members
+
+
+ /// <summary>
+ /// Copy the items of this bag to part of an array.
+ /// <exception cref="ArgumentOutOfRangeException"/> if i is negative.
+ /// <exception cref="ArgumentException"/> if the array does not have room for the items.
+ /// </summary>
+ /// <param name="array">The array to copy to</param>
+ /// <param name="index">The starting index.</param>
+ public override void CopyTo(T[] array, int index)
+ {
+ if (index < 0 || index + Count > array.Length)
+ throw new ArgumentOutOfRangeException();
+
+ foreach (KeyValuePair<T, int> p in dict)
+ for (int j = 0; j < p.Value; j++)
+ array[index++] = p.Key;
+ }
+
+ #endregion
+
+ #region IExtensible<T> Members
+
+ /// <summary>
+ /// Report if this is a set collection.
+ /// </summary>
+ /// <value>Always true</value>
+ public virtual bool AllowsDuplicates { get { return true; } }
+
+ /// <summary>
+ /// By convention this is true for any collection with set semantics.
+ /// </summary>
+ /// <value>True if only one representative of a group of equal items
+ /// is kept in the collection together with the total count.</value>
+ public virtual bool DuplicatesByCounting { get { return true; } }
+
+ /// <summary>
+ /// Add an item to this bag.
+ /// </summary>
+ /// <param name="item">The item to add.</param>
+ /// <returns>Always true</returns>
+ public virtual bool Add(T item)
+ {
+ updatecheck();
+ add(ref item);
+ if (ActiveEvents != 0)
+ raiseForAdd(item);
+ return true;
+ }
+
+ /// <summary>
+ /// Add an item to this bag.
+ /// </summary>
+ /// <param name="item">The item to add.</param>
+ void SCG.ICollection<T>.Add(T item)
+ {
+ Add(item);
+ }
+
+ private void add(ref T item)
+ {
+ KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 1);
+ if (dict.Find(ref p))
+ {
+ p.Value++;
+ dict.Update(p);
+ item = p.Key;
+ }
+ else
+ dict.Add(p);
+ size++;
+ }
+
+ /// <summary>
+ /// Add the elements from another collection with a more specialized item type
+ /// to this collection.
+ /// </summary>
+ /// <param name="items">The items to add</param>
+ public virtual void AddAll(SCG.IEnumerable<T> items)
+ {
+ updatecheck();
+#warning We could easily raise bag events
+ bool mustRaiseAdded = (ActiveEvents & EventTypeEnum.Added) != 0;
+ CircularQueue<T> wasAdded = mustRaiseAdded ? new CircularQueue<T>() : null;
+ bool wasChanged = false;
+ foreach (T item in items)
+ {
+ T jtem = item;
+ add(ref jtem);
+ wasChanged = true;
+ if (mustRaiseAdded)
+ wasAdded.Enqueue(jtem);
+ }
+ if (!wasChanged)
+ return;
+ if (mustRaiseAdded)
+ foreach (T item in wasAdded)
+ raiseItemsAdded(item, 1);
+ if ((ActiveEvents & EventTypeEnum.Changed) != 0)
+ raiseCollectionChanged();
+ }
+
+ #endregion
+
+ #region IEnumerable<T> Members
+
+
+ /// <summary>
+ /// Choose some item of this collection.
+ /// </summary>
+ /// <exception cref="NoSuchItemException">if collection is empty.</exception>
+ /// <returns></returns>
+ public override T Choose()
+ {
+ return dict.Choose().Key;
+ }
+
+ /// <summary>
+ /// Create an enumerator for this bag.
+ /// </summary>
+ /// <returns>The enumerator</returns>
+ public override SCG.IEnumerator<T> GetEnumerator()
+ {
+ int left;
+ int mystamp = stamp;
+
+ foreach (KeyValuePair<T, int> p in dict)
+ {
+ left = p.Value;
+ while (left > 0)
+ {
+ if (mystamp != stamp)
+ throw new CollectionModifiedException();
+
+ left--;
+ yield return p.Key;
+ }
+ }
+ }
+ #endregion
+
+ #region Diagnostics
+ /// <summary>
+ /// Test internal structure of data (invariants)
+ /// </summary>
+ /// <returns>True if pass</returns>
+ public virtual bool Check()
+ {
+ bool retval = dict.Check();
+ int count = 0;
+
+ foreach (KeyValuePair<T, int> p in dict)
+ count += p.Value;
+
+ if (count != size)
+ {
+ Logger.Log(string.Format("count({0}) != size({1})", count, size));
+ retval = false;
+ }
+
+ return retval;
+ }
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5f198526/src/Lucene.Net.Tests/core/Support/C5/Sorting.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/core/Support/C5/Sorting.cs b/src/Lucene.Net.Tests/core/Support/C5/Sorting.cs
new file mode 100644
index 0000000..58a16ae
--- /dev/null
+++ b/src/Lucene.Net.Tests/core/Support/C5/Sorting.cs
@@ -0,0 +1,235 @@
+\ufeff/*
+ Copyright (c) 2003-2016 Niels Kokholm, Peter Sestoft, and Rasmus Lystr�m
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+using System;
+using SCG = System.Collections.Generic;
+namespace Lucene.Net.Support.C5
+{
+ /// <summary>
+ /// A utility class with functions for sorting arrays with respect to an IComparer<T>
+ /// </summary>
+ [Serializable]
+ public class Sorting
+ {
+ Sorting() { }
+
+ /// <summary>
+ /// Sort part of array in place using IntroSort
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">If the <code>start</code>
+ /// and <code>count</code> arguments does not describe a valid range.</exception>
+ /// <param name="array">Array to sort</param>
+ /// <param name="start">Index of first position to sort</param>
+ /// <param name="count">Number of elements to sort</param>
+ /// <param name="comparer">IComparer<T> to sort by</param>
+ public static void IntroSort<T>(T[] array, int start, int count, SCG.IComparer<T> comparer)
+ {
+ if (start < 0 || count < 0 || start + count > array.Length)
+ throw new ArgumentOutOfRangeException();
+ new Sorter<T>(array, comparer).IntroSort(start, start + count);
+ }
+
+ /// <summary>
+ /// Sort an array in place using IntroSort and default comparer
+ /// </summary>
+ /// <exception cref="NotComparableException">If T is not comparable</exception>
+ /// <param name="array">Array to sort</param>
+ public static void IntroSort<T>(T[] array)
+ {
+ new Sorter<T>(array, SCG.Comparer<T>.Default).IntroSort(0, array.Length);
+ }
+
+
+ /// <summary>
+ /// Sort part of array in place using Insertion Sort
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">If the <code>start</code>
+ /// and <code>count</code> arguments does not describe a valid range.</exception>
+ /// <param name="array">Array to sort</param>
+ /// <param name="start">Index of first position to sort</param>
+ /// <param name="count">Number of elements to sort</param>
+ /// <param name="comparer">IComparer<T> to sort by</param>
+ public static void InsertionSort<T>(T[] array, int start, int count, SCG.IComparer<T> comparer)
+ {
+ if (start < 0 || count < 0 || start + count > array.Length)
+ throw new ArgumentOutOfRangeException();
+ new Sorter<T>(array, comparer).InsertionSort(start, start + count);
+ }
+
+
+ /// <summary>
+ /// Sort part of array in place using Heap Sort
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">If the <code>start</code>
+ /// and <code>count</code> arguments does not describe a valid range.</exception>
+ /// <param name="array">Array to sort</param>
+ /// <param name="start">Index of first position to sort</param>
+ /// <param name="count">Number of elements to sort</param>
+ /// <param name="comparer">IComparer<T> to sort by</param>
+ public static void HeapSort<T>(T[] array, int start, int count, SCG.IComparer<T> comparer)
+ {
+ if (start < 0 || count < 0 || start + count > array.Length)
+ throw new ArgumentOutOfRangeException();
+ new Sorter<T>(array, comparer).HeapSort(start, start + count);
+ }
+
+ [Serializable]
+ class Sorter<T>
+ {
+ T[] a;
+
+ SCG.IComparer<T> c;
+
+
+ internal Sorter(T[] a, SCG.IComparer<T> c) { this.a = a; this.c = c; }
+
+
+ internal void IntroSort(int f, int b)
+ {
+ if (b - f > 31)
+ {
+ int depth_limit = (int)Math.Floor(2.5 * Math.Log(b - f, 2));
+
+ introSort(f, b, depth_limit);
+ }
+ else
+ InsertionSort(f, b);
+ }
+
+
+ private void introSort(int f, int b, int depth_limit)
+ {
+ const int size_threshold = 14;//24;
+
+ if (depth_limit-- == 0)
+ HeapSort(f, b);
+ else if (b - f <= size_threshold)
+ InsertionSort(f, b);
+ else
+ {
+ int p = partition(f, b);
+
+ introSort(f, p, depth_limit);
+ introSort(p, b, depth_limit);
+ }
+ }
+
+
+ private int compare(T i1, T i2) { return c.Compare(i1, i2); }
+
+
+ private int partition(int f, int b)
+ {
+ int bot = f, mid = (b + f) / 2, top = b - 1;
+ T abot = a[bot], amid = a[mid], atop = a[top];
+
+ if (compare(abot, amid) < 0)
+ {
+ if (compare(atop, abot) < 0)//atop<abot<amid
+ { a[top] = amid; amid = a[mid] = abot; a[bot] = atop; }
+ else if (compare(atop, amid) < 0) //abot<=atop<amid
+ { a[top] = amid; amid = a[mid] = atop; }
+ //else abot<amid<=atop
+ }
+ else
+ {
+ if (compare(amid, atop) > 0) //atop<amid<=abot
+ { a[bot] = atop; a[top] = abot; }
+ else if (compare(abot, atop) > 0) //amid<=atop<abot
+ { a[bot] = amid; amid = a[mid] = atop; a[top] = abot; }
+ else //amid<=abot<=atop
+ { a[bot] = amid; amid = a[mid] = abot; }
+ }
+
+ int i = bot, j = top;
+
+ while (true)
+ {
+ while (compare(a[++i], amid) < 0) ;
+
+ while (compare(amid, a[--j]) < 0) ;
+
+ if (i < j)
+ {
+ T tmp = a[i]; a[i] = a[j]; a[j] = tmp;
+ }
+ else
+ return i;
+ }
+ }
+
+
+ internal void InsertionSort(int f, int b)
+ {
+ for (int j = f + 1; j < b; j++)
+ {
+ T key = a[j], other;
+ int i = j - 1;
+
+ if (c.Compare(other = a[i], key) > 0)
+ {
+ a[j] = other;
+ while (i > f && c.Compare(other = a[i - 1], key) > 0) { a[i--] = other; }
+
+ a[i] = key;
+ }
+ }
+ }
+
+
+ internal void HeapSort(int f, int b)
+ {
+ for (int i = (b + f) / 2; i >= f; i--) heapify(f, b, i);
+
+ for (int i = b - 1; i > f; i--)
+ {
+ T tmp = a[f]; a[f] = a[i]; a[i] = tmp;
+ heapify(f, i, f);
+ }
+ }
+
+
+ private void heapify(int f, int b, int i)
+ {
+ T pv = a[i], lv, rv, max = pv;
+ int j = i, maxpt = j;
+
+ while (true)
+ {
+ int l = 2 * j - f + 1, r = l + 1;
+
+ if (l < b && compare(lv = a[l], max) > 0) { maxpt = l; max = lv; }
+
+ if (r < b && compare(rv = a[r], max) > 0) { maxpt = r; max = rv; }
+
+ if (maxpt == j)
+ break;
+
+ a[j] = max;
+ max = pv;
+ j = maxpt;
+ }
+
+ if (j > i)
+ a[j] = pv;
+ }
+ }
+ }
+}
\ No newline at end of file