/* * Copyright 2014-2017 Real Logic Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.aeron; import org.junit.Test; import org.agrona.concurrent.UnsafeBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertThat; import static io.aeron.BufferBuilder.MIN_ALLOCATED_CAPACITY; public class BufferBuilderTest { private final BufferBuilder bufferBuilder = new BufferBuilder(); @Test public void shouldInitialiseToDefaultValues() { assertThat(bufferBuilder.capacity(), is(0)); assertThat(bufferBuilder.buffer().capacity(), is(0)); assertThat(bufferBuilder.limit(), is(0)); } @Test public void shouldGrowDirectBuffer() { final BufferBuilder builder = new BufferBuilder(0, true); assertThat(builder.capacity(), is(0)); assertThat(builder.buffer().capacity(), is(0)); assertThat(builder.limit(), is(0)); final int appendedLength = 10; final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[appendedLength]); builder.append(srcBuffer, 0, srcBuffer.capacity()); assertThat(builder.capacity(), is(MIN_ALLOCATED_CAPACITY)); assertThat(builder.buffer().capacity(), is(MIN_ALLOCATED_CAPACITY)); assertThat(builder.limit(), is(appendedLength)); } @Test public void shouldAppendNothingForZeroLength() { final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[MIN_ALLOCATED_CAPACITY]); bufferBuilder.append(srcBuffer, 0, 0); assertThat(bufferBuilder.limit(), is(0)); } @Test public void shouldGrowToMultipleOfInitialCapacity() { final int srcCapacity = MIN_ALLOCATED_CAPACITY * 5; final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[srcCapacity]); bufferBuilder.append(srcBuffer, 0, srcBuffer.capacity()); assertThat(bufferBuilder.limit(), is(srcCapacity)); assertThat(bufferBuilder.capacity(), greaterThanOrEqualTo(srcCapacity)); } @Test public void shouldAppendThenReset() { final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[MIN_ALLOCATED_CAPACITY]); bufferBuilder.append(srcBuffer, 0, srcBuffer.capacity()); assertThat(bufferBuilder.limit(), is(srcBuffer.capacity())); bufferBuilder.reset(); assertThat(bufferBuilder.limit(), is(0)); } @Test public void shouldAppendOneBufferWithoutResizing() { final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[MIN_ALLOCATED_CAPACITY]); final byte[] bytes = "Hello World".getBytes(StandardCharsets.UTF_8); srcBuffer.putBytes(0, bytes, 0, bytes.length); bufferBuilder.append(srcBuffer, 0, bytes.length); final byte[] temp = new byte[bytes.length]; bufferBuilder.buffer().getBytes(0, temp, 0, bytes.length); assertThat(bufferBuilder.limit(), is(bytes.length)); assertThat(bufferBuilder.capacity(), is(MIN_ALLOCATED_CAPACITY)); assertArrayEquals(temp, bytes); } @Test public void shouldAppendTwoBuffersWithoutResizing() { final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[MIN_ALLOCATED_CAPACITY]); final byte[] bytes = "1111111122222222".getBytes(StandardCharsets.UTF_8); srcBuffer.putBytes(0, bytes, 0, bytes.length); bufferBuilder.append(srcBuffer, 0, bytes.length / 2); bufferBuilder.append(srcBuffer, bytes.length / 2, bytes.length / 2); final byte[] temp = new byte[bytes.length]; bufferBuilder.buffer().getBytes(0, temp, 0, bytes.length); assertThat(bufferBuilder.limit(), is(bytes.length)); assertThat(bufferBuilder.capacity(), is(MIN_ALLOCATED_CAPACITY)); assertArrayEquals(temp, bytes); } @Test public void shouldFillBufferWithoutResizing() { final int bufferLength = 128; final byte[] buffer = new byte[bufferLength]; Arrays.fill(buffer, (byte)7); final UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); final BufferBuilder bufferBuilder = new BufferBuilder(bufferLength); bufferBuilder.append(srcBuffer, 0, bufferLength); final byte[] temp = new byte[bufferLength]; bufferBuilder.buffer().getBytes(0, temp, 0, bufferLength); assertThat(bufferBuilder.limit(), is(bufferLength)); assertThat(bufferBuilder.capacity(), is(bufferLength)); assertArrayEquals(temp, buffer); } @Test public void shouldResizeWhenBufferJustDoesNotFit() { final int bufferLength = 128; final byte[] buffer = new byte[bufferLength + 1]; Arrays.fill(buffer, (byte)7); final UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); final BufferBuilder bufferBuilder = new BufferBuilder(bufferLength); bufferBuilder.append(srcBuffer, 0, buffer.length); final byte[] temp = new byte[buffer.length]; bufferBuilder.buffer().getBytes(0, temp, 0, buffer.length); assertThat(bufferBuilder.limit(), is(buffer.length)); assertThat(bufferBuilder.capacity(), greaterThan(bufferLength)); assertArrayEquals(temp, buffer); } @Test public void shouldAppendTwoBuffersAndResize() { final int bufferLength = 128; final byte[] buffer = new byte[bufferLength]; final int firstLength = buffer.length / 4; final int secondLength = buffer.length / 2; Arrays.fill(buffer, 0, firstLength + secondLength, (byte)7); final UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); final BufferBuilder bufferBuilder = new BufferBuilder(bufferLength / 2); bufferBuilder.append(srcBuffer, 0, firstLength); bufferBuilder.append(srcBuffer, firstLength, secondLength); final byte[] temp = new byte[buffer.length]; bufferBuilder.buffer().getBytes(0, temp, 0, secondLength + firstLength); assertThat(bufferBuilder.limit(), is(firstLength + secondLength)); assertThat(bufferBuilder.capacity(), greaterThanOrEqualTo(firstLength + secondLength)); assertArrayEquals(temp, buffer); } @Test public void shouldCompactBufferToLowerLimit() { final int bufferLength = MIN_ALLOCATED_CAPACITY / 2; final byte[] buffer = new byte[bufferLength]; final UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); final BufferBuilder bufferBuilder = new BufferBuilder(); final int bufferCount = 5; for (int i = 0; i < bufferCount; i++) { bufferBuilder.append(srcBuffer, 0, buffer.length); } final int expectedLimit = buffer.length * bufferCount; assertThat(bufferBuilder.limit(), is(expectedLimit)); final int expandedCapacity = bufferBuilder.capacity(); assertThat(expandedCapacity, greaterThan(expectedLimit)); bufferBuilder.reset(); bufferBuilder.append(srcBuffer, 0, buffer.length); bufferBuilder.append(srcBuffer, 0, buffer.length); bufferBuilder.append(srcBuffer, 0, buffer.length); bufferBuilder.compact(); assertThat(bufferBuilder.limit(), is(buffer.length * 3)); assertThat(bufferBuilder.capacity(), lessThan(expandedCapacity)); } }