Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Bzip2DeflateService.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/* Bzip2DeflateService.h (C) 2000-2021 */
9/* */
10/* Service de compression utilisant la bibliothèque 'bzip2'. */
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 <bzlib.h>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
36class Bzip2DeflateService
37: public AbstractService
38, public IDeflateService
39{
40 public:
41 Bzip2DeflateService(const ServiceBuildInfo& sbi)
42 : AbstractService(sbi)
43 {
44 }
45
46 public:
47
48 void build() override {}
49
50 void compress(ByteConstArrayView values,ByteArray& compressed_values) override
51 {
52 Integer input_size = values.size();
53 // D'après la doc, il faut allouer au moins 1% de plus que la taille
54 // d'entrée plus encore 600 bytes
55 Integer compressed_init_size = (Integer)(((Real)input_size) * 1.01) + 600;
56 compressed_values.resize(compressed_init_size);
57 //compressed_values.copy(values);
58
59 char* dest = (char*)compressed_values.data();
60 unsigned int dest_len = (unsigned int)compressed_init_size;
61
62 char* source = (char*)values.data();
63 unsigned int source_len = (unsigned int)input_size;
64
65 int blockSize100k = 9;
66 int verbosity = 1;
67 int workFactor = 30;
68
69#if 0
70 info() << "CHECK COMPRESS dest=" << (void*)dest
71 << " dest_len=" << dest_len
72 << " source=" << (void*)source
73 << " source_len=" << source_len;
74#endif
75
76 int r = BZ2_bzBuffToBuffCompress(dest,
77 &dest_len,
78 source,
79 source_len,
80 blockSize100k,
81 verbosity,
82 workFactor);
83 if (r!=BZ_OK)
84 throw IOException(A_FUNCINFO,String::format("io error during compression r={0}",r));
85 // Attention overflow des Int32;
86 Real ratio = 0.0;
87 if (source_len>0)
88 ratio = ((double)dest_len * 100.0 ) / (double)source_len;
89 info() << "Bzip2 compress r=" << r << " source_len=" << source_len
90 << " dest_len=" << dest_len << " ratio=" << ratio;
91 compressed_values.resize(dest_len);
92 }
93
94 void decompress(ByteConstArrayView compressed_values,ByteArrayView values) override
95 {
96 char* dest = (char*)values.data();
97 unsigned int dest_len = (unsigned int)values.size();
98
99 char* source = (char*)compressed_values.data();
100 unsigned int source_len = (unsigned int)compressed_values.size();
101
102 // small vaut 1 si on souhaite economiser la memoire (mais c'est moins rapide)
103 // et 0 sinon.
104 int small = 0;
105 int verbosity = 1;
106 int r = BZ2_bzBuffToBuffDecompress(dest,&dest_len,
107 source,source_len,
108 small,verbosity);
109 info() << "Bzip2 decompress r=" << r << " source_len=" << source_len
110 << " dest_len=" << dest_len;
111 if (r!=BZ_OK)
112 ARCANE_THROW(IOException,"IO error during decompression r={0}",r);
113 }
114};
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
121class Bzip2DataCompressor
122: public AbstractService
123, public IDataCompressor
124{
125 public:
126 explicit Bzip2DataCompressor(const ServiceBuildInfo& sbi)
127 : AbstractService(sbi), m_name(sbi.serviceInfo()->localName())
128 {
129 }
130
131 public:
132
133 void build() override {}
134 String name() const override { return m_name; }
135 Int64 minCompressSize() const override { return 512; }
136 void compress(Span<const std::byte> values,Array<std::byte>& compressed_values) override
137 {
138 Int64 input_size = values.size();
139 // D'après la doc, il faut allouer au moins 1% de plus que la taille
140 // d'entrée plus encore 600 bytes
141 Integer compressed_init_size = (Integer)(((Real)input_size) * 1.01) + 600;
142 compressed_values.resize(compressed_init_size);
143
144 char* dest = reinterpret_cast<char*>(compressed_values.data());
145 unsigned int dest_len = _toUInt(compressed_init_size);
146
147 char* source = const_cast<char*>(reinterpret_cast<const char*>(values.data()));
148 unsigned int source_len = _toUInt(input_size);
149
150 int blockSize100k = 9;
151 int verbosity = 1;
152 int workFactor = 30;
153
154 int r = BZ2_bzBuffToBuffCompress(dest,
155 &dest_len,
156 source,
157 source_len,
158 blockSize100k,
159 verbosity,
160 workFactor);
161 if (r!=BZ_OK)
162 ARCANE_THROW(IOException,"IO error during compression r={0}",r);
163
164 // Attention overflow des Int32;
165 Real ratio = 0.0;
166 if (source_len>0)
167 ratio = ((double)dest_len * 100.0 ) / (double)source_len;
168 info() << "Bzip2 compress r=" << r << " source_len=" << source_len
169 << " dest_len=" << dest_len << " ratio=" << ratio;
170 compressed_values.resize(dest_len);
171 }
172
173 void decompress(Span<const std::byte> compressed_values,Span<std::byte> values) override
174 {
175 char* dest = reinterpret_cast<char*>(values.data());
176 unsigned int dest_len = _toUInt(values.size());
177
178 char* source = const_cast<char*>(reinterpret_cast<const char*>(compressed_values.data()));
179 unsigned int source_len = _toUInt(compressed_values.size());
180
181 // small vaut 1 si on souhaite economiser la memoire (mais c'est moins rapide)
182 // et 0 sinon.
183 int small = 0;
184 int verbosity = 1;
185 int r = BZ2_bzBuffToBuffDecompress(dest,&dest_len,
186 source,source_len,
187 small,verbosity);
188 info(5) << "Bzip2 decompress r=" << r << " source_len=" << source_len
189 << " dest_len=" << dest_len;
190 if (r!=BZ_OK)
191 ARCANE_THROW(IOException,"IO error during decompression r={0}",r);
192 }
193 private:
194 String m_name;
195 private:
196 unsigned int _toUInt(Int64 vsize)
197 {
198 // Vérifie qu'on tient dans un 'int'.
199 Int64 max_uint_size = std::numeric_limits<unsigned int>::max();
200 if (vsize>max_uint_size)
201 ARCANE_THROW(IOException,"Array is too large to fit in 'unsigned int' type: size={0} max={1}",
202 vsize,max_uint_size);
203 return static_cast<unsigned int>(vsize);
204 }
205};
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
213
215 ServiceProperty("Bzip2DataCompressor",ST_Application|ST_CaseOption),
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220
221} // End namespace Arcane
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
#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.
Service de compression utilisant la bibliothèque 'Bzip2'.
Int64 minCompressSize() const override
Taille minimale du tableau en dessous de laquelle il n'est pas utile de compresser.
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.
String name() const override
Nom de l'algorithme.
void build() override
Construction de niveau build du service.
void compress(Span< const std::byte > values, Array< std::byte > &compressed_values) override
Compresse les données values et les stocke dans compressed_values.
Service de compression utilisant la bibliothèque 'Bzip2'.
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.
void decompress(ByteConstArrayView compressed_values, ByteArrayView values) override
Décompresse les données compressed_values et les stocke dans values.
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.
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