diff options
author | rexim <reximkut@gmail.com> | 2024-03-17 00:07:38 +0700 |
---|---|---|
committer | rexim <reximkut@gmail.com> | 2024-03-17 00:07:38 +0700 |
commit | f447e5e6b43326645a4990f2039ba728581c6f06 (patch) | |
tree | b26d9d131270b0022ce45d689bb2ec870364053a | |
parent | 6658d0649e83f3dd4ec863abadc7c187a4f66276 (diff) |
Implement custom ring buffer style queue
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | queue.adb | 43 | ||||
-rw-r--r-- | queue.ads | 18 | ||||
-rw-r--r-- | test.adb | 31 |
4 files changed, 79 insertions, 15 deletions
@@ -2,7 +2,7 @@ set -xe -gnatmake -O3 -Wall -Wextra -gnat2022 game.adb -largs -L./raylib/raylib-5.0_linux_amd64/lib/ -l:libraylib.a -lm +gnatmake -Wall -Wextra -gnat2022 game.adb -largs -L./raylib/raylib-5.0_linux_amd64/lib/ -l:libraylib.a -lm ./game # gnatmake -gnat2022 test.adb 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; diff --git a/queue.ads b/queue.ads new file mode 100644 index 0000000..fdfa484 --- /dev/null +++ b/queue.ads @@ -0,0 +1,18 @@ +generic + type Item is private; +package Queue is + INIT_CAPACITY: constant Integer := 256; + + type Items_Array is array (Natural range <>) of Item; + type Items_Array_Access is access Items_Array; + + type Queue is record + Items: Items_Array_Access := null; + Start: Integer := 0; + Count: Integer := 0; + end record; + + procedure Grow(Q: in out Queue); + procedure Enqueue(Q: in out Queue; X: Item); + function Dequeue(Q: in out Queue; X: out Item) return Boolean; +end Queue; @@ -4,21 +4,24 @@ with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Strings; use Ada.Strings; with Ada.Containers.Vectors; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; +with Queue; procedure Test is - type State is record - X: Integer; - Y: Integer; - end record; - - procedure Foo(S: in State; V: out Integer) is - begin - V := S.X*2; - end; - - S: State := (X => 69, Y => 420); + package String_Queue is new Queue(Item => Unbounded_String); + use String_Queue; + Q: String_Queue.Queue; + X: Unbounded_String; begin - Put_Line(S'Image); - Foo(S, S.Y); - Put_Line(S'Image); + for Index in 1..16 loop + Enqueue(Q, To_Unbounded_String(Index'Image)); + end loop; + while Dequeue(Q, X) loop + null; + end loop; + for Index in 32..42 loop + Enqueue(Q, To_Unbounded_String(Index'Image)); + end loop; + while Dequeue(Q, X) loop + Put_Line(To_String(X)); + end loop; end; |