ByteQueue.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: public class ByteQueue {
16:
17: private static final class Block {
18: private volatile Block p = null;
19: private volatile Block n = null;
20:
21: private static final int s = 1 << 16;
22: private static final byte[] a = new byte[s];
23: private volatile long w = 0;
24: private volatile long r = w;
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36: private int clear () {
37: return skip (used ());
38: }
39:
40:
41:
42: private int read () {
43: return r != w ? a[(int) (r++) & (s - 1)] & 0xff : -1;
44: }
45:
46:
47:
48: private int read (byte[] array, int offset, int length) {
49: length = Math.min (length, (int) (w - r));
50: int offset0 = offset;
51: for (;;) {
52: int k = Math.min (length, s - ((int) r & (s - 1)));
53: if (k == 0) {
54: return offset - offset0;
55: }
56: System.arraycopy (a, (int) r & (s - 1),
57: array, offset,
58: k);
59: r += k;
60: offset += k;
61: length -= k;
62: }
63: }
64:
65:
66:
67: private int skip (int length) {
68: length = Math.min (length, (int) (w - r));
69: r += length;
70: return length;
71: }
72:
73:
74:
75: private int unused () {
76: return (int) (r + s - w);
77: }
78:
79:
80:
81: private int used () {
82: return (int) (w - r);
83: }
84:
85:
86:
87: private int write (int data) {
88: if (w == r + s) {
89: return 0;
90: }
91: a[(int) (w++) & (s - 1)] = (byte) data;
92: return 1;
93: }
94:
95:
96:
97: private int write (byte[] array, int offset, int length) {
98: length = Math.min (length, (int) (r + s - w));
99: int offset0 = offset;
100: for (;;) {
101: int k = Math.min (length, s - ((int) w & (s - 1)));
102: if (k == 0) {
103: return offset - offset0;
104: }
105: System.arraycopy (array, offset,
106: a, (int) w & (s - 1),
107: k);
108: w += k;
109: offset += k;
110: length -= k;
111: }
112: }
113:
114: }
115:
116: private volatile Block h = new Block ();
117: private volatile Block t = h;
118:
119: private static final int s = 0x7fffffff;
120: private volatile long w = 0;
121: private volatile long r = w;
122:
123:
124:
125:
126:
127:
128:
129:
130:
131: protected int clear () {
132: return skip (used ());
133: }
134:
135:
136:
137: protected int read () {
138: int data = h.read ();
139: if (data < 0) {
140: if (h == t) {
141: return data;
142: }
143: Block n = h.n;
144: n.p = null;
145: h.n = null;
146: h = n;
147: data = h.read ();
148: }
149: r++;
150: return data;
151: }
152:
153:
154:
155: protected int read (byte[] array, int offset, int length) {
156: if (length == 0) {
157: return 0;
158: }
159:
160: long r0 = r;
161: int k = h.read (array, offset, length);
162: r += k;
163: offset += k;
164: length -= k;
165: while (length != 0) {
166: if (h == t) {
167: return (int) (r - r0);
168: }
169: Block n = h.n;
170: n.p = null;
171: h.n = null;
172: h = n;
173: k = h.read (array, offset, length);
174: r += k;
175: offset += k;
176: length -= k;
177: }
178: return (int) (r - r0);
179: }
180:
181:
182:
183: protected int skip (int length) {
184: if (length == 0) {
185: return 0;
186: }
187:
188: long r0 = r;
189: int k = h.skip (length);
190: r += k;
191: length -= k;
192: while (length != 0) {
193: if (h == t) {
194: return (int) (r - r0);
195: }
196: Block n = h.n;
197: n.p = null;
198: h.n = null;
199: h = n;
200: k = h.skip (length);
201: r += k;
202: length -= k;
203: }
204: return (int) (r - r0);
205: }
206:
207:
208:
209: protected int unused () {
210: return (int) (r + s - w);
211: }
212:
213:
214:
215: protected int used () {
216: return (int) (w - r);
217: }
218:
219:
220:
221: protected int write (int data) {
222: if (w == r + s) {
223: return 0;
224: }
225: if (t.write (data) == 0) {
226: Block n = new Block ();
227: n.p = t;
228: t.n = n;
229: t = n;
230: t.write (data);
231: }
232: w++;
233: Thread wt = waitThread;
234: if (wt != null) {
235: wt.interrupt ();
236: }
237: return 1;
238: }
239:
240:
241:
242: protected int write (byte[] array, int offset, int length) {
243: if (length == 0) {
244: return 0;
245: }
246: length = Math.min (length, (int) (r + s - w));
247: long w0 = w;
248: int k = t.write (array, offset, length);
249: w += k;
250: offset += k;
251: length -= k;
252: while (length != 0) {
253: Block n = new Block ();
254: n.p = t;
255: t.n = n;
256: t = n;
257: k = t.write (array, offset, length);
258: w += k;
259: offset += k;
260: length -= k;
261: }
262: Thread wt = waitThread;
263: if (wt != null) {
264: wt.interrupt ();
265: }
266: return (int) (w - w0);
267: }
268:
269:
270: private volatile Thread waitThread = null;
271: private volatile int waitNumber;
272: private volatile int cancelNumber;
273:
274:
275:
276: protected void cancel () {
277: Thread wt = waitThread;
278: if (wt != null) {
279: cancelNumber = waitNumber;
280: wt.interrupt ();
281: }
282: }
283:
284:
285:
286:
287:
288:
289: protected int waitAndRead () {
290: int data = -1;
291: waitThread = Thread.currentThread ();
292: waitNumber++;
293: while (waitNumber != cancelNumber) {
294: data = read ();
295: if (0 <= data || waitNumber == cancelNumber) {
296: break;
297: }
298: try {
299:
300: Thread.sleep (Long.MAX_VALUE);
301:
302: } catch (InterruptedException ie) {
303: }
304: }
305: waitThread = null;
306: return data;
307: }
308:
309:
310:
311:
312:
313:
314: protected int waitAndRead (byte[] array, int offset, int length) {
315: if (length == 0) {
316: return 0;
317: }
318: int data = waitAndRead ();
319: if (data < 0) {
320: return -1;
321: }
322: array[offset] = (byte) data;
323: return 1 + read (array, offset + 1, Math.min (length - 1, used ()));
324: }
325:
326:
327: }