/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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 org.apache.hadoop.hbase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hbase.KeyValue.Type;
import org.apache.hadoop.hbase.testclassification.MiscTests;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.util.ByteBufferUtils;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category({ MiscTests.class, SmallTests.class })
public class TestByteBufferKeyValue {
private static final String QUAL2 = "qual2";
private static final String FAM2 = "fam2";
private static final String QUAL1 = "qual1";
private static final String FAM1 = "fam1";
private static final String ROW1 = "row1";
private static final byte[] row1 = Bytes.toBytes(ROW1);
private static final byte[] fam1 = Bytes.toBytes(FAM1);
private static final byte[] fam2 = Bytes.toBytes(FAM2);
private static final byte[] qual1 = Bytes.toBytes(QUAL1);
private static final byte[] qual2 = Bytes.toBytes(QUAL2);
private static final Tag t1 = new ArrayBackedTag((byte) 1, Bytes.toBytes("TAG1"));
private static final Tag t2 = new ArrayBackedTag((byte) 2, Bytes.toBytes("TAG2"));
private static final ArrayList<Tag> tags = new ArrayList<Tag>();
static {
tags.add(t1);
tags.add(t2);
}
@Test
public void testByteBufferBackedKeyValue() throws Exception {
KeyValue kvCell = new KeyValue(row1, fam1, qual1, 0l, Type.Put, row1);
ByteBuffer buf = ByteBuffer.allocateDirect(kvCell.getBuffer().length);
ByteBufferUtils.copyFromArrayToBuffer(buf, kvCell.getBuffer(), 0, kvCell.getBuffer().length);
ByteBufferCell offheapKV = new ByteBufferKeyValue(buf, 0, buf.capacity(), 0l);
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKV.getRowByteBuffer(),
offheapKV.getRowPosition(), offheapKV.getRowLength()));
assertEquals(
FAM1,
ByteBufferUtils.toStringBinary(offheapKV.getFamilyByteBuffer(),
offheapKV.getFamilyPosition(), offheapKV.getFamilyLength()));
assertEquals(
QUAL1,
ByteBufferUtils.toStringBinary(offheapKV.getQualifierByteBuffer(),
offheapKV.getQualifierPosition(), offheapKV.getQualifierLength()));
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKV.getValueByteBuffer(),
offheapKV.getValuePosition(), offheapKV.getValueLength()));
assertEquals(0L, offheapKV.getTimestamp());
assertEquals(Type.Put.getCode(), offheapKV.getTypeByte());
// Use the array() APIs
assertEquals(
ROW1,
Bytes.toStringBinary(offheapKV.getRowArray(),
offheapKV.getRowOffset(), offheapKV.getRowLength()));
assertEquals(
FAM1,
Bytes.toStringBinary(offheapKV.getFamilyArray(),
offheapKV.getFamilyOffset(), offheapKV.getFamilyLength()));
assertEquals(
QUAL1,
Bytes.toStringBinary(offheapKV.getQualifierArray(),
offheapKV.getQualifierOffset(), offheapKV.getQualifierLength()));
assertEquals(
ROW1,
Bytes.toStringBinary(offheapKV.getValueArray(),
offheapKV.getValueOffset(), offheapKV.getValueLength()));
assertEquals(0L, offheapKV.getTimestamp());
assertEquals(Type.Put.getCode(), offheapKV.getTypeByte());
kvCell = new KeyValue(row1, fam2, qual2, 0l, Type.Put, row1);
buf = ByteBuffer.allocateDirect(kvCell.getBuffer().length);
ByteBufferUtils.copyFromArrayToBuffer(buf, kvCell.getBuffer(), 0, kvCell.getBuffer().length);
offheapKV = new ByteBufferKeyValue(buf, 0, buf.capacity(), 0l);
assertEquals(
FAM2,
ByteBufferUtils.toStringBinary(offheapKV.getFamilyByteBuffer(),
offheapKV.getFamilyPosition(), offheapKV.getFamilyLength()));
assertEquals(
QUAL2,
ByteBufferUtils.toStringBinary(offheapKV.getQualifierByteBuffer(),
offheapKV.getQualifierPosition(), offheapKV.getQualifierLength()));
byte[] nullQualifier = new byte[0];
kvCell = new KeyValue(row1, fam1, nullQualifier, 0L, Type.Put, row1);
buf = ByteBuffer.allocateDirect(kvCell.getBuffer().length);
ByteBufferUtils.copyFromArrayToBuffer(buf, kvCell.getBuffer(), 0, kvCell.getBuffer().length);
offheapKV = new ByteBufferKeyValue(buf, 0, buf.capacity(), 0l);
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKV.getRowByteBuffer(),
offheapKV.getRowPosition(), offheapKV.getRowLength()));
assertEquals(
FAM1,
ByteBufferUtils.toStringBinary(offheapKV.getFamilyByteBuffer(),
offheapKV.getFamilyPosition(), offheapKV.getFamilyLength()));
assertEquals(
"",
ByteBufferUtils.toStringBinary(offheapKV.getQualifierByteBuffer(),
offheapKV.getQualifierPosition(), offheapKV.getQualifierLength()));
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKV.getValueByteBuffer(),
offheapKV.getValuePosition(), offheapKV.getValueLength()));
assertEquals(0L, offheapKV.getTimestamp());
assertEquals(Type.Put.getCode(), offheapKV.getTypeByte());
}
@Test
public void testByteBufferBackedKeyValueWithTags() throws Exception {
KeyValue kvCell = new KeyValue(row1, fam1, qual1, 0l, Type.Put, row1, tags);
ByteBuffer buf = ByteBuffer.allocateDirect(kvCell.getBuffer().length);
ByteBufferUtils.copyFromArrayToBuffer(buf, kvCell.getBuffer(), 0, kvCell.getBuffer().length);
ByteBufferCell offheapKV = new ByteBufferKeyValue(buf, 0, buf.capacity(), 0l);
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKV.getRowByteBuffer(),
offheapKV.getRowPosition(), offheapKV.getRowLength()));
assertEquals(
FAM1,
ByteBufferUtils.toStringBinary(offheapKV.getFamilyByteBuffer(),
offheapKV.getFamilyPosition(), offheapKV.getFamilyLength()));
assertEquals(
QUAL1,
ByteBufferUtils.toStringBinary(offheapKV.getQualifierByteBuffer(),
offheapKV.getQualifierPosition(), offheapKV.getQualifierLength()));
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKV.getValueByteBuffer(),
offheapKV.getValuePosition(), offheapKV.getValueLength()));
assertEquals(0L, offheapKV.getTimestamp());
assertEquals(Type.Put.getCode(), offheapKV.getTypeByte());
// change tags to handle both onheap and offheap stuff
List<Tag> resTags = TagUtil.asList(offheapKV.getTagsArray(), offheapKV.getTagsOffset(),
offheapKV.getTagsLength());
Tag tag1 = resTags.get(0);
assertEquals(t1.getType(), tag1.getType());
assertEquals(TagUtil.getValueAsString(t1), TagUtil.getValueAsString(tag1));
Tag tag2 = resTags.get(1);
assertEquals(tag2.getType(), tag2.getType());
assertEquals(TagUtil.getValueAsString(t2), TagUtil.getValueAsString(tag2));
Tag res = CellUtil.getTag(offheapKV, (byte) 2);
assertEquals(TagUtil.getValueAsString(t2), TagUtil.getValueAsString(tag2));
res = CellUtil.getTag(offheapKV, (byte) 3);
assertNull(res);
}
@Test
public void testGetKeyMethods() throws Exception {
KeyValue kvCell = new KeyValue(row1, fam1, qual1, 0l, Type.Put, row1, tags);
ByteBuffer buf = ByteBuffer.allocateDirect(kvCell.getKeyLength());
ByteBufferUtils.copyFromArrayToBuffer(buf, kvCell.getBuffer(), kvCell.getKeyOffset(),
kvCell.getKeyLength());
ByteBufferCell offheapKeyOnlyKV = new ByteBufferKeyOnlyKeyValue(buf, 0, buf.capacity());
assertEquals(
ROW1,
ByteBufferUtils.toStringBinary(offheapKeyOnlyKV.getRowByteBuffer(),
offheapKeyOnlyKV.getRowPosition(), offheapKeyOnlyKV.getRowLength()));
assertEquals(
FAM1,
ByteBufferUtils.toStringBinary(offheapKeyOnlyKV.getFamilyByteBuffer(),
offheapKeyOnlyKV.getFamilyPosition(), offheapKeyOnlyKV.getFamilyLength()));
assertEquals(
QUAL1,
ByteBufferUtils.toStringBinary(offheapKeyOnlyKV.getQualifierByteBuffer(),
offheapKeyOnlyKV.getQualifierPosition(),
offheapKeyOnlyKV.getQualifierLength()));
assertEquals(0L, offheapKeyOnlyKV.getTimestamp());
assertEquals(Type.Put.getCode(), offheapKeyOnlyKV.getTypeByte());
}
}