proxygen
Compression.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-present 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 #pragma once
18 
19 #include <cstdint>
20 #include <limits>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include <folly/Optional.h>
26 #include <folly/Range.h>
28 #include <folly/io/IOBuf.h>
29 
34 namespace folly {
35 namespace io {
36 
37 enum class CodecType {
43  USER_DEFINED = 0,
44 
49  NO_COMPRESSION = 1,
50 
55  LZ4 = 2,
56 
61  SNAPPY = 3,
62 
68  ZLIB = 4,
69 
73  LZ4_VARINT_SIZE = 5,
74 
80  LZMA2 = 6,
82 
89  ZSTD = 8,
90 
97  GZIP = 9,
98 
103  LZ4_FRAME = 10,
104 
112  BZIP2 = 11,
113 
126  ZSTD_FAST = 12,
127 
128  NUM_CODEC_TYPES = 13,
129 };
130 
131 class Codec {
132  public:
133  virtual ~Codec() {}
134 
135  static constexpr uint64_t UNLIMITED_UNCOMPRESSED_LENGTH = uint64_t(-1);
142  uint64_t maxUncompressedLength() const;
143 
147  CodecType type() const {
148  return type_;
149  }
150 
154  bool needsUncompressedLength() const;
155 
161  std::unique_ptr<IOBuf> compress(const folly::IOBuf* data);
162 
168  std::string compress(StringPiece data);
169 
182  std::unique_ptr<IOBuf> uncompress(
183  const IOBuf* data,
184  folly::Optional<uint64_t> uncompressedLength = folly::none);
185 
191  std::string uncompress(
192  StringPiece data,
193  folly::Optional<uint64_t> uncompressedLength = folly::none);
194 
199  uint64_t maxCompressedLength(uint64_t uncompressedLength) const;
200 
209  folly::Optional<uint64_t> getUncompressedLength(
210  const folly::IOBuf* data,
211  folly::Optional<uint64_t> uncompressedLength = folly::none) const;
212 
213  protected:
214  Codec(
215  CodecType type,
218  bool counters = true);
219 
220  public:
227  virtual std::vector<std::string> validPrefixes() const;
228 
235  virtual bool canUncompress(
236  const folly::IOBuf* data,
237  folly::Optional<uint64_t> uncompressedLength = folly::none) const;
238 
239  private:
240  // default: no limits (save for special value UNKNOWN_UNCOMPRESSED_LENGTH)
241  virtual uint64_t doMaxUncompressedLength() const;
242  // default: doesn't need uncompressed length
243  virtual bool doNeedsUncompressedLength() const;
244  virtual std::unique_ptr<IOBuf> doCompress(const folly::IOBuf* data) = 0;
245  virtual std::unique_ptr<IOBuf> doUncompress(
246  const folly::IOBuf* data,
247  folly::Optional<uint64_t> uncompressedLength) = 0;
248  // default: an implementation is provided by default to wrap the strings into
249  // IOBufs and delegate to the IOBuf methods. This incurs a copy of the output
250  // from IOBuf to string. Implementers, at their discretion, can override
251  // these methods to avoid the copy.
252  virtual std::string doCompressString(StringPiece data);
253  virtual std::string doUncompressString(
254  StringPiece data,
255  folly::Optional<uint64_t> uncompressedLength);
256 
257  virtual uint64_t doMaxCompressedLength(uint64_t uncompressedLength) const = 0;
258  // default: returns the passed uncompressedLength.
259  virtual folly::Optional<uint64_t> doGetUncompressedLength(
260  const folly::IOBuf* data,
261  folly::Optional<uint64_t> uncompressedLength) const;
262 
272 };
273 
274 class StreamCodec : public Codec {
275  public:
276  ~StreamCodec() override {}
277 
281  bool needsDataLength() const;
282 
283  /*****************************************************************************
284  * Streaming API
285  *****************************************************************************
286  * A low-level stateful streaming API.
287  * Streaming operations can be started in two ways:
288  * 1. From a clean Codec on which no non-const methods have been called.
289  * 2. A call to resetStream(), which will reset any codec to a clean state.
290  * After a streaming operation has begun, either compressStream() or
291  * uncompressStream() must be called until the streaming operation ends.
292  * compressStream() ends when it returns true with flushOp END.
293  * uncompressStream() ends when it returns true. At this point the codec
294  * may be reused by calling resetStream().
295  *
296  * compress() and uncompress() can be called at any time, but they interrupt
297  * any ongoing streaming operations (state is lost and resetStream() must be
298  * called before another streaming operation).
299  */
300 
309  void resetStream(folly::Optional<uint64_t> uncompressedLength = folly::none);
310 
311  enum class FlushOp { NONE, FLUSH, END };
312 
345  bool compressStream(
346  folly::ByteRange& input,
349 
386  bool uncompressStream(
387  folly::ByteRange& input,
388  folly::MutableByteRange& output,
390 
391  protected:
393  CodecType type,
396  bool counters = true)
397  : Codec(type, std::move(level), name, counters) {}
398 
399  // Returns the uncompressed length last passed to resetStream() or none if it
400  // hasn't been called yet.
402  return uncompressedLength_;
403  }
404 
405  private:
406  // default: Implemented using the streaming API.
407  std::unique_ptr<IOBuf> doCompress(const folly::IOBuf* data) override;
408  std::unique_ptr<IOBuf> doUncompress(
409  const folly::IOBuf* data,
410  folly::Optional<uint64_t> uncompressedLength) override;
411 
412  // default: Returns false
413  virtual bool doNeedsDataLength() const;
414  virtual void doResetStream() = 0;
415  virtual bool doCompressStream(
416  folly::ByteRange& input,
417  folly::MutableByteRange& output,
418  FlushOp flushOp) = 0;
419  virtual bool doUncompressStream(
420  folly::ByteRange& input,
421  folly::MutableByteRange& output,
422  FlushOp flushOp) = 0;
423 
424  enum class State {
425  RESET,
426  COMPRESS,
427  COMPRESS_FLUSH,
428  COMPRESS_END,
429  UNCOMPRESS,
430  END,
431  };
432  void assertStateIs(State expected) const;
433 
434  State state_{State::RESET};
435  ByteRange previousInput_{};
436  folly::Optional<uint64_t> uncompressedLength_{};
437  bool progressMade_{true};
438 };
439 
440 constexpr int COMPRESSION_LEVEL_FASTEST = -1;
441 constexpr int COMPRESSION_LEVEL_DEFAULT = -2;
442 constexpr int COMPRESSION_LEVEL_BEST = -3;
443 
460 std::unique_ptr<Codec> getCodec(
461  CodecType type,
462  int level = COMPRESSION_LEVEL_DEFAULT);
463 
480 std::unique_ptr<StreamCodec> getStreamCodec(
481  CodecType type,
482  int level = COMPRESSION_LEVEL_DEFAULT);
483 
522 std::unique_ptr<Codec> getAutoUncompressionCodec(
523  std::vector<std::unique_ptr<Codec>> customCodecs = {},
524  std::unique_ptr<Codec> terminalCodec = {});
525 
529 bool hasCodec(CodecType type);
530 
535 } // namespace io
536 } // namespace folly
constexpr int COMPRESSION_LEVEL_DEFAULT
Definition: Compression.h:441
virtual ~Codec()
Definition: Compression.h:133
bool hasCodec(CodecType type)
folly::detail::CompressionCounter compressionMilliseconds_
Definition: Compression.h:270
StreamCodec(CodecType type, folly::Optional< int > level=folly::none, folly::StringPiece name={}, bool counters=true)
Definition: Compression.h:392
PskType type
bool hasStreamCodec(CodecType type)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
folly::detail::CompressionCounter bytesAfterCompression_
Definition: Compression.h:265
folly::detail::CompressionCounter bytesBeforeDecompression_
Definition: Compression.h:266
const char * name
Definition: http_parser.c:437
folly::detail::CompressionCounter decompressions_
Definition: Compression.h:269
std::unique_ptr< StreamCodec > getStreamCodec(CodecType type, int level)
Type type_
Definition: JSONSchema.cpp:208
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
folly::detail::CompressionCounter bytesBeforeCompression_
Definition: Compression.h:264
folly::detail::CompressionCounter bytesAfterDecompression_
Definition: Compression.h:267
constexpr int COMPRESSION_LEVEL_BEST
Definition: Compression.h:442
folly::detail::CompressionCounter decompressionMilliseconds_
Definition: Compression.h:271
folly::Optional< uint64_t > uncompressedLength() const
Definition: Compression.h:401
CodecType type() const
Definition: Compression.h:147
const char * string
Definition: Conv.cpp:212
folly::detail::CompressionCounter compressions_
Definition: Compression.h:268
Wrapper around the makeCompressionCounterHandler() extension point.
Definition: Counters.h:70
CodecType type_
Definition: Compression.h:263
std::unique_ptr< Codec > getAutoUncompressionCodec(std::vector< std::unique_ptr< Codec >> customCodecs, std::unique_ptr< Codec > terminalCodec)
constexpr int COMPRESSION_LEVEL_FASTEST
Definition: Compression.h:440
std::unique_ptr< Codec > getCodec(CodecType type, int level)
constexpr None none
Definition: Optional.h:87