A library for working with phylogenetic and population genetic data.
v0.32.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-2024 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 utils namespace here already, 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 
176 {
177 public:
178 
179  // -------------------------------------------------------------
180  // Constructors and Rule of Five
181  // -------------------------------------------------------------
182 
191  std::shared_ptr<BaseOutputTarget> output_target,
192  std::size_t block_size = GzipBlockOStream::GZIP_DEFAULT_BLOCK_SIZE,
194  std::shared_ptr<ThreadPool> thread_pool = nullptr
195  )
196  : output_target_( output_target )
197  , block_size_( block_size )
198  , compression_level_( compression_level )
199  , thread_pool_( thread_pool )
200  {
201  if( compression_level_ == GzipCompressionLevel::kNoCompression ) {
202  throw std::invalid_argument(
203  "Cannot use compression level kNoCompression with a gzip block output."
204  );
205  }
206  }
207 
208  GzipBlockOutputTarget( GzipBlockOutputTarget const& ) = delete;
210 
213 
214  ~GzipBlockOutputTarget() override = default;
215 
216  // -------------------------------------------------------------
217  // Overloaded Internal Members
218  // -------------------------------------------------------------
219 
220 private:
221 
225  std::ostream& out_stream_() override
226  {
227  // Lazy loading. Needed in case we want to write in parallel to many files - having all
228  // open when creating the output targets might overflow the file pointers.
229  if( !stream_ || !stream_->good() ) {
230  // Although we are in untils namespace here, we specify the namespace full,
231  // in order to avoid ambiguous overload when compiled with C++17.
232  stream_ = genesis::utils::make_unique<GzipBlockOStream>(
233  output_target_->ostream(), block_size_, compression_level_, thread_pool_
234  );
235  }
236  assert( stream_ );
237  assert( stream_->good() );
238  return *stream_;
239  }
240 
246  std::string target_name_() const override
247  {
248 
249  return "gzip-compressed " + output_target_->target_name();
250  }
251 
255  std::string target_string_() const override
256  {
257  return output_target_->target_name();
258  }
259 
260  // -------------------------------------------------------------
261  // Member Variables
262  // -------------------------------------------------------------
263 
264  // Need the wrapped target in order to keep it alive when it was handed over from
265  // a function such as to_file()
266  std::shared_ptr<BaseOutputTarget> output_target_;
267 
268  // Compressing block gzip stream
269  std::unique_ptr<GzipBlockOStream> stream_;
270 
271  // Need to store our settings, as we use lazy instanciation of the output stream
272  std::size_t block_size_;
273  GzipCompressionLevel compression_level_;
274  std::shared_ptr<ThreadPool> thread_pool_;
275 
276 };
277 
278 } // namespace utils
279 } // namespace genesis
280 
281 #endif // include guard
genesis::utils::GzipBlockOStream::GZIP_DEFAULT_BLOCK_SIZE
static const std::size_t GZIP_DEFAULT_BLOCK_SIZE
Definition: gzip_block_ostream.hpp:110
genesis::utils::BaseOutputTarget
Abstract base class for writing data to an output target.
Definition: base_output_target.hpp:59
genesis::utils::GzipBlockOutputTarget::operator=
GzipBlockOutputTarget & operator=(GzipBlockOutputTarget const &)=delete
std.hpp
Provides some valuable additions to STD.
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::shared_ptr< ThreadPool > thread_pool=nullptr)
Construct the output target using another output target (FileOutputTarget, StringOutputTarget,...
Definition: gzip_output_target.hpp:190
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:175
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