82 lines
1.8 KiB
ObjectPascal
82 lines
1.8 KiB
ObjectPascal
MODULE Queue;
|
|
IMPORT
|
|
Boxes;
|
|
TYPE
|
|
Instance* = POINTER TO LIMITED RECORD
|
|
size: LONGINT;
|
|
first,last: LONGINT;
|
|
_queue: POINTER TO ARRAY OF Boxes.Box;
|
|
END;
|
|
|
|
PROCEDURE (self: Instance) Initialize(capacity: LONGINT),NEW;
|
|
BEGIN
|
|
self.size := 0;
|
|
self.first := 0;
|
|
self.last := 0;
|
|
NEW(self._queue,capacity)
|
|
END Initialize;
|
|
|
|
PROCEDURE New*(capacity: LONGINT): Instance;
|
|
VAR
|
|
aQueue: Instance;
|
|
BEGIN
|
|
NEW(aQueue);aQueue.Initialize(capacity);RETURN aQueue
|
|
END New;
|
|
|
|
PROCEDURE (self: Instance) IsEmpty*(): BOOLEAN, NEW;
|
|
BEGIN
|
|
RETURN self.size = 0;
|
|
END IsEmpty;
|
|
|
|
PROCEDURE (self: Instance) Capacity*(): LONGINT, NEW;
|
|
BEGIN
|
|
RETURN LEN(self._queue)
|
|
END Capacity;
|
|
|
|
PROCEDURE (self: Instance) Size*(): LONGINT, NEW;
|
|
BEGIN
|
|
RETURN self.size
|
|
END Size;
|
|
|
|
PROCEDURE (self: Instance) IsFull*(): BOOLEAN, NEW;
|
|
BEGIN
|
|
RETURN self.size = self.Capacity()
|
|
END IsFull;
|
|
|
|
PROCEDURE (self: Instance) Push*(b: Boxes.Box), NEW;
|
|
VAR
|
|
i, j, newCapacity, oldSize: LONGINT;
|
|
queue: POINTER TO ARRAY OF Boxes.Box;
|
|
BEGIN
|
|
INC(self.size);
|
|
self._queue[self.last] := b;
|
|
self.last := (self.last + 1) MOD self.Capacity();
|
|
IF self.IsFull() THEN
|
|
(* grow queue *)
|
|
newCapacity := self.Capacity() + (self.Capacity() DIV 2);
|
|
(* new queue *)
|
|
NEW(queue,newCapacity);
|
|
(* move data from old to new queue *)
|
|
i := self.first; j := 0; oldSize := self.Capacity() - self.first + self.last;
|
|
WHILE (j < oldSize) & (j < newCapacity - 1) DO
|
|
queue[j] := self._queue[i];
|
|
i := (i + 1) MOD newCapacity;INC(j)
|
|
END;
|
|
self._queue := queue;self.first := 0;self.last := j
|
|
END
|
|
END Push;
|
|
|
|
PROCEDURE (self: Instance) Pop*(): Boxes.Box, NEW;
|
|
VAR
|
|
b: Boxes.Box;
|
|
BEGIN
|
|
ASSERT(~self.IsEmpty());
|
|
DEC(self.size);
|
|
b := self._queue[self.first];
|
|
self._queue[self.first] := NIL;
|
|
self.first := (self.first + 1) MOD self.Capacity();
|
|
RETURN b
|
|
END Pop;
|
|
|
|
END Queue.
|