source: trunk/src/org/expeditee/gio/TimeoutQueue.java@ 1097

Last change on this file since 1097 was 1097, checked in by davidb, 6 years ago

Newly structured files from Corey's work on logic/graphics separation

File size: 3.6 KB
Line 
1package org.expeditee.gio;
2
3import java.util.Collection;
4import java.util.HashMap;
5import java.util.HashSet;
6import java.util.PriorityQueue;
7
8public class TimeoutQueue {
9
10 private PriorityQueue<Long> _timeoutQueue;
11
12 private HashSet<TimeoutHandle> _cancelledTimeouts;
13
14 private HashMap<TimeoutHandle, Long> _timeoutHandleMap;
15
16 private HashMap<Long, HashSet<TimeoutHandle>> _timeoutMap;
17
18 public TimeoutQueue()
19 {
20 _timeoutQueue = new PriorityQueue<Long>();
21 _cancelledTimeouts = new HashSet<TimeoutHandle>();
22 _timeoutHandleMap = new HashMap<TimeoutHandle, Long>();
23 _timeoutMap = new HashMap<Long, HashSet<TimeoutHandle>>();
24 }
25
26 public TimeoutHandle addTimeout(long milliseconds)
27 {
28 if (milliseconds < 0) return null;
29
30 milliseconds += System.currentTimeMillis();
31
32 TimeoutHandle handle = new TimeoutHandle();
33
34 _timeoutQueue.add(milliseconds);
35 _timeoutHandleMap.put(handle, milliseconds);
36 if (!_timeoutMap.containsKey(milliseconds)) {
37 _timeoutMap.put(milliseconds, new HashSet<TimeoutHandle>());
38 }
39 _timeoutMap.get(milliseconds).add(handle);
40
41 return handle;
42 }
43
44 public void cancelTimeout(TimeoutHandle handle)
45 {
46 if (handle == null) return;
47
48 if (!_timeoutHandleMap.containsKey(handle)) return;
49
50 _cancelledTimeouts.add(handle);
51 }
52
53 public Long getNextTimeout()
54 {
55 while (!_timeoutQueue.isEmpty()) {
56 long nextTimeout = _timeoutQueue.peek();
57 HashSet<TimeoutHandle> handlesForNextTimeout = handlesForTimeout(nextTimeout);
58 if (handlesAreCancelled(handlesForNextTimeout)) {
59 _timeoutQueue.poll();
60 _timeoutMap.remove(nextTimeout);
61 _cancelledTimeouts.removeAll(handlesForNextTimeout);
62 for (TimeoutHandle handle : handlesForNextTimeout) _timeoutHandleMap.remove(handle);
63 } else {
64 return nextTimeout - System.currentTimeMillis();
65 }
66 }
67
68 // No valid timeout found
69 return null;
70 }
71
72 public HashSet<TimeoutHandle> popExpiredTimeouts()
73 {
74 HashSet<TimeoutHandle> ret = new HashSet<TimeoutHandle>();
75
76 while (!_timeoutQueue.isEmpty()) {
77 long nextTimeout = _timeoutQueue.peek();
78 long nextTimeoutRelative = nextTimeout - System.currentTimeMillis();
79 if (nextTimeoutRelative > 0) break;
80 HashSet<TimeoutHandle> handlesForNextTimeout = popNextTimeout();
81 ret.addAll(handlesForNextTimeout);
82 }
83
84 return ret;
85 }
86
87 private boolean handlesAreCancelled(Collection<TimeoutHandle> handles)
88 {
89 if (handles == null) return false;
90
91 return _cancelledTimeouts.containsAll(handles);
92 }
93
94 private boolean handleIsCancelled(TimeoutHandle handle)
95 {
96 if (handle == null) return false;
97
98 return _cancelledTimeouts.contains(handle);
99 }
100
101 private HashSet<TimeoutHandle> handlesForTimeout(long timeout)
102 {
103 if (!_timeoutMap.containsKey(timeout)) return null;
104
105 return _timeoutMap.get(timeout);
106 }
107
108 private HashSet<TimeoutHandle> popNextTimeout()
109 {
110 if (_timeoutQueue.isEmpty()) return null;
111
112 long nextTimeout = _timeoutQueue.poll();
113 HashSet<TimeoutHandle> handlesForNextTimeout = handlesForTimeout(nextTimeout);
114 _timeoutMap.remove(nextTimeout);
115 for (TimeoutHandle handle : handlesForNextTimeout) {
116 if (handleIsCancelled(handle)) {
117 handlesForNextTimeout.remove(handle);
118 _cancelledTimeouts.remove(handle);
119 }
120 _timeoutHandleMap.remove(handle);
121 }
122
123 return handlesForNextTimeout;
124 }
125
126 public static class TimeoutHandle {
127
128 private static long _nextHandle = 1;
129
130 private static long getNextHandle()
131 {
132 long ret = _nextHandle;
133 _nextHandle++;
134 return ret;
135 }
136
137 private long _handle;
138
139 public TimeoutHandle()
140 {
141 _handle = getNextHandle();
142 }
143
144 public long getHandle()
145 {
146 return _handle;
147 }
148 }
149
150}
Note: See TracBrowser for help on using the repository browser.