iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 3
1
Software Development

從零開始土炮MQ系列 第 3

二、基本的 queue (2) - Priority Queue

2.4. Priority Queue

有時,在某些情況下,必需打破 FIFO 的原則,需要讓後面進來的特定的資源提早被離開 Queue。

我們再來看個例子。

有 10 個病人到診所,己經掛完號,領了號碼牌,排隊等著叫號看診。
突然,有一名爸爸,背著高燒不退的孩子,衝到診所掛號看病。

這時,有三種處理情境。

  • 所有病人的病況都一樣嚴重,所以維持原本的看診順序。(所有資源的權重相同,一視同仁。)
  • 孩子的病況比其他病人都還要嚴重,診所判斷需要提前看診。(最新資源的權重大於其他,優先處理。)
  • 孩子的病況很嚴重,但是診所處理不來,只能轉診。(將資源轉到其他的 Queue 之中,並行處理。)

第一種情況,就是一般的 Queue 的特性,前面己經討論過了,就不再多說明。

第三種情況,是多個 Queue 與 Router 的組合技,這部份後面會提到,就先略過不提。

先討論第二種情況,當資源加入 Queue 後,離開 Queue 順序會因為權重而有所變更。用白話來說,這就是插隊機制

https://ithelp.ithome.com.tw/upload/images/20190920/20107551C7Kpi6tsTC.png
這種打破 FIFO 特性,卻又保留部份 FIFO 的 Queu,稱為 Priority Queue 。

而權重的比對,可以組合 Compare 與不同的 排序演算法的實作,來決定各資源離開的順序。

雖然實作方式有很多種。但在下面的簡易實作,使用一個 Priority 做為參數,以便排序使用。

public class PriorityQueue
{
    private class QueueBlock
    {
        public int Priority { set; get; }
        public int Entity { set; get; }
    }

    private const int MaxSize = 20;
    private readonly QueueBlock[] _buffer = new QueueBlock[MaxSize];
    private int _index = 0;

    public void Enqueue(int priority, int item)
    {
        var block = new QueueBlock() { Priority = priority, Entity = item };

        for (int i = _index; i >= 0; i--)
        {
            if (i - 1 < 0 || _buffer[i - 1].Priority <= priority)
            {
                _buffer[i] = block;
                break;
            }
            else
            {
                _buffer[i] = _buffer[i - 1];
            }
        }

        _index++;
    }

    public bool IsEmpty {...}
    public int Dequeue(){...}
}

上一篇
二、基本的 queue (1) - Line Queue & Circle Queue
下一篇
二、基本的 queue(3) - Linked List
系列文
從零開始土炮MQ30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言