org.apache.hadoop.hbase.IndividualBytesFieldCell.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hbase.IndividualBytesFieldCell.java

Source

/**
 * 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 org.apache.commons.lang3.ArrayUtils;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.ClassSize;
import org.apache.yetus.audience.InterfaceAudience;

@InterfaceAudience.Private
public class IndividualBytesFieldCell implements ExtendedCell, Cloneable {

    private static final long FIXED_OVERHEAD = ClassSize.align( // do alignment(padding gap)
            ClassSize.OBJECT // object header
                    + KeyValue.TIMESTAMP_TYPE_SIZE // timestamp and type
                    + Bytes.SIZEOF_LONG // sequence id
                    + 5 * ClassSize.REFERENCE); // references to all byte arrays: row, family, qualifier, value, tags

    // The following fields are backed by individual byte arrays
    private final byte[] row;
    private final int rOffset;
    private final int rLength;
    private final byte[] family;
    private final int fOffset;
    private final int fLength;
    private final byte[] qualifier;
    private final int qOffset;
    private final int qLength;
    private final byte[] value;
    private final int vOffset;
    private final int vLength;
    private final byte[] tags; // A byte array, rather than an array of org.apache.hadoop.hbase.Tag
    private final int tagsOffset;
    private final int tagsLength;

    // Other fields
    private long timestamp;
    private final byte type; // A byte, rather than org.apache.hadoop.hbase.KeyValue.Type
    private long seqId;

    public IndividualBytesFieldCell(byte[] row, byte[] family, byte[] qualifier, long timestamp, KeyValue.Type type,
            byte[] value) {
        this(row, family, qualifier, timestamp, type, 0L /* sequence id */, value, null /* tags */);
    }

    public IndividualBytesFieldCell(byte[] row, byte[] family, byte[] qualifier, long timestamp, KeyValue.Type type,
            long seqId, byte[] value, byte[] tags) {
        this(row, 0, ArrayUtils.getLength(row), family, 0, ArrayUtils.getLength(family), qualifier, 0,
                ArrayUtils.getLength(qualifier), timestamp, type, seqId, value, 0, ArrayUtils.getLength(value),
                tags, 0, ArrayUtils.getLength(tags));
    }

    public IndividualBytesFieldCell(byte[] row, int rOffset, int rLength, byte[] family, int fOffset, int fLength,
            byte[] qualifier, int qOffset, int qLength, long timestamp, KeyValue.Type type, long seqId,
            byte[] value, int vOffset, int vLength, byte[] tags, int tagsOffset, int tagsLength) {

        // Check row, family, qualifier and value
        KeyValue.checkParameters(row, rLength, // row and row length
                family, fLength, // family and family length
                qLength, // qualifier length
                vLength); // value length

        // Check timestamp
        if (timestamp < 0) {
            throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
        }

        // Check tags
        RawCell.checkForTagsLength(tagsLength);
        checkArrayBounds(row, rOffset, rLength);
        checkArrayBounds(family, fOffset, fLength);
        checkArrayBounds(qualifier, qOffset, qLength);
        checkArrayBounds(value, vOffset, vLength);
        checkArrayBounds(tags, tagsOffset, tagsLength);
        // No local copy is made, but reference to the input directly
        this.row = row;
        this.rOffset = rOffset;
        this.rLength = rLength;
        this.family = family;
        this.fOffset = fOffset;
        this.fLength = fLength;
        this.qualifier = qualifier;
        this.qOffset = qOffset;
        this.qLength = qLength;
        this.value = value;
        this.vOffset = vOffset;
        this.vLength = vLength;
        this.tags = tags;
        this.tagsOffset = tagsOffset;
        this.tagsLength = tagsLength;

        // Set others
        this.timestamp = timestamp;
        this.type = type.getCode();
        this.seqId = seqId;
    }

    private void checkArrayBounds(byte[] bytes, int offset, int length) {
        if (offset < 0 || length < 0) {
            throw new IllegalArgumentException("Negative number! offset=" + offset + "and length=" + length);
        }
        if (bytes == null && (offset != 0 || length != 0)) {
            throw new IllegalArgumentException("Null bytes array but offset=" + offset + "and length=" + length);
        }
        if (bytes != null && bytes.length < offset + length) {
            throw new IllegalArgumentException(
                    "Out of bounds! bytes.length=" + bytes.length + ", offset=" + offset + ", length=" + length);
        }
    }

    private long heapOverhead() {
        return FIXED_OVERHEAD + ClassSize.ARRAY // row      , can not be null
                + ((family == null) ? 0 : ClassSize.ARRAY) // family   , can be null
                + ((qualifier == null) ? 0 : ClassSize.ARRAY) // qualifier, can be null
                + ((value == null) ? 0 : ClassSize.ARRAY) // value    , can be null
                + ((tags == null) ? 0 : ClassSize.ARRAY); // tags     , can be null
    }

    /**
     * Implement Cell interface
     */
    // 1) Row
    @Override
    public byte[] getRowArray() {
        // If row is null, the constructor will reject it, by {@link KeyValue#checkParameters()},
        // so it is safe to return row without checking.
        return row;
    }

    @Override
    public int getRowOffset() {
        return rOffset;
    }

    @Override
    public short getRowLength() {
        // If row is null or rLength is invalid, the constructor will reject it, by {@link KeyValue#checkParameters()},
        // so it is safe to call rLength and make the type conversion.
        return (short) (rLength);
    }

    // 2) Family
    @Override
    public byte[] getFamilyArray() {
        // Family could be null
        return (family == null) ? HConstants.EMPTY_BYTE_ARRAY : family;
    }

    @Override
    public int getFamilyOffset() {
        return fOffset;
    }

    @Override
    public byte getFamilyLength() {
        // If fLength is invalid, the constructor will reject it, by {@link KeyValue#checkParameters()},
        // so it is safe to make the type conversion.
        return (byte) (fLength);
    }

    // 3) Qualifier
    @Override
    public byte[] getQualifierArray() {
        // Qualifier could be null
        return (qualifier == null) ? HConstants.EMPTY_BYTE_ARRAY : qualifier;
    }

    @Override
    public int getQualifierOffset() {
        return qOffset;
    }

    @Override
    public int getQualifierLength() {
        return qLength;
    }

    // 4) Timestamp
    @Override
    public long getTimestamp() {
        return timestamp;
    }

    //5) Type
    @Override
    public byte getTypeByte() {
        return type;
    }

    //6) Sequence id
    @Override
    public long getSequenceId() {
        return seqId;
    }

    //7) Value
    @Override
    public byte[] getValueArray() {
        // Value could be null
        return (value == null) ? HConstants.EMPTY_BYTE_ARRAY : value;
    }

    @Override
    public int getValueOffset() {
        return vOffset;
    }

    @Override
    public int getValueLength() {
        return vLength;
    }

    // 8) Tags
    @Override
    public byte[] getTagsArray() {
        // Tags can could null
        return (tags == null) ? HConstants.EMPTY_BYTE_ARRAY : tags;
    }

    @Override
    public int getTagsOffset() {
        return tagsOffset;
    }

    @Override
    public int getTagsLength() {
        return tagsLength;
    }

    /**
     * Implement HeapSize interface
     */
    @Override
    public long heapSize() {
        // Size of array headers are already included into overhead, so do not need to include it for each byte array
        return heapOverhead() // overhead, with array headers included
                + ClassSize.align(getRowLength()) // row
                + ClassSize.align(getFamilyLength()) // family
                + ClassSize.align(getQualifierLength()) // qualifier
                + ClassSize.align(getValueLength()) // value
                + ClassSize.align(getTagsLength()); // tags
    }

    /**
     * Implement Cloneable interface
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone(); // only a shadow copy
    }

    @Override
    public void setSequenceId(long seqId) {
        if (seqId < 0) {
            throw new IllegalArgumentException("Sequence Id cannot be negative. ts=" + seqId);
        }
        this.seqId = seqId;
    }

    @Override
    public void setTimestamp(long ts) {
        if (ts < 0) {
            throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts);
        }
        this.timestamp = ts;
    }

    @Override
    public void setTimestamp(byte[] ts) {
        setTimestamp(Bytes.toLong(ts, 0));
    }

    @Override
    public String toString() {
        return CellUtil.toString(this, true);
    }
}