<> <> <> <> <<>> DIRECTORY DragOpsCross USING [Word, ZerosWord], SparseMemory USING [Bank, BankRep, Base, BaseRep, IndexInBank, IndexInBase, IndexInSpace, Page, PageRep, Space, SpaceRep, WordParts]; SparseMemoryImpl: CEDAR PROGRAM EXPORTS SparseMemory SHARES SparseMemory = BEGIN OPEN DragOpsCross, SparseMemory; <> NoMore: PUBLIC ERROR = CODE; Create: PUBLIC PROC RETURNS [Base] = { <> < NOT Probe[base, index]>> RETURN [NEW[BaseRep _ ALL[NIL]]]; }; Fetch: PUBLIC PROC [base: Base, index: Word, default: Word _ ZerosWord] RETURNS [Word] = { <> < Fetch[base, index, default] = default>> parts: WordParts = LOOPHOLE[index]; IF base # NIL THEN { space: Space = base[parts.inBase]; IF space # NIL THEN { bank: Bank = space[parts.inSpace]; IF bank # NIL THEN { page: Page = bank[parts.inBank]; IF page # NIL THEN RETURN [page.words[parts.inPage]]; }; }; }; RETURN [default]; }; FetchWithCode: PUBLIC PROC [base: Base, index: Word] RETURNS [word: Word, present: BOOL] = { <> < Fetch[base, index, default] = default>> parts: WordParts = LOOPHOLE[index]; IF base # NIL THEN { space: Space = base[parts.inBase]; IF space # NIL THEN { bank: Bank = space[parts.inSpace]; IF bank # NIL THEN { page: Page = bank[parts.inBank]; IF page # NIL THEN RETURN [page.words[parts.inPage], TRUE]; }; }; }; RETURN [ZerosWord, FALSE]; }; FetchPage: PUBLIC PROC [base: Base, index: Word] RETURNS [Page] = { <> parts: WordParts = LOOPHOLE[index]; IF base # NIL THEN { space: Space = base[parts.inBase]; IF space # NIL THEN { bank: Bank = space[parts.inSpace]; IF bank # NIL THEN RETURN [bank[parts.inBank]]; }; }; RETURN [NIL]; }; Store: PUBLIC PROC [base: Base, index: Word, new: Word _ ZerosWord] = { <> <> < Fetch[base', x, default] = Fetch[base, index, default]>> < Probe[base', x] = Probe[base, index]>> < Fetch[base', index, default] = new>> < Probe[base', index]>> parts: WordParts = LOOPHOLE[index]; IF base # NIL THEN { space: Space _ base[parts.inBase]; IF space = NIL THEN {space _ base[parts.inBase] _ NEW[SpaceRep _ ALL[NIL]]}; {bank: Bank _ space[parts.inSpace]; IF bank = NIL THEN {bank _ space[parts.inSpace] _ NEW[BankRep _ ALL[NIL]]}; {page: Page _ bank[parts.inBank]; IF page = NIL THEN { page _ bank[parts.inBank] _ NEW[PageRep _ [NIL, ALL[ZerosWord]]]}; page.words[parts.inPage] _ new; }; }; }; }; Probe: PUBLIC PROC [base: Base, index: Word] RETURNS [present: BOOL] = { <> < NOT Probe[base, index]>> parts: WordParts = LOOPHOLE[index]; IF base # NIL THEN { space: Space = base[parts.inBase]; IF space # NIL THEN { bank: Bank = space[parts.inSpace]; IF bank # NIL THEN IF bank[parts.inBank] # NIL THEN RETURN [TRUE]; }; }; RETURN [FALSE]; }; NextPresent: PUBLIC PROC [base: Base, start: Word] RETURNS [Word] = { <> <>> <> < >> <> < Probe[base, index]>> parts: WordParts _ LOOPHOLE[start]; IF base # NIL THEN FOR spaceIndex: IndexInBase IN [parts.inBase..LAST[IndexInBase]] DO space: Space = base[spaceIndex]; IF space # NIL THEN FOR bankIndex: IndexInSpace IN [parts.inSpace..LAST[IndexInSpace]] DO bank: Bank = space[bankIndex]; IF bank # NIL THEN FOR pageIndex: IndexInBank IN [parts.inBank..LAST[IndexInBank]] DO IF bank[pageIndex] # NIL THEN RETURN [LOOPHOLE[ WordParts[spaceIndex, bankIndex, pageIndex, parts.inPage] ]]; ENDLOOP; parts.inBank _ parts.inPage _ 0; ENDLOOP; parts.inSpace _ parts.inBank _ parts.inPage _ 0; ENDLOOP; ERROR NoMore; }; END.