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.util; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import java.util.ArrayList; 024import java.util.List; 025import org.apache.hadoop.hbase.ArrayBackedTag; 026import org.apache.hadoop.hbase.KeyValue; 027import org.apache.hadoop.hbase.Tag; 028import org.apache.hadoop.hbase.testclassification.MiscTests; 029import org.apache.hadoop.hbase.testclassification.SmallTests; 030import org.junit.jupiter.api.Test; 031 032@org.junit.jupiter.api.Tag(MiscTests.TAG) 033@org.junit.jupiter.api.Tag(SmallTests.TAG) 034public class TestByteRangeWithKVSerialization { 035 036 static void writeCell(PositionedByteRange pbr, KeyValue kv) throws Exception { 037 pbr.putInt(kv.getKeyLength()); 038 pbr.putInt(kv.getValueLength()); 039 pbr.put(kv.getBuffer(), kv.getKeyOffset(), kv.getKeyLength()); 040 pbr.put(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength()); 041 int tagsLen = kv.getTagsLength(); 042 pbr.put((byte) (tagsLen >> 8 & 0xff)); 043 pbr.put((byte) (tagsLen & 0xff)); 044 pbr.put(kv.getTagsArray(), kv.getTagsOffset(), tagsLen); 045 pbr.putVLong(kv.getSequenceId()); 046 } 047 048 static KeyValue readCell(PositionedByteRange pbr) throws Exception { 049 int kvStartPos = pbr.getPosition(); 050 int keyLen = pbr.getInt(); 051 int valLen = pbr.getInt(); 052 pbr.setPosition(pbr.getPosition() + keyLen + valLen); // Skip the key and value section 053 int tagsLen = ((pbr.get() & 0xff) << 8) ^ (pbr.get() & 0xff); 054 pbr.setPosition(pbr.getPosition() + tagsLen); // Skip the tags section 055 long mvcc = pbr.getVLong(); 056 KeyValue kv = new KeyValue(pbr.getBytes(), kvStartPos, 057 (int) KeyValue.getKeyValueDataStructureSize(keyLen, valLen, tagsLen)); 058 kv.setSequenceId(mvcc); 059 return kv; 060 } 061 062 @Test 063 public void testWritingAndReadingCells() throws Exception { 064 final byte[] FAMILY = Bytes.toBytes("f1"); 065 final byte[] QUALIFIER = Bytes.toBytes("q1"); 066 final byte[] VALUE = Bytes.toBytes("v"); 067 int kvCount = 1000000; 068 List<KeyValue> kvs = new ArrayList<>(kvCount); 069 int totalSize = 0; 070 Tag[] tags = new Tag[] { new ArrayBackedTag((byte) 1, "tag1") }; 071 for (int i = 0; i < kvCount; i++) { 072 KeyValue kv = new KeyValue(Bytes.toBytes(i), FAMILY, QUALIFIER, i, VALUE, tags); 073 kv.setSequenceId(i); 074 kvs.add(kv); 075 totalSize += kv.getLength() + Bytes.SIZEOF_LONG; 076 } 077 PositionedByteRange pbr = new SimplePositionedMutableByteRange(totalSize); 078 for (KeyValue kv : kvs) { 079 writeCell(pbr, kv); 080 } 081 082 PositionedByteRange pbr1 = 083 new SimplePositionedMutableByteRange(pbr.getBytes(), 0, pbr.getPosition()); 084 for (int i = 0; i < kvCount; i++) { 085 KeyValue kv = readCell(pbr1); 086 KeyValue kv1 = kvs.get(i); 087 assertTrue(kv.equals(kv1)); 088 assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(), 089 kv1.getValueArray(), kv1.getValueOffset(), kv1.getValueLength())); 090 assertTrue(Bytes.equals(kv.getTagsArray(), kv.getTagsOffset(), kv.getTagsLength(), 091 kv1.getTagsArray(), kv1.getTagsOffset(), kv1.getTagsLength())); 092 assertEquals(kv1.getSequenceId(), kv.getSequenceId()); 093 } 094 } 095}