Feature #21721
openAllow `Queue` and `SizedQueue` to be used as LIFO queues
Description
Context¶
Since Queue and SizedQueue gained a proper timeout mechanism, I've been wanting to use them to implement simpler and more efficient connection pools. However for connection pools you ideally want a LIFO queue because it's preferable to checkout the most recently used connection.
Problem¶
Both Queue and SizedQueue only support FIFO because you can only enqueue elements at the beginning of the backing array, and only dequeue at the end.
Queue#push (aliased as Queue#<< and Queue#enq) calls Array#unshift on the backing array and Queue#pop (aliased as Queue#deq and Queue#shift) calls Array#pop.
Hence it is impossible to use these two classes for anything other than FIFO queues.
I tried to use git blame to see if there was a justification for this, but I ended up in a git blame loop around May 2000 https://github.com/ruby/ruby/commit/9da4f78db46764be6dae5e7e83ff48cbecb3fb23
Feature¶
I'd like to introduce either of two new methods (or both) to allow for LIFO:
- A method to dequeue from the beginning of the backing array (
array_shift). - A method to enqueue from the end of the backing array (
array_push).
A difficulty I have however is that since the common shift/pop/push terms are already used with uncommon meaning, it's hard to come up with good names. Ideas welcome.
Possible alternatives¶
- Define different classes for LIFO queues
- But I find that less flexible, and it means exposing new constant names in the global namespace.
- Add an initializer argument to define the queue ordering, e.g.
Queue.new([], lifo: true)- Similarly, I find this less flexible than to decide the order during enqueue/dequeue
- Add an argument to
Queue#popandQueue#push, e.g.queue.push(element, front: true).
No data to display