Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
LZ4DeflateService.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/* LZ4DeflateService.h (C) 2000-2021 */
9/* */
10/* Compression service using the 'lz4' 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 <lz4.h>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
37class LZ4DeflateService
38: public AbstractService
39, public IDeflateService
40{
41 public:
42
43 explicit LZ4DeflateService(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 int dest_capacity = LZ4_compressBound(input_size);
56 // According to the documentation, we must allocate at least 1% more than the
57 // input size plus another 600 bytes
58 //Integer compressed_init_size = (Integer)(((Real)input_size) * 1.01) + 600;
59 compressed_values.resize(dest_capacity);
60 //compressed_values.copy(values);
61
62 char* dest = reinterpret_cast<char*>(compressed_values.data());
63
64 const char* source = reinterpret_cast<const char*>(values.data());
65 unsigned int source_len = (unsigned int)input_size;
66
67#if 0
68 info() << "CHECK COMPRESS dest=" << (void*)dest
69 << " dest_len=" << dest_len
70 << " source=" << (void*)source
71 << " source_len=" << source_len;
72#endif
73
74 int r = LZ4_compress_default(source, dest, source_len, dest_capacity);
75
76 if (r == 0)
77 throw IOException(A_FUNCINFO, String::format("io error during compression r={0}", r));
78 int dest_len = r;
79 Real ratio = (dest_len * 100.0) / source_len;
80 info() << "LZ4 compress r=" << r << " source_len=" << source_len
81 << " dest_len=" << dest_len << " ratio=" << ratio;
82 compressed_values.resize(dest_len);
83 }
84
85 void decompress(ByteConstArrayView compressed_values, ByteArrayView values) override
86 {
87 char* dest = reinterpret_cast<char*>(values.data());
88 int dest_len = values.size();
89
90 const char* source = reinterpret_cast<const char*>(compressed_values.data());
91 int source_len = compressed_values.size();
92
93 int r = LZ4_decompress_safe(source, dest, source_len, dest_len);
94 info() << "LZ4 decompress r=" << r << " source_len=" << source_len << " dest_len=" << dest_len;
95 if (r < 0)
96 throw IOException(A_FUNCINFO, String::format("io error during decompression r={0}", r));
97 }
98};
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
106class LZ4DataCompressor
107: public AbstractService
108, public IDataCompressor
109{
110 public:
111
112 explicit LZ4DataCompressor(const ServiceBuildInfo& sbi)
113 : AbstractService(sbi)
114 , m_name(sbi.serviceInfo()->localName())
115 {
116 }
117
118 public:
119
120 void build() override {}
121 String name() const override { return m_name; }
122 Int64 minCompressSize() const override { return 512; }
123 void compress(Span<const std::byte> values, Array<std::byte>& compressed_values) override
124 {
125 // Although theoretically supporting an array size of 64 bits,
126 // the 'LZ4' algorithm uses 'int' for sizes and does not
127 // support values greater than LZ4_MAX_INPUT_SIZE.
128 int input_size = _toInt(values.size());
129 // Checks if we do not exceed LZ4_MAX_INPUT_SIZE
130 if (input_size > LZ4_MAX_INPUT_SIZE)
131 ARCANE_THROW(IOException, "Array is too large for LZ4: size={0} max={1}", input_size, LZ4_MAX_INPUT_SIZE);
132
133 int dest_capacity = LZ4_compressBound(input_size);
134 compressed_values.resize(dest_capacity);
135
136 char* dest = reinterpret_cast<char*>(compressed_values.data());
137 const char* source = reinterpret_cast<const char*>(values.data());
138
139 int r = LZ4_compress_default(source, dest, input_size, dest_capacity);
140 if (r == 0)
141 ARCANE_THROW(IOException, "IO error during compression r={0}", r);
142 int dest_len = r;
143 if (input_size > 0) {
144 Real ratio = (dest_len * 100.0) / input_size;
145 info(5) << "LZ4 compress r=" << r << " source_len=" << input_size
146 << " dest_len=" << dest_len << " ratio=" << ratio;
147 }
148 compressed_values.resize(dest_len);
149 }
150
151 void decompress(Span<const std::byte> compressed_values, Span<std::byte> values) override
152 {
153 char* dest = reinterpret_cast<char*>(values.data());
154 int dest_len = _toInt(values.size());
155
156 const char* source = reinterpret_cast<const char*>(compressed_values.data());
157 int source_len = _toInt(compressed_values.size());
158
159 int r = LZ4_decompress_safe(source, dest, source_len, dest_len);
160 info(5) << "LZ4 decompress r=" << r << " source_len=" << source_len << " dest_len=" << dest_len;
161 if (r < 0)
162 ARCANE_THROW(IOException, "IO error during decompression r={0}", r);
163 }
164
165 private:
166
167 String m_name;
168
169 private:
170
171 int _toInt(Int64 vsize)
172 {
173 // Checks if it fits in an 'int'.
174 Int64 max_int_size = std::numeric_limits<int>::max();
175 if (vsize > max_int_size)
176 ARCANE_THROW(IOException, "Array is too large to fit in 'int' type: size={0} max={1}", vsize, max_int_size);
177 return static_cast<int>(vsize);
178 }
179};
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
187
189 ServiceProperty("LZ4DataCompressor", ST_Application | ST_CaseOption),
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
195} // End namespace Arcane
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
#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.
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.
Compression service using the 'LZ4' library.
void compress(Span< const std::byte > values, Array< std::byte > &compressed_values) override
Compresses the data values and stores it in compressed_values.
void build() override
Build-level construction of the service.
void decompress(Span< const std::byte > compressed_values, Span< std::byte > values) override
Decompresses the data compressed_values and stores it in values.
Int64 minCompressSize() const override
Minimum array size below which compression is not useful.
String name() const override
Algorithm name.
Compression service using the 'LZ4' library.
void decompress(ByteConstArrayView compressed_values, ByteArrayView values) override
Decompresses the data compressed_values and stores it in values.
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.
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