64 lines
1.7 KiB
Plaintext
64 lines
1.7 KiB
Plaintext
MODULE Queue;
|
|
IMPORT StdLog,Boxes;
|
|
|
|
TYPE
|
|
Queue* = POINTER TO RECORD
|
|
first,last: LONGINT;
|
|
queue: POINTER TO ARRAY OF Boxes.Object;
|
|
END;
|
|
|
|
PROCEDURE NewQueue*(cap: LONGINT): Queue;
|
|
VAR
|
|
q: Queue;
|
|
BEGIN
|
|
NEW(q);q.first := 0; q.last := 0;
|
|
NEW(q.queue,cap);
|
|
RETURN q
|
|
END NewQueue;
|
|
|
|
PROCEDURE (q: Queue) IsEmpty*(): BOOLEAN, NEW;
|
|
VAR
|
|
BEGIN
|
|
RETURN (q.first = q.last)
|
|
END IsEmpty;
|
|
|
|
PROCEDURE (q: Queue) Push*(o: Boxes.Object),NEW;
|
|
VAR
|
|
i,j,oldSize,newSize: LONGINT;
|
|
queue: POINTER TO ARRAY OF Boxes.Object;
|
|
BEGIN
|
|
IF q.IsEmpty() THEN
|
|
q.queue[q.last] := o;
|
|
q.last := (q.last + 1) MOD LEN(q.queue)
|
|
ELSE
|
|
q.queue[q.last] := o;
|
|
q.last := (q.last + 1) MOD LEN(q.queue);
|
|
IF q.first = q.last THEN
|
|
(* grow queue *)
|
|
newSize := LEN(q.queue) + (LEN(q.queue) DIV 2);
|
|
(* new queue*)
|
|
NEW(queue,newSize);
|
|
(* move data from old queue to new queue *)
|
|
i := q.first; j := 0;oldSize := LEN(q.queue) - q.first + q.last;
|
|
WHILE (j < oldSize ) & (j < LEN(queue) - 1) DO
|
|
queue[j] := q.queue[i];
|
|
i := (i + 1) MOD LEN(q.queue);INC(j)
|
|
END;
|
|
q.queue := queue;q.first := 0;q.last := j
|
|
END
|
|
END;
|
|
END Push;
|
|
|
|
PROCEDURE (q: Queue) Pop*(): Boxes.Object, NEW;
|
|
VAR
|
|
o: Boxes.Object;
|
|
BEGIN
|
|
ASSERT(~q.IsEmpty());
|
|
o := q.queue[q.first];
|
|
q.queue[q.first] := NIL;
|
|
q.first := (q.first + 1) MOD LEN(q.queue);
|
|
RETURN o;
|
|
END Pop;
|
|
|
|
END Queue.
|