TickerQueue.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.lang.*;
16: import java.util.*;
17:
18: public class TickerQueue {
19:
20: public static final boolean TKQ_USE_TICKER0 = true;
21: public static final int TKQ_MASK = 255;
22:
23:
24:
25:
26: public static class Ticker {
27: public Ticker () {
28: time = Long.MAX_VALUE;
29: }
30: protected long time;
31:
32:
33:
34:
35:
36: protected void tick () {
37: }
38: }
39:
40:
41:
42:
43:
44:
45:
46:
47:
48: public static final Ticker[] tkqArray = new Ticker[TKQ_MASK + 1];
49: public static int tkqHead;
50: public static int tkqTail;
51: public static Ticker tkqTicker0;
52: public static long tkqTime0;
53:
54:
55:
56:
57: public static void tkqInit () {
58:
59: if (TKQ_USE_TICKER0) {
60: tkqTicker0 = tkqArray[tkqTail = tkqHead = 0] = new Ticker ();
61: } else {
62: tkqArray[tkqTail = tkqHead = 0] = new Ticker ();
63: }
64: tkqTime0 = tkqTicker0.time = Long.MAX_VALUE;
65: }
66:
67:
68:
69:
70: public static void tkqRun (long currentTime) {
71: if (TKQ_USE_TICKER0) {
72: while (tkqTime0 <= currentTime) {
73: Ticker ticker0 = tkqTicker0;
74: tkqTime0 = (tkqTicker0 = tkqArray[tkqHead = tkqHead + 1 & TKQ_MASK]).time;
75: ticker0.time = Long.MAX_VALUE;
76: ticker0.tick ();
77: }
78: } else {
79: if (tkqTime0 <= currentTime) {
80: Ticker nextTicker0 = tkqArray[tkqHead];
81: do {
82: Ticker ticker0 = nextTicker0;
83: tkqTime0 = (nextTicker0 = tkqArray[tkqHead = tkqHead + 1 & TKQ_MASK]).time;
84: ticker0.time = Long.MAX_VALUE;
85: ticker0.tick ();
86: } while (tkqTime0 <= currentTime);
87: }
88: }
89: }
90:
91:
92:
93:
94: public static void tkqAdd (Ticker newTicker, long newTime) {
95: if (newTicker.time != Long.MAX_VALUE) {
96: tkqRemove (newTicker);
97: }
98: newTicker.time = newTime;
99: int count = tkqTail - tkqHead & TKQ_MASK;
100: if (count == TKQ_MASK) {
101: throw new Error ("tkqAdd: overflow");
102: }
103: if (count == 0 || newTime < tkqTime0) {
104:
105: if (TKQ_USE_TICKER0) {
106: tkqTicker0 = tkqArray[tkqHead = tkqHead - 1 & TKQ_MASK] = newTicker;
107: } else {
108: tkqArray[tkqHead = tkqHead - 1 & TKQ_MASK] = newTicker;
109: }
110: tkqTime0 = newTime;
111: return;
112: }
113:
114:
115:
116:
117: int l = 0;
118: int r = count;
119: while (l < r) {
120: int m = l + r >> 1;
121: if (tkqArray[m + tkqHead & TKQ_MASK].time <= newTime) {
122: l = m + 1;
123: } else {
124: r = m;
125: }
126: }
127:
128:
129:
130: if (l << 1 < count) {
131: l = l - 1 + tkqHead & TKQ_MASK;
132: r = tkqHead = tkqHead - 1 & TKQ_MASK;
133: while (l != r) {
134: int m = r + 1 & TKQ_MASK;
135: tkqArray[r] = tkqArray[m];
136: r = m;
137: }
138: } else {
139: l = l + tkqHead & TKQ_MASK;
140: r = tkqTail = tkqTail + 1 & TKQ_MASK;
141: while (l != r) {
142: int m = r - 1 & TKQ_MASK;
143: tkqArray[r] = tkqArray[m];
144: r = m;
145: }
146: }
147:
148:
149: tkqArray[l] = newTicker;
150: }
151:
152:
153:
154:
155: public static void tkqRemove (Ticker oldTicker) {
156: long oldTime = oldTicker.time;
157: if (oldTime == Long.MAX_VALUE) {
158: return;
159: }
160: oldTicker.time = Long.MAX_VALUE;
161: if (tkqHead == tkqTail) {
162: return;
163: }
164: if (TKQ_USE_TICKER0) {
165: if (tkqTicker0 == oldTicker) {
166: tkqTime0 = (tkqTicker0 = tkqArray[tkqHead = tkqHead + 1 & TKQ_MASK]).time;
167: return;
168: }
169: } else {
170: if (tkqArray[tkqHead] == oldTicker) {
171: tkqTime0 = tkqArray[tkqHead = tkqHead + 1 & TKQ_MASK].time;
172: return;
173: }
174: }
175:
176: int count = tkqTail - tkqHead & TKQ_MASK;
177:
178: int l = 0;
179: int r = count;
180: while (l < r) {
181: int m = l + r >> 1;
182: if (tkqArray[m + tkqHead & TKQ_MASK].time < oldTime) {
183: l = m + 1;
184: } else {
185: r = m;
186: }
187: }
188:
189:
190:
191: while (l < count && tkqArray[l + tkqHead & TKQ_MASK] != oldTicker) {
192: l++;
193: }
194: if (l == count) {
195: return;
196: }
197:
198:
199:
200: if (l << 1 < count) {
201: r = l + tkqHead & TKQ_MASK;
202: l = tkqHead & TKQ_MASK;
203: tkqHead = tkqHead + 1 & TKQ_MASK;
204: while (l != r) {
205: int m = r - 1 & TKQ_MASK;
206: tkqArray[r] = tkqArray[m];
207: r = m;
208: }
209: } else {
210: r = l + tkqHead & TKQ_MASK;
211: l = tkqTail & TKQ_MASK;
212: tkqTail = tkqTail - 1 & TKQ_MASK;
213: while (l != r) {
214: int m = r + 1 & TKQ_MASK;
215: tkqArray[r] = tkqArray[m];
216: r = m;
217: }
218: }
219:
220: }
221:
222:
223:
224: public static void tkqRemoveAll () {
225: while (tkqHead != tkqTail) {
226: if (TKQ_USE_TICKER0) {
227: tkqRemove (tkqTicker0);
228: } else {
229: tkqRemove (tkqArray[tkqHead]);
230: }
231: }
232: }
233:
234:
235:
236:
237: public static class TestTicker extends Ticker {
238: private int value;
239: private TestTicker (int value) {
240: this.value = value;
241: }
242: @Override protected void tick () {
243: System.out.print (time);
244: System.out.print ('(');
245: System.out.print (value);
246: System.out.print (')');
247: System.out.print (' ');
248: }
249: }
250:
251: public static void tkqTest () {
252: tkqInit ();
253: TestTicker[] tickers = new TestTicker[100];
254: for (int i = 0; i < 100; i++) {
255: tickers[i] = new TestTicker (i);
256: }
257:
258: System.out.println ("test 1");
259: for (int i = 0; i < 100; i++) {
260: tkqAdd (tickers[i], i);
261: }
262: tkqRun (100);
263: System.out.println ();
264:
265: System.out.println ("test 2");
266: for (int i = 100 - 1; i >= 0; i--) {
267: tkqAdd (tickers[i], i);
268: }
269: tkqRun (100);
270: System.out.println ();
271:
272: System.out.println ("test 3");
273: for (int i = 0; i < 100; i++) {
274: tkqAdd (tickers[i], (int) (Math.random () * 100));
275: }
276: tkqRun (100);
277: System.out.println ();
278:
279: System.out.println ("test 4");
280: for (int i = 0; i < 100; i++) {
281: tkqAdd (tickers[i], i);
282: }
283: for (int i = 0; i < 100; i += 2) {
284: tkqRemove (tickers[i]);
285: }
286: tkqRun (100);
287: System.out.println ();
288:
289: System.out.println ("test 5");
290: for (int i = 0; i < 100; i++) {
291: tkqAdd (tickers[i], i);
292: }
293: for (int i = 1; i < 100; i += 2) {
294: tkqRemove (tickers[i]);
295: }
296: tkqRun (100);
297: System.out.println ();
298:
299: {
300: System.out.println ("test 6");
301: int t = 0;
302: for (int i = 0; i < 50; i++) {
303: tkqAdd (tickers[i], t++);
304: }
305: for (int j = 0; j < 5; j++) {
306: for (int i = 0; i < 50; i++) {
307: tkqAdd (tickers[50 + i], t++);
308: }
309: tkqRun (t - 50 - 1);
310: System.out.println ();
311: for (int i = 0; i < 50; i++) {
312: tkqAdd (tickers[i], t++);
313: }
314: tkqRun (t - 50 - 1);
315: System.out.println ();
316: }
317: }
318: }
319:
320:
321: }
322:
323:
324: