How to Implement a Queue (FIFO) Data Structure in Batch Script
In computer science, a Queue is a data structure that follows the FIFO (First-In, First-Out) principle. Imagine a line of people waiting for a bus: the first person to join the line is the first one to get on the bus. Queues are essential for managing background tasks, processing logs in order, or building a "To-Do" list for a multi-stage automation script.
In this guide, we will demonstrate how to build a Queue in Batch using two pointers: "Head" and "Tail."
The Strategy: Head and Tail Pointers
To implement a queue:
- Initialize
head=1(where we take items from) andtail=0(where we add items to). - ENQUEUE (Add): Increment
tailand store the value atQUEUE_%tail%. - DEQUEUE (Remove): Retrieve the value at
QUEUE_%head%and then incrementhead.
Since Batch does not have native array or queue objects, this implementation simulates one using sequentially numbered environment variables (QUEUE_1, QUEUE_2, etc.) and two pointers that track the front and back of the queue independently.
Implementation Script
@echo off
setlocal enabledelayedexpansion
set "head=1"
set "tail=0"
echo --- QUEUE DEMONSTRATION (FIFO^) ---
:: 1. ENQUEUE elements (Add to back)
call :enqueue "Fix Permissions"
call :enqueue "Cleanup Logs"
call :enqueue "Restart Service"
echo.
call :size
call :peek
echo.
:: 2. DEQUEUE elements (Remove from front)
:process_loop
if !head! GTR !tail! (
echo [VACANT] All tasks in the queue are complete.
goto :end
)
call :dequeue
echo [STARTING] !result!
goto :process_loop
:end
echo.
echo --- QUEUE COMPLETE ---
endlocal
pause
exit /b 0
:: ============================================
:: QUEUE FUNCTIONS
:: ============================================
:enqueue
:: Usage: call :enqueue "value"
set /a "tail+=1"
set "QUEUE_!tail!=%~1"
echo Adding: %~1
exit /b
:dequeue
:: Usage: call :dequeue (result stored in !result!)
if !head! GTR !tail! (
echo [ERROR] Queue underflow - cannot dequeue from an empty queue.
set "result="
exit /b 1
)
set "result=!QUEUE_%head%!"
set "QUEUE_!head!="
set /a "head+=1"
exit /b
:peek
:: Usage: call :peek (displays front element without removing it)
if !head! GTR !tail! (
echo [PEEK] Queue is empty.
exit /b 1
)
echo Next in line: !QUEUE_%head%!
exit /b
:size
:: Usage: call :size (displays current queue length)
set /a "count=tail - head + 1"
if !count! LSS 0 set "count=0"
echo Queue Size: !count!
exit /b
Why Use a Queue in Batch?
- Job Schedulers: If your script finds 50 files that need processing, you can "Enqueue" their paths. The script then "Dequeues" them one-by-one, ensuring that every file is handled in the order it was discovered.
- Breadcrumb Traces: Recording the steps a script took in order, so you can output a "Timeline" of events for an audit log.
- Buffer Management: Temporarily storing user inputs or system events while you perform another task, ensuring no data is lost during the "Waiting" period.
Visualizing the Process
- Initial:
[ ](head=1, tail=0) - Add "A":
[ A ](head=1, tail=1) - Add "B":
[ A, B ](head=1, tail=2) - Remove: Result "A", Queue
[ B ](head=2, tail=2)
Best Practices
The queue is empty when head is greater than tail. Always check this condition before attempting to dequeue. The :dequeue function in this guide includes this guard automatically and returns an error code on underflow.
- Empty Check: The queue is empty when
head > tail. Always check this condition before attempting to dequeue. - Memory Management: Unlike a real queue in languages like C++, Batch doesn't "Delete" the old variables automatically. The
:dequeuefunction in this guide explicitly unsets each consumed variable. After high-volume processing, you can also clear the entire namespace by looping through remaining entries. - Maximum Size: Batch variables are limited by system memory. While you can store thousands of items, very large queues can slow down the
setcommand lookups.
To clear the entire queue at once, loop from !head! to !tail! and unset each QUEUE_n variable, then reset head to 1 and tail to 0. This prevents stale data from lingering in the environment.
Conclusion
Implementing a queue data structure transforms your scripts from simple command-lists into orderly "Task Managers." By mastering the FIFO principle and the dual-pointer (Head/Tail) methodology, you can ensure that your automation processes data fairly and predictably. This level of organizational logic is essential for building robust, professional-grade processing pipelines in any Windows environment.