FastByteBuffer(from jodd)


import java.util.Arrays;

/**
 * Faster {@code byte} buffer. Works faster for smaller buffer sizes.
 * After eg. length of 2048 the performances are practically the same.
 */
public class FastByteBuffer {

    private byte[] buffer;
    private int offset;
    
    /**
     * Creates a new {@code byte} buffer. The buffer capacity is
     * initially 64 bytes, though its size increases if necessary.
     */
    public FastByteBuffer() {
        this.buffer = new byte[64];
    }

    /**
     * Creates a new {@code byte} buffer, with a buffer capacity of
     * the specified size.
     *
     * @param size the initial size.
     * @throws IllegalArgumentException if size is negative.
     */
    public FastByteBuffer(final int size) {
        this.buffer = new byte[size];
    }

    /**
     * Grows the buffer.
     */
    private void grow(final int minCapacity) {
        final int oldCapacity = buffer.length;
        int newCapacity = oldCapacity << 1;
        if (newCapacity - minCapacity < 0) {
            // special case, min capacity is larger then a grow
            newCapacity = minCapacity + 512;
        }
        buffer = Arrays.copyOf(buffer, newCapacity);
    }

    /**
     * Appends single {@code byte} to buffer.
     */
    public void append(final byte element) {
        if (offset - buffer.length >= 0) {
            grow(offset);
        }

        buffer[offset++] = element;
    }

    /**
     * Appends {@code byte} array to buffer.
     */
    public FastByteBuffer append(final byte[] array, final int off, final int len) {
        if (offset + len - buffer.length > 0) {
            grow(offset + len);
        }

        System.arraycopy(array, off, buffer, offset, len);
        offset += len;
        return this;
    }

    /**
     * Appends {@code byte} array to buffer.
     */
    public FastByteBuffer append(final byte[] array) {
        return append(array, 0, array.length);
    }

    /**
     * Appends another fast buffer to this one.
     */
    public FastByteBuffer append(final FastByteBuffer buff) {
        if (buff.offset == 0) {
            return this;
        }
        append(buff.buffer, 0, buff.offset);
        return this;
    }

    /**
     * Returns buffer size.
     */
    public int size() {
        return offset;
    }

    /**
     * Tests if this buffer has no elements.
     */
    public boolean isEmpty() {
        return offset == 0;
    }

    /**
     * Resets the buffer content.
     */
    public void clear() {
        offset = 0;
    }

    /**
     * Creates {@code byte} array from buffered content.
     */
    public byte[] toArray() {
        return Arrays.copyOf(buffer, offset);
    }

    /**
     * Creates {@code byte} subarray from buffered content.
     */
    public byte[] toArray(final int start, final int len) {
        final byte[] array = new byte[len];

        if (len == 0) {
            return array;
        }

        System.arraycopy(buffer, start, array, 0, len);

        return array;
    }

    /**
     * Returns {@code byte} element at given index.
     */
    public byte get(final int index) {
        if (index >= offset) {
            throw new IndexOutOfBoundsException();
        }
        return buffer[index];
    }

}


import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

class FastByteBufferTest extends FastBufferTestBase {

    @Test
    void testAppend() {
        FastByteBuffer buff = new FastByteBuffer(3);

        buff.append(buff);
        buff.append((byte)173);
        buff.append(array((byte)8,(byte)98));

        assertArrayEquals(array((byte)173, (byte)8, (byte)98), buff.toArray());

        buff.append(buff);

        assertArrayEquals(array((byte)173, (byte)8, (byte)98, (byte)173, (byte)8, (byte)98), buff.toArray());

        buff.append(array((byte)173, (byte)5, (byte)3), 1, 1);

        assertArrayEquals(array((byte)173, (byte)8, (byte)98, (byte)173, (byte)8, (byte)98, (byte)5), buff.toArray());

        FastByteBuffer buff2 = new FastByteBuffer(3);
        buff2.append(buff);

        assertEquals(7, buff2.toArray().length);
    }

    @Test
    void testClear() {
        FastByteBuffer buff = new FastByteBuffer();

        assertTrue(buff.isEmpty());

        buff.append((byte)1);

        assertFalse(buff.isEmpty());

        buff.clear();

        assertTrue(buff.isEmpty());

        try {
            buff.get(0);
            fail("error");
        } catch (IndexOutOfBoundsException ignore) {
        }

        byte[] arr = buff.toArray();

        assertEquals(0, arr.length);
    }

    @Test
    void testToArray() {
        final FastByteBuffer buff = new FastByteBuffer();

        byte sum = 0;

        for (int j = 0; j < COUNT; j++) {
            for (int i = 1; i <= SIZE; i++) {
                buff.append((byte)i);
                sum += i;
            }
        }

        buff.append((byte)173);
        sum += 173;

        byte[] array = buff.toArray();
        byte sum2 = 0;
        for (byte l : array) {
            sum2 += l;
        }

        assertEquals(sum, sum2);


        array = buff.toArray(1, buff.size() - 2);
        sum2 = 0;
        for (byte l : array) {
            sum2 += l;
        }

        assertEquals(sum - (byte)1 - (byte)173, sum2);
    }

    @Test
    void testToSubArray() {
        FastByteBuffer buff = new FastByteBuffer();

        int total = SIZE + (SIZE/2);

        for (int i = 1; i <= total; i++) {
            buff.append((byte)i);
        }

        byte[] array = buff.toArray(SIZE + 1, total - SIZE  - 1);

        assertEquals(total - SIZE - 1, array.length);
        assertEquals((byte)(SIZE + 2), array[0]);
    }

    @Test
    void testBig() {
        List l = new ArrayList<>();
        FastByteBuffer fbf = new FastByteBuffer();

        Random rnd = new Random();
        for (int i = 0; i < 100_000; i++) {
            int n = rnd.nextInt();
            l.add((byte)n);
            fbf.append((byte)n);
        }

        for (int i = 0; i < l.size(); i++) {
            assertEquals(l.get(i).byteValue(), fbf.get(i));
        }
    }


    protected byte[] array(byte... arr) {
        return arr;
    }

}


你可能感兴趣的:(FastByteBuffer(from jodd))