Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional parameters to ZstdCompressor #73

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 66 additions & 7 deletions src/compression.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,28 @@

struct ZstdCompressor <: TranscodingStreams.Codec
cstream::CStream
level::Int
endOp::LibZstd.ZSTD_EndDirective
parameters::Dict{LibZstd.ZSTD_cParameter, Cint}
function ZstdCompressor(cstream, level, endOp=:continue; kwargs...)
_parameters = Dict{LibZstd.ZSTD_cParameter, Cint}(LibZstd.ZSTD_c_compressionLevel => level)
for (k,v) in kwargs
_parameters[_symbols_to_cParameters[k]] = v
end

Check warning on line 12 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L11-L12

Added lines #L11 - L12 were not covered by tests
return new(cstream, endOp, _parameters)
end
end

function Base.show(io::IO, codec::ZstdCompressor)
parameters_string = ""
for (k,v) in codec.parameters
if k != LibZstd.ZSTD_c_compressionLevel
parameters_string *= string(", ", replace(string(k), "ZSTD_c_" => ""), "=", v)

Check warning on line 21 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L21

Added line #L21 was not covered by tests
end
end
if codec.endOp == LibZstd.ZSTD_e_end
print(io, "ZstdFrameCompressor(level=$(codec.level))")
print(io, "ZstdFrameCompressor(level=$(codec.level)$parameters_string)")
else
print(io, summary(codec), "(level=$(codec.level))")
print(io, summary(codec), "(level=$(codec.level)$parameters_string)")
end
end

Expand All @@ -27,13 +40,59 @@
---------
- `level`: compression level (1..$(MAX_CLEVEL))
"""
function ZstdCompressor(;level::Integer=DEFAULT_COMPRESSION_LEVEL)
function ZstdCompressor(;level::Integer=DEFAULT_COMPRESSION_LEVEL, kwargs...)
if !(1 ≤ level ≤ MAX_CLEVEL)
throw(ArgumentError("level must be within 1..$(MAX_CLEVEL)"))
end
return ZstdCompressor(CStream(), level)
return ZstdCompressor(CStream(), level; kwargs...)
end

const _symbols_to_cParameters = Dict(
:compressionLevel => LibZstd.ZSTD_c_compressionLevel,
:windowLog => LibZstd.ZSTD_c_windowLog,
:hashLog => LibZstd.ZSTD_c_hashLog,
:chainLog => LibZstd.ZSTD_c_chainLog,
:searchLog => LibZstd.ZSTD_c_searchLog,
:minMatch => LibZstd.ZSTD_c_minMatch,
:targetLength => LibZstd.ZSTD_c_targetLength,
:strategy => LibZstd.ZSTD_c_strategy,
:enableLongDistanceMatching => LibZstd.ZSTD_c_enableLongDistanceMatching,
:ldmHashLog => LibZstd.ZSTD_c_ldmHashLog,
:ldmMinMatch => LibZstd.ZSTD_c_ldmMinMatch,
:ldmBucketSizeLog => LibZstd.ZSTD_c_ldmBucketSizeLog,
:ldmHashRateLog => LibZstd.ZSTD_c_ldmHashRateLog,
:contentSizeFlag => LibZstd.ZSTD_c_contentSizeFlag,
:checksumFlag => LibZstd.ZSTD_c_checksumFlag,
:dictIDFlag => LibZstd.ZSTD_c_dictIDFlag,
:nbWorkers => LibZstd.ZSTD_c_nbWorkers,
:jobSize => LibZstd.ZSTD_c_jobSize,
:overlapLog => LibZstd.ZSTD_c_overlapLog
)

function Base.propertynames(compressor::ZstdCompressor)
return (fieldnames(ZstdCompressor)..., keys(_symbols_to_cParameters)...)

Check warning on line 73 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L72-L73

Added lines #L72 - L73 were not covered by tests
end

function Base.getproperty(compressor::ZstdCompressor, name::Symbol)
if name == :level
return Int(get(compressor.parameters, LibZstd.ZSTD_c_compressionLevel, DEFAULT_COMPRESSION_LEVEL))
elseif haskey(_symbols_to_cParameters, name)
return compressor.parameters[_symbols_to_cParameters[name]]

Check warning on line 80 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L80

Added line #L80 was not covered by tests
else
return getfield(compressor, name)
end
end

function Base.setproperty!(compressor::ZstdCompressor, name::Symbol, value)
if name == :level
compressor.parameters[LibZstd.ZSTD_c_compressionLevel] = value
elseif haskey(_symbols_to_cParameters, name)
compressor.parameters[_symbols_to_cParameters[name]] = value

Check warning on line 90 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L86-L90

Added lines #L86 - L90 were not covered by tests
else
return setfield!(compressor, name, value)

Check warning on line 92 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L92

Added line #L92 was not covered by tests
end
return nothing

Check warning on line 94 in src/compression.jl

View check run for this annotation

Codecov / codecov/patch

src/compression.jl#L94

Added line #L94 was not covered by tests
end
ZstdCompressor(cstream, level) = ZstdCompressor(cstream, level, :continue)

"""
ZstdFrameCompressor(;level=$(DEFAULT_COMPRESSION_LEVEL))
Expand Down Expand Up @@ -79,7 +138,7 @@
# -------

function TranscodingStreams.initialize(codec::ZstdCompressor)
code = initialize!(codec.cstream, codec.level)
code = initialize!(codec.cstream, codec.parameters)
if iserror(code)
zstderror(codec.cstream, code)
end
Expand Down
22 changes: 20 additions & 2 deletions src/libzstd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,26 @@
Base.unsafe_convert(::Type{Ptr{InBuffer}}, cstream::CStream) = Base.unsafe_convert(Ptr{InBuffer}, cstream.ibuffer)
Base.unsafe_convert(::Type{Ptr{OutBuffer}}, cstream::CStream) = Base.unsafe_convert(Ptr{OutBuffer}, cstream.obuffer)

function initialize!(cstream::CStream, level::Integer)
return LibZstd.ZSTD_initCStream(cstream, level)
function initialize!(cstream::CStream, parameters::Dict{LibZstd.ZSTD_cParameter, Cint})
# Mimick ZSTD_initCStream
# https://github.com/facebook/zstd/blob/20707e3718ee14250fb8a44b3bf023ea36bd88df/lib/zstd.h#L832-L841
code = LibZstd.ZSTD_CCtx_reset(cstream, LibZstd.ZSTD_reset_session_only)
if iserror(code)
zstderror(cstream, code)

Check warning on line 64 in src/libzstd.jl

View check run for this annotation

Codecov / codecov/patch

src/libzstd.jl#L64

Added line #L64 was not covered by tests
end

code = LibZstd.ZSTD_CCtx_refCDict(cstream, C_NULL)
if iserror(code)
zstderror(cstream, code)

Check warning on line 69 in src/libzstd.jl

View check run for this annotation

Codecov / codecov/patch

src/libzstd.jl#L69

Added line #L69 was not covered by tests
end

for (k,v) in parameters
code = LibZstd.ZSTD_CCtx_setParameter(cstream, k, v)
if iserror(code)
zstderror(cstream, code)

Check warning on line 75 in src/libzstd.jl

View check run for this annotation

Codecov / codecov/patch

src/libzstd.jl#L75

Added line #L75 was not covered by tests
end
end
return Csize_t(0)
end

function reset!(cstream::CStream, srcsize::Integer)
Expand Down
Loading