This repository was archived by the owner on Apr 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Add more compression formats #90
Merged
Merged
Changes from 9 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
255664b
Move most of the code from https://github.com/JuliaOpt/JuMP.jl/pull/1…
dourouc05 86824a7
Refactor to use a dictionary storing all the variance within compress…
dourouc05 bbd1eed
Same refactoring for model types.
dourouc05 698b8cc
Start restructuring compression format handling.
dourouc05 7460eae
Finalise implementation based on types.
dourouc05 68f635d
Add documentation for AbstractCompressionScheme.
dourouc05 3139964
Clean up code.
dourouc05 38534cf
Add more tests.
dourouc05 e7c932d
Comment out XZ.
dourouc05 21cb685
Remove dependency for commented out code.
dourouc05 2b71875
Comment out XZ.
dourouc05 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,8 @@ authors = ["Oscar Dowson <[email protected]"] | |
| version = "0.2.2" | ||
|
|
||
| [deps] | ||
| CodecBzip2 = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" | ||
| CodecXz = "ba30903b-d9e8-5048-a5ec-d1f5b0d4b47b" | ||
| CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193" | ||
| DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" | ||
| HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,8 +3,11 @@ module MathOptFormat | |
| import MathOptInterface | ||
| const MOI = MathOptInterface | ||
|
|
||
| import CodecBzip2 | ||
| import CodecXz | ||
| import CodecZlib | ||
|
|
||
| include("compression.jl") | ||
| include("CBF/CBF.jl") | ||
| include("LP/LP.jl") | ||
| include("MOF/MOF.jl") | ||
|
|
@@ -133,36 +136,51 @@ function create_unique_variable_names( | |
| end | ||
| end | ||
|
|
||
| function gzip_open(f::Function, filename::String, mode::String) | ||
| if endswith(filename, ".gz") | ||
| if mode == "r" | ||
| open(CodecZlib.GzipDecompressorStream, filename, mode) do io | ||
| f(io) | ||
| end | ||
| elseif mode == "w" | ||
| open(CodecZlib.GzipCompressorStream, filename, mode) do io | ||
| f(io) | ||
| """ | ||
| List of accepted export formats. `AUTOMATIC_FILE_FORMAT` corresponds to | ||
| a detection from the file name, only based on the extension (regardless of | ||
| compression format). | ||
| """ | ||
| @enum(FileFormat, FORMAT_CBF, FORMAT_LP, FORMAT_MOF, FORMAT_MPS, AUTOMATIC_FILE_FORMAT) | ||
|
|
||
| const _file_formats = Dict{FileFormat, Tuple{String, Any}}( | ||
| # ENUMERATED VALUE => extension, model type | ||
| FORMAT_CBF => (".cbf", CBF.Model), | ||
| FORMAT_LP => (".lp", LP.Model), | ||
| FORMAT_MOF => (".mof.json", MOF.Model), | ||
| FORMAT_MPS => (".mps", MPS.Model) | ||
| ) | ||
|
|
||
| function _filename_to_format(filename::String) | ||
| for compr_ext in ["", ".bz2", ".gz", ".xz"] | ||
| for (type, format) in _file_formats | ||
| if endswith(filename, "$(format[1])$(compr_ext)") | ||
| return type | ||
| end | ||
| else | ||
| throw(ArgumentError("Mode must be \"r\" or \"w\"")) | ||
| end | ||
| else | ||
| return open(f, filename, mode) | ||
| end | ||
|
|
||
| error("File type of $(filename) not recognized by MathOptFormat.jl.") | ||
| end | ||
|
|
||
| function _filename_to_model(filename::String) | ||
| return _file_formats[_filename_to_format(filename)][2]() | ||
| end | ||
|
|
||
| const MATH_OPT_FORMATS = Union{ | ||
| CBF.InnerModel, LP.InnerModel, MOF.Model, MPS.InnerModel | ||
| } | ||
|
|
||
| function MOI.write_to_file(model::MATH_OPT_FORMATS, filename::String) | ||
| gzip_open(filename, "w") do io | ||
| function MOI.write_to_file(model::MATH_OPT_FORMATS, filename::String; compression::AbstractCompressionScheme=AutomaticCompression()) | ||
| compression = _automatic_compression(filename, compression) | ||
| _compressed_open(filename, "w", compression) do io | ||
| MOI.write_to_file(model, io) | ||
| end | ||
| end | ||
|
|
||
| function MOI.read_from_file(model::MATH_OPT_FORMATS, filename::String) | ||
| gzip_open(filename, "r") do io | ||
| function MOI.read_from_file(model::MATH_OPT_FORMATS, filename::String; compression::AbstractCompressionScheme=AutomaticCompression()) | ||
| compression = _automatic_compression(filename, compression) | ||
| _compressed_open(filename, "r", compression) do io | ||
| MOI.read_from_file(model, io) | ||
| end | ||
| end | ||
|
|
@@ -173,19 +191,9 @@ end | |
| Create a MOI model by reading `filename`. Type of the returned model depends on | ||
| the extension of `filename`. | ||
| """ | ||
| function read_from_file(filename::String) | ||
| model = if endswith(filename, ".mof.json.gz") || endswith(filename, ".mof.json") | ||
| MOF.Model() | ||
| elseif endswith(filename, ".cbf.gz") || endswith(filename, ".cbf") | ||
| CBF.Model() | ||
| elseif endswith(filename, ".mps.gz") || endswith(filename, ".mps") | ||
| MPS.Model() | ||
| elseif endswith(filename, ".lp.gz") || endswith(filename, ".lp") | ||
| LP.Model() | ||
| else | ||
| error("File-type of $(filename) not supported by MathOptFormat.jl.") | ||
| end | ||
| MOI.read_from_file(model, filename) | ||
| function read_from_file(filename::String; compression::AbstractCompressionScheme=AutomaticCompression()) | ||
| model = _filename_to_model(filename) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. function read_from_file(
filename::String;
compression::AbstractCompressionScheme = AutomaticCompression(),
file_format::FileFormat = AUTOMATIC_FILE_FORMAT,
)
if file_format == AUTOMATIC_FILE_FORMAT
for (format, (ext, _)) in _FILE_FORMATS
if endswith(filename, ext) || occursin("$(ext).", filename)
file_format = format
break
end
end
error(
"Unable to detect automatically format of $(filename). Use the " *
"`file_format` keyword to specify the file format."
)
end
model = _FILE_FORMATS[file_format]()
MOI.read_from_file(model, filename; compression = compression)
return model
endYou might want to do something similar with |
||
| MOI.read_from_file(model, filename, compression=compression) | ||
| return model | ||
| end | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| function error_mode(mode::String) | ||
| throw(ArgumentError("For dealing with compressed data, mode must be \"r\" or \"w\"; $mode given")) | ||
| end | ||
|
|
||
| """ | ||
| abstract type AbstractCompressionScheme end | ||
|
|
||
| Base type to implement a new compression scheme for MathOptFormat. To do so, | ||
| create a concrete subtype (e.g., named after the compression scheme) and | ||
| implement `open(f::Function, filename::String, mode::String, ::YourScheme)`. | ||
| """ | ||
| abstract type AbstractCompressionScheme end | ||
|
|
||
| struct AutomaticCompression <: AbstractCompressionScheme end | ||
| # No open() implementation, this would not make sense (flag to indicate that _filename_to_compression should be called). | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. function _compressed_open(
f::Function,
filename::String,
mode::String,
::AutomaticCompression
)
compression = _filename_to_compression(filename)
return _compressed_open(f, filename, mode, compression)
end |
||
|
|
||
| struct NoCompression <: AbstractCompressionScheme end | ||
| function _compressed_open( | ||
| f::Function, filename::String, mode::String, ::NoCompression | ||
| ) | ||
| return Base.open(f, filename, mode) | ||
| end | ||
|
|
||
| struct Gzip <: AbstractCompressionScheme end | ||
| function _compressed_open( | ||
| f::Function, filename::String, mode::String, ::Gzip | ||
| ) | ||
| return if mode == "w" | ||
| Base.open(f, CodecZlib.GzipCompressorStream, filename, mode) | ||
| elseif mode == "r" | ||
| Base.open(f, CodecZlib.GzipDecompressorStream, filename, mode) | ||
| else | ||
| error_mode(mode) | ||
| end | ||
| end | ||
|
|
||
| struct Bzip2 <: AbstractCompressionScheme end | ||
| function _compressed_open( | ||
| f::Function, filename::String, mode::String, ::Bzip2 | ||
| ) | ||
| if mode == "w" | ||
| Base.open(f, CodecBzip2.Bzip2CompressorStream, filename, mode) | ||
| elseif mode == "r" | ||
| Base.open(f, CodecBzip2.Bzip2DecompressorStream, filename, mode) | ||
| else | ||
| error_mode(mode) | ||
| end | ||
| end | ||
|
|
||
| # struct Xz <: AbstractCompressionScheme end | ||
| # function _compressed_open( | ||
| # f::Function, filename::String, mode::String, ::Xz | ||
| # ) | ||
| # return if mode == "w" | ||
| # Base.open(f, CodecXz.XzDecompressorStream, filename, mode) | ||
| # elseif mode == "r" | ||
| # Base.open(f, CodecXz.XzCompressorStream, filename, mode) | ||
| # else | ||
| # error_mode(mode) | ||
| # end | ||
| # end | ||
|
|
||
| function _automatic_compression(filename::String, compression::AbstractCompressionScheme) | ||
| if compression == AutomaticCompression() | ||
| return _filename_to_compression(filename) | ||
| end | ||
| return compression | ||
| end | ||
|
|
||
| function _filename_to_compression(filename::String) | ||
| if endswith(filename, ".bz2") | ||
| return Bzip2() | ||
| elseif endswith(filename, ".gz") | ||
| return Gzip() | ||
| # elseif endswith(filename, ".xz") | ||
| # return Xz() | ||
| else | ||
| return NoCompression() | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.