--file GSort.mesa (converted from GPsortDefs 3-Mar-81)
--last modified by: 
  -- Evans on  November 24, 1980  10:51 AM 
  -- Sandman on  July 8, 1980  9:03 AM 
  -- Sweet on  9-Mar-81  9:23:17
  -- Satterthwaite on August 13, 1982 2:29 pm
  

GSort: DEFINITIONS = {
  
  GetProcType: TYPE = PROC [p: LONG POINTER] RETURNS [CARDINAL];
  PutProcType: TYPE = PROC [p: LONG POINTER, len: CARDINAL];
  CompareProcType: TYPE = PROC [p1: LONG POINTER, p2: LONG POINTER] RETURNS [INTEGER];

  Sort: PROC [
    get: GetProcType, put: PutProcType, compare: CompareProcType,
    expectedItemSize: CARDINAL ← 30, maxItemSize: CARDINAL ← 1000,
    pagesInHeap: CARDINAL ← 100];
  RecordTooLong: ERROR;
  
-- The declarations below can be used to run the sort package as a coroutine
-- in the following way
--
--    OutToSort: GSort.SortItemPort;
--    buffer: LONG POINTER; (possibly TO YourDataItem)
--    LOOPHOLE[OutToSort, GSort.Port].out ← GSort.Sort;
--    buffer ← LOOPHOLE[OutToSort, GSort.SortStarter] [
--      nextItem: @OutToSort,
--      ... other params as in call to Sort];
--    ... construct a sort record in buffer
--    buffer ← OutToSort[(length of record currently in buffer)];
--    ... keep doing that until there are no more data
--    LOOPHOLE[OutToSort, GSort.SortStopper][];
--    ... at this point, the put proc gets called with the sorted records


  Port: TYPE = MACHINE DEPENDENT RECORD [in, out: UNSPECIFIED];
  SortItemPort: TYPE = PORT [len: CARDINAL] RETURNS [p: LONG POINTER];
  SortStarter: TYPE = PORT [
    nextItem: POINTER TO SortItemPort,
    put: PutProcType,
    compare: CompareProcType,
    expectedItemSize: CARDINAL ← 30, maxItemSize: CARDINAL ← 1000,
    pagesInHeap: CARDINAL ← 100] RETURNS [p: LONG POINTER];
  SortStopper: TYPE = PORT [len: CARDINAL ← 0];
    
  }.