Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
LZ4DeflateService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* Service de compression utilisant la bibliothèque 'lz4'. */
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/FactoryService.h"
20#include "arcane/AbstractService.h"
21#include "arcane/IDeflateService.h"
22
23#include <lz4.h>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
36class LZ4DeflateService
37: public AbstractService
38, public IDeflateService
39{
40 public:
41
42 explicit LZ4DeflateService(const ServiceBuildInfo& sbi)
43 : AbstractService(sbi)
44 {
45 }
46
47 public:
48
49 void build() override {}
50
51 void compress(ByteConstArrayView values,ByteArray& compressed_values) override
52 {
53 Integer input_size = values.size();
54 int dest_capacity = LZ4_compressBound(input_size);
55 // D'après la doc, il faut allouer au moins 1% de plus que la taille
56 // d'entrée plus encore 600 bytes
57 //Integer compressed_init_size = (Integer)(((Real)input_size) * 1.01) + 600;
58 compressed_values.resize(dest_capacity);
59 //compressed_values.copy(values);
60
61 char* dest = reinterpret_cast<char*>(compressed_values.data());
62
63 const char* source = reinterpret_cast<const char*>(values.data());
64 unsigned int source_len = (unsigned int)input_size;
65
66#if 0
67 info() << "CHECK COMPRESS dest=" << (void*)dest
68 << " dest_len=" << dest_len
69 << " source=" << (void*)source
70 << " source_len=" << source_len;
71#endif
72
73 int r = LZ4_compress_default(source,dest,source_len,dest_capacity);
74
75 if (r==0)
76 throw IOException(A_FUNCINFO,String::format("io error during compression r={0}",r));
77 int dest_len = r;
78 Real ratio = (dest_len * 100.0 ) / source_len;
79 info() << "LZ4 compress r=" << r << " source_len=" << source_len
80 << " dest_len=" << dest_len << " ratio=" << ratio;
81 compressed_values.resize(dest_len);
82 }
83
84 void decompress(ByteConstArrayView compressed_values,ByteArrayView values) override
85 {
86 char* dest = reinterpret_cast<char*>(values.data());
87 int dest_len = values.size();
88
89 const char* source = reinterpret_cast<const char*>(compressed_values.data());
90 int source_len = compressed_values.size();
91
92 int r = LZ4_decompress_safe(source,dest,source_len,dest_len);
93 info() << "LZ4 decompress r=" << r << " source_len=" << source_len << " dest_len=" << dest_len;
94 if (r<0)
95 throw IOException(A_FUNCINFO,String::format("io error during decompression r={0}",r));
96 }
97};
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
104class LZ4DataCompressor
105: public AbstractService
106, public IDataCompressor
107{
108 public:
109
110 explicit LZ4DataCompressor(const ServiceBuildInfo& sbi)
111 : AbstractService(sbi), m_name(sbi.serviceInfo()->localName())
112 {
113 }
114
115 public:
116
117 void build() override {}
118 String name() const override { return m_name; }
119 Int64 minCompressSize() const override { return 512; }
120 void compress(Span<const std::byte> values,Array<std::byte>& compressed_values) override
121 {
122 // Même si supporte en théorie une taille de tableau sur 64 bits,
123 // l'algorithme 'LZ4' utilise des 'int' pour les tailles et de
124 // plus ne supporte pas les valeurs supérieures à LZ4_MAX_INPUT_SIZE.
125 int input_size = _toInt(values.size());
126 // Vérifie qu'on ne dépasse pas LZ4_MAX_INPUT_SIZE
127 if (input_size>LZ4_MAX_INPUT_SIZE)
128 ARCANE_THROW(IOException,"Array is too large for LZ4: size={0} max={1}",input_size,LZ4_MAX_INPUT_SIZE);
129
130 int dest_capacity = LZ4_compressBound(input_size);
131 compressed_values.resize(dest_capacity);
132
133 char* dest = reinterpret_cast<char*>(compressed_values.data());
134 const char* source = reinterpret_cast<const char*>(values.data());
135
136 int r = LZ4_compress_default(source,dest,input_size,dest_capacity);
137 if (r==0)
138 ARCANE_THROW(IOException,"IO error during compression r={0}",r);
139 int dest_len = r;
140 if (input_size>0){
141 Real ratio = (dest_len * 100.0 ) / input_size;
142 info(5) << "LZ4 compress r=" << r << " source_len=" << input_size
143 << " dest_len=" << dest_len << " ratio=" << ratio;
144 }
145 compressed_values.resize(dest_len);
146 }
147
148 void decompress(Span<const std::byte> compressed_values,Span<std::byte> values) override
149 {
150 char* dest = reinterpret_cast<char*>(values.data());
151 int dest_len = _toInt(values.size());
152
153 const char* source = reinterpret_cast<const char*>(compressed_values.data());
154 int source_len = _toInt(compressed_values.size());
155
156 int r = LZ4_decompress_safe(source,dest,source_len,dest_len);
157 info(5) << "LZ4 decompress r=" << r << " source_len=" << source_len << " dest_len=" << dest_len;
158 if (r<0)
159 ARCANE_THROW(IOException,"IO error during decompression r={0}",r);
160 }
161 private:
162 String m_name;
163 private:
164 int _toInt(Int64 vsize)
165 {
166 // Vérifie qu'on tient dans un 'int'.
167 Int64 max_int_size = std::numeric_limits<int>::max();
168 if (vsize>max_int_size)
169 ARCANE_THROW(IOException,"Array is too large to fit in 'int' type: size={0} max={1}",vsize,max_int_size);
170 return static_cast<int>(vsize);
171 }
172};
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
176
180
182 ServiceProperty("LZ4DataCompressor",ST_Application|ST_CaseOption),
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
188} // End namespace Arcane
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
constexpr const_pointer data() const noexcept
Pointeur sur le début de la vue.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Tableau d'items de types quelconques.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
const T * data() const
Accès à la racine du tableau hors toute protection.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface d'un service permettant de compresser/décompresser des données.
Interface d'un service permettant de compresser/décompresser des données.
Exception lorsqu'une erreur d'entrée/sortie est détectée.
Definition IOException.h:32
virtual String localName() const =0
Partie locale du nom du service.
Service de compression utilisant la bibliothèque 'LZ4'.
void compress(Span< const std::byte > values, Array< std::byte > &compressed_values) override
Compresse les données values et les stocke dans compressed_values.
void build() override
Construction de niveau build du service.
void decompress(Span< const std::byte > compressed_values, Span< std::byte > values) override
Décompresse les données compressed_values et les stocke dans values.
Int64 minCompressSize() const override
Taille minimale du tableau en dessous de laquelle il n'est pas utile de compresser.
String name() const override
Nom de l'algorithme.
Service de compression utilisant la bibliothèque 'LZ4'.
void decompress(ByteConstArrayView compressed_values, ByteArrayView values) override
Décompresse les données compressed_values et les stocke dans values.
void build() override
Construction de niveau build du service.
void compress(ByteConstArrayView values, ByteArray &compressed_values) override
Compresse les données values et les stocke dans compressed_values.
Structure contenant les informations pour créer un service.
IServiceInfo * serviceInfo() const
Accès au IServiceInfo associé
Propriétés de création d'un service.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:212
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:422
Vue d'un tableau d'éléments de type T.
Definition Span.h:513
Chaîne de caractères unicode.
TraceMessage info() const
Flot pour un message d'information.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:534
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:208
@ ST_Application
Le service s'utilise au niveau de l'application.
@ ST_CaseOption
Le service s'utilise au niveau du jeu de données.
double Real
Type représentant un réel.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:563