1 /*
2  * Copyright 2012 The Netty Project
3  *
4  * The Netty Project licenses this file to you under the Apache License,
5  * version 2.0 (the "License"); you may not use this file except in compliance
6  * with the License. You may obtain a copy of the License at:
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  */
16 module hunt.net.buffer.UnpooledByteBufAllocator;
17 
18 import hunt.net.buffer.AbstractByteBufAllocator;
19 import hunt.net.buffer.ByteBuf;
20 import hunt.net.buffer.ByteBufAllocator;
21 import hunt.net.buffer.ByteBufUtil;
22 import hunt.net.buffer.CompositeByteBuf;
23 import hunt.net.buffer.UnpooledHeapByteBuf;
24 // import hunt.net.buffer.UnpooledUnsafeHeapByteBuf;
25 
26 
27 import hunt.Byte;
28 import hunt.io.ByteBuffer;
29 import hunt.Exceptions;
30 import hunt.stream.Common;
31 import hunt.net.Exceptions;
32 import hunt.util.StringBuilder;
33 
34 import std.conv;
35 import std.format;
36 import std.concurrency : initOnce;
37 
38 // import io.netty.util.internal.LongCounter;
39 // import io.netty.util.internal.PlatformDependent;
40 // import io.netty.util.internal.StringUtil;
41 
42 
43 /**
44  * Simplistic {@link ByteBufAllocator} implementation that does not pool anything.
45  */
46 final class UnpooledByteBufAllocator : AbstractByteBufAllocator { // ByteBufAllocatorMetricProvider
47 
48     // private final UnpooledByteBufAllocatorMetric metric = new UnpooledByteBufAllocatorMetric();
49     private bool disableLeakDetector;
50     private bool noCleaner;
51 
52     /**
53      * Default instance which uses leak-detection for direct buffers.
54      */
55     static UnpooledByteBufAllocator DEFAULT() {
56         __gshared UnpooledByteBufAllocator inst;
57         // new UnpooledByteBufAllocator(PlatformDependent.directBufferPreferred());
58         return initOnce!inst(new UnpooledByteBufAllocator(false));
59     }
60             
61 
62     /**
63      * Create a new instance which uses leak-detection for direct buffers.
64      *
65      * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than
66      *                     a heap buffer
67      */
68     this(bool preferDirect) {
69         this(preferDirect, false);
70     }
71 
72     /**
73      * Create a new instance
74      *
75      * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than
76      *                     a heap buffer
77      * @param disableLeakDetector {@code true} if the leak-detection should be disabled completely for this
78      *                            allocator. This can be useful if the user just want to depend on the GC to handle
79      *                            direct buffers when not explicit released.
80      */
81     this(bool preferDirect, bool disableLeakDetector) {
82         // this(preferDirect, disableLeakDetector, PlatformDependent.useDirectBufferNoCleaner());
83         this(preferDirect, disableLeakDetector, false);
84     }
85 
86     /**
87      * Create a new instance
88      *
89      * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than
90      *                     a heap buffer
91      * @param disableLeakDetector {@code true} if the leak-detection should be disabled completely for this
92      *                            allocator. This can be useful if the user just want to depend on the GC to handle
93      *                            direct buffers when not explicit released.
94      * @param tryNoCleaner {@code true} if we should try to use {@link PlatformDependent#allocateDirectNoCleaner(int)}
95      *                            to allocate direct memory.
96      */
97     this(bool preferDirect, bool disableLeakDetector, bool tryNoCleaner) {
98         super(preferDirect);
99         this.disableLeakDetector = disableLeakDetector;
100         // noCleaner = tryNoCleaner && PlatformDependent.hasUnsafe()
101         //         && PlatformDependent.hasDirectBufferNoCleanerConstructor();
102     }
103 
104     override
105     protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
106         // return PlatformDependent.hasUnsafe() ?
107         //         new InstrumentedUnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity) :
108         //         new InstrumentedUnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
109         return new InstrumentedUnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
110     }
111 
112     override
113     protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
114         ByteBuf buf;
115         implementationMissing(false);
116         return null;
117         // if (PlatformDependent.hasUnsafe()) {
118         //     buf = noCleaner ? new InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf(this, initialCapacity, maxCapacity) :
119         //             new InstrumentedUnpooledUnsafeDirectByteBuf(this, initialCapacity, maxCapacity);
120         // } else {
121         //     buf = new InstrumentedUnpooledDirectByteBuf(this, initialCapacity, maxCapacity);
122         // }
123         // return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
124     }
125 
126     override
127     CompositeByteBuf compositeHeapBuffer(int maxNumComponents) {
128         CompositeByteBuf buf = new CompositeByteBuf(this, false, maxNumComponents);
129         // return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
130         return buf;
131     }
132 
133     override
134     CompositeByteBuf compositeDirectBuffer(int maxNumComponents) {
135         CompositeByteBuf buf = new CompositeByteBuf(this, true, maxNumComponents);
136         // return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
137         return buf;
138     }
139 
140     // override
141     bool isDirectBufferPooled() {
142         return false;
143     }
144 
145     // override
146     // ByteBufAllocatorMetric metric() {
147     //     return metric;
148     // }
149 
150     void incrementDirect(int amount) {
151         // metric.directCounter.add(amount);
152     }
153 
154     void decrementDirect(int amount) {
155         // metric.directCounter.add(-amount);
156     }
157 
158     void incrementHeap(int amount) {
159         // metric.heapCounter.add(amount);
160     }
161 
162     void decrementHeap(int amount) {
163         // metric.heapCounter.add(-amount);
164     }
165 
166 }
167 
168 
169 
170 // private final class InstrumentedUnpooledUnsafeHeapByteBuf : UnpooledUnsafeHeapByteBuf {
171 //     this(UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
172 //         super(alloc, initialCapacity, maxCapacity);
173 //     }
174 
175 //     override
176 //     protected byte[] allocateArray(int initialCapacity) {
177 //         byte[] bytes = super.allocateArray(initialCapacity);
178 //         (cast(UnpooledByteBufAllocator) alloc()).incrementHeap(bytes.length);
179 //         return bytes;
180 //     }
181 
182 //     override
183 //     protected void freeArray(byte[] array) {
184 //         int length = cast(int)array.length;
185 //         super.freeArray(array);
186 //         (cast(UnpooledByteBufAllocator) alloc()).decrementHeap(length);
187 //     }
188 // }
189 
190 
191 private final class InstrumentedUnpooledHeapByteBuf : UnpooledHeapByteBuf {
192     this(UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
193         super(alloc, initialCapacity, maxCapacity);
194     }
195 
196     override
197     protected byte[] allocateArray(int initialCapacity) {
198         byte[] bytes = super.allocateArray(initialCapacity);
199         (cast(UnpooledByteBufAllocator) alloc()).incrementHeap(cast(int)bytes.length);
200         return bytes;
201     }
202 
203     override
204     protected void freeArray(byte[] array) {
205         int length = cast(int)array.length;
206         super.freeArray(array);
207         (cast(UnpooledByteBufAllocator) alloc()).decrementHeap(length);
208     }
209 }
210 
211 
212 // private final class InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf
213 //         : UnpooledUnsafeNoCleanerDirectByteBuf {
214 //     this(
215 //             UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
216 //         super(alloc, initialCapacity, maxCapacity);
217 //     }
218 
219 //     override
220 //     protected ByteBuffer allocateDirect(int initialCapacity) {
221 //         ByteBuffer buffer = super.allocateDirect(initialCapacity);
222 //         (cast(UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity());
223 //         return buffer;
224 //     }
225 
226 //     override
227 //     ByteBuffer reallocateDirect(ByteBuffer oldBuffer, int initialCapacity) {
228 //         int capacity = oldBuffer.capacity();
229 //         ByteBuffer buffer = super.reallocateDirect(oldBuffer, initialCapacity);
230 //         (cast(UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity() - capacity);
231 //         return buffer;
232 //     }
233 
234 //     override
235 //     protected void freeDirect(ByteBuffer buffer) {
236 //         int capacity = buffer.capacity();
237 //         super.freeDirect(buffer);
238 //         (cast(UnpooledByteBufAllocator) alloc()).decrementDirect(capacity);
239 //     }
240 // }
241 
242 // private final class InstrumentedUnpooledUnsafeDirectByteBuf : UnpooledUnsafeDirectByteBuf {
243 //     this(
244 //             UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
245 //         super(alloc, initialCapacity, maxCapacity);
246 //     }
247 
248 //     override
249 //     protected ByteBuffer allocateDirect(int initialCapacity) {
250 //         ByteBuffer buffer = super.allocateDirect(initialCapacity);
251 //         (cast(UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity());
252 //         return buffer;
253 //     }
254 
255 //     override
256 //     protected void freeDirect(ByteBuffer buffer) {
257 //         int capacity = buffer.capacity();
258 //         super.freeDirect(buffer);
259 //         (cast(UnpooledByteBufAllocator) alloc()).decrementDirect(capacity);
260 //     }
261 // }
262 
263 
264 // private final class InstrumentedUnpooledDirectByteBuf : UnpooledDirectByteBuf {
265 //     this(
266 //             UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
267 //         super(alloc, initialCapacity, maxCapacity);
268 //     }
269 
270 //     override
271 //     protected ByteBuffer allocateDirect(int initialCapacity) {
272 //         ByteBuffer buffer = super.allocateDirect(initialCapacity);
273 //         (cast(UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity());
274 //         return buffer;
275 //     }
276 
277 //     override
278 //     protected void freeDirect(ByteBuffer buffer) {
279 //         int capacity = buffer.capacity();
280 //         super.freeDirect(buffer);
281 //         (cast(UnpooledByteBufAllocator) alloc()).decrementDirect(capacity);
282 //     }
283 // }
284 
285 // private final class UnpooledByteBufAllocatorMetric : ByteBufAllocatorMetric {
286 //     final LongCounter directCounter = PlatformDependent.newLongCounter();
287 //     final LongCounter heapCounter = PlatformDependent.newLongCounter();
288 
289 //     override
290 //     long usedHeapMemory() {
291 //         return heapCounter.value();
292 //     }
293 
294 //     override
295 //     long usedDirectMemory() {
296 //         return directCounter.value();
297 //     }
298 
299 //     override
300 //     String toString() {
301 //         return StringUtil.simpleClassName(this) +
302 //                 "(usedHeapMemory: " + usedHeapMemory() + "; usedDirectMemory: " + usedDirectMemory() + ')';
303 //     }
304 // }