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 java.nio.ByteBuffer; 021import org.apache.hadoop.hbase.KeyValue; 022import org.apache.hadoop.hbase.util.ByteBufferUtils; 023import org.apache.yetus.audience.InterfaceAudience; 024 025/** 026 * Stores the state of data block encoder at the beginning of new key. 027 */ 028@InterfaceAudience.Private 029class CompressionState { 030 int keyLength; 031 int valueLength; 032 033 short rowLength; 034 int prevOffset = FIRST_KEY; 035 byte familyLength; 036 int qualifierLength; 037 byte type; 038 039 private final static int FIRST_KEY = -1; 040 041 boolean isFirst() { 042 return prevOffset == FIRST_KEY; 043 } 044 045 /** 046 * Analyze the key and fill the state. Uses mark() and reset() in ByteBuffer. 047 * @param in Buffer at the position where key starts 048 * @param keyLength Length of key in bytes 049 * @param valueLength Length of values in bytes 050 */ 051 void readKey(ByteBuffer in, int keyLength, int valueLength) { 052 readKey(in, keyLength, valueLength, 0, null); 053 } 054 055 /** 056 * Analyze the key and fill the state assuming we know previous state. Uses mark() and reset() in 057 * ByteBuffer to avoid moving the position. 058 * <p> 059 * This method overrides all the fields of this instance, except {@link #prevOffset}, which is 060 * usually manipulated directly by encoders and decoders. 061 * @param in Buffer at the position where key starts 062 * @param keyLength Length of key in bytes 063 * @param valueLength Length of values in bytes 064 * @param commonPrefix how many first bytes are common with previous KeyValue 065 * @param previousState State from previous KeyValue 066 */ 067 void readKey(ByteBuffer in, int keyLength, int valueLength, int commonPrefix, 068 CompressionState previousState) { 069 this.keyLength = keyLength; 070 this.valueLength = valueLength; 071 072 // fill the state 073 in.mark(); // mark beginning of key 074 075 if (commonPrefix < KeyValue.ROW_LENGTH_SIZE) { 076 rowLength = in.getShort(); 077 ByteBufferUtils.skip(in, rowLength); 078 079 familyLength = in.get(); 080 081 qualifierLength = keyLength - rowLength - familyLength - KeyValue.KEY_INFRASTRUCTURE_SIZE; 082 ByteBufferUtils.skip(in, familyLength + qualifierLength); 083 } else { 084 rowLength = previousState.rowLength; 085 familyLength = previousState.familyLength; 086 qualifierLength = previousState.qualifierLength + keyLength - previousState.keyLength; 087 ByteBufferUtils.skip(in, (KeyValue.ROW_LENGTH_SIZE + KeyValue.FAMILY_LENGTH_SIZE) + rowLength 088 + familyLength + qualifierLength); 089 } 090 091 readTimestamp(in); 092 093 type = in.get(); 094 095 in.reset(); 096 } 097 098 protected void readTimestamp(ByteBuffer in) { 099 // used in subclasses to add timestamp to state 100 ByteBufferUtils.skip(in, KeyValue.TIMESTAMP_SIZE); 101 } 102 103 void copyFrom(CompressionState state) { 104 keyLength = state.keyLength; 105 valueLength = state.valueLength; 106 107 rowLength = state.rowLength; 108 prevOffset = state.prevOffset; 109 familyLength = state.familyLength; 110 qualifierLength = state.qualifierLength; 111 type = state.type; 112 } 113}