// <copyright file="KeyedPriorityQueue.cs" company="Microsoft">Copyright (c) Microsoft Corporation.  All rights reserved.</copyright>
namespace Microshaoft
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
//internal sealed class KeyedPriorityQueueHeadChangedEventArgs<T> : EventArgs where T : class
//{
// private T oldFirstElement;
// private T newFirstElement;
// public KeyedPriorityQueueHeadChangedEventArgs(T oldFirstElement, T newFirstElement)
// {
// this.oldFirstElement = oldFirstElement;
// this.newFirstElement = newFirstElement;
// }
// public T OldFirstElement { get { return oldFirstElement; } }
// public T NewFirstElement { get { return newFirstElement; } }
//}
///// <summary> Combines the functionality of a dictionary and a heap-sorted priority queue.
///// Enqueue and Dequeue operations are O(log n), Peek is O(1) and Remove is O(n).
///// Used by the SchedulerService classes to maintain an ordered list of running timers, etc.
///// Lesser priority values are higher priority.</summary>
///// <typeparam name="K">Key</typeparam>
///// <typeparam name="V">Value</typeparam>
///// <typeparam name="P">Priority</typeparam>
[Serializable]
public class KeyedPriorityQueue<TKey, TValue, TPriority>
where TValue : class
{
//private ConcurrentBag<HeapNode<TKey, TValue, TPriority>> _heap = new ConcurrentBag<HeapNode<TKey, TValue, TPriority>>();
private List<HeapNode<TKey, TValue, TPriority>> _heap = new List<HeapNode<TKey, TValue, TPriority>>();
private int _size;
private Comparer<TPriority> _priorityComparer = Comparer<TPriority>.Default;
private HeapNode<TKey, TValue, TPriority> _placeHolder = default(HeapNode<TKey, TValue, TPriority>);
//public event EventHandler<KeyedPriorityQueueHeadChangedEventArgs<V>> FirstElementChanged;
private Action<TValue, TValue> _onKeyedPriorityQueueHeadChangedProcessAction = null;
private Func<HeapNode<TKey, TValue, TPriority>, HeapNode<TKey, TValue, TPriority>, bool> _onPriorityComparerProcessFunction = null;
public KeyedPriorityQueue
(
Action<TValue, TValue> onKeyedPriorityQueueHeadChangedProcessAction = null
, Func<HeapNode<TKey, TValue, TPriority>, HeapNode<TKey, TValue, TPriority>, bool> onPriorityComparerProcessFunction = null
)
{
_onKeyedPriorityQueueHeadChangedProcessAction = onKeyedPriorityQueueHeadChangedProcessAction;
_onPriorityComparerProcessFunction = onPriorityComparerProcessFunction;
_heap.Add(default(HeapNode<TKey, TValue, TPriority>)); // Dummy zeroth element, heap is 1-based
}
public void Enqueue
(
TKey key
, TValue value
, TPriority priority
)
{
TValue oldHead = _size > 0 ? _heap[1].Value : null;
int i = ++_size;
int parent = i / 2;
if (i == _heap.Count)
{
_heap.Add(_placeHolder);
}
var heapNode = new HeapNode<TKey, TValue, TPriority>(key, value, priority);
bool isHigher = IsHigher(heapNode, _heap[parent]);
while (i > 1 && isHigher)
{
_heap[i] = _heap[parent];
i = parent;
parent = i / 2;
}
_heap[i] = heapNode;
TValue newHead = _heap[1].Value;
if (!newHead.Equals(oldHead))
{
RaiseHeadChangedEvent(oldHead, newHead);
}
}
public TValue Dequeue()
{
TValue oldHead = (_size < 1) ? null : DequeueImpl();
TValue newHead = (_size < 1) ? null : _heap[1].Value;
RaiseHeadChangedEvent(null, newHead);
return oldHead;
}
private TValue DequeueImpl()
{
Debug.Assert(_size > 0, "Queue Underflow");
TValue oldHead = _heap[1].Value;
_heap[1] = _heap[_size];
_heap[_size--] = _placeHolder;
Heapify(1);
return oldHead;
}
public TValue Remove(TKey key)
{
if (_size < 1)
{
return null;
}
TValue oldHead = _heap[1].Value;
for (int i = 1; i <= _size; i++)
{
if (_heap[i].Key.Equals(key))
{
TValue retval = _heap[i].Value;
Swap(i, _size);
_heap[_size--] = _placeHolder;
Heapify(i);
TValue newHead = _heap[1].Value;
if (!oldHead.Equals(newHead))
{
RaiseHeadChangedEvent(oldHead, newHead);
}
return retval;
}
}
return null;
}
public TValue Peek()
{
return (_size < 1) ? null : _heap[1].Value;
}
public int Count
{
get
{
return _size;
}
}
public TValue FindByPriority(TPriority priority, Predicate<TValue> match)
{
return _size < 1 ? null : Search(priority, 1, match);
}
public ReadOnlyCollection<TValue> Values
{
get
{
List<TValue> values = new List<TValue>();
for (int i = 1; i <= _size; i++)
{
values.Add(_heap[i].Value);
}
return new ReadOnlyCollection<TValue>(values);
}
}
public ReadOnlyCollection<TKey> Keys
{
get
{
List<TKey> keys = new List<TKey>();
for (int i = 1; i <= _size; i++)
{
keys.Add(_heap[i].Key);
}
return new ReadOnlyCollection<TKey>(keys);
}
}
public void Clear()
{
_heap.Clear();
_size = 0;
}
private void RaiseHeadChangedEvent(TValue oldHead, TValue newHead)
{
if (oldHead != newHead)
{
//EventHandler<KeyedPriorityQueueHeadChangedEventArgs<V>> fec = FirstElementChanged;
if (_onKeyedPriorityQueueHeadChangedProcessAction != null)
{
_onKeyedPriorityQueueHeadChangedProcessAction(oldHead, newHead);
}
}
}
private TValue Search(TPriority priority, int i, Predicate<TValue> match)
{
Debug.Assert(i >= 1 || i <= _size, "Index out of range: i = " + i + ", size = " + _size);
TValue value = null;
var isHigher = IsHigher(_heap[i], priority);
if (isHigher)
{
if (match(_heap[i].Value))
{
value = _heap[i].Value;
}
int left = 2 * i;
int right = left + 1;
if (value == null && left <= _size)
{
value = Search(priority, left, match);
}
if (value == null && right <= _size)
{
value = Search(priority, right, match);
}
}
return value;
}
private void Heapify(int i)
{
Debug.Assert(i >= 1 || i <= _size, "Index out of range: i = " + i + ", size = " + _size);
int left = 2 * i;
int right = left + 1;
int highest = i;
if (left <= _size && IsHigher(_heap[left], _heap[i]))
{
highest = left;
}
if (right <= _size && IsHigher(_heap[right], _heap[highest]))
{
highest = right;
}
if (highest != i)
{
Swap(i, highest);
Heapify(highest);
}
}
private void Swap(int i, int j)
{
Debug.Assert(i >= 1 || j >= 1 || i <= _size || j <= _size, "Index out of range: i = " + i + ", j = " + j + ", size = " + _size);
HeapNode<TKey, TValue, TPriority> temp = _heap[i];
_heap[i] = _heap[j];
_heap[j] = temp;
}
private bool IsHigher
(
HeapNode<TKey, TValue, TPriority> compare
, TPriority compareWithPriority
)
{
var r = false;
if (_onPriorityComparerProcessFunction != null)
{
var compareWithHeapNode
= new HeapNode<TKey, TValue, TPriority>
(default(TKey), default(TValue), compareWithPriority);
r = _onPriorityComparerProcessFunction(compare, compareWithHeapNode);
}
else
{
r = _priorityComparer.Compare(compare.Priority, compareWithPriority) < 1;
}
return r;
}
private bool IsHigher
(
HeapNode<TKey, TValue, TPriority> compare
, HeapNode<TKey, TValue, TPriority> compareWith
)
{
var r = false;
if (_onPriorityComparerProcessFunction != null)
{
r = _onPriorityComparerProcessFunction(compare, compareWith);
}
else
{
r = _priorityComparer.Compare(compare.Priority, compareWith.Priority) < 1;
}
return r;
}
[Serializable]
public struct HeapNode<KeyT, ValueT, PriorityT>
{
public KeyT Key;
public ValueT Value;
public PriorityT Priority;
public HeapNode(KeyT key, ValueT value, PriorityT priority)
{
Key = key;
Value = value;
Priority = priority;
}
}
}
}

KeyedPriorityQueue的更多相关文章

  1. WWF3.5SP1 参考源码索引

    http://www.projky.com/dotnet/WF3.5SP1/System/Runtime/Serialization/FormatterServicesNoSerializableCh ...

随机推荐

  1. javascript中this

    js函数中的this指向问题:(this对象是在运行时基于函数的执行环境绑定的) 与普通变量获取不同,内部函数在搜索this和arguments这两个变量时,只搜索到其活动对象为止,所以this无法像 ...

  2. excel工具类

    excel工具类 import com.iport.framework.util.ValidateUtil; import org.apache.commons.lang3.StringUtils; ...

  3. 各种Js封装

    获取ClassName元素 function getClass(classname,id){ if(document.getElementsByClassName){ if(id){ return $ ...

  4. beaglebone black 安装QNX过程

    首先去http://community.qnx.com/sf/go/projects.bsp/frs.texas_instruments_am335_beaglebo 把下面4个下载下来.

  5. 关于Window Server2008 服务器上无法播放音频文件的解决方案

    在偌大的百度当中查找我所需要的资源信息,但网络上所描述的都不能解决,发生此类问题的人很多,但是都没有得到准确的解决方法!经个人各方面的尝试,其实非常简单的解决了无法播放音频文件的问题,如果各位今后也遇 ...

  6. AD域的安装(在Windows Server 2003中安装Active Directory)

    在Active Directory中提供了一组服务器作为身份验证服务器或登录服务器,这类服务器被称作域控制器(Domain Controller,简称DC).建立一个AD域的过程实际就是在一台运行Wi ...

  7. PHP与MYSQL事务处理

    /*MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事务rollback 事务回滚commit 事务确认2.直接用set来改变mysql的 ...

  8. 消除左递归c语言文法

    <程序> -〉 <外部声明> | <函数定义><外部声明> -〉<头文件> | <变量> | <结构体> <头 ...

  9. TCP/IP模型详解

    上述为TCP/IP的协议模型,主机到网络层又被称为网络接口层,网络互联层又被称为网间层. 网络接口层:实际上,TCP/IP参考模型并没有真正描述这一层的实现,只是要求能够提供给其上层一个访问接口,以便 ...

  10. HTTP缓存

    本文是<HTTP权威指南>读书笔记 Web缓存是可以自动保存常见文档副本的设备.当Web请求抵达缓存时,如果本地在“已缓存”的的副本,就可以从本地存储设备而不是原始服务器中提取这个文档.使 ...