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
40 ByteBuffer get(int size) {
41 if (buf == null) {
42 return newBuffer(size);
43 } else if (buf.capacity() < size) {
44 return newBuffer(size);
45 } else if (buf.capacity() * percentual / 100 > size) {
46 if (++exceedCount == maxExceedCount) {
47 return newBuffer(size);
48 } else {
49 buf.clear();
50 }
51 } else {
52 exceedCount = 0;
53 buf.clear();
54 }
55 return buf;
56 }
57
58 private ByteBuffer newBuffer(int size) {
59 if (buf != null) {
60 exceedCount = 0;
61 ByteBufferUtil.destroy(buf);
62 }
63 buf = ByteBuffer.allocateDirect(normalizeCapacity(size));
64 return buf;
65 }
66
67 private static int normalizeCapacity(int capacity) {
68
69 int q = capacity >>> 10;
70 int r = capacity & 1023;
71 if (r != 0) {
72 q ++;
73 }
74 return q << 10;
75 }
76
77 public void releaseExternalResources() {
78 if (buf != null) {
79 ByteBufferUtil.destroy(buf);
80 }
81 }
82 }