-- file CoreImpDefs.mesa (See also Core*.mesa.)
-- Last edited by Kierr, February 24, 1978 3:30 PM.
-- Edited by Brotz, July 30, 1980 10:46 AM.

-- CoreImpDefs are definitions used in implementation of Core.

DIRECTORY
AltoFileDefs: FROM "AltoFileDefs",
crD: FROM "CoreDefs",
gsD: FROM "GlobalStorageDefs",
ovD: FROM "OverviewDefs",
SegmentDefs: FROM "SegmentDefs";

crID: DEFINITIONS
SHARES crD =

BEGIN

OPEN crD;

-- Purpose: provides a Laurel style interface to files and raw storage/structures.

--
Topology of this file:
--
AltoCore: INTERNAL MODULE
--
VDATable: INTERNAL MODULE
--
FreePageMonitor: INTERNAL MODULE


-- INTERNAL MODULE: AltoCore.Mesa
-- Purpose: provides support for Alto file system in Laurel.


AltoReadPages: PROCEDURE [buffer: gsD.MemoryPagePtr, byteCount: CARDINAL,
pageNumber: UPageNumber, uFH: UFileHandle]
RETURNS [erc: ovD.ErrorCode, bytesRead: CARDINAL];
-- Reads up to "byteCount" bytes of data from the file asscoiated with uFH beginning with
-- page "pageNumber" into the memory page(s) beginning at "buffer". The byteCount
-- must be a multiple of 512 (an even page). The bytesRead returned is the count of bytes
-- actually read and will be equal to the requested byteCount except at EOF, when it may
-- be less. (Note that if pageNumber is beyound the end-of-file then bytesRead=0 is
-- returned.)
-- Error Codes: diskError.


AltoWritePages: PROCEDURE [buffer: gsD.MemoryPagePtr, byteCount: CARDINAL,
pageNumber: UPageNumber, uFH: UFileHandle]
RETURNS [erc: ovD.ErrorCode];
-- Writes byteCount of data from memory, beginning at buffer, to pageNumber of the file
-- aFH. The operation is legal only if the file was opened in update OpenMode. This can
-- be used to extend the file’s size by writing beyond the current end. (Note, however,
-- that the file is never shortened.) The byteCount must always be a multiple of 512, an
-- even page, except on the last page of the file. And it cannot be 0.
-- Regarding byteCount, let "remainder" be (byteCount MOD 512). If non-zero, remainder
-- denotes the number of bytes supplied by the client to be written on the last page of the
-- current transaction. The number of byte actually written will be the
-- MAX[current-bytes-on-that-file-page, remainder]; the value of all bytes beyond
-- remainder are indeterminate.
-- Side effects: Updates the file size in the uFH as needed.
-- Error Codes: diskFull, diskError, fileTooBig.


GetVDA: PROCEDURE [targetPage: AltoPageNumber, aFH: AltoFileHandle]
RETURNS [erc: ovD.ErrorCode, vDA: VDA];
-- Get the VDA for the target page, either from the table or, if necessary, by reading the
-- disk.
-- ErrorCodes: DiskError.


MakeFileIndexCanonical: PROCEDURE [page: UPageNumber, byte: CARDINAL]
RETURNS [UPageNumber, CARDINAL[0 .. 512)];
-- All FileIndexes (e.g., page,byte) have to property that the corresponding CharIndex is
-- (page*512 + byte). But canonical FileIndexes also have the property that byte is IN
-- [0 .. 512).


MapUToAltoPage: PROCEDURE [page: UPageNumber] RETURNS [AltoPageNumber];


MapAltoToUPage: PROCEDURE [page: AltoPageNumber] RETURNS [UPageNumber];


-- Data Structures and Types for AltoCore: INTERNAL MODULE.

AltoFileHandle: TYPE = POINTER TO alto UFileObject;
UPageNumber: TYPE = PageNumber;
AltoPageNumber: TYPE = SegmentDefs.PageNumber; -- equal 1+UPageNumber

CAsPtr: TYPE = POINTER TO ARRAY [0..0) OF gsD.MemoryPagePtr;

VDA: TYPE = AltoFileDefs.vDA; -- Rename vDA to standard spelling.

-- END of AltoCore: INTERNAL MODULE;


-- VDATable: INTERNAL MODULE =
-- The vDA table is represented as a set of chunks, indexed by a descriptor block.


TableGetVDA: PROCEDURE [vDATable: VDATablePtr, page: AltoPageNumber]
RETURNS [vDA: VDA];
-- Look in vDATable for page. Return the contents of the entry if present; otherwise,
-- return fillinDA.


TablePutVDA: PROCEDURE [vDATable: VDATablePtr, page: AltoPageNumber, vDA: VDA];
-- Puts the pair (page, vDA) in vDATable. The auxilliary entries which overlap between
-- chunks are also stored. Adds a new chunk if necessary.


CallProcedureForChunks: PROCEDURE [firstPage, lastPage: AltoPageNumber,
aFH: AltoFileHandle,
proc: PROCEDURE [firstP, lastP: AltoPageNumber, aFH: AltoFileHandle,
vDAPtr: VDAsPtr] RETURNS [erc: ovD.ErrorCode]]
RETURNS [erc: ovD.ErrorCode];
-- The proc is called for each included chunck of the vDA array, unless it asks to be
-- stopped via returning a non-ok ErrorCode. At each call to "proc", the vDAs array and
-- its limits are given as args.
-- The ErrorCode returned is the one returned by proc.


-- Data Structures and Types for VDATable: INTERNAL MODULE.

-- Stuff to define Chunk Table, see also CoreDefs.mesa.
chunkSpan: CARDINAL = 64; -- Number of pages per chunk.
lowerPad: CARDINAL = 1; -- Number of extra entries before chunk.
upperPad: CARDINAL = 1; -- Number of extra entries after a chunk.
chunkSize: CARDINAL = chunkSpan+lowerPad+upperPad; -- Includes extra entries.
maxVDAIndex: CARDINAL = (numberOfChunks*chunkSpan)-1;

-- Chunk addressing structure, an example: Using chunkSpan=32 and numberOfChunks=3,
-- let chunk0,1,2 be the address of memory allocated for the three chunks respectively.
-- Then a VDAArray will have vDAArray[0]=chunk0, cDAArray[1]=(chunk1-32), and
-- vDAArray[2]=(chunk2-64). Assuming that there are no holes, to get to entry i you can
-- say "vDAArray[i/32]↑[i]".

-- END of VDATable: INTERNAL MODULE;



-- FreePageMonitor: INTERNAL MODULE;
-- This module is responsible for maintaining a free page count and announcing changes to
-- the client.


UpdateFreePageCount: PROCEDURE;
-- This is called internally to set up (and announce if necessary and enabled) the free page
-- tally by actually counting whenever currentFPC might be wrong.


DecrementFreePageCount: PROCEDURE [deltaFPC: CARDINAL];
-- This is called internally to change (and announce if necessary and enabled) the free page
-- tally by subtracting deltaFPC from the current total.

-- END of FreePageMonitor: INTERNAL MODULE;



END. -- of CoreImpDefs --