2222import java .util .Arrays ;
2323import java .util .Random ;
2424
25+ import org .junit .BeforeClass ;
2526import org .junit .Test ;
2627
2728import io .netty .buffer .ByteBuf ;
2829import org .apache .cassandra .config .DatabaseDescriptor ;
30+ import org .assertj .core .api .Assertions ;
2931
3032import static org .junit .Assert .assertArrayEquals ;
3133import static org .junit .Assert .assertEquals ;
3234
3335public class BufferPoolAllocatorTest
3436{
35- @ Test
36- public void testAdoptedBufferContentAfterResize () {
37+
38+ @ BeforeClass
39+ public static void beforeClass ()
40+ {
3741 DatabaseDescriptor .clientInitialization ();
38- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (200 , 500 );
39- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
42+ // cache size hould be more than a macro chunk size for proper pool testing
43+ // if it is 0 or less than a macro chunk size we actually do not pool
44+ DatabaseDescriptor .getRawConfig ().networking_cache_size_in_mb = 128 ;
45+ }
4046
47+ @ Test
48+ public void testAdoptedBufferContentAfterResize () {
49+ ByteBuf buffer = allocateByteBuf (200 , 500 );
50+ int originalCapacity = buffer .capacity ();
4151 byte [] content = new byte [300 ];
4252
4353 Random rand = new Random ();
4454 rand .nextBytes (content );
4555
4656 buffer .writeBytes (Arrays .copyOfRange (content , 0 , 200 ));
47- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
57+ assertEquals (originalCapacity , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
4858
4959 buffer .writeBytes (Arrays .copyOfRange (content , 200 , 300 ));
60+ int increasedCapacity = buffer .capacity ();
61+ assertEquals (increasedCapacity , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
5062
5163 byte [] bufferContent = new byte [300 ];
5264
5365 BufferPoolAllocator .Wrapped wrapped = (BufferPoolAllocator .Wrapped ) buffer ;
5466 ByteBuffer adopted = wrapped .adopt ();
5567 adopted .get (bufferContent );
5668 assertArrayEquals (content , bufferContent );
57- assertEquals (500 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
69+ assertEquals (increasedCapacity , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
5870
5971 GlobalBufferPoolAllocator .instance .put (adopted );
60- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
72+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
6173 }
6274
6375 @ Test
6476 public void testAdoptedBufferContentBeforeResize () {
65- DatabaseDescriptor .clientInitialization ();
66- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (200 , 300 );
67- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
77+ ByteBuf buffer = allocateByteBuf (200 , 300 );
78+ int originalCapacity = buffer .capacity ();
6879
6980 byte [] content = new byte [200 ];
7081
7182 Random rand = new Random ();
7283 rand .nextBytes (content );
7384
7485 buffer .writeBytes (content );
75- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
86+ assertEquals (originalCapacity , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
7687
7788 byte [] bufferContent = new byte [200 ];
7889
@@ -82,115 +93,121 @@ public void testAdoptedBufferContentBeforeResize() {
8293 assertArrayEquals (content , bufferContent );
8394
8495 GlobalBufferPoolAllocator .instance .put (adopted );
85- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
96+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
8697 }
8798
8899 @ Test
89100 public void testPutPooledBufferBackIntoPool () {
90- DatabaseDescriptor .clientInitialization ();
91- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (200 , 500 );
92- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
101+ ByteBuf buffer = allocateByteBuf (200 , 500 );
93102 buffer .writeBytes (new byte [200 ]);
94103
95104 buffer .release ();
96- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
105+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
97106 }
98107
99108 @ Test
100109 public void testPutResizedBufferBackIntoPool () {
101- DatabaseDescriptor .clientInitialization ();
102- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (200 , 500 );
103- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
110+ ByteBuf buffer = allocateByteBuf (200 , 500 );
104111 buffer .writeBytes (new byte [500 ]);
105112
106113 buffer .release ();
107- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
114+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
108115 }
109116
110117 @ Test
111118 public void testBufferDefaultMaxCapacity ()
112119 {
113- DatabaseDescriptor .clientInitialization ();
114120 ByteBuf noMaxCapacity = GlobalBufferPoolAllocator .instance .buffer (100 );
115121 noMaxCapacity .writeBytes (new byte [100 ]);
116122 assertEquals (100 , noMaxCapacity .readableBytes ());
117123 noMaxCapacity .release ();
118- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
124+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
119125 }
120126
121127 @ Test
122128 public void testBufferWithMaxCapacity ()
123129 {
124- DatabaseDescriptor .clientInitialization ();
125- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (100 , 500 );
130+ ByteBuf buffer = allocateByteBuf (100 , 500 );
126131 buffer .writeBytes (new byte [500 ]);
127132 assertEquals (500 , buffer .readableBytes ());
128- assertEquals (500 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
133+ assertEquals (buffer . capacity () , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
129134 buffer .release ();
130- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
135+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
131136 }
132137
133138 @ Test
134139 public void testBufferContentAfterResize ()
135140 {
136- DatabaseDescriptor .clientInitialization ();
137- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (200 , 300 );
138- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
141+ ByteBuf buffer = allocateByteBuf (200 , 300 );
142+ int originalCapacity = buffer .capacity ();
139143
140144 byte [] content = new byte [300 ];
141-
142145 Random rand = new Random ();
143146 rand .nextBytes (content );
144147
145148 buffer .writeBytes (Arrays .copyOfRange (content , 0 , 200 ));
146- assertEquals (200 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
149+ assertEquals (originalCapacity , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
147150
148151 buffer .writeBytes (Arrays .copyOfRange (content , 200 , 300 ));
149152
150153 byte [] bufferContent = new byte [300 ];
151154 buffer .readBytes (bufferContent );
152155 assertArrayEquals (content , bufferContent );
153- assertEquals (300 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
156+ Assertions .assertThat (buffer .capacity ()).isGreaterThanOrEqualTo (300 );
157+ assertEquals (buffer .capacity (), GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
158+
154159 buffer .release ();
155- assertEquals (0 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
160+ ensureThatAllMemoryIsReturnedBackToBufferPool ();
161+
156162 }
157163
158164 @ Test (expected = IndexOutOfBoundsException .class )
159165 public void testBufferExceedMaxCapacity ()
160166 {
161- DatabaseDescriptor .clientInitialization ();
162- ByteBuf maxCapacity = GlobalBufferPoolAllocator .instance .buffer (100 , 200 );
167+ ByteBuf maxCapacity = allocateByteBuf (100 , 200 );
163168 try
164169 {
165170 maxCapacity .writeBytes (new byte [300 ]);
166171 } finally {
167172 maxCapacity .release ();
168- assertEquals ( 0 , GlobalBufferPoolAllocator . instance . usedSizeInBytes () );
173+ ensureThatAllMemoryIsReturnedBackToBufferPool ( );
169174 }
170175 }
171176
172177 @ Test
173178 public void testResizeBufferMultipleTimes ()
174179 {
175- DatabaseDescriptor .clientInitialization ();
176- ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (100 , 2000 );
180+ ByteBuf buffer = allocateByteBuf (100 , 2000 );
177181 buffer .writeBytes (new byte [200 ]);
178182 assertEquals (200 , buffer .readableBytes ());
179- assertEquals (256 , buffer .capacity ());
180- assertEquals (256 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
183+ assertEquals (buffer .capacity (), GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
181184
182185 buffer .writeBytes (new byte [100 ]);
183186 assertEquals (300 , buffer .readableBytes ());
184- assertEquals (512 , buffer .capacity ());
185- assertEquals (512 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
187+ assertEquals (buffer .capacity (), GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
186188
187189 buffer .writeBytes (new byte [300 ]);
188190 assertEquals (600 , buffer .readableBytes ());
189- assertEquals (1024 , buffer .capacity ());
190- assertEquals (1024 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
191+ assertEquals (buffer .capacity (), GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
191192
192193 buffer .release ();
193- assertEquals (0 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
194+ ensureThatAllMemoryIsReturnedBackToBufferPool ();
195+ }
196+
197+ private static ByteBuf allocateByteBuf (int initialCapacity , int maxCapacity )
198+ {
199+ ByteBuf buffer = GlobalBufferPoolAllocator .instance .buffer (initialCapacity , maxCapacity );
200+ int originalCapacity = buffer .capacity ();
201+
202+ // BufferPool can allocate more capacity than requested to avoid fragmentation
203+ Assertions .assertThat (originalCapacity ).isGreaterThanOrEqualTo (initialCapacity );
204+ assertEquals (originalCapacity , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
205+ return buffer ;
194206 }
195207
208+ private static void ensureThatAllMemoryIsReturnedBackToBufferPool ()
209+ {
210+ assertEquals (0 , GlobalBufferPoolAllocator .instance .usedSizeInBytes ());
211+ assertEquals (0 , GlobalBufferPoolAllocator .instance .overflowMemoryInBytes ());
212+ }
196213}
0 commit comments