-- File: ArpaAddressCacheImpl.mesa - last edit:
-- JAV                 25-Feb-87 14:32:10

-- Copyright (C) 1985, 1986, 1987 by Xerox Corporation. All rights reserved.


DIRECTORY
  ArpaAddressCache USING [],
  ArpaRouter USING [InternetAddress, unknownInternetAddress],
  Heap USING [Create],
  String USING [Compare, CopyToNewString];
  
ArpaAddressCacheImpl: MONITOR 
  IMPORTS ArpaRouter, Heap, String
  EXPORTS ArpaAddressCache = {
  
  Handle: TYPE = LONG POINTER TO Object;
  
  Object: TYPE = RECORD[
    name: LONG STRING ← NIL,
    addr: ArpaRouter.InternetAddress ← ArpaRouter.unknownInternetAddress,
    next: Handle ← NIL];
  
  root, lastEntry: Handle ← NIL;
  zone: UNCOUNTED ZONE ← Heap.Create[
    initial: 5, increment: 5, largeNodeThreshold: 256];
  
  Flush: PUBLIC ENTRY PROC = {
    this: Handle ← NIL;
    FOR this ← root, root UNTIL this = NIL DO
      root ← this.next;
      zone.FREE[@this.name];
      zone.FREE[@this];
      ENDLOOP;
    root ← lastEntry ← NIL;
    };
    
  AddEntry: PUBLIC ENTRY PROC[name: LONG STRING, addr: ArpaRouter.InternetAddress] = {
    IF lastEntry = NIL THEN 
      root ← lastEntry ← zone.NEW[Object ← [
	name: String.CopyToNewString[name, zone],
	addr: addr,
	next: NIL]]
    ELSE {
      lastEntry.next ← zone.NEW[Object ← [
	name: String.CopyToNewString[name, zone],
	addr: addr,
	next: NIL]];
      lastEntry ← lastEntry.next};
    };
    
  Enumerate: PUBLIC PROC[
    proc: PROC[name: LONG STRING, addr: ArpaRouter.InternetAddress]] = {
    FOR i: Handle ← root, i.next UNTIL i = NIL DO
      proc[i.name, i.addr];
      ENDLOOP;
    };
  
  Lookup: PUBLIC PROC[name: LONG STRING] 
    RETURNS [addr: ArpaRouter.InternetAddress, hit: BOOLEAN] = {
    hit ← FALSE; 
    addr ← ArpaRouter.unknownInternetAddress;
      FOR i: Handle ← root, i.next UNTIL i = NIL DO
	IF (String.Compare[name, i.name, TRUE] = 0) THEN RETURN[i.addr, TRUE];
      ENDLOOP;
    };
    
  LookupAddr: PUBLIC PROCEDURE [addr: ArpaRouter.InternetAddress] RETURNS [name: LONG STRING ← NIL] = {
    FOR i: Handle ← root, i.next UNTIL i = NIL DO
      IF addr = i.addr THEN RETURN[i.name];
    ENDLOOP;
  };
    
}.