<<>> <> <> <> <> < CompareInt.>> <<>> DIRECTORY Heap, HeapPrivate USING [QueueBody, QueueRec], Rope; HeapImpl: CEDAR PROGRAM EXPORTS Heap = BEGIN OPEN Heap, HeapPrivate; Queue: TYPE = REF QueueRec; QueueRec: PUBLIC TYPE = HeapPrivate.QueueRec; Overflow: PUBLIC ERROR = CODE; CreateQueue: PUBLIC PROC [compare: CompareEvents, conjectureSize: CARDINAL ¬ 64, reusable: Queue ¬ NIL] RETURNS [heap: Queue] ~ { IF reusable # NIL THEN { heap ¬ reusable; heap.compare ¬ compare } ELSE { heap ¬ NEW[QueueRec ¬ [compare: compare]]; heap.array ¬ NEW[QueueBody[PowerOf2[conjectureSize]]]; }; }; PowerOf2: PROC [in: CARDINAL] RETURNS [out: CARDINAL ¬ 64] ~ { UNTIL out >= in DO out ¬ out * 2; ENDLOOP; IF out > largestHeap THEN out ¬ largestHeap; }; largestHeap: NAT = 10000000; --Was 32758 in the D-world InsertEvent: PUBLIC PROC [heap: Queue, event: Event] ~ TRUSTED { oldSize: CARDINAL = heap.size; array: REF QueueBody ¬ heap.array; pL: Event ¬ event; pos: CARDINAL ¬ heap.size ¬ oldSize + 1; IF oldSize = array.max THEN { <> newMax: NAT; new: REF QueueBody; IF array.max = largestHeap THEN {heap.size ¬ oldSize; ERROR Overflow}; newMax ¬ IF array.max < largestHeap/2 THEN array.max*2 ELSE largestHeap; new ¬ NEW[QueueBody[newMax]]; FOR i: CARDINAL IN [0..oldSize) DO new.data[i] ¬ array.data[i]; ENDLOOP; heap.array ¬ array ¬ new; }; <> UNTIL pos = 1 DO pH: Event ¬ array.data[pos/2 - 1]; IF heap.compare[pL, pH] = less THEN EXIT; array.data[pos - 1] ¬ pH; pos ¬ pos / 2; ENDLOOP; array.data[pos - 1] ¬ pL; }; NextEvent: PUBLIC PROC [heap: Queue] RETURNS [event: Event ¬ NIL] ~ TRUSTED { array: REF QueueBody ¬ heap.array; size: CARDINAL = heap.size; SELECT size FROM 0 => <> RETURN [NIL]; 1 => { <> event ¬ array.data[0]; heap.size ¬ 0; }; 2 => { <> event ¬ array.data[0]; array.data[0] ¬ array.data[1]; heap.size ¬ 1; }; ENDCASE => { <> lower: CARDINAL ¬ 2; pos: CARDINAL ¬ 1; event ¬ array.data[0]; <> UNTIL lower >= size DO eL: Event = array.data[lower-1]; eR: Event = array.data[lower]; IF heap.compare[eL, eR] # greater THEN { array.data[pos - 1] ¬ eR; pos ¬ lower + 1; } ELSE { array.data[pos - 1] ¬ eL; pos ¬ lower; }; lower ¬ pos*2; ENDLOOP; heap.size ¬ size - 1; SELECT TRUE FROM lower = size => array.data[pos - 1] ¬ array.data[lower - 1]; pos # size => { <> pL: Event ¬ array.data[size - 1]; UNTIL pos = 1 DO pH: Event ¬ array.data[pos/2 - 1]; IF heap.compare[pL, pH] = less THEN EXIT; array.data[pos - 1] ¬ pH; pos ¬ pos / 2; ENDLOOP; array.data[pos - 1] ¬ pL; }; ENDCASE; }; }; PeekNextEvent: PUBLIC PROC [heap: Queue] RETURNS [event: Event] ~ { RETURN [IF heap.size = 0 THEN NIL ELSE heap.array.data[0]]; }; Erase: PUBLIC PROC [heap: Queue] ~ { heap.size ¬ 0; }; Empty: PUBLIC PROC [heap: Queue] RETURNS [empty: BOOL ¬ FALSE] ~ { RETURN [heap.size = 0]; }; GetSize: PUBLIC PROC [heap: Queue] RETURNS [CARDINAL] ~ { RETURN [heap.size]; }; <> <<>> <> <> <> <> <<};>> <<>> <> <> <> <<};>> <<>> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<}>> <<>> END.