fba9d87e65
git-svn-id: file:///srv/devel/repo-conversion/nusu@40 d2e56fa2-650e-0410-a79f-9358c0239efd
191 lines
6.8 KiB
C#
191 lines
6.8 KiB
C#
#region CPL License
|
|
/*
|
|
Nuclex Framework
|
|
Copyright (C) 2002-2007 Nuclex Development Labs
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the IBM Common Public License as
|
|
published by the IBM Corporation; either version 1.0 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
IBM Common Public License for more details.
|
|
|
|
You should have received a copy of the IBM Common Public
|
|
License along with this library
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections;
|
|
|
|
namespace Nuclex.Support.Collections {
|
|
|
|
/// <summary>Queue that dequeues items in order of their priority</summary>
|
|
public class UnintrusivePriorityQueue<ItemType, PriorityType>
|
|
: ICollection, IEnumerable<ItemType>
|
|
where PriorityType : IComparable<PriorityType> {
|
|
|
|
#region struct Entry
|
|
|
|
/// <summary>An entry in the priority queue</summary>
|
|
private struct Entry {
|
|
|
|
/// <summary>Initializes a new priority queue entry</summary>
|
|
/// <param name="item">Item to be stored in the entry</param>
|
|
/// <param name="priority">Priority of the item in the entry</param>
|
|
public Entry(ItemType item, PriorityType priority) {
|
|
this.Item = item;
|
|
this.Priority = priority;
|
|
}
|
|
|
|
/// <summary>Item contained in this priority queue entry</summary>
|
|
public ItemType Item;
|
|
/// <summary>Priority assigned to this entry</summary>
|
|
public PriorityType Priority;
|
|
|
|
}
|
|
|
|
#endregion // struct Entry
|
|
|
|
#region class EntryComparer
|
|
|
|
/// <summary>Compares two priority queue entries based on their priority</summary>
|
|
private class EntryComparer : IComparer<Entry> {
|
|
|
|
/// <summary>Compares the left entry to the right entry</summary>
|
|
/// <param name="left">Entry on the left side</param>
|
|
/// <param name="right">Entry on the right side</param>
|
|
/// <returns>The relationship of the two entries</returns>
|
|
public int Compare(Entry left, Entry right) {
|
|
return left.Priority.CompareTo(right.Priority);
|
|
}
|
|
|
|
/// <summary>Default instance for this comparer</summary>
|
|
public static readonly EntryComparer Instance = new EntryComparer();
|
|
|
|
}
|
|
|
|
#endregion // class EntryComparer
|
|
|
|
#region class UnwrappingEnumerator
|
|
|
|
/// <summary>Enumerates all items contained in a priority queue</summary>
|
|
private class UnwrappingEnumerator : IEnumerator<ItemType> {
|
|
|
|
/// <summary>Initializes a new priority queue enumerator</summary>
|
|
/// <param name="entryEnumerator">Enumerator of entries to unwrap</param>
|
|
public UnwrappingEnumerator(IEnumerator<Entry> entryEnumerator) {
|
|
this.entryEnumerator = entryEnumerator;
|
|
}
|
|
|
|
/// <summary>Resets the enumerator to its initial state</summary>
|
|
public void Reset() {
|
|
this.entryEnumerator.Reset();
|
|
}
|
|
|
|
/// <summary>The current item being enumerated</summary>
|
|
ItemType IEnumerator<ItemType>.Current {
|
|
get { return this.entryEnumerator.Current.Item; }
|
|
}
|
|
|
|
/// <summary>Releases all resources used by the enumerator</summary>
|
|
public void Dispose() {
|
|
this.entryEnumerator.Dispose();
|
|
}
|
|
|
|
/// <summary>Moves to the next item in the priority queue</summary>
|
|
/// <returns>True if a next item was found, false if the end has been reached</returns>
|
|
public bool MoveNext() {
|
|
return this.entryEnumerator.MoveNext();
|
|
}
|
|
|
|
/// <summary>The current item being enumerated</summary>
|
|
object IEnumerator.Current {
|
|
get { return this.entryEnumerator.Current.Item; }
|
|
}
|
|
|
|
/// <summary>Enumerator for entries to be unwrapped by this enumerator</summary>
|
|
private IEnumerator<Entry> entryEnumerator;
|
|
|
|
}
|
|
|
|
#endregion // class Enumerator
|
|
|
|
/// <summary>Initializes a new non-intrusive priority queue</summary>
|
|
public UnintrusivePriorityQueue() {
|
|
this.intrusiveQueue = new PriorityQueue<Entry>(EntryComparer.Instance);
|
|
}
|
|
|
|
/// <summary>Takes the item with the highest priority off from the queue</summary>
|
|
/// <returns>The item with the highest priority in the list</returns>
|
|
public ItemType Dequeue() {
|
|
return this.intrusiveQueue.Dequeue().Item;
|
|
}
|
|
|
|
/// <summary>Puts an item into the priority queue</summary>
|
|
/// <param name="item">Item to be queued</param>
|
|
/// <param name="priority">Priority of the item to be queued</param>
|
|
public void Enqueue(ItemType item, PriorityType priority) {
|
|
this.intrusiveQueue.Enqueue(new Entry(item, priority));
|
|
}
|
|
|
|
/// <summary>Removes all items from the priority queue</summary>
|
|
public void Clear() {
|
|
this.intrusiveQueue.Clear();
|
|
}
|
|
|
|
/// <summary>Total number of items in the priority queue</summary>
|
|
public int Count {
|
|
get { return this.intrusiveQueue.Count; }
|
|
}
|
|
|
|
/// <summary>Copies the contents of the priority queue into an array</summary>
|
|
/// <param name="array">Array to copy the priority queue into</param>
|
|
/// <param name="index">Starting index for the destination array</param>
|
|
public void CopyTo(Array array, int index) {
|
|
|
|
Entry[] entries = new Entry[this.intrusiveQueue.Count];
|
|
|
|
this.intrusiveQueue.CopyTo(array, 0);
|
|
|
|
for(int entryIndex = 0; entryIndex < this.intrusiveQueue.Count; ++entryIndex)
|
|
array.SetValue(entries[entryIndex], entryIndex + index);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtains an object that can be used to synchronize accesses to the priority queue
|
|
/// from different threads
|
|
/// </summary>
|
|
public object SyncRoot {
|
|
get { return this.intrusiveQueue.SyncRoot; }
|
|
}
|
|
|
|
/// <summary>Whether operations performed on this priority queue are thread safe</summary>
|
|
public bool IsSynchronized {
|
|
get { return this.intrusiveQueue.IsSynchronized; }
|
|
}
|
|
|
|
/// <summary>Returns a typesafe enumerator for the priority queue</summary>
|
|
/// <returns>A new enumerator for the priority queue</returns>
|
|
public IEnumerator<ItemType> GetEnumerator() {
|
|
return new UnwrappingEnumerator(this.intrusiveQueue.GetEnumerator());
|
|
}
|
|
|
|
/// <summary>Returns an enumerator for the priority queue</summary>
|
|
/// <returns>A new enumerator for the priority queue</returns>
|
|
IEnumerator IEnumerable.GetEnumerator() {
|
|
return new UnwrappingEnumerator(this.intrusiveQueue.GetEnumerator());
|
|
}
|
|
|
|
/// <summary>Intrusive priority queue being wrapped by this class</summary>
|
|
private PriorityQueue<Entry> intrusiveQueue;
|
|
|
|
}
|
|
|
|
} // namespace Nuclex.Support.Collections
|