implements a dynamic FIFO queue.
dynqueue.pp
contains types and classes needed to implement a dynamic FIFO queue for arbitrary data.
Represents the size and content for a data item in TDynamicDataQueue.

TDynamicQueueItem is a record type used to represent the size and content for an arbitrary data item added to TDynamicDataQueue.

Size for the item structure and its Data.
Content for the queue item.
Pointer to a TDynamicQueueItem type.
Pointer to the PDynamicQueueItem type.
Implements a FIFO queue for arbitrary data.

TDynamicDataQueue is a class used to queue arbitrary data for First-In-First-Out usage.

TDynamicDataQueue provides overloaded Push and Pop methods used to enqueue or dequeue data using an untyped buffer or a TStream instance. Use the Top method to peek at data in the queue without removing it.

Internally, TDynamicDataQueue maintains a ring queue for pointers to chunks of data using the TDynamicQueueItem type. It is optimized to reduce the amount of data movement required when adding or removing items.

TDynamicDataQueue is used to implement storage for the TCustomLazComponentQueue component in the lresources.pp unit in the Lazarus Component Library (LCL).

TCustomLazComponentQueue
Sets the value for the MaximumBlockSize property.
New value for the property.
Sets the value for the MinimumBlockSize property.
New value for the property.
Re-allocates the storage for the ring queue, optionally increasing its size.

GrowItems is a procedure used to re-allocate the storage for the ring queue. GrowItems ensures that the capacity for the internal queue storage is a minimum of eight (8) TDynamicQueueItem entries. If that threshold has already been crossed, the capacity is doubled with each call to the method.

GrowItems copies existing items in the queue into the newly allocated storage, and frees the memory allocated to the old queue storage. The internal index positions to the top and bottom of the queue are reset to their new values.

GrowItems is called from the AddItem method when additional storage is needed for the ring queue.

Ensures space is available, and allocates storage for a new queue item.

AddItem is a procedure used to allocate storage for a new item in the ring queue. AddItem ensures that space is available in the queue for a new queue entry, and calls GrowItems when needed.

AddItem checks the internal storage for the queue to ensure that it is assigned, and does not already contain a data item at the next position in the queue. An Exception is raised when either condition is not met.

AddItem allocates memory at the queue position by calling GetMem using the size of the TDynamicQueueItem type and the additional space specified in ItemSize.

AddItem is used in the implementation of the PushInternal method.

Raises an Exception if the item storage is not assigned, or when it already contains an item at the new position. The exception message is: 'TDynamicDataQueue.AddItem NewIndex=[n]'.

Space required for the arbitrary data stored in the new queue item.
Calculates the size for a memory block allocated for a new queue item.

CalculateItemSize is an Integer function used to calculate the memory block size needed for a new item added to the queue.

ItemSize contains the size requested for the data structure and its arbitrary content, and is used by default as the return value for the method. CalculateItemSize ensures that the return value is in the range defined by the MinimumBlockSize and MaximumBlockSize properties.

CalculateItemSize is used in the implementation of the private PushInternal method.

Size of the memory block size needed to store a new item with the specified data size.
Size requested for the queue item structure and its data.
Performs actions needed to store arbitrary byte values for an item in the FIFO queue.

PushInternal is an Integer function used to perform actions needed to store arbitrary data for queue items in the FIFO queue. The new queue item is added to the bottom (end, tail, etc.) of the queue.

Arguments to the method provide the location where the data for the new item is stored, and the number of bytes required for the arbitrary byte data. Source is the untyped buffer with the item data. AStream is the TStream instance where the item data can be found. Both storage mechanisms are not used at the same time; preference is given to Source (when assigned).

PushInternal calls System.Move to transfer byte data from Source to the internal storage for the queue, or calls the Read method in AStream to read the item data. The Size property is incremented by the number of bytes actually read in the method. AddItem is called to adjust the internal storage allocation for the calculated item size.

PushInternal assumes that the TStream instance is already positioned at the location needed to access the item data for the queue entry. It does not reposition the stream prior to or following a call to the TStream.Read method. Be aware that reading from a stream can raise an exception.

The return value contains the number of bytes transferred to the internal queue storage in the method.

PushInternal is used in the implementation of the overloaded Push methods.

Number of bytes stored in the queue storage for the new item.
Untyped buffer with the arbitrary byte data added to the queue.
TStream instance where the arbitrary byte data for the item can be found.
Number of bytes expected in the data for the queue item.
Performs actions needed to read, and to optionally remove, an item in the FIFO queue.
Number of bytes read/removed from the internal queue storage.
Untyped buffer where data for the queue item is stored.
Stream instance where data for the queue item is stored.
Number of bytes expected in the queue item.
Indicates if item data should remain in the internal queue storage; used to implement Top.
Constructor for the class instance.

Create is the constructor for the class instance. Create sets the default values for the following properties:

MinimumBlockSize
  Set to 512 (bytes)
MaximumBlockSize
  Set to 4096 (bytes)

Destructor for the class instance.

Destroy is the overridden destructor for the class instance. Destroy calls the Clear method to remove items stored in the queue, and to free memory allocated for their storage. Destroy calls the inherited destructor prior to exiting from the method.

Frees data items and storage allocated for the queue.

Clear is a procedure used to free all items stored in the queue, and the memory allocated for their storage. Clear iterates over the items in the queue, and calls FreeMem to de-allocate memory reserved to store each item structure and its data. The internal storage for the queue is set to Nil when all items have been de-allocated.

Clear resets the values for internal members used for the queue Size, and those used for item positions in the queue.

Checks for errors in queue settings, item storage space, or item content.

ConsistencyCheck is a procedure used to raise an exception when an error is detected in queue settings, its item storage space, or the content for item data. ConsistencyCheck raises an exception when the following conditions are detected:

- Size contains a negative non-zero value.
- MinimumBlockSize is larger than MaximumBlockSize.
- MinimumBlockSize is less than sixteen (16) bytes.
- Internal storage has not been assigned, but Size contains a non-zero value.
- The item capacity is zero (0) or a negative value.
- Internal index positions for Top and new items contain a negative value.
- Internal index positions for Top and new items are larger than the capacity for the queue.

ConsistencyCheck is NOT used in the current implementation.

Raises an Exception when an error condition is found in the queue settings, its storage space, or the items in the queue. The exception message is: 'TDynamicDataQueue.ConsistencyCheck'.

Generates debugging information for the queue state and optional item data in the queue.
Includes the contents of the item data when set to True.
Adds the specified content to the FIFO queue.

Push is an overloaded Integer function used to add the specified item data to the bottom of the FIFO queue. Overloaded variants are provided to supply item data as a sequence of arbitrary byte values, either from an untyped buffer or from a TStream instance.

Push assumes that AStream is already positioned at the start of the data for the new item. It does not reposition the stream instance.

Push calls the PushInternal method to perform the actions needed to enqueue the specified item data.

The return value contains the number of bytes added for the new item data to the internal storage for the ring queue.

Use Pop to dequeue an item from the top of the queue. Use Top to get the item data for the next item without removing it from the queue. Use Size to get the number of bytes allocated for items in the internal storage in the FIFO queue.

Number of bytes added to the internal queue storage in the method.
Untyped buffer with the arbitrary item data added in the method.
Number of bytes needed for the item data added in the method.
TStream instance where the byte values for the item data is stored.
Removes an item from the top of the FIFO queue.

Pop is an overloaded Integer function used to remove an item from the top of the FIFO queue. Overloaded variants are provided to get item data and store them as a sequence of arbitrary byte values, either in an untyped buffer or in a TStream instance.

Pop assumes that AStream is already positioned where the item data will be written. It does not reposition the stream instance. Be aware that writing to a stream can raise an exception.

Pop calls the PopTopInternal method to perform the actions needed to get the data for the queue item, and to removed the entry from the top of FIFO queue.

The return value contains the number of bytes needed for the item data, and removed from the internal storage for the queue.

Use Push to enqueue a new item to the bottom of the FIFO queue. Use Top to get the item data at the top of the queue without removing it from the queue.

Number of bytes needed for item data removed from the queue.
Untyped buffer where the queue item is stored after removal.
Number of bytes for the item data.
TStream instance where the item data removed from the queue is stored.
Gets the data for the first queue entry, but does not remove it from the queue.

Top is an overloaded Integer function used to get the item data stored at the top of the FIFO queue without removing it from the queue internal storage. Overloaded variants are provided to get and store item data as a sequence of arbitrary byte values, either in an untyped buffer or in a TStream instance.

Please note: Top assumes that AStream is already positioned where the item data will be written. It does not reposition the stream instance. Be aware that writing to a stream can raise an exception.

Top calls the PopTopInternal method to perform the actions needed to get the data for the queue item from the top of FIFO queue.

The return value contains the number of bytes needed for the item data in the internal storage for the queue.

Use Push to enqueue a new item to the bottom of the FIFO queue. Use Pop to get and remove the item data at the top of the queue.

Number of bytes needed for item data in the queue.
Untyped buffer where the queue item is stored.
Number of bytes for the item data.
TStream instance where the item data is stored.
Total memory required for item data stored in the queue.

Size is a read-only Int64 property that contains the total memory required for item data stored in the queue. The value in Size in incremented in PushInternal when an item is successfully added to the ring queue storage. Conversely, the value in Size is decremented when the PopTopInternal method successfully removes an item from the storage for the ring queue.

Indicates the smallest memory block size allocated for an item added to the queue.

MinimumBlockSize is an Integer property which indicates the smallest memory block size allocated for an item added to the queue. MinimumBlockSize and MaximumBlockSize are used in the CalculateItemSize method to derive the actual block size allocated for a queue item and its arbitrary data.

The default value for MinimumBlockSize is 512, as set in the Create constructor. MinimumBlockSize cannot be set to a value smaller than sixteen (16) bytes, or a value larger than MaximumBlockSize.

Indicates the largest memory block size allocated for an item added to the queue.

MaximumBlockSize is an Integer property which indicates the largest memory block size allocated for an item added to the queue. MinimumBlockSize and MaximumBlockSize are used in the CalculateItemSize method to derive the actual block size allocated for a queue item and its arbitrary data.

The default value for MaximumBlockSize is 4096, as set in the Create constructor. MaximumBlockSize cannot be set to a value smaller than MinimumBlockSize.