// IfsBTreeRes.bcpl -- Resident portion of IFS interface to the B-Tree package
// Copyright Xerox Corporation 1979, 1980

// Last modified November 14, 1980  11:57 AM by Taft

get "BTree.decl"
get "IfsVMem.decl"

external
[
// Outgoing procedures
BVWRP; BVRRP; BtLockCell; BtUnlockCell

// Incoming procedures
@VRRP; @VWRP
LockCell; UnlockCell; Yield; DefaultArgs; Usc; IFSError
]

structure FCE:		// Free chain entry (def shared with IfsBTreeSwap)
[
FreeMarker word
next word
]

manifest ecBtOutOfVMem = 28
manifest ecBtRefFreePage = 30

// Procedures to access a specified page of the B-Tree.
// The first 1024 words of the file are reserved for the file map, regardless
// of the physical page size of the disk or the logical B-Tree page size.
// The first virtual page in the tree (the state page) is virtual page zero,
// but is physically the first page after the file map (i.e., page 2 in
// the normal case involving Trident disks.)

// There are 3 "page sizes" of interest:
// 1) logVMPageLength, the VMEM page size, fixed at 256 words.
// 2) TREE.LogPageLength, the "logical" page size of the B-Tree.
// 3) FVMD.logVPagesPerDiskPage, the page size of the disk on which the
//    B-Tree now resides.
// The page group size, alignment, etc., must be based on
// the greater of (2) and (3).  This is FVMD.logPageGroupSize.

//----------------------------------------------------------------------------
let BVRRP(tree, treePage) = BVWRP(tree, treePage, VRRP)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and BVWRP(tree, treePage, RefProc, freeOK; numargs na) = valof
//----------------------------------------------------------------------------
[
DefaultArgs(lv na, -2, VWRP, false)
Yield()
let vPage = 1024 rshift logVMPageLength +
 1 lshift tree>>TREE.vmd>>FVMD.logVPagesPerDiskPage +
 treePage lshift (tree>>TREE.LogPageLength-logVMPageLength)
if Usc(vPage, tree>>TREE.vmd>>VMD.length) ge 0 then
   IFSError(ecBtOutOfVMem, tree)
let ptr = RefProc(tree>>TREE.vmd>>FVMD.base + vPage)
unless freeOK % ptr>>FCE.FreeMarker ge 0 do
   IFSError(ecBtRefFreePage, tree)
resultis ptr
]


// Lock and unlock B-Tree pages

//----------------------------------------------------------------------------
and BtLockCell(tree, cell) = LockCell(cell)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and BtUnlockCell(tree, cell) = UnlockCell(cell)
//----------------------------------------------------------------------------