From 1a47ff8094ee414a47aebd310826906d89428a09 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Fri, 30 May 2008 12:27:06 +0000
Subject: * This is Melanie's XEngine script engine. I've not tested this real
well, however, it's confirmed to compile and OpenSimulator to run
successfully without this script engine active.
---
ThirdParty/SmartThreadPool/PriorityQueue.cs | 240 ++++++++++++++++++++++++++++
1 file changed, 240 insertions(+)
create mode 100644 ThirdParty/SmartThreadPool/PriorityQueue.cs
(limited to 'ThirdParty/SmartThreadPool/PriorityQueue.cs')
diff --git a/ThirdParty/SmartThreadPool/PriorityQueue.cs b/ThirdParty/SmartThreadPool/PriorityQueue.cs
new file mode 100644
index 0000000..63d5e84
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/PriorityQueue.cs
@@ -0,0 +1,240 @@
+// Ami Bar
+// amibar@gmail.com
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+
+namespace Amib.Threading.Internal
+{
+ #region PriorityQueue class
+
+ ///
+ /// PriorityQueue class
+ /// This class is not thread safe because we use external lock
+ ///
+ public sealed class PriorityQueue : IEnumerable
+ {
+ #region Private members
+
+ ///
+ /// The number of queues, there is one for each type of priority
+ ///
+ private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
+
+ ///
+ /// Work items queues. There is one for each type of priority
+ ///
+ private Queue [] _queues = new Queue[_queuesCount];
+
+ ///
+ /// The total number of work items within the queues
+ ///
+ private int _workItemsCount = 0;
+
+ ///
+ /// Use with IEnumerable interface
+ ///
+ private int _version = 0;
+
+ #endregion
+
+ #region Contructor
+
+ public PriorityQueue()
+ {
+ for(int i = 0; i < _queues.Length; ++i)
+ {
+ _queues[i] = new Queue();
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Enqueue a work item.
+ ///
+ /// A work item
+ public void Enqueue(IHasWorkItemPriority workItem)
+ {
+ Debug.Assert(null != workItem);
+
+ int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
+ Debug.Assert(queueIndex >= 0);
+ Debug.Assert(queueIndex < _queuesCount);
+
+ _queues[queueIndex].Enqueue(workItem);
+ ++_workItemsCount;
+ ++_version;
+ }
+
+ ///
+ /// Dequeque a work item.
+ ///
+ /// Returns the next work item
+ public IHasWorkItemPriority Dequeue()
+ {
+ IHasWorkItemPriority workItem = null;
+
+ if(_workItemsCount > 0)
+ {
+ int queueIndex = GetNextNonEmptyQueue(-1);
+ Debug.Assert(queueIndex >= 0);
+ workItem = _queues[queueIndex].Dequeue() as IHasWorkItemPriority;
+ Debug.Assert(null != workItem);
+ --_workItemsCount;
+ ++_version;
+ }
+
+ return workItem;
+ }
+
+ ///
+ /// Find the next non empty queue starting at queue queueIndex+1
+ ///
+ /// The index-1 to start from
+ ///
+ /// The index of the next non empty queue or -1 if all the queues are empty
+ ///
+ private int GetNextNonEmptyQueue(int queueIndex)
+ {
+ for(int i = queueIndex+1; i < _queuesCount; ++i)
+ {
+ if(_queues[i].Count > 0)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ ///
+ /// The number of work items
+ ///
+ public int Count
+ {
+ get
+ {
+ return _workItemsCount;
+ }
+ }
+
+ ///
+ /// Clear all the work items
+ ///
+ public void Clear()
+ {
+ if (_workItemsCount > 0)
+ {
+ foreach(Queue queue in _queues)
+ {
+ queue.Clear();
+ }
+ _workItemsCount = 0;
+ ++_version;
+ }
+ }
+
+ #endregion
+
+ #region IEnumerable Members
+
+ ///
+ /// Returns an enumerator to iterate over the work items
+ ///
+ /// Returns an enumerator
+ public IEnumerator GetEnumerator()
+ {
+ return new PriorityQueueEnumerator(this);
+ }
+
+ #endregion
+
+ #region PriorityQueueEnumerator
+
+ ///
+ /// The class the implements the enumerator
+ ///
+ private class PriorityQueueEnumerator : IEnumerator
+ {
+ private PriorityQueue _priorityQueue;
+ private int _version;
+ private int _queueIndex;
+ private IEnumerator _enumerator;
+
+ public PriorityQueueEnumerator(PriorityQueue priorityQueue)
+ {
+ _priorityQueue = priorityQueue;
+ _version = _priorityQueue._version;
+ _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
+ if (_queueIndex >= 0)
+ {
+ _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
+ }
+ else
+ {
+ _enumerator = null;
+ }
+ }
+
+ #region IEnumerator Members
+
+ public void Reset()
+ {
+ _version = _priorityQueue._version;
+ _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
+ if (_queueIndex >= 0)
+ {
+ _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
+ }
+ else
+ {
+ _enumerator = null;
+ }
+ }
+
+ public object Current
+ {
+ get
+ {
+ Debug.Assert(null != _enumerator);
+ return _enumerator.Current;
+ }
+ }
+
+ public bool MoveNext()
+ {
+ if (null == _enumerator)
+ {
+ return false;
+ }
+
+ if(_version != _priorityQueue._version)
+ {
+ throw new InvalidOperationException("The collection has been modified");
+
+ }
+ if (!_enumerator.MoveNext())
+ {
+ _queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
+ if(-1 == _queueIndex)
+ {
+ return false;
+ }
+ _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
+ _enumerator.MoveNext();
+ return true;
+ }
+ return true;
+ }
+
+ #endregion
+ }
+
+ #endregion
+ }
+
+ #endregion
+}
--
cgit v1.1