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 // }