-- Transport Mechanism Filestore - public DEFS for heap storage --

-- [Juniper]<Grapevine>MS>HeapDefs.mesa

-- Andrew Birrell  24-Feb-81 15:19:36 --

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

HeapDefs:	DEFINITIONS = BEGIN



-- General --

Buffer:		TYPE = RECORD[ where: 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 = 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 = 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: 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: 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.