5a5f9d8992c89e2a5740e191ebcaab275083effa
[folly.git] / folly / io / Compression.h
1 /*
2  * Copyright 2013 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_IO_COMPRESSION_H_
18 #define FOLLY_IO_COMPRESSION_H_
19
20 #include <cstdint>
21 #include <limits>
22 #include <memory>
23
24 #include "folly/io/IOBuf.h"
25
26 /**
27  * Compression / decompression over IOBufs
28  */
29
30 namespace folly { namespace io {
31
32 enum class CodecType {
33   /**
34    * Use no compression.
35    * Levels supported: 0
36    */
37   NO_COMPRESSION = 0,
38
39   /**
40    * Use LZ4 compression.
41    * Levels supported: 1 = fast, 2 = best; default = 1
42    */
43   LZ4 = 1,
44
45   /**
46    * Use Snappy compression.
47    * Levels supported: 1
48    */
49   SNAPPY = 2,
50
51   /**
52    * Use zlib compression.
53    * Levels supported: 0 = no compression, 1 = fast, ..., 9 = best; default = 6
54    */
55   ZLIB = 3,
56
57   NUM_CODEC_TYPES = 4,
58 };
59
60 class Codec {
61  public:
62   virtual ~Codec() { }
63
64   /**
65    * Return the maximum length of data that may be compressed with this codec.
66    * NO_COMPRESSION and ZLIB support arbitrary lengths;
67    * LZ4 supports up to 1.9GiB; SNAPPY supports up to 4GiB.
68    */
69   uint64_t maxUncompressedLength() const;
70
71   /**
72    * Return the codec's type.
73    */
74   CodecType type() const;
75
76   /**
77    * Does this codec need the exact uncompressed length on decompression?
78    */
79   bool needsUncompressedLength() const;
80
81   /**
82    * Compress data, returning an IOBuf (which may share storage with data).
83    * Throws std::invalid_argument if data is larger than
84    * maxUncompressedLength().
85    *
86    * Regardless of the behavior of the underlying compressor, compressing
87    * an empty IOBuf chain will return an empty IOBuf chain.
88    */
89   std::unique_ptr<IOBuf> compress(const folly::IOBuf* data);
90
91   /**
92    * Uncompress data. Throws std::runtime_error on decompression error.
93    *
94    * Some codecs (LZ4) require the exact uncompressed length; this is indicated
95    * by needsUncompressedLength().
96    *
97    * For other codes (zlib), knowing the exact uncompressed length ahead of
98    * time might be faster.
99    *
100    * Regardless of the behavior of the underlying compressor, uncompressing
101    * an empty IOBuf chain will return an empty IOBuf chain.
102    */
103   static constexpr uint64_t UNKNOWN_UNCOMPRESSED_LENGTH = uint64_t(-1);
104
105   std::unique_ptr<IOBuf> uncompress(
106       const IOBuf* data,
107       uint64_t uncompressedLength = UNKNOWN_UNCOMPRESSED_LENGTH);
108
109  private:
110   // default: no limits (save for special value UNKNOWN_UNCOMPRESSED_LENGTH)
111   virtual uint64_t doMaxUncompressedLength() const;
112   // default: doesn't need uncompressed length
113   virtual bool doNeedsUncompressedLength() const;
114   virtual CodecType doType() const = 0;
115   virtual std::unique_ptr<IOBuf> doCompress(const folly::IOBuf* data) = 0;
116   virtual std::unique_ptr<IOBuf> doUncompress(const folly::IOBuf* data,
117                                               uint64_t uncompressedLength) = 0;
118 };
119
120 constexpr int COMPRESSION_LEVEL_FASTEST = -1;
121 constexpr int COMPRESSION_LEVEL_DEFAULT = -2;
122 constexpr int COMPRESSION_LEVEL_BEST = -3;
123
124 /**
125  * Return a codec for the given type. Throws on error.  The level
126  * is a non-negative codec-dependent integer indicating the level of
127  * compression desired, or one of the following constants:
128  *
129  * COMPRESSION_LEVEL_FASTEST is fastest (uses least CPU / memory,
130  *   worst compression)
131  * COMPRESSION_LEVEL_DEFAULT is the default (likely a tradeoff between
132  *   FASTEST and BEST)
133  * COMPRESSION_LEVEL_BEST is the best compression (uses most CPU / memory,
134  *   best compression)
135  */
136 std::unique_ptr<Codec> getCodec(CodecType type,
137                                 int level = COMPRESSION_LEVEL_DEFAULT);
138
139 }}  // namespaces
140
141 #endif /* FOLLY_IO_COMPRESSION_H_ */
142