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.encoding; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.io.ByteArrayInputStream; 025import java.io.ByteArrayOutputStream; 026import java.nio.ByteBuffer; 027import org.apache.hadoop.hbase.HConstants; 028import org.apache.hadoop.hbase.KeyValue; 029import org.apache.hadoop.hbase.KeyValue.Type; 030import org.apache.hadoop.hbase.PrivateCellUtil; 031import org.apache.hadoop.hbase.codec.Codec.Decoder; 032import org.apache.hadoop.hbase.codec.Codec.Encoder; 033import org.apache.hadoop.hbase.codec.KeyValueCodecWithTags; 034import org.apache.hadoop.hbase.io.encoding.BufferedDataBlockEncoder.OnheapDecodedCell; 035import org.apache.hadoop.hbase.testclassification.IOTests; 036import org.apache.hadoop.hbase.testclassification.MediumTests; 037import org.apache.hadoop.hbase.util.Bytes; 038import org.apache.hadoop.hbase.util.ObjectIntPair; 039import org.junit.jupiter.api.Tag; 040import org.junit.jupiter.api.Test; 041 042@Tag(IOTests.TAG) 043@Tag(MediumTests.TAG) 044public class TestBufferedDataBlockEncoder { 045 046 byte[] row1 = Bytes.toBytes("row1"); 047 byte[] row2 = Bytes.toBytes("row2"); 048 byte[] row_1_0 = Bytes.toBytes("row10"); 049 050 byte[] fam1 = Bytes.toBytes("fam1"); 051 byte[] fam2 = Bytes.toBytes("fam2"); 052 byte[] fam_1_2 = Bytes.toBytes("fam12"); 053 054 byte[] qual1 = Bytes.toBytes("qual1"); 055 byte[] qual2 = Bytes.toBytes("qual2"); 056 057 byte[] val = Bytes.toBytes("val"); 058 059 @Test 060 public void testEnsureSpaceForKey() { 061 BufferedDataBlockEncoder.SeekerState state = 062 new BufferedDataBlockEncoder.SeekerState(new ObjectIntPair<>(), false); 063 for (int i = 1; i <= 65536; ++i) { 064 state.keyLength = i; 065 state.ensureSpaceForKey(); 066 state.keyBuffer[state.keyLength - 1] = (byte) ((i - 1) % 0xff); 067 for (int j = 0; j < i - 1; ++j) { 068 // Check that earlier bytes were preserved as the buffer grew. 069 assertEquals((byte) (j % 0xff), state.keyBuffer[j]); 070 } 071 } 072 } 073 074 @Test 075 public void testCommonPrefixComparators() { 076 KeyValue kv1 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 077 KeyValue kv2 = new KeyValue(row1, fam_1_2, qual1, 1L, Type.Maximum); 078 assertTrue((BufferedDataBlockEncoder.compareCommonFamilyPrefix(kv1, kv2, 4) < 0)); 079 080 kv1 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 081 kv2 = new KeyValue(row_1_0, fam_1_2, qual1, 1L, Type.Maximum); 082 assertTrue((BufferedDataBlockEncoder.compareCommonRowPrefix(kv1, kv2, 4) < 0)); 083 084 kv1 = new KeyValue(row1, fam1, qual2, 1L, Type.Put); 085 kv2 = new KeyValue(row1, fam1, qual1, 1L, Type.Maximum); 086 assertTrue((BufferedDataBlockEncoder.compareCommonQualifierPrefix(kv1, kv2, 4) > 0)); 087 } 088 089 @Test 090 public void testKVCodecWithTagsForDecodedCellsWithNoTags() throws Exception { 091 KeyValue kv1 = new KeyValue(Bytes.toBytes("r"), Bytes.toBytes("f"), Bytes.toBytes("1"), 092 HConstants.LATEST_TIMESTAMP, Bytes.toBytes("1")); 093 // kv1.getKey() return a copy of the Key bytes which starts from RK_length. Means from offsets, 094 // we need to reduce the KL and VL parts. 095 OnheapDecodedCell c1 = new OnheapDecodedCell(kv1.getKey(), kv1.getRowLength(), 096 kv1.getFamilyOffset() - KeyValue.ROW_OFFSET, kv1.getFamilyLength(), 097 kv1.getQualifierOffset() - KeyValue.ROW_OFFSET, kv1.getQualifierLength(), kv1.getTimestamp(), 098 kv1.getTypeByte(), kv1.getValueArray(), kv1.getValueOffset(), kv1.getValueLength(), 099 kv1.getSequenceId(), kv1.getTagsArray(), kv1.getTagsOffset(), kv1.getTagsLength()); 100 KeyValue kv2 = new KeyValue(Bytes.toBytes("r2"), Bytes.toBytes("f"), Bytes.toBytes("2"), 101 HConstants.LATEST_TIMESTAMP, Bytes.toBytes("2")); 102 OnheapDecodedCell c2 = new OnheapDecodedCell(kv2.getKey(), kv2.getRowLength(), 103 kv2.getFamilyOffset() - KeyValue.ROW_OFFSET, kv2.getFamilyLength(), 104 kv2.getQualifierOffset() - KeyValue.ROW_OFFSET, kv2.getQualifierLength(), kv2.getTimestamp(), 105 kv2.getTypeByte(), kv2.getValueArray(), kv2.getValueOffset(), kv2.getValueLength(), 106 kv2.getSequenceId(), kv2.getTagsArray(), kv2.getTagsOffset(), kv2.getTagsLength()); 107 KeyValue kv3 = new KeyValue(Bytes.toBytes("r3"), Bytes.toBytes("cf"), Bytes.toBytes("qual"), 108 HConstants.LATEST_TIMESTAMP, Bytes.toBytes("3")); 109 BufferedDataBlockEncoder.OffheapDecodedExtendedCell c3 = 110 new BufferedDataBlockEncoder.OffheapDecodedExtendedCell(ByteBuffer.wrap(kv2.getKey()), 111 kv2.getRowLength(), kv2.getFamilyOffset() - KeyValue.ROW_OFFSET, kv2.getFamilyLength(), 112 kv2.getQualifierOffset() - KeyValue.ROW_OFFSET, kv2.getQualifierLength(), 113 kv2.getTimestamp(), kv2.getTypeByte(), ByteBuffer.wrap(kv2.getValueArray()), 114 kv2.getValueOffset(), kv2.getValueLength(), kv2.getSequenceId(), 115 ByteBuffer.wrap(kv2.getTagsArray()), kv2.getTagsOffset(), kv2.getTagsLength()); 116 ByteArrayOutputStream os = new ByteArrayOutputStream(); 117 KeyValueCodecWithTags codec = new KeyValueCodecWithTags(); 118 Encoder encoder = codec.getEncoder(os); 119 encoder.write(c1); 120 encoder.write(c2); 121 encoder.write(c3); 122 ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); 123 Decoder decoder = codec.getDecoder(is); 124 assertTrue(decoder.advance()); 125 assertTrue(PrivateCellUtil.equals(c1, decoder.current())); 126 assertTrue(decoder.advance()); 127 assertTrue(PrivateCellUtil.equals(c2, decoder.current())); 128 assertTrue(decoder.advance()); 129 assertTrue(PrivateCellUtil.equals(c3, decoder.current())); 130 assertFalse(decoder.advance()); 131 } 132}