1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.channel.socket.nio;
17
18 import org.jboss.netty.util.ExternalResourceReleasable;
19 import org.jboss.netty.util.internal.ByteBufferUtil;
20
21 import java.nio.ByteBuffer;
22
23 final class SocketReceiveBufferAllocator implements ExternalResourceReleasable {
24
25 private ByteBuffer buf;
26 private int exceedCount;
27 private final int maxExceedCount;
28 private final int percentual;
29
30 SocketReceiveBufferAllocator() {
31 this(16, 80);
32 }
33
34 SocketReceiveBufferAllocator(int maxExceedCount, int percentual) {
35 this.maxExceedCount = maxExceedCount;
36 this.percentual = percentual;
37 }
38
39 ByteBuffer get(int size) {
40 if (buf == null) {
41 return newBuffer(size);
42 }
43 if (buf.capacity() < size) {
44 return newBuffer(size);
45 }
46 if (buf.capacity() * percentual / 100 > size) {
47 if (++exceedCount == maxExceedCount) {
48 return newBuffer(size);
49 } else {
50 buf.clear();
51 }
52 } else {
53 exceedCount = 0;
54 buf.clear();
55 }
56 return buf;
57 }
58
59 private ByteBuffer newBuffer(int size) {
60 if (buf != null) {
61 exceedCount = 0;
62 ByteBufferUtil.destroy(buf);
63 }
64 buf = ByteBuffer.allocateDirect(normalizeCapacity(size));
65 return buf;
66 }
67
68 private static int normalizeCapacity(int capacity) {
69
70 int q = capacity >>> 10;
71 int r = capacity & 1023;
72 if (r != 0) {
73 q ++;
74 }
75 return q << 10;
76 }
77
78 public void releaseExternalResources() {
79 if (buf != null) {
80 ByteBufferUtil.destroy(buf);
81 }
82 }
83 }