A library for working with phylogenetic and population genetic data.
v0.27.0
gzip_output_target.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_IO_GZIP_OUTPUT_TARGET_H_
2 #define GENESIS_UTILS_IO_GZIP_OUTPUT_TARGET_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2021 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lczech@carnegiescience.edu>
23  Department of Plant Biology, Carnegie Institution For Science
24  260 Panama Street, Stanford, CA 94305, USA
25 */
26 
38 
39 #include <cassert>
40 #include <memory>
41 #include <string>
42 #include <stdexcept>
43 
44 namespace genesis {
45 namespace utils {
46 
47 // =================================================================================================
48 // Gzip Output Target
49 // =================================================================================================
50 
61 class GzipOutputTarget final : public BaseOutputTarget
62 {
63 public:
64 
65  // -------------------------------------------------------------
66  // Constructors and Rule of Five
67  // -------------------------------------------------------------
68 
74  explicit GzipOutputTarget(
75  std::shared_ptr<BaseOutputTarget> output_target,
77  )
78  : output_target_( output_target )
79  , compression_level_( compression_level )
80  {}
81 
82  GzipOutputTarget( GzipOutputTarget const& ) = delete;
83  GzipOutputTarget( GzipOutputTarget&& ) = default;
84 
85  GzipOutputTarget& operator= ( GzipOutputTarget const& ) = delete;
87 
88  ~GzipOutputTarget() override = default;
89 
90  // -------------------------------------------------------------
91  // Overloaded Internal Members
92  // -------------------------------------------------------------
93 
94 private:
95 
99  std::ostream& out_stream_() override
100  {
101  // Lazy loading. Needed in case we want to write in parallel to many files - having all
102  // open when creating the output targets might overflow the file pointers.
103  if( !stream_ || !stream_->good() ) {
104  // Although we are in untils namespace here, we specify the namespace full,
105  // in order to avoid ambiguous overload when compiled with C++17.
106  stream_ = genesis::utils::make_unique<GzipOStream>(
107  output_target_->ostream(), compression_level_
108  );
109  }
110  assert( stream_ );
111  assert( stream_->good() );
112  return *stream_;
113  }
114 
123  std::string target_name_() const override
124  {
125  if( compression_level_ == GzipCompressionLevel::kNoCompression ) {
126  return output_target_->target_name();
127  }
128  return "gzip-compressed " + output_target_->target_name();
129  }
130 
134  std::string target_string_() const override
135  {
136  return output_target_->target_name();
137  }
138 
139  // -------------------------------------------------------------
140  // Member Variables
141  // -------------------------------------------------------------
142 
143  // Need the wrapped target in order to keep it alive when it was handed over from
144  // a function such as to_file()
145  std::shared_ptr<BaseOutputTarget> output_target_;
146 
147  GzipCompressionLevel compression_level_;
148  std::unique_ptr<GzipOStream> stream_;
149 
150 };
151 
152 // =================================================================================================
153 // Gzip Block Output Target
154 // =================================================================================================
155 
175 {
176 public:
177 
178  // -------------------------------------------------------------
179  // Constructors and Rule of Five
180  // -------------------------------------------------------------
181 
190  std::shared_ptr<BaseOutputTarget> output_target,
191  std::size_t block_size = GzipBlockOStream::GZIP_DEFAULT_BLOCK_SIZE,
193  std::size_t num_threads = 0
194  )
195  : output_target_( output_target )
196  , block_size_( block_size )
197  , compression_level_( compression_level )
198  , num_threads_( num_threads )
199  {
200  if( compression_level_ == GzipCompressionLevel::kNoCompression ) {
201  throw std::invalid_argument(
202  "Cannot use compression level kNoCompression with a gzip block output."
203  );
204  }
205  }
206 
207  GzipBlockOutputTarget( GzipBlockOutputTarget const& ) = delete;
209 
212 
213  ~GzipBlockOutputTarget() override = default;
214 
215  // -------------------------------------------------------------
216  // Overloaded Internal Members
217  // -------------------------------------------------------------
218 
219 private:
220 
224  std::ostream& out_stream_() override
225  {
226  // Lazy loading. Needed in case we want to write in parallel to many files - having all
227  // open when creating the output targets might overflow the file pointers.
228  if( !stream_ || !stream_->good() ) {
229  // Although we are in untils namespace here, we specify the namespace full,
230  // in order to avoid ambiguous overload when compiled with C++17.
231  stream_ = genesis::utils::make_unique<GzipBlockOStream>(
232  output_target_->ostream(), block_size_, compression_level_, num_threads_
233  );
234  }
235  assert( stream_ );
236  assert( stream_->good() );
237  return *stream_;
238  }
239 
245  std::string target_name_() const override
246  {
247 
248  return "gzip-compressed " + output_target_->target_name();
249  }
250 
254  std::string target_string_() const override
255  {
256  return output_target_->target_name();
257  }
258 
259  // -------------------------------------------------------------
260  // Member Variables
261  // -------------------------------------------------------------
262 
263  // Need the wrapped target in order to keep it alive when it was handed over from
264  // a function such as to_file()
265  std::shared_ptr<BaseOutputTarget> output_target_;
266 
267  // Compressing block gzip stream
268  std::unique_ptr<GzipBlockOStream> stream_;
269 
270  // Need to store our settings, as we use lazy instanciation of the output stream
271  std::size_t block_size_;
272  GzipCompressionLevel compression_level_;
273  std::size_t num_threads_;
274 
275 };
276 
277 } // namespace utils
278 } // namespace genesis
279 
280 #endif // include guard
genesis::utils::GzipBlockOStream::GZIP_DEFAULT_BLOCK_SIZE
static const std::size_t GZIP_DEFAULT_BLOCK_SIZE
Definition: gzip_block_ostream.hpp:111
genesis::utils::BaseOutputTarget
Abstract base class for writing data to an output target.
Definition: base_output_target.hpp:48
genesis::utils::GzipBlockOutputTarget::GzipBlockOutputTarget
GzipBlockOutputTarget(std::shared_ptr< BaseOutputTarget > output_target, std::size_t block_size=GzipBlockOStream::GZIP_DEFAULT_BLOCK_SIZE, GzipCompressionLevel compression_level=GzipCompressionLevel::kDefaultCompression, std::size_t num_threads=0)
Construct the output target using another output target (FileOutputTarget, StringOutputTarget,...
Definition: gzip_output_target.hpp:189
genesis::utils::GzipBlockOutputTarget::operator=
GzipBlockOutputTarget & operator=(GzipBlockOutputTarget const &)=delete
std.hpp
Provides some valuable additions to STD.
genesis::utils::GzipCompressionLevel
GzipCompressionLevel
List of possible compression levels used for GzipOStream.
Definition: gzip_stream.hpp:100
genesis::utils::GzipOutputTarget::GzipOutputTarget
GzipOutputTarget(std::shared_ptr< BaseOutputTarget > output_target, GzipCompressionLevel compression_level=GzipCompressionLevel::kDefaultCompression)
Construct the output target using another output target (FileOutputTarget, StringOutputTarget,...
Definition: gzip_output_target.hpp:74
genesis::utils::GzipOutputTarget::operator=
GzipOutputTarget & operator=(GzipOutputTarget const &)=delete
gzip_stream.hpp
genesis::utils::GzipOutputTarget
Output target for writing byte data to a gzip/zlib-compressed target.
Definition: gzip_output_target.hpp:61
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
gzip_block_ostream.hpp
genesis::utils::GzipBlockOutputTarget
Output target for writing byte data to a gzip-compressed target in blocks of gzip data.
Definition: gzip_output_target.hpp:174
genesis::utils::GzipCompressionLevel::kNoCompression
@ kNoCompression
genesis::utils::GzipOutputTarget::~GzipOutputTarget
~GzipOutputTarget() override=default
genesis::utils::GzipCompressionLevel::kDefaultCompression
@ kDefaultCompression
genesis::utils::GzipBlockOutputTarget::~GzipBlockOutputTarget
~GzipBlockOutputTarget() override=default
base_output_target.hpp