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; 019 020import static org.junit.jupiter.api.Assertions.assertTrue; 021 022import java.io.ByteArrayInputStream; 023import java.io.DataOutputStream; 024import java.nio.ByteBuffer; 025import java.util.ArrayList; 026import java.util.List; 027import org.apache.hadoop.hbase.ArrayBackedTag; 028import org.apache.hadoop.hbase.ByteBufferExtendedCell; 029import org.apache.hadoop.hbase.ByteBufferKeyValue; 030import org.apache.hadoop.hbase.Cell; 031import org.apache.hadoop.hbase.KeyValue; 032import org.apache.hadoop.hbase.Tag; 033import org.apache.hadoop.hbase.io.util.LRUDictionary; 034import org.apache.hadoop.hbase.nio.SingleByteBuff; 035import org.apache.hadoop.hbase.testclassification.MiscTests; 036import org.apache.hadoop.hbase.testclassification.SmallTests; 037import org.apache.hadoop.hbase.util.ByteBufferUtils; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.junit.jupiter.api.Test; 040 041@org.junit.jupiter.api.Tag(MiscTests.TAG) 042@org.junit.jupiter.api.Tag(SmallTests.TAG) 043public class TestTagCompressionContext { 044 045 private static final byte[] ROW = Bytes.toBytes("r1"); 046 private static final byte[] CF = Bytes.toBytes("f"); 047 private static final byte[] Q = Bytes.toBytes("q"); 048 private static final byte[] V = Bytes.toBytes("v"); 049 050 @Test 051 public void testCompressUncompressTags1() throws Exception { 052 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 053 TagCompressionContext context = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE); 054 KeyValue kv1 = createKVWithTags(2); 055 int tagsLength1 = kv1.getTagsLength(); 056 ByteBuffer ib = ByteBuffer.wrap(kv1.getTagsArray()); 057 context.compressTags(baos, ib, kv1.getTagsOffset(), tagsLength1); 058 KeyValue kv2 = createKVWithTags(3); 059 int tagsLength2 = kv2.getTagsLength(); 060 ib = ByteBuffer.wrap(kv2.getTagsArray()); 061 context.compressTags(baos, ib, kv2.getTagsOffset(), tagsLength2); 062 063 context.clear(); 064 065 byte[] dest = new byte[tagsLength1]; 066 ByteBuffer ob = ByteBuffer.wrap(baos.toByteArray()); 067 context.uncompressTags(new SingleByteBuff(ob), dest, 0, tagsLength1); 068 assertTrue( 069 Bytes.equals(kv1.getTagsArray(), kv1.getTagsOffset(), tagsLength1, dest, 0, tagsLength1)); 070 dest = new byte[tagsLength2]; 071 context.uncompressTags(new SingleByteBuff(ob), dest, 0, tagsLength2); 072 assertTrue( 073 Bytes.equals(kv2.getTagsArray(), kv2.getTagsOffset(), tagsLength2, dest, 0, tagsLength2)); 074 } 075 076 @Test 077 public void testCompressUncompressTagsWithOffheapKeyValue1() throws Exception { 078 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 079 DataOutputStream daos = new ByteBufferWriterDataOutputStream(baos); 080 TagCompressionContext context = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE); 081 ByteBufferExtendedCell kv1 = (ByteBufferExtendedCell) createOffheapKVWithTags(2); 082 int tagsLength1 = kv1.getTagsLength(); 083 context.compressTags(daos, kv1.getTagsByteBuffer(), kv1.getTagsPosition(), tagsLength1); 084 ByteBufferExtendedCell kv2 = (ByteBufferExtendedCell) createOffheapKVWithTags(3); 085 int tagsLength2 = kv2.getTagsLength(); 086 context.compressTags(daos, kv2.getTagsByteBuffer(), kv2.getTagsPosition(), tagsLength2); 087 088 context.clear(); 089 090 byte[] dest = new byte[tagsLength1]; 091 ByteBuffer ob = ByteBuffer.wrap(baos.getBuffer()); 092 context.uncompressTags(new SingleByteBuff(ob), dest, 0, tagsLength1); 093 assertTrue( 094 Bytes.equals(kv1.getTagsArray(), kv1.getTagsOffset(), tagsLength1, dest, 0, tagsLength1)); 095 dest = new byte[tagsLength2]; 096 context.uncompressTags(new SingleByteBuff(ob), dest, 0, tagsLength2); 097 assertTrue( 098 Bytes.equals(kv2.getTagsArray(), kv2.getTagsOffset(), tagsLength2, dest, 0, tagsLength2)); 099 } 100 101 @Test 102 public void testCompressUncompressTags2() throws Exception { 103 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 104 TagCompressionContext context = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE); 105 KeyValue kv1 = createKVWithTags(1); 106 int tagsLength1 = kv1.getTagsLength(); 107 context.compressTags(baos, kv1.getTagsArray(), kv1.getTagsOffset(), tagsLength1); 108 KeyValue kv2 = createKVWithTags(3); 109 int tagsLength2 = kv2.getTagsLength(); 110 context.compressTags(baos, kv2.getTagsArray(), kv2.getTagsOffset(), tagsLength2); 111 112 context.clear(); 113 114 ByteArrayInputStream bais = new ByteArrayInputStream(baos.getBuffer()); 115 byte[] dest = new byte[tagsLength1]; 116 context.uncompressTags(bais, dest, 0, tagsLength1); 117 assertTrue( 118 Bytes.equals(kv1.getTagsArray(), kv1.getTagsOffset(), tagsLength1, dest, 0, tagsLength1)); 119 dest = new byte[tagsLength2]; 120 context.uncompressTags(bais, dest, 0, tagsLength2); 121 assertTrue( 122 Bytes.equals(kv2.getTagsArray(), kv2.getTagsOffset(), tagsLength2, dest, 0, tagsLength2)); 123 } 124 125 @Test 126 public void testCompressUncompressTagsWithOffheapKeyValue2() throws Exception { 127 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 128 DataOutputStream daos = new ByteBufferWriterDataOutputStream(baos); 129 TagCompressionContext context = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE); 130 ByteBufferExtendedCell kv1 = (ByteBufferExtendedCell) createOffheapKVWithTags(1); 131 int tagsLength1 = kv1.getTagsLength(); 132 context.compressTags(daos, kv1.getTagsByteBuffer(), kv1.getTagsPosition(), tagsLength1); 133 ByteBufferExtendedCell kv2 = (ByteBufferExtendedCell) createOffheapKVWithTags(3); 134 int tagsLength2 = kv2.getTagsLength(); 135 context.compressTags(daos, kv2.getTagsByteBuffer(), kv2.getTagsPosition(), tagsLength2); 136 137 context.clear(); 138 139 ByteArrayInputStream bais = new ByteArrayInputStream(baos.getBuffer()); 140 byte[] dest = new byte[tagsLength1]; 141 context.uncompressTags(bais, dest, 0, tagsLength1); 142 assertTrue( 143 Bytes.equals(kv1.getTagsArray(), kv1.getTagsOffset(), tagsLength1, dest, 0, tagsLength1)); 144 dest = new byte[tagsLength2]; 145 context.uncompressTags(bais, dest, 0, tagsLength2); 146 assertTrue( 147 Bytes.equals(kv2.getTagsArray(), kv2.getTagsOffset(), tagsLength2, dest, 0, tagsLength2)); 148 } 149 150 private KeyValue createKVWithTags(int noOfTags) { 151 List<Tag> tags = new ArrayList<>(); 152 for (int i = 0; i < noOfTags; i++) { 153 tags.add(new ArrayBackedTag((byte) i, "tagValue" + i)); 154 } 155 KeyValue kv = new KeyValue(ROW, CF, Q, 1234L, V, tags); 156 return kv; 157 } 158 159 private Cell createOffheapKVWithTags(int noOfTags) { 160 List<Tag> tags = new ArrayList<>(); 161 for (int i = 0; i < noOfTags; i++) { 162 tags.add(new ArrayBackedTag((byte) i, "tagValue" + i)); 163 } 164 KeyValue kv = new KeyValue(ROW, CF, Q, 1234L, V, tags); 165 ByteBuffer dbb = ByteBuffer.allocateDirect(kv.getBuffer().length); 166 ByteBufferUtils.copyFromArrayToBuffer(dbb, kv.getBuffer(), 0, kv.getBuffer().length); 167 ByteBufferKeyValue offheapKV = new ByteBufferKeyValue(dbb, 0, kv.getBuffer().length, 0); 168 return offheapKV; 169 } 170}