zstd-0.1.0.0: Codec/Compression/Zstd/Efficient.hs
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in
-- the LICENSE file in the root directory of this source tree. An
-- additional grant of patent rights can be found in the PATENTS file
-- in the same directory.
-- |
-- Module : Codec.Compression.Zstd.Efficient
-- Copyright : (c) 2016-present, Facebook, Inc. All rights reserved.
--
-- License : BSD3
-- Maintainer : bryano@fb.com
-- Stability : experimental
-- Portability : GHC
--
-- These functions allow for pre-allocation and reuse of relatively
-- expensive data structures, such as compression and decompression
-- contexts and dictionaries.
--
-- If your application mostly deals with small payloads and is
-- particularly sensitive to latency or throughput, using these
-- pre-allocated structures may make a noticeable difference to
-- performance.
module Codec.Compression.Zstd.Efficient
(
-- * Basic entry points
Decompress(..)
, decompressedSize
, C.maxCLevel
-- ** Cheaper operations using contexts
-- *** Compression
, CCtx
, withCCtx
, compressCCtx
-- *** Decompression
, DCtx
, withDCtx
, decompressDCtx
-- * Dictionary-based compression
, Dict
, mkDict
, fromDict
, trainFromSamples
, getDictID
-- ** Basic pure API
, compressUsingDict
, decompressUsingDict
-- ** Pre-digested dictionaries
, Base.CDict
, createCDict
, compressUsingCDict
, Base.DDict
, createDDict
, decompressUsingDDict
) where
import Codec.Compression.Zstd.Internal
import Codec.Compression.Zstd.Types (Decompress(..), Dict(..), mkDict)
import Codec.Compression.Zstd.Base.Types (CDict(..), DDict(..))
import Data.ByteString.Internal (ByteString(..))
import Foreign.ForeignPtr (withForeignPtr)
import System.IO.Unsafe (unsafePerformIO)
import qualified Codec.Compression.Zstd.FFI as C
import qualified Codec.Compression.Zstd.Base as Base
-- | Compress the given data as a single zstd compressed frame.
compressCCtx :: CCtx
-- ^ Compression context.
-> Int
-- ^ Compression level. Must be >= 1 and <= 'C.maxCLevel'.
-> ByteString
-- ^ Payload to compress.
-> IO ByteString
compressCCtx (CCtx cc) level bs =
compressWith "compressCCtx" (C.compressCCtx cc) level bs
-- | Decompress a single-frame payload of known size. Typically this
-- will be a payload that was compressed with 'compress'.
--
-- /Note:/ This function is not capable of decompressing a payload
-- generated by the streaming or lazy compression APIs.
decompressDCtx :: DCtx
-- ^ Decompression context.
-> ByteString
-- ^ Compressed payload.
-> IO Decompress
decompressDCtx (DCtx cc) bs = decompressWith (C.decompressDCtx cc) bs
-- | Compress the given data as a single zstd compressed frame, using
-- a prebuilt dictionary.
compressUsingDict :: Dict
-- ^ Compression dictionary.
-> Int
-- ^ Compression level. Must be >= 1 and <= 'C.maxCLevel'.
-> ByteString
-- ^ Payload to compress.
-> ByteString
compressUsingDict dict level bs =
unsafePerformIO . withCCtx $ \(CCtx ctx) ->
withDict dict $ \dictPtr dictLen ->
let compressor dp dl sp sl l =
C.compressUsingDict ctx dp dl sp sl dictPtr dictLen l
in compressWith "compressUsingDict" compressor level bs
-- | Decompress a single-frame payload of known size, using a prebuilt
-- dictionary. Typically this will be a payload that was compressed
-- with 'compressUsingDict'.
--
-- /Note:/ This function is not capable of decompressing a payload
-- generated by the streaming or lazy compression APIs.
decompressUsingDict :: Dict
-- ^ Dictionary.
-> ByteString
-- ^ Payload to decompress.
-> Decompress
decompressUsingDict dict bs =
unsafePerformIO . withDCtx $ \(DCtx ctx) ->
withDict dict $ \dictPtr dictLen ->
let decompressor dp dl sp sl =
C.decompressUsingDict ctx dp dl sp sl dictPtr dictLen
in decompressWith decompressor bs
-- | Create a pre-digested compression dictionary.
createCDict :: Int -- ^ Compression level.
-> Dict -- ^ Dictionary.
-> CDict
createCDict level d = unsafePerformIO $
withDict d $ \dict size -> Base.createCDict dict (fromIntegral size) level
-- | Compress the given data as a single zstd compressed frame, using
-- a pre-built, pre-digested dictionary.
compressUsingCDict :: CCtx
-- ^ Compression context.
-> CDict
-- ^ Compression dictionary.
-> ByteString
-- ^ Payload to compress.
-> IO ByteString
compressUsingCDict (CCtx ctx) (CD fp) bs =
withForeignPtr fp $ \dict -> do
let compressor dp dl sp sl _ = C.compressUsingCDict ctx dp dl sp sl dict
compressWith "compressUsingCDict" compressor 0 bs
-- | Create a pre-digested compression dictionary.
createDDict :: Dict -- ^ Dictionary.
-> DDict
createDDict d = unsafePerformIO $
withDict d $ \dict size -> Base.createDDict dict (fromIntegral size)
-- | Decompress a single-frame payload of known size, using a
-- pre-built, pre-digested dictionary. Typically this will be a
-- payload that was compressed with 'compressUsingCDict'.
--
-- /Note:/ This function is not capable of decompressing a payload
-- generated by the streaming or lazy compression APIs.
decompressUsingDDict :: DCtx
-- ^ Decompression context.
-> DDict
-- ^ Decompression dictionary.
-> ByteString
-- ^ Payload to compress.
-> IO Decompress
decompressUsingDDict (DCtx ctx) (DD fp) bs =
withForeignPtr fp $ \dict -> do
let decompressor dp dl sp sl = C.decompressUsingDDict ctx dp dl sp sl dict
decompressWith decompressor bs