1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.buffer;
18
19 import io.netty.util.ResourceLeakDetector;
20 import io.netty.util.ResourceLeakTracker;
21 import io.netty.util.internal.PlatformDependent;
22 import io.netty.util.internal.StringUtil;
23
24
25
26
27 public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
28 static final int DEFAULT_INITIAL_CAPACITY = 256;
29 static final int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE;
30 static final int DEFAULT_MAX_COMPONENTS = 16;
31 static final int CALCULATE_THRESHOLD = 1048576 * 4;
32
33 static {
34 ResourceLeakDetector.addExclusions(AbstractByteBufAllocator.class, "toLeakAwareBuffer");
35 }
36
37 protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) {
38 ResourceLeakTracker<ByteBuf> leak;
39 switch (ResourceLeakDetector.getLevel()) {
40 case SIMPLE:
41 leak = AbstractByteBuf.leakDetector.track(buf);
42 if (leak != null) {
43 buf = new SimpleLeakAwareByteBuf(buf, leak);
44 }
45 break;
46 case ADVANCED:
47 case PARANOID:
48 leak = AbstractByteBuf.leakDetector.track(buf);
49 if (leak != null) {
50 buf = new AdvancedLeakAwareByteBuf(buf, leak);
51 }
52 break;
53 }
54 return buf;
55 }
56
57 protected static CompositeByteBuf toLeakAwareBuffer(CompositeByteBuf buf) {
58 ResourceLeakTracker<ByteBuf> leak;
59 switch (ResourceLeakDetector.getLevel()) {
60 case SIMPLE:
61 leak = AbstractByteBuf.leakDetector.track(buf);
62 if (leak != null) {
63 buf = new SimpleLeakAwareCompositeByteBuf(buf, leak);
64 }
65 break;
66 case ADVANCED:
67 case PARANOID:
68 leak = AbstractByteBuf.leakDetector.track(buf);
69 if (leak != null) {
70 buf = new AdvancedLeakAwareCompositeByteBuf(buf, leak);
71 }
72 break;
73 default:
74 break;
75 }
76 return buf;
77 }
78
79 private final boolean directByDefault;
80 private final ByteBuf emptyBuf;
81
82
83
84
85 protected AbstractByteBufAllocator() {
86 this(false);
87 }
88
89
90
91
92
93
94
95 protected AbstractByteBufAllocator(boolean preferDirect) {
96 directByDefault = preferDirect && PlatformDependent.hasUnsafe();
97 emptyBuf = new EmptyByteBuf(this);
98 }
99
100 @Override
101 public ByteBuf buffer() {
102 if (directByDefault) {
103 return directBuffer();
104 }
105 return heapBuffer();
106 }
107
108 @Override
109 public ByteBuf buffer(int initialCapacity) {
110 if (directByDefault) {
111 return directBuffer(initialCapacity);
112 }
113 return heapBuffer(initialCapacity);
114 }
115
116 @Override
117 public ByteBuf buffer(int initialCapacity, int maxCapacity) {
118 if (directByDefault) {
119 return directBuffer(initialCapacity, maxCapacity);
120 }
121 return heapBuffer(initialCapacity, maxCapacity);
122 }
123
124 @Override
125 public ByteBuf ioBuffer() {
126 if (PlatformDependent.hasUnsafe()) {
127 return directBuffer(DEFAULT_INITIAL_CAPACITY);
128 }
129 return heapBuffer(DEFAULT_INITIAL_CAPACITY);
130 }
131
132 @Override
133 public ByteBuf ioBuffer(int initialCapacity) {
134 if (PlatformDependent.hasUnsafe()) {
135 return directBuffer(initialCapacity);
136 }
137 return heapBuffer(initialCapacity);
138 }
139
140 @Override
141 public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) {
142 if (PlatformDependent.hasUnsafe()) {
143 return directBuffer(initialCapacity, maxCapacity);
144 }
145 return heapBuffer(initialCapacity, maxCapacity);
146 }
147
148 @Override
149 public ByteBuf heapBuffer() {
150 return heapBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
151 }
152
153 @Override
154 public ByteBuf heapBuffer(int initialCapacity) {
155 return heapBuffer(initialCapacity, DEFAULT_MAX_CAPACITY);
156 }
157
158 @Override
159 public ByteBuf heapBuffer(int initialCapacity, int maxCapacity) {
160 if (initialCapacity == 0 && maxCapacity == 0) {
161 return emptyBuf;
162 }
163 validate(initialCapacity, maxCapacity);
164 return newHeapBuffer(initialCapacity, maxCapacity);
165 }
166
167 @Override
168 public ByteBuf directBuffer() {
169 return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
170 }
171
172 @Override
173 public ByteBuf directBuffer(int initialCapacity) {
174 return directBuffer(initialCapacity, DEFAULT_MAX_CAPACITY);
175 }
176
177 @Override
178 public ByteBuf directBuffer(int initialCapacity, int maxCapacity) {
179 if (initialCapacity == 0 && maxCapacity == 0) {
180 return emptyBuf;
181 }
182 validate(initialCapacity, maxCapacity);
183 return newDirectBuffer(initialCapacity, maxCapacity);
184 }
185
186 @Override
187 public CompositeByteBuf compositeBuffer() {
188 if (directByDefault) {
189 return compositeDirectBuffer();
190 }
191 return compositeHeapBuffer();
192 }
193
194 @Override
195 public CompositeByteBuf compositeBuffer(int maxNumComponents) {
196 if (directByDefault) {
197 return compositeDirectBuffer(maxNumComponents);
198 }
199 return compositeHeapBuffer(maxNumComponents);
200 }
201
202 @Override
203 public CompositeByteBuf compositeHeapBuffer() {
204 return compositeHeapBuffer(DEFAULT_MAX_COMPONENTS);
205 }
206
207 @Override
208 public CompositeByteBuf compositeHeapBuffer(int maxNumComponents) {
209 return toLeakAwareBuffer(new CompositeByteBuf(this, false, maxNumComponents));
210 }
211
212 @Override
213 public CompositeByteBuf compositeDirectBuffer() {
214 return compositeDirectBuffer(DEFAULT_MAX_COMPONENTS);
215 }
216
217 @Override
218 public CompositeByteBuf compositeDirectBuffer(int maxNumComponents) {
219 return toLeakAwareBuffer(new CompositeByteBuf(this, true, maxNumComponents));
220 }
221
222 private static void validate(int initialCapacity, int maxCapacity) {
223 if (initialCapacity < 0) {
224 throw new IllegalArgumentException("initialCapacity: " + initialCapacity + " (expected: 0+)");
225 }
226 if (initialCapacity > maxCapacity) {
227 throw new IllegalArgumentException(String.format(
228 "initialCapacity: %d (expected: not greater than maxCapacity(%d)",
229 initialCapacity, maxCapacity));
230 }
231 }
232
233
234
235
236 protected abstract ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity);
237
238
239
240
241 protected abstract ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity);
242
243 @Override
244 public String toString() {
245 return StringUtil.simpleClassName(this) + "(directByDefault: " + directByDefault + ')';
246 }
247 }