1 package com.ctc.wstx.io;
2
3 /**
4 * This is a small utility class, whose main functionality is to allow
5 * simple reuse of raw byte/char buffers. It is usually used through
6 * <code>ThreadLocal</code> member of the owning class pointing to
7 * instance of this class through a <code>SoftReference</code>. The
8 * end result is a low-overhead GC-cleanable recycling: hopefully
9 * ideal for use by stream readers.
10 *<p>
11 * Regarding implementation: the key design goal is simplicity; and to
12 * that end, different types of buffers are handled separately. While
13 * code may look inelegant as a result (wouldn't it be neat to just
14 * have generic char[]/byte[] buffer accessors?), benefit is that
15 * no data structures are needed, just simple references. As long
16 * as usage pattern is well known (which it is, for stream readers)
17 * this should be highly optimal and robust implementation.
18 */
19 public final class BufferRecycler
20 {
21 private volatile char[] mSmallCBuffer = null; // temp buffers
22 private volatile char[] mMediumCBuffer = null; // text collector
23 private volatile char[] mFullCBuffer = null; // for actual parsing buffer
24
25 private volatile byte[] mFullBBuffer = null;
26
27 public BufferRecycler() { }
28
29 // // // Char buffers:
30
31 // // Small buffers, for temporary parsing
32
33 public synchronized char[] getSmallCBuffer(int minSize)
34 {
35 char[] result = mSmallCBuffer;
36 if (result != null && result.length >= minSize) {
37 mSmallCBuffer = null;
38 return result;
39 }
40 //System.err.println("DEBUG: Alloc CSmall: "+result);
41 return null;
42 }
43
44 public synchronized void returnSmallCBuffer(char[] buffer)
45 {
46 //System.err.println("DEBUG: Return CSmall ("+buffer.length+"): "+buffer);
47 mSmallCBuffer = buffer;
48 }
49
50 // // Medium buffers, for text output collection
51
52 public synchronized char[] getMediumCBuffer(int minSize)
53 {
54 char[] result = mMediumCBuffer;
55 if (result != null && result.length >= minSize) {
56 mMediumCBuffer = null;
57 return result;
58 }
59 //System.err.println("DEBUG: Alloc CMed: "+result);
60 return null;
61 }
62
63 public synchronized void returnMediumCBuffer(char[] buffer)
64 {
65 mMediumCBuffer = buffer;
66 //System.err.println("DEBUG: Return CMed ("+buffer.length+"): "+buffer);
67 }
68
69 // // Full buffers, for parser buffering
70
71 public synchronized char[] getFullCBuffer(int minSize)
72 {
73 char[] result = mFullCBuffer;
74 if (result != null && result.length >= minSize) {
75 mFullCBuffer = null;
76 return result;
77 }
78 //System.err.println("DEBUG: Alloc CFull: "+result);
79 return null;
80 }
81
82 public synchronized void returnFullCBuffer(char[] buffer)
83 {
84 mFullCBuffer = buffer;
85 //System.err.println("DEBUG: Return CFull ("+buffer.length+"): "+buffer);
86 }
87
88 // // // Byte buffers:
89
90 // // Full byte buffers, for byte->char conversion (Readers)
91
92 public synchronized byte[] getFullBBuffer(int minSize)
93 {
94 byte[] result = mFullBBuffer;
95 if (result != null && result.length >= minSize) {
96 mFullBBuffer = null;
97 return result;
98 }
99 //System.err.println("DEBUG: Alloc BFull: "+result);
100 return null;
101 }
102
103 public synchronized void returnFullBBuffer(byte[] buffer)
104 {
105 mFullBBuffer = buffer;
106 //System.err.println("DEBUG: Return BFull ("+buffer.length+"): "+buffer);
107 }
108 }
109