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.io.DataInputStream; 020import java.io.DataOutputStream; 021import java.io.IOException; 022import java.nio.ByteBuffer; 023import org.apache.hadoop.hbase.Cell; 024import org.apache.hadoop.hbase.nio.ByteBuff; 025import org.apache.hadoop.hbase.util.ByteBufferUtils; 026import org.apache.hadoop.hbase.util.Bytes; 027import org.apache.yetus.audience.InterfaceAudience; 028 029/** 030 * Just copy data, do not do any kind of compression. Use for comparison and 031 * benchmarking. 032 */ 033@InterfaceAudience.Private 034public class CopyKeyDataBlockEncoder extends BufferedDataBlockEncoder { 035 036 private static class CopyKeyEncodingState extends EncodingState { 037 NoneEncoder encoder = null; 038 } 039 040 @Override 041 public void startBlockEncoding(HFileBlockEncodingContext blkEncodingCtx, 042 DataOutputStream out) throws IOException { 043 if (blkEncodingCtx.getClass() != HFileBlockDefaultEncodingContext.class) { 044 throw new IOException(this.getClass().getName() + " only accepts " 045 + HFileBlockDefaultEncodingContext.class.getName() + " as the " 046 + "encoding context."); 047 } 048 049 HFileBlockDefaultEncodingContext encodingCtx = 050 (HFileBlockDefaultEncodingContext) blkEncodingCtx; 051 encodingCtx.prepareEncoding(out); 052 053 NoneEncoder encoder = new NoneEncoder(out, encodingCtx); 054 CopyKeyEncodingState state = new CopyKeyEncodingState(); 055 state.encoder = encoder; 056 blkEncodingCtx.setEncodingState(state); 057 } 058 059 @Override 060 public int internalEncode(Cell cell, 061 HFileBlockDefaultEncodingContext encodingContext, DataOutputStream out) 062 throws IOException { 063 CopyKeyEncodingState state = (CopyKeyEncodingState) encodingContext 064 .getEncodingState(); 065 NoneEncoder encoder = state.encoder; 066 return encoder.write(cell); 067 } 068 069 @Override 070 public Cell getFirstKeyCellInBlock(ByteBuff block) { 071 int keyLength = block.getIntAfterPosition(Bytes.SIZEOF_INT); 072 int pos = 3 * Bytes.SIZEOF_INT; 073 ByteBuffer key = block.asSubByteBuffer(pos + keyLength).duplicate(); 074 return createFirstKeyCell(key, keyLength); 075 } 076 077 @Override 078 public String toString() { 079 return CopyKeyDataBlockEncoder.class.getSimpleName(); 080 } 081 082 @Override 083 public EncodedSeeker createSeeker(final HFileBlockDecodingContext decodingCtx) { 084 return new SeekerStateBufferedEncodedSeeker(decodingCtx); 085 } 086 087 @Override 088 protected ByteBuffer internalDecodeKeyValues(DataInputStream source, int allocateHeaderLength, 089 int skipLastBytes, HFileBlockDefaultDecodingContext decodingCtx) throws IOException { 090 int decompressedSize = source.readInt(); 091 ByteBuffer buffer = ByteBuffer.allocate(decompressedSize + 092 allocateHeaderLength); 093 buffer.position(allocateHeaderLength); 094 ByteBufferUtils.copyFromStreamToBuffer(buffer, source, decompressedSize); 095 096 return buffer; 097 } 098 099 private static class SeekerStateBufferedEncodedSeeker 100 extends BufferedEncodedSeeker<SeekerState> { 101 102 private SeekerStateBufferedEncodedSeeker(HFileBlockDecodingContext decodingCtx) { 103 super(decodingCtx); 104 } 105 106 @Override 107 protected void decodeNext() { 108 current.keyLength = currentBuffer.getInt(); 109 current.valueLength = currentBuffer.getInt(); 110 current.ensureSpaceForKey(); 111 currentBuffer.get(current.keyBuffer, 0, current.keyLength); 112 current.valueOffset = currentBuffer.position(); 113 currentBuffer.skip(current.valueLength); 114 if (includesTags()) { 115 // Read short as unsigned, high byte first 116 current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff); 117 currentBuffer.skip(current.tagsLength); 118 } 119 if (includesMvcc()) { 120 current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer); 121 } else { 122 current.memstoreTS = 0; 123 } 124 current.nextKvOffset = currentBuffer.position(); 125 } 126 127 @Override 128 protected void decodeFirst() { 129 currentBuffer.skip(Bytes.SIZEOF_INT); 130 current.lastCommonPrefix = 0; 131 decodeNext(); 132 } 133 } 134 135}