1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.channel;
17
18 import io.netty5.buffer.api.Buffer;
19 import io.netty5.buffer.api.BufferAllocator;
20
21 import java.util.AbstractMap;
22 import java.util.Map.Entry;
23 import java.util.function.Predicate;
24
25 import static io.netty5.util.internal.ObjectUtil.checkPositive;
26
27
28
29
30
31 public class DefaultMaxBytesRecvBufferAllocator implements MaxBytesRecvBufferAllocator {
32 private volatile int maxBytesPerRead;
33 private volatile int maxBytesPerIndividualRead;
34
35 private final class HandleImpl implements Handle {
36 private int individualReadMax;
37 private int bytesToRead;
38 private int lastBytesRead;
39 private int attemptBytesRead;
40 private final Predicate<Handle> defaultMaybeMoreSupplier = h -> attemptBytesRead == lastBytesRead;
41
42 @Override
43 public Buffer allocate(BufferAllocator alloc) {
44 return alloc.allocate(guess());
45 }
46
47 @Override
48 public int guess() {
49 return Math.min(individualReadMax, bytesToRead);
50 }
51
52 @Override
53 public void reset() {
54 bytesToRead = maxBytesPerRead();
55 individualReadMax = maxBytesPerIndividualRead();
56 }
57
58 @Override
59 public void incMessagesRead(int amt) {
60 }
61
62 @Override
63 public void lastBytesRead(int bytes) {
64 lastBytesRead = bytes;
65
66
67 bytesToRead -= bytes;
68 }
69
70 @Override
71 public int lastBytesRead() {
72 return lastBytesRead;
73 }
74
75 @Override
76 public boolean continueReading(boolean autoRead) {
77 return continueReading(autoRead, defaultMaybeMoreSupplier);
78 }
79
80 @Override
81 public boolean continueReading(boolean autoRead, Predicate<Handle> maybeMoreDataSupplier) {
82
83 return bytesToRead > 0 && maybeMoreDataSupplier.test(this);
84 }
85
86 @Override
87 public void readComplete() {
88 }
89
90 @Override
91 public void attemptedBytesRead(int bytes) {
92 attemptBytesRead = bytes;
93 }
94
95 @Override
96 public int attemptedBytesRead() {
97 return attemptBytesRead;
98 }
99 }
100
101 public DefaultMaxBytesRecvBufferAllocator() {
102 this(64 * 1024, 64 * 1024);
103 }
104
105 public DefaultMaxBytesRecvBufferAllocator(int maxBytesPerRead, int maxBytesPerIndividualRead) {
106 checkMaxBytesPerReadPair(maxBytesPerRead, maxBytesPerIndividualRead);
107 this.maxBytesPerRead = maxBytesPerRead;
108 this.maxBytesPerIndividualRead = maxBytesPerIndividualRead;
109 }
110
111 @Override
112 public Handle newHandle() {
113 return new HandleImpl();
114 }
115
116 @Override
117 public int maxBytesPerRead() {
118 return maxBytesPerRead;
119 }
120
121 @Override
122 public DefaultMaxBytesRecvBufferAllocator maxBytesPerRead(int maxBytesPerRead) {
123 checkPositive(maxBytesPerRead, "maxBytesPerRead");
124
125
126 synchronized (this) {
127 final int maxBytesPerIndividualRead = maxBytesPerIndividualRead();
128 if (maxBytesPerRead < maxBytesPerIndividualRead) {
129 throw new IllegalArgumentException(
130 "maxBytesPerRead cannot be less than " +
131 "maxBytesPerIndividualRead (" + maxBytesPerIndividualRead + "): " + maxBytesPerRead);
132 }
133
134 this.maxBytesPerRead = maxBytesPerRead;
135 }
136 return this;
137 }
138
139 @Override
140 public int maxBytesPerIndividualRead() {
141 return maxBytesPerIndividualRead;
142 }
143
144 @Override
145 public DefaultMaxBytesRecvBufferAllocator maxBytesPerIndividualRead(int maxBytesPerIndividualRead) {
146 checkPositive(maxBytesPerIndividualRead, "maxBytesPerIndividualRead");
147
148
149 synchronized (this) {
150 final int maxBytesPerRead = maxBytesPerRead();
151 if (maxBytesPerIndividualRead > maxBytesPerRead) {
152 throw new IllegalArgumentException(
153 "maxBytesPerIndividualRead cannot be greater than " +
154 "maxBytesPerRead (" + maxBytesPerRead + "): " + maxBytesPerIndividualRead);
155 }
156
157 this.maxBytesPerIndividualRead = maxBytesPerIndividualRead;
158 }
159 return this;
160 }
161
162 @Override
163 public synchronized Entry<Integer, Integer> maxBytesPerReadPair() {
164 return new AbstractMap.SimpleEntry<>(maxBytesPerRead, maxBytesPerIndividualRead);
165 }
166
167 private static void checkMaxBytesPerReadPair(int maxBytesPerRead, int maxBytesPerIndividualRead) {
168 checkPositive(maxBytesPerRead, "maxBytesPerRead");
169 checkPositive(maxBytesPerIndividualRead, "maxBytesPerIndividualRead");
170 if (maxBytesPerRead < maxBytesPerIndividualRead) {
171 throw new IllegalArgumentException(
172 "maxBytesPerRead cannot be less than " +
173 "maxBytesPerIndividualRead (" + maxBytesPerIndividualRead + "): " + maxBytesPerRead);
174 }
175 }
176
177 @Override
178 public DefaultMaxBytesRecvBufferAllocator maxBytesPerReadPair(int maxBytesPerRead,
179 int maxBytesPerIndividualRead) {
180 checkMaxBytesPerReadPair(maxBytesPerRead, maxBytesPerIndividualRead);
181
182
183 synchronized (this) {
184 this.maxBytesPerRead = maxBytesPerRead;
185 this.maxBytesPerIndividualRead = maxBytesPerIndividualRead;
186 }
187 return this;
188 }
189 }