using System;
using System.Collections;
using System.Threading;
using System.Diagnostics;
using NGrid;
using NGrid.Threading;
namespace NGridTest{
public class GridSort
{
// the 'Node's are chained to form a single linked list
[Serializable]
private class Node : GObject
{
private IComparer comparer;
private object nodeValue;
private Node left;
private bool swap;
public Node(IComparer comparer, Node left, object nodeValue)
{
this.comparer = comparer;
this.left = left;
this.nodeValue = nodeValue;
}
// compare with the values
public void CompareSwap()
{
// locking 'left' and then 'this'
using (new Lock(left))
{
using (new Lock(this))
{
swap = (comparer.Compare(left.Value, this.Value) > 0);
if (swap)
{
object tmp = this.Value;
this.Value = left.Value;
left.Value = tmp;
}
}
}
}
// value holded by this node
public object Value
{
get { return nodeValue; }
set
{
nodeValue = value;
}
}
// indicates if values were swaped when calling 'CompareSwap'
public bool Swap
{
get { return swap; }
}
}
public static void Sort(Array array, IComparer comparer)
{
// building the node single-linked list
Node[] nodes = new Node[array.Length];
nodes[0] = (Node)(new Node(comparer, null, array.GetValue(0))).GetProxy();
for (int i = 1; i < array.Length; i++)
nodes[i] = (Node)(new Node(comparer, nodes[i - 1], array.GetValue(i))).GetProxy();
// looping until no swap occurs any more
bool swapOccured = true;
while (swapOccured)
{
GThread[] threads = new GThread[array.Length - 1];
// starting 'even' grid threads
for (int j = 0; j < threads.Length; j += 2)
{
threads[j] = (new GThread(new ThreadStart(nodes[j + 1].CompareSwap))).GetProxy();
threads[j].Start();
}
// starting 'odd' grid threads
for (int j = 1; j < threads.Length; j += 2)
{
threads[j] = (new GThread(new ThreadStart(nodes[j + 1].CompareSwap))).GetProxy();
threads[j].Start();
}
// joining and checking if a 'swap' occurred
swapOccured = false;
for (int j = 0; j < threads.Length; j++)
{
threads[j].Join();
swapOccured |= nodes[j + 1].Swap;
}
}
// collecting the ordered values
for (int i = 0; i < array.Length; i++)
{
array.SetValue(nodes[i].Value, i);
}
}
}
class Program
{
/// <summary>
/// Sorts a <c>n</c>-dimensional array of integers. Returns the time of execution.
/// </summary>
static double SortingTest(int nb)
{
Stopwatch time = new Stopwatch();
Random t = new Random();
Console.WriteLine("Gnration des donnes trier ...");
int[] table = new int[nb];
for (int i = 0; i < nb; i++)
{
table.SetValue(t.Next(1000), i);
}
Console.WriteLine("Affichage du tableau non tri ...");
for (int i = 0; i < nb; i++)
{
Console.Write("{0} ", table[i]);
}
Console.WriteLine();
Console.WriteLine("Dbut du tri des donnes ...");
time.Start();
GridSort.Sort(table, System.Collections.Comparer.Default);
time.Stop();
Console.WriteLine("Affichage du tableau tri ...");
for (int i = 0; i < nb; i++)
{
Console.Write("{0} ", table[i]);
}
Console.WriteLine();
return time.Elapsed.TotalSeconds;
}
static void Main(string[] args)
{
int nb;
if (args.Length == 0)
{
Console.WriteLine("Aucun paramtre donn : taille du tableau prise 20 par dfaut.");
nb = 20;
}
else
{
nb = int.Parse(args[0]);
}
double timeElapsed = SortingTest(nb);
Console.WriteLine("Fin du programme : {0}s.", timeElapsed.ToString());
Console.WriteLine("Appuyer sur une touche pour continuer ...");
Console.ReadKey(true);
}
}
}
|