惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - 于斯人也

JsonHelper MergeJsonTemplate Add Indexer to DynamicJson Etw EventSourceProvider_EventsProducer.cs OopConsoleTraceEventListenerMonitor_TraceControllerEventsConsumer.cs WorkFlowHelper ConcurrentAsyncQueue 2014-09-07 JsonHelper developed by using Newtonsoft.Json.NET, Deserialize to <T> object , XmlToJson/JsonToXml, QuoteName by using JToken Path. Udp SocketAsyncEventArgs SocketAsyncDataHandler C#: using JsonReader avoid Deserialize Json to dynamic XmlValidationHelper XSD、Schema(XmlSchemaSet)、XmlReader(XmlValidationSettings)、XmlDocument、XDocument Validate SharePoint 2013 Apps TokenHelper SharePointContext OAuth Provider-Hosted App (抄袭,测试 csc.rsp 用) nuget packages batch install csc.rsp Nuget MVC/WebAPI、SignalR、Rx、Json、EntityFramework、OAuth、Spatial SQL 2012 Group By Rollup, Grouping SQL 2012 Restore HeaderOnly EasyPerformanceCounterHelper 并发异步处理队列 .NET 4.5+ (改进性能计数器) 2013-11-16 CodeTimerPerformance EasyPerformanceCounterHelper .NET 4.5 csc.rsp Nuget MVC/WebAPI 5.0、SignalR 2.0、Rx、Json、Azure、EntityFramework、OAuth、Spatial MEF Parts Sample
KeyedPriorityQueue
于斯人也 · 2014-09-04 · via 博客园 - 于斯人也

// <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;
            }
        }
    }
}