<> <> <> ExtendibleHash: CEDAR DEFINITIONS = BEGIN <> <> ExtendibleHashTable: TYPE = REF ExtendibleHashTableRep; ExtendibleHashTableRep: TYPE; -- This represents the volatile state of an open hash table Entry: TYPE = LONG POINTER TO EntryRep; EntryRep: TYPE = MACHINE DEPENDENT RECORD [ entryWordSize(0): CARD32, entryContents(WORDS[INT]): ARRAY [0..0) OF CARD32 ]; HashValue: TYPE = RECORD [high: CARD32, low: CARD32]; EntSize: TYPE = CARD; UpdateType: TYPE = {insert, replace, insertOrReplace}; <<>> <> <> <> wordsPerPage: INT = 512; PageStorage: TYPE = REF ANY; PageNumber: TYPE = CARD; statePage: PageNumber = 0; <> PageSize: TYPE = CARD; PagePtr: TYPE = LONG POINTER --TO ARRAY [0..pageSize) OF WORD--; ReferenceType: TYPE = {read, write, new}; UpdateState: TYPE = {modified, unchanged}; <<>> <> ReferencePage: TYPE = UNSAFE PROC [storage: PageStorage, number: PageNumber, type: ReferenceType, clientPerCallData: REF] RETURNS [ptr: PagePtr]; <> <> <<>> ReleasePage: TYPE = UNSAFE PROC [storage: PageStorage, number: PageNumber, update: UpdateState _ unchanged, clientPerCallData: REF]; <> <<>> PageStoragePrimitives: TYPE = RECORD [ referencePage: ReferencePage, releasePage: ReleasePage ]; <> State: TYPE = {closed, suspended, open}; <> <<>> New: PROC [ storPrim: PageStoragePrimitives, initialState: State[closed..suspended] _ closed] RETURNS [hashTable: ExtendibleHashTable]; <> <<>> Open: PROC [hashTable: ExtendibleHashTable, storage: PageStorage, pageSize: PageSize, initialize: BOOLEAN _ FALSE, initialDirectorySize: CARD _ 512, clientPerCallData: REF _ NIL]; <> <> <<>> SetState: PROC [hashTable: ExtendibleHashTable, state: State[closed..suspended]]; <> <<>> GetState: PROC [hashTable: ExtendibleHashTable] RETURNS [state: State, entryCount: CARD, greatestPage: PageNumber, log2DirectorySize: CARD, storage: PageStorage]; <> <<>> Validate: PROC [hashTable: ExtendibleHashTable, hashFunction: PROC [entry: Entry] RETURNS [hashValue: HashValue]]; <> <> <<>> <> <> <<>> ReadEntry: UNSAFE PROC [hashTable: ExtendibleHashTable, hashValue: HashValue, proc: UNSAFE PROC [entry: Entry, wordsForEntriesOnPage: INT, overFlowPageProc: UNSAFE PROC RETURNS [entry: Entry, wordsForEntriesOnPage: INT]], clientPerCallData: REF _ NIL]; <> <> <> <<>> DeleteEntry: UNSAFE PROC [hashTable: ExtendibleHashTable, hashValue: HashValue, proc: UNSAFE PROC [entry: Entry, wordsForEntriesOnPage: INT, overFlowPageProc: UNSAFE PROC RETURNS [entry: Entry, wordsForEntriesOnPage: INT]] RETURNS [entryToDelete: Entry], clientPerCallData: REF _ NIL]; <> <<>> UpdateEntry: UNSAFE PROC [ hashTable: ExtendibleHashTable, hashValue: HashValue, words: EntSize, findProc: UNSAFE PROC [entry: Entry, wordsForEntriesOnPage: INT, overFlowPageProc: UNSAFE PROC RETURNS [entry: Entry, wordsForEntriesOnPage: INT]] RETURNS [entryToUpdate: Entry], modifyProc: UNSAFE PROC [entry: Entry], updateType: UpdateType _ insertOrReplace, clientPerCallData: REF _ NIL]; <> <> <> <<>> <> Error: ERROR [reason: Reason]; Reason: TYPE = {badSeal, closed, entrySizesWrong, other, wrongEntryProduced, wrongPageSize, wrongUpdateType, entrySizeTooBig, notPowerOfTwoDirectorySize, notAnEntry, outOfRoom, overWriteOfNextEntry}; END.