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; 019 020import java.io.IOException; 021import java.io.OutputStream; 022import java.nio.ByteBuffer; 023import org.apache.hadoop.hbase.io.HeapSize; 024import org.apache.hadoop.hbase.util.ByteBufferUtils; 025import org.apache.yetus.audience.InterfaceAudience; 026 027/** 028 * Extension to {@link Cell} with server side required functions. Server side Cell implementations 029 * must implement this. 030 */ 031@InterfaceAudience.Private 032public interface ExtendedCell extends RawCell, HeapSize { 033 int CELL_NOT_BASED_ON_CHUNK = -1; 034 035 /** 036 * Write this cell to an OutputStream in a {@link KeyValue} format. <br> 037 * KeyValue format <br> 038 * <code><4 bytes keylength> <4 bytes valuelength> <2 bytes rowlength> 039 * <row> <1 byte columnfamilylength> <columnfamily> <columnqualifier> 040 * <8 bytes timestamp> <1 byte keytype> <value> <2 bytes tagslength> 041 * <tags></code> 042 * @param out Stream to which cell has to be written 043 * @param withTags Whether to write tags. 044 * @return how many bytes are written. 045 */ 046 // TODO remove the boolean param once HBASE-16706 is done. 047 default int write(OutputStream out, boolean withTags) throws IOException { 048 // Key length and then value length 049 ByteBufferUtils.putInt(out, KeyValueUtil.keyLength(this)); 050 ByteBufferUtils.putInt(out, getValueLength()); 051 052 // Key 053 PrivateCellUtil.writeFlatKey(this, out); 054 055 if (getValueLength() > 0) { 056 // Value 057 out.write(getValueArray(), getValueOffset(), getValueLength()); 058 } 059 060 // Tags length and tags byte array 061 if (withTags && getTagsLength() > 0) { 062 // Tags length 063 out.write((byte) (0xff & (getTagsLength() >> 8))); 064 out.write((byte) (0xff & getTagsLength())); 065 066 // Tags byte array 067 out.write(getTagsArray(), getTagsOffset(), getTagsLength()); 068 } 069 070 return getSerializedSize(withTags); 071 } 072 073 /** 074 * KeyValue format 075 * <p/> 076 * <code><4 bytes keylength> <4 bytes valuelength> <2 bytes rowlength> 077 * <row> <1 byte columnfamilylength> <columnfamily> <columnqualifier> 078 * <8 bytes timestamp> <1 byte keytype> <value> <2 bytes tagslength> 079 * <tags></code> 080 * @param withTags Whether to write tags. 081 * @return Bytes count required to serialize this Cell in a {@link KeyValue} format. 082 */ 083 // TODO remove the boolean param once HBASE-16706 is done. 084 default int getSerializedSize(boolean withTags) { 085 return KeyValueUtil.length(getRowLength(), getFamilyLength(), getQualifierLength(), 086 getValueLength(), getTagsLength(), withTags); 087 } 088 089 /** Returns Serialized size (defaults to include tag length). */ 090 @Override 091 default int getSerializedSize() { 092 return getSerializedSize(true); 093 } 094 095 /** 096 * Write this Cell into the given buf's offset in a {@link KeyValue} format. 097 * @param buf The buffer where to write the Cell. 098 * @param offset The offset within buffer, to write the Cell. 099 */ 100 default void write(ByteBuffer buf, int offset) { 101 KeyValueUtil.appendTo(this, buf, offset, true); 102 } 103 104 /** 105 * Does a deep copy of the contents to a new memory area and returns it as a new cell. 106 * @return The deep cloned cell 107 */ 108 default ExtendedCell deepClone() { 109 // When being added to the memstore, deepClone() is called and KeyValue has less heap overhead. 110 return new KeyValue(this); 111 } 112 113 /** 114 * Extracts the id of the backing bytebuffer of this cell if it was obtained from fixed sized 115 * chunks as in case of MemstoreLAB 116 * @return the chunk id if the cell is backed by fixed sized Chunks, else return 117 * {@link #CELL_NOT_BASED_ON_CHUNK}; i.e. -1. 118 */ 119 default int getChunkId() { 120 return CELL_NOT_BASED_ON_CHUNK; 121 } 122 123 /** 124 * Sets with the given seqId. 125 * @param seqId sequence ID 126 */ 127 void setSequenceId(long seqId) throws IOException; 128 129 /** 130 * Sets with the given timestamp. 131 * @param ts timestamp 132 */ 133 void setTimestamp(long ts) throws IOException; 134 135 /** 136 * Sets with the given timestamp. 137 * @param ts buffer containing the timestamp value 138 */ 139 void setTimestamp(byte[] ts) throws IOException; 140 141 /** 142 * A region-specific unique monotonically increasing sequence ID given to each Cell. It always 143 * exists for cells in the memstore but is not retained forever. It will be kept for 144 * {@link HConstants#KEEP_SEQID_PERIOD} days, but generally becomes irrelevant after the cell's 145 * row is no longer involved in any operations that require strict consistency. 146 * @return seqId (always > 0 if exists), or 0 if it no longer exists 147 */ 148 long getSequenceId(); 149 150 /** Returns The byte representation of the KeyValue.TYPE of this cell: one of Put, Delete, etc */ 151 byte getTypeByte(); 152 153 /** 154 * Typically, at server side, you'd better always use the {@link #getTypeByte()} as this method 155 * does not expose the {@code Maximum} and {@code Minimum} because they will not be returned to 156 * client, but at server side, we do have cells with these types so if you use this method it will 157 * cause exceptions. 158 */ 159 @Override 160 default Type getType() { 161 return PrivateCellUtil.code2Type(getTypeByte()); 162 } 163}