com.yahoo.pulsar.common.compression.Crc32cChecksumTest.java Source code

Java tutorial

Introduction

Here is the source code for com.yahoo.pulsar.common.compression.Crc32cChecksumTest.java

Source

/**
 * Copyright 2016 Yahoo Inc.
 *
 * 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 com.yahoo.pulsar.common.compression;

import static com.scurrilous.circe.params.CrcParameters.CRC32C;
import static org.testng.Assert.assertEquals;

import org.testng.annotations.Test;

import com.scurrilous.circe.IncrementalIntHash;
import com.scurrilous.circe.crc.StandardCrcProvider;
import com.yahoo.pulsar.checksum.utils.Crc32cChecksum;
import com.yahoo.pulsar.checksum.utils.Crc32cSse42Provider;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;

public class Crc32cChecksumTest {

    private static final byte[] inputBytes = "data".getBytes();
    private static final int expectedChecksum = 0xaed87dd1;

    private static final IncrementalIntHash SOFTWARE_CRC32C_HASH = new StandardCrcProvider()
            .getIncrementalInt(CRC32C);
    private static final IncrementalIntHash HARDWARE_CRC32C_HASH;

    static {
        IncrementalIntHash hardwareCRC32C = null;
        try {
            hardwareCRC32C = new Crc32cSse42Provider().getIncrementalInt(CRC32C);
        } catch (Throwable t) {
            // Native CRC32C Not supported, skip tests
            hardwareCRC32C = null;
        }

        HARDWARE_CRC32C_HASH = hardwareCRC32C;
    }

    @Test
    public void testCrc32c() {
        ByteBuf payload = Unpooled.wrappedBuffer(inputBytes);
        int checksum = Crc32cChecksum.computeChecksum(payload);
        payload.release();
        assertEquals(expectedChecksum, checksum);
    }

    @Test
    public void testCrc32cHardware() {
        if (HARDWARE_CRC32C_HASH == null) {
            return;
        }

        ByteBuf payload = Unpooled.wrappedBuffer(inputBytes);

        // compute checksum using sse4.2 hw instruction
        int hw = HARDWARE_CRC32C_HASH.calculate(payload.array(), payload.arrayOffset() + payload.readerIndex(),
                payload.readableBytes());
        assertEquals(hw, expectedChecksum);
    }

    @Test
    public void testCrc32cSoftware() {
        ByteBuf payload = Unpooled.wrappedBuffer(inputBytes);

        // compute checksum using sw algo
        int sw = SOFTWARE_CRC32C_HASH.calculate(payload.array(), payload.arrayOffset() + payload.readerIndex(),
                payload.readableBytes());
        assertEquals(sw, expectedChecksum);
    }

    @Test
    public void testCrc32cDirectMemoryHardware() {
        if (HARDWARE_CRC32C_HASH == null) {
            return;
        }

        ByteBuf payload = ByteBufAllocator.DEFAULT.directBuffer(inputBytes.length);
        payload.writeBytes(inputBytes);

        // read directly from memory address
        int checksum = HARDWARE_CRC32C_HASH.calculate(payload.memoryAddress(), payload.readableBytes());

        payload.release();
        assertEquals(checksum, expectedChecksum);
    }

    @Test
    public void testCrc32cIncremental() {
        if (HARDWARE_CRC32C_HASH == null) {
            return;
        }

        String data = "data-abcd-data-123-$%#";

        for (int i = 0; i < 20; i++) {
            String doubleData = data + data;

            int doubleDataCrcHW = HARDWARE_CRC32C_HASH.calculate(doubleData.getBytes());
            int data1CrcHW = HARDWARE_CRC32C_HASH.calculate(data.getBytes());
            int data2CrcHW = HARDWARE_CRC32C_HASH.resume(data1CrcHW, data.getBytes());
            assertEquals(doubleDataCrcHW, data2CrcHW);

            int doubleDataCrcSW = SOFTWARE_CRC32C_HASH.calculate(doubleData.getBytes());
            int data1CrcSW = SOFTWARE_CRC32C_HASH.calculate(data.getBytes());
            int data2CrcSW = SOFTWARE_CRC32C_HASH.resume(data1CrcSW, data.getBytes());
            assertEquals(doubleDataCrcSW, data2CrcSW);

            assertEquals(doubleDataCrcHW, doubleDataCrcSW);

            data += data;
        }
    }

    @Test
    public void testCrc32cIncrementalUsingProvider() {

        final byte[] data = "data".getBytes();
        final byte[] doubleData = "datadata".getBytes();
        ByteBuf payload = Unpooled.wrappedBuffer(data);
        ByteBuf doublePayload = Unpooled.wrappedBuffer(doubleData);

        int expectedChecksum = Crc32cChecksum.computeChecksum(doublePayload);

        // (1) heap-memory
        int checksum = Crc32cChecksum.computeChecksum(payload);
        int incrementalChecksum = Crc32cChecksum.resumeChecksum(checksum, payload);
        assertEquals(expectedChecksum, incrementalChecksum);
        payload.release();
        doublePayload.release();

        // (2) direct-memory
        payload = ByteBufAllocator.DEFAULT.directBuffer(data.length);
        payload.writeBytes(data);
        checksum = Crc32cChecksum.computeChecksum(payload);
        incrementalChecksum = Crc32cChecksum.resumeChecksum(checksum, payload);
        assertEquals(expectedChecksum, incrementalChecksum);
        payload.release();

    }

}