How to make a queue switches from FIFO mode to priority mode?

Posted by enzom83 on Programmers See other posts from Programmers or by enzom83
Published on 2012-09-25T00:32:55Z Indexed on 2012/09/25 3:49 UTC
Read the original article Hit count: 257

I would like to implement a queue capable of operating both in the FIFO mode and in the priority mode. This is a message queue, and the priority is first of all based on the message type: for example, if the messages of A type have higher priority than the messages of the B type, as a consequence all messages of A type are dequeued first, and finally the messages of B type are dequeued.

Priority mode: my idea consists of using multiple queues, one for each type of message; in this way, I can manage a priority based on the message type: just take first the messages from the queue at a higher priority and progressively from lower priority queues.

FIFO mode: how to handle FIFO mode using multiple queues? In other words, the user does not see multiple queues, but it uses the queue as if it were a single queue, so that the messages leave the queue in the order they arrive when the priority mode is disabled. In order to achieve this second goal I have thought to use a further queue to manage the order of arrival of the types of messages: let me explain better with the following code snippet.

int NUMBER_OF_MESSAGE_TYPES = 4;
int CAPACITY = 50;
Queue[] internalQueues = new Queue[NUMBER_OF_MESSAGE_TYPES];
Queue<int> queueIndexes = new Queue<int>(CAPACITY);

void Enqueue(object message)
{
    int index = ... // the destination queue (ie its index) is chosen according to the type of message.
    internalQueues[index].Enqueue(message);
    queueIndexes.Enqueue(index);
}

object Dequeue()
{
    if (fifo_mode_enabled)
    {
        // What is the next type that has been enqueued?
        int index = queueIndexes.Dequeue();

        return internalQueues[index].Dequeue();
    }

    if (priority_mode_enabled)
    {
        for(int i=0; i < NUMBER_OF_MESSAGE_TYPES; i++)
        {
            int currentQueueIndex = i;
            if (!internalQueues[currentQueueIndex].IsEmpty())
            {
                object result = internalQueues[currentQueueIndex].Dequeue();

                // The following statement is fundamental to a subsequent switching
                // from priority mode to FIFO mode: the messages that have not been
                // dequeued (since they had lower priority) remain in the order in
                // which they were queued.
                queueIndexes.RemoveFirstOccurrence(currentQueueIndex);

                return result;
            }
        }
    }
}

What do you think about this idea? Are there better or more simple implementations?

© Programmers or respective owner

Related posts about object-oriented

Related posts about algorithms