summaryrefslogtreecommitdiff
path: root/queue.adb
diff options
context:
space:
mode:
authorrexim <reximkut@gmail.com>2024-03-17 00:07:38 +0700
committerrexim <reximkut@gmail.com>2024-03-17 00:07:38 +0700
commitf447e5e6b43326645a4990f2039ba728581c6f06 (patch)
treeb26d9d131270b0022ce45d689bb2ec870364053a /queue.adb
parent6658d0649e83f3dd4ec863abadc7c187a4f66276 (diff)
Implement custom ring buffer style queue
Diffstat (limited to 'queue.adb')
-rw-r--r--queue.adb43
1 files changed, 43 insertions, 0 deletions
diff --git a/queue.adb b/queue.adb
new file mode 100644
index 0000000..a758224
--- /dev/null
+++ b/queue.adb
@@ -0,0 +1,43 @@
+with Ada.Unchecked_Deallocation;
+
+package body Queue is
+ procedure Delete_Items_Array is new Ada.Unchecked_Deallocation(Items_Array, Items_Array_Access);
+
+ procedure Grow(Q: in out Queue) is
+ New_Items: Items_Array_Access := new Items_Array(0..Q.Items'Length*2-1);
+ begin
+ for Offset in Q.Items'Range loop
+ New_Items(Offset) := Q.Items((Q.Start + Offset) mod Q.Items'Length);
+ end loop;
+ Delete_Items_Array(Q.Items);
+ Q.Items := New_Items;
+ Q.Start := 0;
+ end;
+
+ procedure Enqueue(Q: in out Queue; X: Item) is
+ begin
+ if Q.Items = null then
+ Q.Items := new Items_Array(0..INIT_CAPACITY-1);
+ end if;
+
+ if Q.Count >= Q.Items'Length then
+ Grow(Q);
+ end if;
+
+ Q.Items((Q.Start + Q.Count) mod Q.Items'Length) := X;
+ Q.Count := Q.Count + 1;
+ end;
+
+ function Dequeue(Q: in out Queue; X: out Item) return Boolean is
+ begin
+ if Q.Count <= 0 then
+ return False;
+ end if;
+
+ X := Q.Items(Q.Start);
+ Q.Start := (Q.Start + 1) mod Q.Items'Length;
+ Q.Count := Q.Count - 1;
+
+ return True;
+ end;
+end Queue;