-- File: AddressCacheImpl.mesa - last edit: -- AOF 31-Aug-86 18:11:17 -- BGY 21-Aug-84 20:15:57 -- Copyright (C) 1984, 1986 by Xerox Corporation. All rights reserved. DIRECTORY AddressCache, Heap, NSName, NSString, String, System; AddressCacheImpl: MONITOR IMPORTS Heap, NSName, NSString, String EXPORTS AddressCache = { Handle: TYPE = LONG POINTER TO Object; Object: TYPE = RECORD[ name: LONG STRING ¬ NIL, addr: System.NetworkAddress ¬ System.nullNetworkAddress, next: Handle ¬ NIL]; root, free: Handle ¬ NIL; cacheSize, inCache: CARDINAL ¬ 0; avail, hits, accesses: CARDINAL ¬ 0; zone: UNCOUNTED ZONE ¬ Heap.Create[ initial: 5, increment: 5, largeNodeThreshold: 256]; GetSize: PUBLIC ENTRY PROC RETURNS[size: CARDINAL] = {size ¬ cacheSize}; SetSize: PUBLIC ENTRY PROC[size: CARDINAL] = { Remove: PROC[this: Handle] RETURNS [Handle]= { IF this.next # NIL THEN this.next ¬ Remove[this.next]; IF size = cacheSize THEN RETURN[this]; zone.FREE[@this.name]; zone.FREE[@this]; inCache ¬ inCache - 1; cacheSize ¬ cacheSize - 1; RETURN[this]; }; IF size = cacheSize THEN RETURN ELSE IF size < cacheSize THEN { -- remove from free list, then cache IF free # NIL THEN free ¬ Remove[free]; IF size < cacheSize THEN root ¬ Remove[root]} ELSE { -- add to free list delta: CARDINAL ¬ size - cacheSize; THROUGH [0..delta) DO free ¬ zone.NEW[Object ¬ [next: free]] ENDLOOP; cacheSize ¬ size; }; }; Flush: PUBLIC ENTRY PROC = { -- remove from cache to free list this: Handle ¬ NIL; FOR this ¬ root, root UNTIL this = NIL DO root ¬ this.next; zone.FREE[@this.name]; this­ ¬ [ name: NIL, addr: System.nullNetworkAddress, next: free]; free ¬ this; ENDLOOP; inCache ¬ 0; }; AddNSName: PUBLIC PROC[name: NSName.Name, addr: System.NetworkAddress] = { qualified: LONG STRING ¬ [NSName.maxFullNameLength]; string: NSString.String ¬ NSString.StringFromMesaString[qualified]; string ¬ NSName.AppendNameToString[string, name, TRUE]; qualified.length ¬ string.length; AddEntry[qualified, addr]; }; AddEntry: PUBLIC ENTRY PROC[name: LONG STRING, addr: System.NetworkAddress] = { IF cacheSize = 0 THEN RETURN; IF free # NIL THEN { -- take from free list to cache new: Handle ¬ free; free ¬ new.next; new­ ¬ [ name: String.CopyToNewString[name, zone], addr: addr, next: root]; root ¬ new; inCache ¬ inCache + 1; } ELSE { -- have to remove least recently used entry last: Handle ¬ root; lru: Handle ¬ root; IF root = NIL THEN RETURN; FOR i: Handle ¬ root, i.next UNTIL i = NIL DO IF i.next # NIL THEN last ¬ i ELSE lru ¬ i; ENDLOOP; last.next ¬ NIL; zone.FREE[@lru.name]; lru­ ¬ [ name: String.CopyToNewString[name, zone], addr: addr, next: root]; root ¬ lru; }; }; Enumerate: PUBLIC ENTRY PROC[ proc: PROC[name: LONG STRING, addr: System.NetworkAddress]] = { FOR i: Handle ¬ root, i.next UNTIL i = NIL DO proc[i.name, i.addr]; ENDLOOP; }; LookupNSName: PUBLIC PROC[name: NSName.Name] RETURNS [addr: System.NetworkAddress, hit: BOOLEAN] = { qualified: LONG STRING ¬ [NSName.maxFullNameLength]; string: NSString.String ¬ NSString.StringFromMesaString[qualified]; string ¬ NSName.AppendNameToString[string, name, TRUE]; qualified.length ¬ string.length; [addr, hit] ¬ Lookup[qualified]; }; Lookup: PUBLIC ENTRY PROC[name: LONG STRING] RETURNS [addr: System.NetworkAddress, hit: BOOLEAN] = { accesses ¬ accesses + 1; hit ¬ FALSE; addr ¬ System.nullNetworkAddress; IF cacheSize = 0 THEN RETURN; FOR i: Handle ¬ root, i.next UNTIL i = NIL DO IF (String.Compare[name, i.name, TRUE] = 0) THEN { hits ¬ hits + 1; RETURN[i.addr, TRUE]}; ENDLOOP; }; GetStatistics: PUBLIC PROC RETURNS[CARDINAL, CARDINAL, CARDINAL] = { RETURN[inCache, hits, accesses]}; }.