// ISFINIT -- initialize indexed sequential file // last edited November 12, 1976 12:42 PM // file reassignments in local copies begun January 20, 1978, by Swinehart get "isf.d" external // entry procedures [ InitFmap // (fmap, len, fp[, check, xtnd, zone, disk]) -> ok morepageio // for extending files -- used at init time only in Spruce WriteFmap // used if at all only at init time in Spruce ] external [ // O.S. CallSwat MoveBlock ActOnDiskPages DefaultArgs Allocate; Free Dvec sysDisk sysZone SetBlock Usc WriteDiskPages Zero // Isf (utilities) NextFmap LookupFmap // Spruce utilities Min ] let InitFmap(fmap, len, fp, check, xtnd, zone, disk, lvPages; numargs n) = valof [ DefaultArgs(lv n, -3, false, 10, -1, sysDisk, 0) // DCS 9-14-78 returns false if len too small or check error accessing file if len ls mapoffset+3 then resultis false fmap>>FM.seal = version MoveBlock(lv fmap>>FM.fp, fp, lFP) let leaderVda = fp>>FP.leaderVirtualDa fmap>>FM.DA0 = leaderVda fmap>>FM.DA1, fmap>>FM.DA2 = fillInDA, fillInDA fmap>>FM.last = mapoffset+2 let end = (len-2)&-2 fmap>>FM.onern, fmap>>FM.oneda = 0, fmap>>FM.DA0 let map = fmap+mapoffset map!0, map!1, map!2 = 0, leaderVda, 1 fmap>>FM.rewrite = check fmap>>FM.extend = (xtnd ls ppc? xtnd, ppc) if zone eq 0 then zone = sysZone let pagesize = 1 lshift disk>>DSK.lnPageSize let scratch, nch = pagesize, (check? 1, 0) // nch used for last page input until after Act.. test zone eq -1 then Dvec(InitFmap, lv scratch) or scratch = Allocate(zone, scratch) let res = ActOnDiskPages(disk, 0, lv fmap>>FM.DA0, fp, 0, nch, DCreadD, lv nch, DCreadD, scratch, 0,0, true) ge 0 if res then test check then [ if nch eq 2*pagesize & (scratch>>FM.last ge mapoffset+2) & (scratch!mapoffset eq 0) & valof [ for i = 1 to checksize-1 do if scratch!i ne fmap!i resultis false; resultis true ] then [ let last = scratch>>FM.last // stored map seems all right -- use it if last gr end then last = end if last ge pagesize then last = pagesize-2 MoveBlock(fmap, scratch, last+1) ] ] or if lvPages then [ @lvPages = scratch>>LD.hintLastPageFa.pageNumber if @lvPages > 0 & scratch>>LD.hintLastPageFa.charPos eq 0 then @lvPages = @lvPages-1 ] if zone ne -1 then Free(zone, scratch) fmap>>FM.end = end fmap>>FM.disk = disk fmap>>FM.zone = zone resultis res ] and morepageio(fmap, firstrn, scratch, npg, wflag) be [ let pagesize, firstda = 1 lshift fmap>>FM.disk>>DSK.lnPageSize, LookupFmap(fmap, firstrn) let zone = fmap>>FM.zone if wflag eq -1 then test zone eq -1 ifso [ scratch = pagesize; Dvec(morepageio, lv scratch) ] ifnot scratch = Allocate(zone, pagesize) let lastrn, lastmaprn = firstrn+npg, NextFmap(fmap) let rn = lastmaprn-1 let DAs = vec ppc+2 // ppc+3 words! DAs!0 = (rn eq 0? eofDA, LookupFmap(fmap, rn-1)) let nch = nil while rn ls lastrn do [ DAs!1 = LookupFmap(fmap, rn) let np = Min(ppc, lastrn-rn) SetBlock(DAs+2, fillInDA, np+1) let nrn = ActOnDiskPages(fmap>>FM.disk, 0, DAs+1-rn, lv fmap>>FM.fp, rn, rn+np-1, DCreadD, lv nch, DCreadD, scratch) if nch eq 0 then // extend file test nrn eq rn ifnot // too hard to pick up np = nrn-rn ifso [ let nxp = fmap>>FM.extend unless (nxp gr 0) & (wflag ne 0) do CallSwat("Attempt to access non-existent page") if np ls nxp then np = nxp Zero(scratch, pagesize) SetBlock(DAs+2, fillInDA, np+1) DAs!(np+2) = eofDA WriteDiskPages(fmap>>FM.disk, 0, DAs+1-rn, lv fmap>>FM.fp, rn, rn+np, DCwriteD, 0, 0, scratch) ] for j = 1 to np do [ let xrn, xda = rn+j, DAs!(j+1) ExtendFmap(fmap, xrn, xda) if xrn eq firstrn then firstda = xda ] DAs!0 = DAs!np rn = rn+np ] ExtendFmap(fmap, firstrn, firstda) // just in case map is full if NextFmap(fmap) gr lastmaprn then WriteFmap(fmap) if (wflag eq -1) & (zone ne -1) then Free(zone, scratch) ] and WriteFmap(fmap) be [ if fmap>>FM.rewrite then [ ActOnDiskPages(fmap>>FM.disk, 0, lv fmap>>FM.DA0, lv fmap>>FM.fp, 1, 1, DCwriteD, 0, DCwriteD, fmap) ] ] and ExtendFmap(fmap, rn, da) = valof [ fmap>>FM.onern, fmap>>FM.oneda = rn, da let last = fmap>>FM.last let lastp = lv (fmap!last) if rn ne @lastp then resultis false let curva = da test curva eq (lastp!-1)+@lastp-(lastp!-2) ifso // still in same chunk @lastp = @lastp+1 ifnot // start new chunk test last eq fmap>>FM.end ifso // out of space resultis false ifnot [ lastp!1, lastp!2 = curva, @lastp+1 fmap>>FM.last = last+2 ] resultis true ] // DCS, January 20, 1978 10:41 PM, file reassignments // September 14, 1978 10:26 AM, InitFmap checks existence of file, check or not, // returns false on check error (file with that fp does not exist) // September 18, 1978 8:26 AM, if not checking and not check error (InitFmap), and if // lvPages (new) arg supplied, fill it with numPages value from length hint in leader page //