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.compress.zstd; 019 020import com.github.luben.zstd.ZstdDictDecompress; 021import edu.umd.cs.findbugs.annotations.Nullable; 022import java.io.IOException; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.io.compress.Compression; 025import org.apache.hadoop.hbase.util.ClassSize; 026import org.apache.hadoop.hbase.util.Pair; 027import org.apache.yetus.audience.InterfaceAudience; 028 029/** 030 * Holds HFile-level settings used by ZstdByteBuffDecompressor. It's expensive to pull these from a 031 * Configuration object every time we decompress a block, so pull them upon opening an HFile, and 032 * reuse them in every block that gets decompressed. 033 */ 034@InterfaceAudience.Private 035public final class ZstdHFileDecompressionContext extends Compression.HFileDecompressionContext { 036 037 public static final long FIXED_OVERHEAD = 038 ClassSize.estimateBase(ZstdHFileDecompressionContext.class, false); 039 040 @Nullable 041 private final ZstdDictDecompress dict; 042 private final int dictId; 043 // Intended to be set to false by some unit tests 044 private final boolean allowByteBuffDecompression; 045 046 private ZstdHFileDecompressionContext(@Nullable ZstdDictDecompress dict, int dictId, 047 boolean allowByteBuffDecompression) { 048 this.dict = dict; 049 this.dictId = dictId; 050 this.allowByteBuffDecompression = allowByteBuffDecompression; 051 } 052 053 @Nullable 054 public ZstdDictDecompress getDict() { 055 return dict; 056 } 057 058 public int getDictId() { 059 return dictId; 060 } 061 062 public boolean isAllowByteBuffDecompression() { 063 return allowByteBuffDecompression; 064 } 065 066 public static ZstdHFileDecompressionContext fromConfiguration(Configuration conf) { 067 boolean allowByteBuffDecompression = 068 conf.getBoolean("hbase.io.compress.zstd.allowByteBuffDecompression", true); 069 Pair<ZstdDictDecompress, Integer> dictAndId = ZstdCodec.getDecompressDictionary(conf); 070 if (dictAndId != null) { 071 return new ZstdHFileDecompressionContext(dictAndId.getFirst(), dictAndId.getSecond(), 072 allowByteBuffDecompression); 073 } else { 074 return new ZstdHFileDecompressionContext(null, 0, allowByteBuffDecompression); 075 } 076 } 077 078 @Override 079 public void close() throws IOException { 080 if (dict != null) { 081 dict.close(); 082 } 083 } 084 085 @Override 086 public long heapSize() { 087 // ZstdDictDecompress objects are cached and shared between ZstdHFileDecompressionContexts, so 088 // don't include ours in our heap size. 089 return FIXED_OVERHEAD; 090 } 091 092 @Override 093 public String toString() { 094 return "ZstdHFileDecompressionContext{dictId=" + dictId + ", allowByteBuffDecompression=" 095 + allowByteBuffDecompression + '}'; 096 } 097}