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  private int bufferSize;
051  private int level;
052  private int window;
053
054  public BrotliCodec() {
055    conf = new Configuration();
056    bufferSize = getBufferSize(conf);
057    level = getLevel(conf);
058    window = getWindow(conf);
059  }
060
061  @Override
062  public Configuration getConf() {
063    return conf;
064  }
065
066  @Override
067  public void setConf(Configuration conf) {
068    this.conf = conf;
069    this.bufferSize = getBufferSize(conf);
070    this.level = getLevel(conf);
071    this.window = getWindow(conf);
072  }
073
074  @Override
075  public Compressor createCompressor() {
076    return new BrotliCompressor(level, window, bufferSize);
077  }
078
079  @Override
080  public Decompressor createDecompressor() {
081    return new BrotliDecompressor(bufferSize);
082  }
083
084  @Override
085  public CompressionInputStream createInputStream(InputStream in) throws IOException {
086    return createInputStream(in, createDecompressor());
087  }
088
089  @Override
090  public CompressionInputStream createInputStream(InputStream in, Decompressor d)
091    throws IOException {
092    return new BlockDecompressorStream(in, d, bufferSize);
093  }
094
095  @Override
096  public CompressionOutputStream createOutputStream(OutputStream out) throws IOException {
097    return createOutputStream(out, createCompressor());
098  }
099
100  @Override
101  public CompressionOutputStream createOutputStream(OutputStream out, Compressor c)
102    throws IOException {
103    return new BlockCompressorStream(out, c, bufferSize,
104      CompressionUtil.compressionOverhead(bufferSize));
105  }
106
107  @Override
108  public Class<? extends Compressor> getCompressorType() {
109    return BrotliCompressor.class;
110  }
111
112  @Override
113  public Class<? extends Decompressor> getDecompressorType() {
114    return BrotliDecompressor.class;
115  }
116
117  @Override
118  public String getDefaultExtension() {
119    return ".br";
120  }
121
122  // Package private
123
124  static int getLevel(Configuration conf) {
125    return conf.getInt(BROTLI_LEVEL_KEY, BROTLI_LEVEL_DEFAULT);
126  }
127
128  static int getWindow(Configuration conf) {
129    return conf.getInt(BROTLI_WINDOW_KEY, BROTLI_WINDOW_DEFAULT);
130  }
131
132  static int getBufferSize(Configuration conf) {
133    return conf.getInt(BROTLI_BUFFERSIZE_KEY, BROTLI_BUFFERSIZE_DEFAULT);
134  }
135
136}