Fixed-length queues
===================
.. mps:prefix:: design.mps.abq
Introduction
------------
:mps:tag:`intro` This is the design of the ABQ module, which implements a
fixed-length queue of small objects.
:mps:tag:`readership` This document is intended for any MM developer.
:mps:tag:`name` The name ABQ originally stood for "Available Block Queue" as
the module is used by the MVT pool.
Requirements
------------
:mps:tag:`req.push` Clients can efficiently push new elements onto the queue.
:mps:tag:`req.pop` Clients can efficiently pop elements from the queue.
:mps:tag:`req.empty` Clients can efficiently test whether the queue is empty.
:mps:tag:`req.abstract` The ABQ module does not know anything about the
elements in the queue other than their size.
:mps:tag:`req.delete` Clients can delete elements from the queue. (Note: not necessarily efficiently.)
:mps:tag:`req.iterate` Clients can iterate over elements in the queue.
Interface
---------
.. c:type:: ABQStruct *ABQ
:c:macro:`ABQ` is the type of a queue. It is an alias for ``ABQStruct *``.
:c:type:`ABQStruct` is defined in the header so that it can be inlined in
client structures: clients must not depend on its implementation
details.
.. c:function:: ABQInit(Arena arena, ABQ abq, void *owner, Count elements, Size elementSize)
Initialize the queue ``abq``. The parameter ``arena`` is the arena
whose control pool should be used to allocate the memory for the
queue; ``owner`` is passed to :c:func:`MeterInit()` for the statistics;
``elements`` is the maximum number of elements that can be stored in
the queue; and ``elementSize`` is the size of each element.
.. c:function:: void ABQFinish(Arena arena, ABQ abq)
Finish ``abq`` and free all resources associated with it.
.. c:function:: Bool ABQPush(ABQ abq, void *element)
If the queue is full, leave it unchanged and return :c:macro:`FALSE`.
Otherwise, push ``element`` on to the queue and return :c:macro:`TRUE`.
.. c:function:: Bool ABQPop(ABQ abq, void *elementReturn)
If the queue is empty, return :c:macro:`FALSE`. Otherwise, copy the first
element on the queue into the memory pointed to by ``elementReturn``,
remove the element from the queue, and return :c:macro:`TRUE`.
.. c:function:: Bool ABQPeek(ABQ abq, void *elementReturn)
If the queue is empty, return :c:macro:`FALSE`. Otherwise, copy the first
element on the queue into the memory pointed to by ``elementReturn``
and return :c:macro:`TRUE`. (This is the same as :c:func:`ABQPop()` except that
the queue is unchanged.)
.. c:function:: Bool ABQIsEmpty(ABQ abq)
If the queue is empty, return :c:macro:`TRUE`, otherwise return :c:macro:`FALSE`.
.. c:function:: Bool ABQIsFull(ABQ abq)
If the queue is full, return :c:macro:`TRUE`, otherwise return :c:macro:`FALSE`.
.. c:function:: Count ABQDepth(ABQ abq)
Return the number of elements in the queue.
.. c:type:: Bool (*ABQIterateMethod)(Bool *deleteReturn, void *element, void *closureP, Size closureS)
A callback function for :c:func:`ABQIterate()`. The parameter ``element`` is
an element in the queue, and ``closureP`` and ``closureS`` are the
values that were originally passed to :c:func:`ABQIterate()`. This function
must set ``*deleteReturn`` to :c:macro:`FALSE` if ``element`` must be kept in
the queue, or :c:macro:`TRUE` if ``element`` must be deleted from the queue.
It must return :c:macro:`TRUE` if the iteration must continue, or :c:macro:`FALSE`
if the iteration must stop after processing ``element``.
.. c:function:: void ABQIterate(ABQ abq, ABQIterateMethod iterate, void *closureP, Size closureS)
Call ``iterate`` for each elements in the queue, passing the element
and ``closureP``. See :c:type:`ABQIterateMethod` for details.