1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with this 4 * work for additional information regarding copyright ownership. The ASF 5 * licenses this file to you under the Apache License, Version 2.0 (the 6 * "License"); you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 * License for the specific language governing permissions and limitations 15 * under the License. 16 */ 17 package org.apache.hadoop.hbase.io.encoding; 18 19 import java.nio.ByteBuffer; 20 21 import org.apache.hadoop.hbase.classification.InterfaceAudience; 22 import org.apache.hadoop.hbase.KeyValue; 23 import org.apache.hadoop.hbase.util.ByteBufferUtils; 24 25 /** 26 * Stores the state of data block encoder at the beginning of new key. 27 */ 28 @InterfaceAudience.Private 29 class CompressionState { 30 int keyLength; 31 int valueLength; 32 33 short rowLength; 34 int prevOffset = FIRST_KEY; 35 byte familyLength; 36 int qualifierLength; 37 byte type; 38 39 private final static int FIRST_KEY = -1; 40 isFirst()41 boolean isFirst() { 42 return prevOffset == FIRST_KEY; 43 } 44 45 /** 46 * Analyze the key and fill the state. 47 * Uses mark() and reset() in ByteBuffer. 48 * @param in Buffer at the position where key starts 49 * @param keyLength Length of key in bytes 50 * @param valueLength Length of values in bytes 51 */ readKey(ByteBuffer in, int keyLength, int valueLength)52 void readKey(ByteBuffer in, int keyLength, int valueLength) { 53 readKey(in, keyLength, valueLength, 0, null); 54 } 55 56 /** 57 * Analyze the key and fill the state assuming we know previous state. 58 * Uses mark() and reset() in ByteBuffer to avoid moving the position. 59 * <p> 60 * This method overrides all the fields of this instance, except 61 * {@link #prevOffset}, which is usually manipulated directly by encoders 62 * and decoders. 63 * @param in Buffer at the position where key starts 64 * @param keyLength Length of key in bytes 65 * @param valueLength Length of values in bytes 66 * @param commonPrefix how many first bytes are common with previous KeyValue 67 * @param previousState State from previous KeyValue 68 */ readKey(ByteBuffer in, int keyLength, int valueLength, int commonPrefix, CompressionState previousState)69 void readKey(ByteBuffer in, int keyLength, int valueLength, 70 int commonPrefix, CompressionState previousState) { 71 this.keyLength = keyLength; 72 this.valueLength = valueLength; 73 74 // fill the state 75 in.mark(); // mark beginning of key 76 77 if (commonPrefix < KeyValue.ROW_LENGTH_SIZE) { 78 rowLength = in.getShort(); 79 ByteBufferUtils.skip(in, rowLength); 80 81 familyLength = in.get(); 82 83 qualifierLength = keyLength - rowLength - familyLength - 84 KeyValue.KEY_INFRASTRUCTURE_SIZE; 85 ByteBufferUtils.skip(in, familyLength + qualifierLength); 86 } else { 87 rowLength = previousState.rowLength; 88 familyLength = previousState.familyLength; 89 qualifierLength = previousState.qualifierLength + 90 keyLength - previousState.keyLength; 91 ByteBufferUtils.skip(in, (KeyValue.ROW_LENGTH_SIZE + 92 KeyValue.FAMILY_LENGTH_SIZE) + 93 rowLength + familyLength + qualifierLength); 94 } 95 96 readTimestamp(in); 97 98 type = in.get(); 99 100 in.reset(); 101 } 102 readTimestamp(ByteBuffer in)103 protected void readTimestamp(ByteBuffer in) { 104 // used in subclasses to add timestamp to state 105 ByteBufferUtils.skip(in, KeyValue.TIMESTAMP_SIZE); 106 } 107 copyFrom(CompressionState state)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 } 119