Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
Bzip2DeflateService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Bzip2DeflateService.h (C) 2000-2021 */
9/* */
10/* Compression service using the 'bzip2' library. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/IOException.h"
15#include "arcane/utils/Array.h"
16#include "arcane/utils/TraceInfo.h"
17#include "arcane/utils/IDataCompressor.h"
18
19#include "arcane/core/FactoryService.h"
20#include "arcane/core/AbstractService.h"
21#include "arcane/core/IDeflateService.h"
22
23#include <bzlib.h>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
37class Bzip2DeflateService
38: public AbstractService
39, public IDeflateService
40{
41 public:
42
43 Bzip2DeflateService(const ServiceBuildInfo& sbi)
44 : AbstractService(sbi)
45 {
46 }
47
48 public:
49
50 void build() override {}
51
52 void compress(ByteConstArrayView values, ByteArray& compressed_values) override
53 {
54 Integer input_size = values.size();
55 // According to the documentation, we must allocate at least 1% more than the input size
56 // plus another 600 bytes
57 Integer compressed_init_size = (Integer)(((Real)input_size) * 1.01) + 600;
58 compressed_values.resize(compressed_init_size);
59 //compressed_values.copy(values);
60
61 char* dest = (char*)compressed_values.data();
62 unsigned int dest_len = (unsigned int)compressed_init_size;
63
64 char* source = (char*)values.data();
65 unsigned int source_len = (unsigned int)input_size;
66
67 int blockSize100k = 9;
68 int verbosity = 1;
69 int workFactor = 30;
70
71#if 0
72 info() << "CHECK COMPRESS dest=" << (void*)dest
73 << " dest_len=" << dest_len
74 << " source=" << (void*)source
75 << " source_len=" << source_len;
76#endif
77
78 int r = BZ2_bzBuffToBuffCompress(dest,
79 &dest_len,
80 source,
81 source_len,
82 blockSize100k,
83 verbosity,
84 workFactor);
85 if (r != BZ_OK)
86 throw IOException(A_FUNCINFO, String::format("io error during compression r={0}", r));
87 // Warning: Int32 overflow.
88 Real ratio = 0.0;
89 if (source_len > 0)
90 ratio = ((double)dest_len * 100.0) / (double)source_len;
91 info() << "Bzip2 compress r=" << r << " source_len=" << source_len
92 << " dest_len=" << dest_len << " ratio=" << ratio;
93 compressed_values.resize(dest_len);
94 }
95
96 void decompress(ByteConstArrayView compressed_values, ByteArrayView values) override
97 {
98 char* dest = (char*)values.data();
99 unsigned int dest_len = (unsigned int)values.size();
100
101 char* source = (char*)compressed_values.data();
102 unsigned int source_len = (unsigned int)compressed_values.size();
103
104 // small is 1 if we want to save memory (but it is slower)
105 // and 0 otherwise.
106 int small = 0;
107 int verbosity = 1;
108 int r = BZ2_bzBuffToBuffDecompress(dest, &dest_len,
109 source, source_len,
110 small, verbosity);
111 info() << "Bzip2 decompress r=" << r << " source_len=" << source_len
112 << " dest_len=" << dest_len;
113 if (r != BZ_OK)
114 ARCANE_THROW(IOException, "IO error during decompression r={0}", r);
115 }
116};
117
118/*---------------------------------------------------------------------------*/
119/*---------------------------------------------------------------------------*/
120
124class Bzip2DataCompressor
125: public AbstractService
126, public IDataCompressor
127{
128 public:
129
130 explicit Bzip2DataCompressor(const ServiceBuildInfo& sbi)
131 : AbstractService(sbi)
132 , m_name(sbi.serviceInfo()->localName())
133 {
134 }
135
136 public:
137
138 void build() override {}
139 String name() const override { return m_name; }
140 Int64 minCompressSize() const override { return 512; }
141 void compress(Span<const std::byte> values, Array<std::byte>& compressed_values) override
142 {
143 Int64 input_size = values.size();
144 // According to the documentation, we must allocate at least 1% more than the input size
145 // plus another 600 bytes
146 Integer compressed_init_size = (Integer)(((Real)input_size) * 1.01) + 600;
147 compressed_values.resize(compressed_init_size);
148
149 char* dest = reinterpret_cast<char*>(compressed_values.data());
150 unsigned int dest_len = _toUInt(compressed_init_size);
151
152 char* source = const_cast<char*>(reinterpret_cast<const char*>(values.data()));
153 unsigned int source_len = _toUInt(input_size);
154
155 int blockSize100k = 9;
156 int verbosity = 1;
157 int workFactor = 30;
158
159 int r = BZ2_bzBuffToBuffCompress(dest,
160 &dest_len,
161 source,
162 source_len,
163 blockSize100k,
164 verbosity,
165 workFactor);
166 if (r != BZ_OK)
167 ARCANE_THROW(IOException, "IO error during compression r={0}", r);
168
169 // Warning: Int32 overflow.
170 Real ratio = 0.0;
171 if (source_len > 0)
172 ratio = ((double)dest_len * 100.0) / (double)source_len;
173 info() << "Bzip2 compress r=" << r << " source_len=" << source_len
174 << " dest_len=" << dest_len << " ratio=" << ratio;
175 compressed_values.resize(dest_len);
176 }
177
178 void decompress(Span<const std::byte> compressed_values, Span<std::byte> values) override
179 {
180 char* dest = reinterpret_cast<char*>(values.data());
181 unsigned int dest_len = _toUInt(values.size());
182
183 char* source = const_cast<char*>(reinterpret_cast<const char*>(compressed_values.data()));
184 unsigned int source_len = _toUInt(compressed_values.size());
185
186 // small is 1 if we want to save memory (but it is slower)
187 // and 0 otherwise.
188 int small = 0;
189 int verbosity = 1;
190 int r = BZ2_bzBuffToBuffDecompress(dest, &dest_len,
191 source, source_len,
192 small, verbosity);
193 info(5) << "Bzip2 decompress r=" << r << " source_len=" << source_len
194 << " dest_len=" << dest_len;
195 if (r != BZ_OK)
196 ARCANE_THROW(IOException, "IO error during decompression r={0}", r);
197 }
198
199 private:
200
201 String m_name;
202
203 private:
204
205 unsigned int _toUInt(Int64 vsize)
206 {
207 // Checks if it fits in an 'int'.
208 Int64 max_uint_size = std::numeric_limits<unsigned int>::max();
209 if (vsize > max_uint_size)
210 ARCANE_THROW(IOException, "Array is too large to fit in 'unsigned int' type: size={0} max={1}",
211 vsize, max_uint_size);
212 return static_cast<unsigned int>(vsize);
213 }
214};
215
216/*---------------------------------------------------------------------------*/
217/*---------------------------------------------------------------------------*/
218
222
224 ServiceProperty("Bzip2DataCompressor", ST_Application | ST_CaseOption),
226
227/*---------------------------------------------------------------------------*/
228/*---------------------------------------------------------------------------*/
229
230} // End namespace Arcane
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
constexpr const_pointer data() const noexcept
Pointer to the start of the view.
constexpr Integer size() const noexcept
Returns the size of the array.
Base class for 1D data vectors.
void resize(Int64 s)
Changes the number of elements in the array to s.
const T * data() const
Access to the root of the array without any protection.
Compression service using the 'Bzip2' library.
Int64 minCompressSize() const override
Minimum array size below which compression is not useful.
void decompress(Span< const std::byte > compressed_values, Span< std::byte > values) override
Decompresses the data compressed_values and stores it in values.
String name() const override
Algorithm name.
void build() override
Build-level construction of the service.
void compress(Span< const std::byte > values, Array< std::byte > &compressed_values) override
Compresses the data values and stores it in compressed_values.
Compression service using the 'Bzip2' library.
void build() override
Build-level construction of the service.
void compress(ByteConstArrayView values, ByteArray &compressed_values) override
Compresses the data values and stores it in compressed_values.
void decompress(ByteConstArrayView compressed_values, ByteArrayView values) override
Decompresses the data compressed_values and stores it in values.
constexpr const_pointer data() const noexcept
Pointer to the allocated memory.
constexpr Integer size() const noexcept
Number of elements in the array.
Interface of a service for compressing/decompressing data.
Interface of a service allowing compression/decompression of data.
Exception when an input/output error is detected.
Definition IOException.h:34
virtual String localName() const =0
Local part of the service name.
Structure containing the information to create a service.
IServiceInfo * serviceInfo() const
Access to the associated IServiceInfo.
Service creation properties.
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
Definition Span.h:539
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:327
View of an array of elements of type T.
Definition Span.h:635
TraceMessage info() const
Flow for an information message.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
ArrayView< Byte > ByteArrayView
C equivalent of a 1D array of characters.
Definition UtilsTypes.h:447
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
Array< Byte > ByteArray
Dynamic one-dimensional array of characters.
Definition UtilsTypes.h:121
@ ST_Application
The service is used at the application level.
@ ST_CaseOption
The service is used at the dataset level.
double Real
Type representing a real number.
ConstArrayView< Byte > ByteConstArrayView
C equivalent of a 1D array of characters.
Definition UtilsTypes.h:476