001package agent.four; 002 003public final class TimeServerLinked implements TimeServer { 004 private static final class Node { 005 final long waketime; 006 final Agent agent; 007 Node next; 008 009 public Node(long waketime, Agent agent, Node next) { 010 this.waketime = waketime; 011 this.agent = agent; 012 this.next = next; 013 } 014 } 015 private long currentTime; 016 private int size; 017 private Node head; 018 019 /* 020 * Invariant: head != null 021 * Invariant: head.agent == null 022 * Invariant: (size == 0) iff (head.next == null) 023 */ 024 public TimeServerLinked() { 025 size = 0; 026 head = new Node(0, null, null); 027 } 028 029 public String toString() { 030 StringBuilder sb = new StringBuilder("["); 031 Node node = head.next; 032 String sep = ""; 033 while (node != null) { 034 sb.append(sep).append("(").append(node.waketime).append(",") 035 .append(node.agent).append(")"); 036 node = node.next; 037 sep = ";"; 038 } 039 sb.append("]"); 040 return (sb.toString()); 041 } 042 043 public long currentTime() { 044 return currentTime; 045 } 046 047 public void enqueue(long waketime, Agent agent) 048 throws IllegalArgumentException 049 { 050 if (waketime <= currentTime) 051 throw new IllegalArgumentException(); 052 Node prevElement = head; 053 while ((prevElement.next != null) && 054 (prevElement.next.waketime <= waketime)) { 055 prevElement = prevElement.next; 056 } 057 Node newElement = new Node(waketime, agent, prevElement.next); 058 prevElement.next = newElement; 059 size++; 060 } 061 062 Agent dequeue() 063 throws IndexOutOfBoundsException 064 { 065 if (size < 1) 066 throw new IndexOutOfBoundsException(); 067 Agent rval = head.next.agent; 068 head.next = head.next.next; 069 size--; 070 return rval; 071 } 072 073 int size() { 074 return size; 075 } 076 077 boolean empty() { 078 return size() == 0; 079 } 080 081 public void run(int duration) { 082 long endtime = currentTime + duration; 083 while ((!empty()) && (head.next.waketime <= endtime)) { 084 currentTime = head.next.waketime; 085 086 Node next = head.next; 087 while (next!=null && (next.waketime == currentTime)) { 088 next.agent.check(); 089 next=next.next; 090 } 091 while ((!empty()) && (head.next.waketime == currentTime)) { 092 dequeue().run(); 093 } 094 } 095 currentTime = endtime; 096 } 097}