using System;
using System.Collections.Generic;
using System.Text;
// This is released under the public domain.
// Originally created by Orvid King for OForms.
namespace Cosmos.Common
{
///
/// A linked queue implementation.
/// This class is thread-safe.
///
public class LinkedQueue
{
///
/// This class represents a single item
/// in the Queue.
///
private class QueueItem
{
///
/// The next object in the
/// queue.
///
public QueueItem NextObject;
///
/// The previous object in
/// the queue.
///
public QueueItem PreviousObject;
///
/// The actual value in this queue item.
///
public T2 Value;
}
private QueueItem FrontItem;
private QueueItem BackItem;
private int depth;
///
/// Creates a new instance of the
/// LinkedQueue class.
///
public LinkedQueue() { }
///
/// The number of items
/// in the queue.
///
public int Count { get { return depth; } }
///
/// Add the specified
/// value at the back
/// of the queue.
///
/// The value to add.
public void Enqueue(T value)
{
lock (this)
{
if (FrontItem == null)
{
// This is the first
// item to be added to the queue.
QueueItem val = new QueueItem();
val.Value = value;
FrontItem = val;
BackItem = val;
}
else
{
QueueItem bkItem = BackItem;
QueueItem val = new QueueItem();
val.Value = value;
bkItem.NextObject = val;
val.PreviousObject = bkItem;
this.BackItem = val;
}
this.depth++;
}
}
///
/// Retrieve the first item
/// in the queue.
///
///
/// The first value in the queue.
///
public T Dequeue()
{
lock (this)
{
if (FrontItem == null)
throw new Exception("No item in the queue!");
this.depth--;
QueueItem val = FrontItem;
if (val.NextObject == null)
{
BackItem = null;
FrontItem = null;
}
else
{
FrontItem = FrontItem.NextObject;
FrontItem.PreviousObject = null;
}
return val.Value;
}
}
}
}