001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with this 004 * work for additional information regarding copyright ownership. The ASF 005 * licenses this file to you under the Apache License, Version 2.0 (the 006 * "License"); you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017package org.apache.hadoop.hbase.io.encoding; 018 019import java.nio.ByteBuffer; 020 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. 047 * Uses mark() and reset() in ByteBuffer. 048 * @param in Buffer at the position where key starts 049 * @param keyLength Length of key in bytes 050 * @param valueLength Length of values in bytes 051 */ 052 void readKey(ByteBuffer in, int keyLength, int valueLength) { 053 readKey(in, keyLength, valueLength, 0, null); 054 } 055 056 /** 057 * Analyze the key and fill the state assuming we know previous state. 058 * Uses mark() and reset() in ByteBuffer to avoid moving the position. 059 * <p> 060 * This method overrides all the fields of this instance, except 061 * {@link #prevOffset}, which is usually manipulated directly by encoders 062 * and decoders. 063 * @param in Buffer at the position where key starts 064 * @param keyLength Length of key in bytes 065 * @param valueLength Length of values in bytes 066 * @param commonPrefix how many first bytes are common with previous KeyValue 067 * @param previousState State from previous KeyValue 068 */ 069 void readKey(ByteBuffer in, int keyLength, int valueLength, 070 int commonPrefix, CompressionState previousState) { 071 this.keyLength = keyLength; 072 this.valueLength = valueLength; 073 074 // fill the state 075 in.mark(); // mark beginning of key 076 077 if (commonPrefix < KeyValue.ROW_LENGTH_SIZE) { 078 rowLength = in.getShort(); 079 ByteBufferUtils.skip(in, rowLength); 080 081 familyLength = in.get(); 082 083 qualifierLength = keyLength - rowLength - familyLength - 084 KeyValue.KEY_INFRASTRUCTURE_SIZE; 085 ByteBufferUtils.skip(in, familyLength + qualifierLength); 086 } else { 087 rowLength = previousState.rowLength; 088 familyLength = previousState.familyLength; 089 qualifierLength = previousState.qualifierLength + 090 keyLength - previousState.keyLength; 091 ByteBufferUtils.skip(in, (KeyValue.ROW_LENGTH_SIZE + 092 KeyValue.FAMILY_LENGTH_SIZE) + 093 rowLength + familyLength + qualifierLength); 094 } 095 096 readTimestamp(in); 097 098 type = in.get(); 099 100 in.reset(); 101 } 102 103 protected void readTimestamp(ByteBuffer in) { 104 // used in subclasses to add timestamp to state 105 ByteBufferUtils.skip(in, KeyValue.TIMESTAMP_SIZE); 106 } 107 108 void copyFrom(CompressionState state) { 109 keyLength = state.keyLength; 110 valueLength = state.valueLength; 111 112 rowLength = state.rowLength; 113 prevOffset = state.prevOffset; 114 familyLength = state.familyLength; 115 qualifierLength = state.qualifierLength; 116 type = state.type; 117 } 118}