rd-net/Test.Lifetimes/Collections/PriorityQueueTest.cs (223 lines of code) (raw):
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Collections;
using JetBrains.Lifetimes;
using JetBrains.Util;
using NUnit.Framework;
namespace Test.Lifetimes.Collections
{
[TestFixture]
public class PriorityQueueTest : LifetimesTestBase
{
[Test]
public void TestEnumerator01()
{
var q = new JetPriorityQueue<int>();
Assert.IsTrue(EmptyArray<int>.Instance.SequenceEqual(q), "EmptyArray<int>.Instance.SequenceEqual(q)");
}
[Test]
public void TestEnumerator02()
{
var q = new JetPriorityQueue<int>();
q.Add(1);
q.Add(2);
q.Add(3);
Assert.IsTrue(new int[] { 1, 2, 3}.SequenceEqual(q), "new int[] {{ 1, 2, 3}}.SequenceEqual(q)");
}
[Test]
public void TestNoComparer()
{
var q = new JetPriorityQueue<int>();
Assert.AreEqual(0, q.Count);
Assert.True(!q.Any());
q.Add(5);
q.Add(3);
q.Add(4);
q.Add(1);
q.Add(2);
Assert.AreEqual(5, q.Count);
Assert.False(!q.Any());
AssertExtract(1, q);
AssertExtract(2, q);
AssertExtract(3, q);
Assert.AreEqual(2, q.Count);
q.Add(5);
q.Add(3);
Assert.AreEqual(4, q.Count);
AssertExtract(3, q);
q.Add(1);
AssertExtract(1, q);
AssertExtract(4, q);
AssertExtract(5, q);
AssertExtract(5, q);
int x;
Assert.False(q.TryPeek(out x));
Assert.False(q.TryExtract(out x));
Assert.AreEqual(0, q.ExtractOrDefault());
}
class Timed
{
internal string Name { get; private set; }
internal DateTime Time { get; private set; }
public Timed(string name, DateTime time)
{
Name = name;
Time = time;
}
internal class Comparer : IComparer<Timed>
{
public int Compare(Timed x, Timed y)
{
if (x.Time > y.Time) return 1;
if (x.Time < y.Time) return -1;
return 0;
}
}
}
[Test]
public void TestWithDateComparer()
{
var q = new BlockingPriorityQueue<Timed>(Lifetime.Eternal, 10, new Timed.Comparer());
for (int i = 0; i < 10; i++)
{
q.Add(new Timed(i.ToString(), DateTime.Now+TimeSpan.FromSeconds(10-i)));
q.Add(new Timed(i.ToString(), DateTime.Now+TimeSpan.FromSeconds(10-i)));
}
Assert.AreEqual("9", q.Extract().Name);
Assert.AreEqual("9", q.Extract().Name);
Assert.AreEqual("8", q.Extract().Name);
Assert.AreEqual("8", q.Extract().Name);
Assert.AreEqual("7", q.Extract().Name);
Assert.AreEqual("7", q.Extract().Name);
Assert.AreEqual("6", q.Extract().Name);
Assert.AreEqual("6", q.Extract().Name);
Assert.AreEqual("5", q.Extract().Name);
Assert.AreEqual("5", q.Extract().Name);
Assert.AreEqual("4", q.Extract().Name);
Assert.AreEqual("4", q.Extract().Name);
Assert.AreEqual("3", q.Extract().Name);
Assert.AreEqual("3", q.Extract().Name);
Assert.AreEqual("2", q.Extract().Name);
Assert.AreEqual("2", q.Extract().Name);
Assert.AreEqual("1", q.Extract().Name);
Assert.AreEqual("1", q.Extract().Name);
Assert.AreEqual("0", q.Extract().Name);
Assert.AreEqual("0", q.Extract().Name);
}
private class DateTimeComparer : IComparer<DateTime>
{
public int Compare(DateTime x, DateTime y)
{
if (x > y) return 1;
if (x < y) return -1;
return 0;
}
}
[Test]
public void TestTimedQueue()
{
var queue = new JetPriorityQueue<DateTime>(10, new DateTimeComparer());
for (int seed = 0; seed < 1000; seed++)
{
var random = new Random(seed);
var now = DateTime.Now;
for (int i = 0; i < 11; i++)
queue.Add(now + TimeSpan.FromMilliseconds(random.Next(0, 1000)));
var lastDateTime = DateTime.MinValue;
DateTime res;
while (queue.TryPeek(out res))
{
res = queue.Extract();
Assert.LessOrEqual(lastDateTime, res, string.Format("Count = {0}, Seed = {1}", queue.Count, seed));
lastDateTime = res;
}
}
}
[Test]
public void TestQueueDifferentSizes()
{
for (var size = 0; size <= 20; size++)
{
var queue = new JetPriorityQueue<int>(size);
for (var seed = 0; seed < 10; seed++)
{
var random = new Random(seed);
var source = new List<int>(size);
for (var i = 0; i < size; i++)
source.Add(random.Next(0, 1000));
for (var i = 0; i < size; i++)
{
queue.Add(source[i]);
Assert.AreEqual(queue.Count, i+1, "Add failed.");
}
int prevVal = -1;
int peekVal;
for (var i = 0; i < size; i++)
{
Assert.True(queue.TryPeek(out peekVal), "TryPeek failed.");
var curVal = queue.Extract();
Assert.AreEqual(peekVal, curVal, "Peek/Extract mismatch.");
Assert.LessOrEqual(prevVal, curVal, string.Format("Values are not ordered (Size = {0}, Seed = {1}, Count = {2}).", size, seed, queue.Count));
prevVal = curVal;
}
Assert.False(queue.TryPeek(out peekVal), "TryPeek failed.");
}
}
}
[Test]
public void TestStable()
{
var q = new JetPriorityQueue<string>();
var a1 = new string('a', 1);
var a2 = new string('a', 1);
var a3 = new string('a', 1);
var a4 = new string('a', 1);
q.Add(a1);
q.Add(a2);
q.Add(a3);
q.Add(a4);
Assert.True(ReferenceEquals(a1, q.Extract()));
Assert.True(ReferenceEquals(a2, q.Extract()));
Assert.True(ReferenceEquals(a3, q.Extract()));
Assert.True(ReferenceEquals(a4, q.Extract()));
}
[Test]
public void TestFailedQueueAt()
{
int[] data =
{
235,
21,
222,
163,
522,
884,
68,
17,
544,
867,
444
};
var q = new JetPriorityQueue<int>();
foreach (var i in data)
{
q.Add(i);
}
var res = new List<int>();
while (!q.Any())
{
res.Add(q.Extract());
}
Console.WriteLine(string.Join(",", res.Select(x => x.ToString()).ToArray()) + " : " + res.Count);
}
private void AssertExtract<T>(T x, IPriorityQueue<T> q)
{
T xx;
Assert.True(q.TryPeek(out xx));
Assert.AreEqual(x, xx);
Assert.True(q.TryExtract(out xx));
Assert.AreEqual(x, xx);
}
}
}