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.Recycler.EnhancedHandle;
20 import io.netty.util.internal.ObjectPool.Handle;
21
22 import java.nio.ByteBuffer;
23 import java.nio.ByteOrder;
24
25
26
27
28 abstract class AbstractPooledDerivedByteBuf extends AbstractReferenceCountedByteBuf {
29
30 private final EnhancedHandle<AbstractPooledDerivedByteBuf> recyclerHandle;
31 private AbstractByteBuf rootParent;
32
33
34
35
36
37
38 private ByteBuf parent;
39
40 @SuppressWarnings("unchecked")
41 AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf> recyclerHandle) {
42 super(0);
43 this.recyclerHandle = (EnhancedHandle<AbstractPooledDerivedByteBuf>) recyclerHandle;
44 }
45
46
47 final void parent(ByteBuf newParent) {
48 assert newParent instanceof SimpleLeakAwareByteBuf;
49 parent = newParent;
50 }
51
52 @Override
53 public final AbstractByteBuf unwrap() {
54 return rootParent;
55 }
56
57 final <U extends AbstractPooledDerivedByteBuf> U init(
58 AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex, int maxCapacity) {
59 wrapped.retain();
60 parent = wrapped;
61 rootParent = unwrapped;
62
63 try {
64 maxCapacity(maxCapacity);
65 setIndex0(readerIndex, writerIndex);
66 resetRefCnt();
67
68 @SuppressWarnings("unchecked")
69 final U castThis = (U) this;
70 wrapped = null;
71 return castThis;
72 } finally {
73 if (wrapped != null) {
74 parent = rootParent = null;
75 wrapped.release();
76 }
77 }
78 }
79
80 @Override
81 protected final void deallocate() {
82
83
84
85 ByteBuf parent = this.parent;
86 recyclerHandle.unguardedRecycle(this);
87 parent.release();
88 }
89
90 @Override
91 public final ByteBufAllocator alloc() {
92 return unwrap().alloc();
93 }
94
95 @Override
96 @Deprecated
97 public final ByteOrder order() {
98 return unwrap().order();
99 }
100
101 @Override
102 public boolean isReadOnly() {
103 return unwrap().isReadOnly();
104 }
105
106 @Override
107 public final boolean isDirect() {
108 return unwrap().isDirect();
109 }
110
111 @Override
112 public boolean hasArray() {
113 return unwrap().hasArray();
114 }
115
116 @Override
117 public byte[] array() {
118 return unwrap().array();
119 }
120
121 @Override
122 public boolean hasMemoryAddress() {
123 return unwrap().hasMemoryAddress();
124 }
125
126 @Override
127 public boolean isContiguous() {
128 return unwrap().isContiguous();
129 }
130
131 @Override
132 public final int nioBufferCount() {
133 return unwrap().nioBufferCount();
134 }
135
136 @Override
137 public final ByteBuffer internalNioBuffer(int index, int length) {
138 return nioBuffer(index, length);
139 }
140
141 @Override
142 public final ByteBuf retainedSlice() {
143 final int index = readerIndex();
144 return retainedSlice(index, writerIndex() - index);
145 }
146
147 @Override
148 public ByteBuf slice(int index, int length) {
149 ensureAccessible();
150
151 return new PooledNonRetainedSlicedByteBuf(this, unwrap(), index, length);
152 }
153
154 final ByteBuf duplicate0() {
155 ensureAccessible();
156
157 return new PooledNonRetainedDuplicateByteBuf(this, unwrap());
158 }
159
160 private static final class PooledNonRetainedDuplicateByteBuf extends UnpooledDuplicatedByteBuf {
161 private final ByteBuf referenceCountDelegate;
162
163 PooledNonRetainedDuplicateByteBuf(ByteBuf referenceCountDelegate, AbstractByteBuf buffer) {
164 super(buffer);
165 this.referenceCountDelegate = referenceCountDelegate;
166 }
167
168 @Override
169 boolean isAccessible0() {
170 return referenceCountDelegate.isAccessible();
171 }
172
173 @Override
174 int refCnt0() {
175 return referenceCountDelegate.refCnt();
176 }
177
178 @Override
179 ByteBuf retain0() {
180 referenceCountDelegate.retain();
181 return this;
182 }
183
184 @Override
185 ByteBuf retain0(int increment) {
186 referenceCountDelegate.retain(increment);
187 return this;
188 }
189
190 @Override
191 ByteBuf touch0() {
192 referenceCountDelegate.touch();
193 return this;
194 }
195
196 @Override
197 ByteBuf touch0(Object hint) {
198 referenceCountDelegate.touch(hint);
199 return this;
200 }
201
202 @Override
203 boolean release0() {
204 return referenceCountDelegate.release();
205 }
206
207 @Override
208 boolean release0(int decrement) {
209 return referenceCountDelegate.release(decrement);
210 }
211
212 @Override
213 public ByteBuf duplicate() {
214 ensureAccessible();
215 return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, this);
216 }
217
218 @Override
219 public ByteBuf retainedDuplicate() {
220 return PooledDuplicatedByteBuf.newInstance(unwrap(), this, readerIndex(), writerIndex());
221 }
222
223 @Override
224 public ByteBuf slice(int index, int length) {
225 checkIndex(index, length);
226 return new PooledNonRetainedSlicedByteBuf(referenceCountDelegate, unwrap(), index, length);
227 }
228
229 @Override
230 public ByteBuf retainedSlice() {
231
232 return retainedSlice(readerIndex(), capacity());
233 }
234
235 @Override
236 public ByteBuf retainedSlice(int index, int length) {
237 return PooledSlicedByteBuf.newInstance(unwrap(), this, index, length);
238 }
239 }
240
241 private static final class PooledNonRetainedSlicedByteBuf extends UnpooledSlicedByteBuf {
242 private final ByteBuf referenceCountDelegate;
243
244 PooledNonRetainedSlicedByteBuf(ByteBuf referenceCountDelegate,
245 AbstractByteBuf buffer, int index, int length) {
246 super(buffer, index, length);
247 this.referenceCountDelegate = referenceCountDelegate;
248 }
249
250 @Override
251 boolean isAccessible0() {
252 return referenceCountDelegate.isAccessible();
253 }
254
255 @Override
256 int refCnt0() {
257 return referenceCountDelegate.refCnt();
258 }
259
260 @Override
261 ByteBuf retain0() {
262 referenceCountDelegate.retain();
263 return this;
264 }
265
266 @Override
267 ByteBuf retain0(int increment) {
268 referenceCountDelegate.retain(increment);
269 return this;
270 }
271
272 @Override
273 ByteBuf touch0() {
274 referenceCountDelegate.touch();
275 return this;
276 }
277
278 @Override
279 ByteBuf touch0(Object hint) {
280 referenceCountDelegate.touch(hint);
281 return this;
282 }
283
284 @Override
285 boolean release0() {
286 return referenceCountDelegate.release();
287 }
288
289 @Override
290 boolean release0(int decrement) {
291 return referenceCountDelegate.release(decrement);
292 }
293
294 @Override
295 public ByteBuf duplicate() {
296 ensureAccessible();
297 return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, unwrap())
298 .setIndex(idx(readerIndex()), idx(writerIndex()));
299 }
300
301 @Override
302 public ByteBuf retainedDuplicate() {
303 return PooledDuplicatedByteBuf.newInstance(unwrap(), this, idx(readerIndex()), idx(writerIndex()));
304 }
305
306 @Override
307 public ByteBuf slice(int index, int length) {
308 checkIndex(index, length);
309 return new PooledNonRetainedSlicedByteBuf(referenceCountDelegate, unwrap(), idx(index), length);
310 }
311
312 @Override
313 public ByteBuf retainedSlice() {
314
315 return retainedSlice(0, capacity());
316 }
317
318 @Override
319 public ByteBuf retainedSlice(int index, int length) {
320 return PooledSlicedByteBuf.newInstance(unwrap(), this, idx(index), length);
321 }
322 }
323 }