-- Copyright (C) 1980, 1981, 1984, 1985  by Xerox Corporation. All rights reserved. 
-- BTreeSupport.mesa:  support for B-Tree package

-- HGM, 15-Sep-85 12:47:05
-- Randy Gobbel		19-May-81 21:20:17
-- Andrew Birrell	 2-Sep-80 14:38:22


DIRECTORY
  BTreeSupportDefs USING [FileHandle, PageHandle, PageNumber],
  Storage USING [Free, Node],
  VMDefs USING [
    GetFileLength, Mark, PageAddress, pageSize, ReadPage, Release, RemapPage,
    SetFileLength, UsePage];


BTreeSupport: PROGRAM

  IMPORTS Storage, VMDefs EXPORTS BTreeSupportDefs =

  BEGIN

  ReadPage: PUBLIC PROCEDURE [
    fileH: BTreeSupportDefs.FileHandle, pageN: BTreeSupportDefs.PageNumber]
    RETURNS [pageH: BTreeSupportDefs.PageHandle] =
    BEGIN
    addr: VMDefs.PageAddress = [file: LOOPHOLE[fileH], page: pageN];
    RETURN[LOOPHOLE[VMDefs.ReadPage[addr, 0 --lookAhead-- ]]]
    END;

  UsePage: PUBLIC PROCEDURE [
    fileH: BTreeSupportDefs.FileHandle, pageN: BTreeSupportDefs.PageNumber]
    RETURNS [pageH: BTreeSupportDefs.PageHandle] =
    BEGIN
    addr: VMDefs.PageAddress = [file: LOOPHOLE[fileH], page: pageN];
    pageH ← LOOPHOLE[VMDefs.UsePage[addr]];
    IF addr.page = VMDefs.GetFileLength[addr.file].page THEN
      VMDefs.SetFileLength[addr.file, [page: addr.page + 1, byte: 0]];
    END;

  WritePage: PUBLIC PROCEDURE [
    fileH: BTreeSupportDefs.FileHandle, pageN: BTreeSupportDefs.PageNumber,
    pageH: BTreeSupportDefs.PageHandle] =
    BEGIN
    addr: VMDefs.PageAddress = [file: LOOPHOLE[fileH], page: pageN];
    VMDefs.RemapPage[LOOPHOLE[pageH], addr];
    VMDefs.Mark[LOOPHOLE[pageH]];
    VMDefs.Release[LOOPHOLE[pageH]];
    END;

  ReleasePage: PUBLIC PROCEDURE [pageH: BTreeSupportDefs.PageHandle] =
    BEGIN VMDefs.Release[LOOPHOLE[pageH]]; END;

  SetLength: PUBLIC PROCEDURE [
    fileH: BTreeSupportDefs.FileHandle, pageN: BTreeSupportDefs.PageNumber] =
    BEGIN
    addr: VMDefs.PageAddress = [file: LOOPHOLE[fileH], page: pageN];
    VMDefs.SetFileLength[addr.file, [page: addr.page, byte: 0]];
    END;

  PageSize: PUBLIC PROCEDURE RETURNS [nWords: CARDINAL] =
    BEGIN RETURN[VMDefs.pageSize] END;

  AllocateWords: PUBLIC PROCEDURE [nWords: CARDINAL] RETURNS [POINTER] =
    BEGIN RETURN[Storage.Node[nWords]]; END;

  FreeWords: PUBLIC PROCEDURE [pntr: POINTER] = BEGIN Storage.Free[pntr]; END;

  END.