001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.io.compress.zstd;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertTrue;
023
024import java.io.IOException;
025import java.nio.ByteBuffer;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.nio.ByteBuff;
028import org.apache.hadoop.hbase.nio.MultiByteBuff;
029import org.apache.hadoop.hbase.nio.SingleByteBuff;
030import org.apache.hadoop.hbase.testclassification.SmallTests;
031import org.apache.hadoop.hbase.util.Bytes;
032import org.junit.ClassRule;
033import org.junit.Test;
034import org.junit.experimental.categories.Category;
035
036@Category(SmallTests.class)
037public class TestZstdByteBuffDecompressor {
038
039  @ClassRule
040  public static final HBaseClassTestRule CLASS_RULE =
041    HBaseClassTestRule.forClass(TestZstdByteBuffDecompressor.class);
042
043  /*
044   * "HBase is fun to use and very fast" compressed with zstd, and then prepended with metadata as a
045   * BlockCompressorStream would. The phrase is split in three parts and put into the payload in
046   * this structure: (block 1: (chunk 1: HBase is), (chunk 2: fun to use)), (block 2: (chunk 1: and
047   * very fast))
048   */
049  private static final byte[] COMPRESSED_PAYLOAD =
050    Bytes.fromHex("000000130000001228b52ffd200949000048426173652069732"
051      + "00000001428b52ffd200b59000066756e20746f207573652"
052      + "00000000d0000001628b52ffd200d690000616e6420766572792066617374");
053
054  @Test
055  public void testCapabilities() {
056    ByteBuff emptySingleHeapBuff = new SingleByteBuff(ByteBuffer.allocate(0));
057    ByteBuff emptyMultiHeapBuff = new MultiByteBuff(ByteBuffer.allocate(0), ByteBuffer.allocate(0));
058    ByteBuff emptySingleDirectBuff = new SingleByteBuff(ByteBuffer.allocateDirect(0));
059    ByteBuff emptyMultiDirectBuff =
060      new MultiByteBuff(ByteBuffer.allocateDirect(0), ByteBuffer.allocateDirect(0));
061
062    try (ZstdByteBuffDecompressor decompressor = new ZstdByteBuffDecompressor(null)) {
063      assertTrue(decompressor.canDecompress(emptySingleHeapBuff, emptySingleHeapBuff));
064      assertTrue(decompressor.canDecompress(emptySingleDirectBuff, emptySingleDirectBuff));
065      assertTrue(decompressor.canDecompress(emptySingleHeapBuff, emptySingleDirectBuff));
066      assertTrue(decompressor.canDecompress(emptySingleDirectBuff, emptySingleHeapBuff));
067      assertFalse(decompressor.canDecompress(emptyMultiHeapBuff, emptyMultiHeapBuff));
068      assertFalse(decompressor.canDecompress(emptyMultiDirectBuff, emptyMultiDirectBuff));
069      assertFalse(decompressor.canDecompress(emptySingleHeapBuff, emptyMultiHeapBuff));
070      assertFalse(decompressor.canDecompress(emptySingleDirectBuff, emptyMultiDirectBuff));
071    }
072  }
073
074  @Test
075  public void testDecompressHeapToHeap() throws IOException {
076    try (ZstdByteBuffDecompressor decompressor = new ZstdByteBuffDecompressor(null)) {
077      ByteBuff output = new SingleByteBuff(ByteBuffer.allocate(64));
078      ByteBuff input = new SingleByteBuff(ByteBuffer.wrap(COMPRESSED_PAYLOAD));
079      int decompressedSize = decompressor.decompress(output, input, COMPRESSED_PAYLOAD.length);
080      assertEquals("HBase is fun to use and very fast",
081        Bytes.toString(output.toBytes(0, decompressedSize)));
082    }
083  }
084
085  @Test
086  public void testDecompressDirectToDirect() throws IOException {
087    try (ZstdByteBuffDecompressor decompressor = new ZstdByteBuffDecompressor(null)) {
088      ByteBuff output = new SingleByteBuff(ByteBuffer.allocateDirect(64));
089      ByteBuff input = new SingleByteBuff(ByteBuffer.allocateDirect(COMPRESSED_PAYLOAD.length));
090      input.put(COMPRESSED_PAYLOAD);
091      input.rewind();
092      int decompressedSize = decompressor.decompress(output, input, COMPRESSED_PAYLOAD.length);
093      assertEquals("HBase is fun to use and very fast",
094        Bytes.toString(output.toBytes(0, decompressedSize)));
095    }
096  }
097
098  @Test
099  public void testDecompressDirectToHeap() throws IOException {
100    try (ZstdByteBuffDecompressor decompressor = new ZstdByteBuffDecompressor(null)) {
101      ByteBuff output = new SingleByteBuff(ByteBuffer.allocate(64));
102      ByteBuff input = new SingleByteBuff(ByteBuffer.allocateDirect(COMPRESSED_PAYLOAD.length));
103      input.put(COMPRESSED_PAYLOAD);
104      input.rewind();
105      int decompressedSize = decompressor.decompress(output, input, COMPRESSED_PAYLOAD.length);
106      assertEquals("HBase is fun to use and very fast",
107        Bytes.toString(output.toBytes(0, decompressedSize)));
108    }
109  }
110
111  @Test
112  public void testDecompressHeapToDirect() throws IOException {
113    try (ZstdByteBuffDecompressor decompressor = new ZstdByteBuffDecompressor(null)) {
114      ByteBuff output = new SingleByteBuff(ByteBuffer.allocateDirect(64));
115      ByteBuff input = new SingleByteBuff(ByteBuffer.wrap(COMPRESSED_PAYLOAD));
116      int decompressedSize = decompressor.decompress(output, input, COMPRESSED_PAYLOAD.length);
117      assertEquals("HBase is fun to use and very fast",
118        Bytes.toString(output.toBytes(0, decompressedSize)));
119    }
120  }
121
122}