-- Copyright (C) 1981, 1984, 1985  by Xerox Corporation. All rights reserved. 
-- HeapDefs.mesa - public DEFS for heap storage --

-- HGM, 15-Sep-85  3:23:42
-- Andrew Birrell  24-Feb-81 15:19:36 --

DIRECTORY
  BodyDefs USING [ItemHeader, RName],
  ObjectDirDefs USING [ObjectNumber, ObjectType],
  ProtocolDefs USING [Handle];

HeapDefs: DEFINITIONS =
  BEGIN



  -- General --

  Buffer: TYPE = RECORD [where: LONG POINTER, length: CARDINAL];

  ObjectNumber: TYPE = ObjectDirDefs.ObjectNumber;
  -- reference counts are maintained internally on object numbers, and the
  -- corresponding object is retained until its reference count falls to
  -- zero --

  ObjectOffset: TYPE = LONG CARDINAL;
  -- Word position within an object. --

  objectStart: ObjectOffset = 0;
  -- Position of first word in any object --

  ObjectType: TYPE = ObjectDirDefs.ObjectType;




  -- Writer primitives --

  WriterHandle: TYPE = LONG POINTER TO WriterData;

  WriterData: TYPE;

  HeapStartWrite: PROCEDURE [type: ObjectType] RETURNS [WriterHandle];
  -- Creates a writer.  Allocates a new object number, initialises the
  -- object to have the given type and to be empty, and sets its
  -- reference count to one.  The "type" is useful only in restarting. --

  HeapWriteData: PROCEDURE [handle: WriterHandle, from: Buffer];
  -- Appends the data to the object, using as many sub-objects as needed. 
  -- The data is not written to permanent storage at this stage. --

  HeapEndWrite: PROCEDURE [
    handle: WriterHandle, action: PROCEDURE [ObjectNumber]];
  -- Ensures (atomically) that the object is on disk and will be there
  -- after a restart.  Destroys the writer; the WriterHandle must not be
  -- used after this point.  Calls "action" with the object number, then
  -- decrements the reference count on the object.  If you still want the
  -- object, "action" must cause the reference count to be incremented. --

  HeapAbandonWrite: PROCEDURE [handle: WriterHandle];
  -- Throws away the object, ensuring that it will not appear after a
  -- restart. --

  GetWriterOffset: PROCEDURE [handle: WriterHandle] RETURNS [ObjectOffset];
  -- Returns the offset in the object of the next word that will be
  -- written. --

  SetWriterOffset: PROCEDURE [handle: WriterHandle, offset: ObjectOffset];
  -- Re-postiions the writer so that "offset" is the offset in the object
  -- of the next word to be written. --




  -- Reader primitives --

  ReaderHandle: TYPE = LONG POINTER TO ReaderData;

  ReaderData: TYPE;

  HeapStartRead: PROCEDURE [ObjectNumber] RETURNS [ReaderHandle];
  -- Creates a reader to read from the given object.  Increments the
  -- reference count on the object. --

  CloseToReader: PROCEDURE [handle: WriterHandle] RETURNS [ReaderHandle];
  -- Similar to HeapEndWrite, but a reader is created.  The object is
  -- left with reference count 1 (for the reader). --

  HeapReadData: PROCEDURE [from: ReaderHandle, to: Buffer]
    RETURNS [end: BOOLEAN, used: CARDINAL];
  -- Fills as much of the buffer as possible by reading from the object. 
  -- On exit, either "end" or "used=to.length" (or both) --

  HeapEndRead: PROCEDURE [from: ReaderHandle];
  -- Decrements the reference count on the object and destroys the
  -- reader.  The ReaderHandle must not be used after this point. --

  CopyReader: PROCEDURE [from: ReaderHandle] RETURNS [ReaderHandle];
  -- Increments the reference count on the object, and returns a new
  -- reader positioned to the same place in the object. --

  GetReaderOffset: PROCEDURE [from: ReaderHandle] RETURNS [ObjectOffset];
  -- Returns the offset in the object of the next word that will be read. --

  SetReaderOffset: PROCEDURE [from: ReaderHandle, offset: ObjectOffset];
  -- Re-positions the reader so that "offset" is the offset in the object
  -- of the next word to be read. --

  GetReaderObject: PROCEDURE [from: ReaderHandle] RETURNS [ObjectNumber];
  -- Tells you the object number for this reader --




  -- Restart primitives --

  HeapRestart: PROGRAM RETURNS [initHeap: BOOLEAN];
  -- Re-constructs the heap objects, and registers them in the object
  -- directory with reference count 0.  The compactor is not yet running. --

  Compactor: PROGRAM;  -- never returns --




  -- Writer utilities --

  HeapWriteString: PROCEDURE [handle: WriterHandle, s: LONG STRING];
  -- Appends the string to the object --

  HeapWriteRName: PROCEDURE [handle: WriterHandle, rName: BodyDefs.RName] = INLINE
    {HeapWriteString[handle, rName]};

  WriteItemHeader: PROCEDURE [handle: WriterHandle, header: BodyDefs.ItemHeader];

  ReceiveComponent: PROCEDURE [handle: WriterHandle, str: ProtocolDefs.Handle];
  -- reads a single R-Server component from the stream --
  -- May signal ProtocolDefs.Failed --

  ReceiveObj: PROCEDURE [handle: WriterHandle, str: ProtocolDefs.Handle];
  -- Reads from the stream into the object until EndSST --
  -- May signal ProtocolDefs.Failed --




  -- Reader utilities --

  HeapReadString: PROCEDURE [from: ReaderHandle, s: LONG STRING]
    RETURNS [ended: BOOLEAN];
  -- Reads a string from the object into the given storage.  Returns
  -- whether the object has now ended. --

  HeapReadRName: PROCEDURE [from: ReaderHandle, rName: BodyDefs.RName]
    RETURNS [ended: BOOLEAN] = INLINE {RETURN[HeapReadString[from, rName]]};

  ReadItemHeader: PROCEDURE [from: ReaderHandle]
    RETURNS [header: BodyDefs.ItemHeader];

  ReadRList: PROCEDURE [
    from: ReaderHandle, work: PROCEDURE [BodyDefs.RName] RETURNS [done: BOOLEAN]];
  -- reads a component, calling "work" for each R-Name. --

  SendComponent: PROCEDURE [from: ReaderHandle, str: ProtocolDefs.Handle];
  -- Copies an R-Server component onto the stream --
  -- May signal ProtocolDefs.Failed --

  SendObj: PROCEDURE [from: ReaderHandle, str: ProtocolDefs.Handle];
  -- Copies the object into the stream, followed by EndSST --
  -- May signal ProtocolDefs.Failed --


  END.