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.brotli;
019
020import java.io.IOException;
021import java.io.InputStream;
022import java.io.OutputStream;
023import org.apache.hadoop.conf.Configurable;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.io.compress.CompressionUtil;
026import org.apache.hadoop.io.compress.BlockCompressorStream;
027import org.apache.hadoop.io.compress.BlockDecompressorStream;
028import org.apache.hadoop.io.compress.CompressionCodec;
029import org.apache.hadoop.io.compress.CompressionInputStream;
030import org.apache.hadoop.io.compress.CompressionOutputStream;
031import org.apache.hadoop.io.compress.Compressor;
032import org.apache.hadoop.io.compress.Decompressor;
033import org.apache.yetus.audience.InterfaceAudience;
034
035/**
036 * Hadoop brotli codec implemented with Brotli4j
037 */
038@InterfaceAudience.Private
039public class BrotliCodec implements Configurable, CompressionCodec {
040
041  public static final String BROTLI_LEVEL_KEY = "hbase.io.compress.brotli.level";
042  // Our default is 6, based on https://blog.cloudflare.com/results-experimenting-brotli/
043  public static final int BROTLI_LEVEL_DEFAULT = 6; // [0,11] or -1
044  public static final String BROTLI_WINDOW_KEY = "hbase.io.compress.brotli.window";
045  public static final int BROTLI_WINDOW_DEFAULT = -1; // [10-24] or -1
046  public static final String BROTLI_BUFFERSIZE_KEY = "hbase.io.compress.brotli.buffersize";
047  public static final int BROTLI_BUFFERSIZE_DEFAULT = 256 * 1024;
048
049  private Configuration conf;
050
051  public BrotliCodec() {
052    conf = new Configuration();
053  }
054
055  @Override
056  public Configuration getConf() {
057    return conf;
058  }
059
060  @Override
061  public void setConf(Configuration conf) {
062    this.conf = conf;
063  }
064
065  @Override
066  public Compressor createCompressor() {
067    return new BrotliCompressor(getLevel(conf), getWindow(conf), getBufferSize(conf));
068  }
069
070  @Override
071  public Decompressor createDecompressor() {
072    return new BrotliDecompressor(getBufferSize(conf));
073  }
074
075  @Override
076  public CompressionInputStream createInputStream(InputStream in) throws IOException {
077    return createInputStream(in, createDecompressor());
078  }
079
080  @Override
081  public CompressionInputStream createInputStream(InputStream in, Decompressor d)
082    throws IOException {
083    return new BlockDecompressorStream(in, d, getBufferSize(conf));
084  }
085
086  @Override
087  public CompressionOutputStream createOutputStream(OutputStream out) throws IOException {
088    return createOutputStream(out, createCompressor());
089  }
090
091  @Override
092  public CompressionOutputStream createOutputStream(OutputStream out, Compressor c)
093    throws IOException {
094    int bufferSize = getBufferSize(conf);
095    return new BlockCompressorStream(out, c, bufferSize,
096      CompressionUtil.compressionOverhead(bufferSize));
097  }
098
099  @Override
100  public Class<? extends Compressor> getCompressorType() {
101    return BrotliCompressor.class;
102  }
103
104  @Override
105  public Class<? extends Decompressor> getDecompressorType() {
106    return BrotliDecompressor.class;
107  }
108
109  @Override
110  public String getDefaultExtension() {
111    return ".br";
112  }
113
114  // Package private
115
116  static int getLevel(Configuration conf) {
117    return conf.getInt(BROTLI_LEVEL_KEY, BROTLI_LEVEL_DEFAULT);
118  }
119
120  static int getWindow(Configuration conf) {
121    return conf.getInt(BROTLI_WINDOW_KEY, BROTLI_WINDOW_DEFAULT);
122  }
123
124  static int getBufferSize(Configuration conf) {
125    return conf.getInt(BROTLI_BUFFERSIZE_KEY, BROTLI_BUFFERSIZE_DEFAULT);
126  }
127
128}