Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
BasicReaderWriterDatabase.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* BasicReaderWriterDatabase.cc (C) 2000-2024 */
9/* */
10/* Base de donnée pour le service 'BasicReaderWriter'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/internal/BasicReaderWriterDatabase.h"
15
16#include "arcane/utils/Array.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/JSONReader.h"
21#include "arcane/utils/JSONWriter.h"
22#include "arcane/utils/CheckedConvert.h"
23#include "arcane/utils/IDataCompressor.h"
24#include "arcane/utils/SmallArray.h"
25#include "arcane/utils/IHashAlgorithm.h"
26#include "arcane/utils/ITraceMng.h"
27
28#include "arcane/ArcaneException.h"
29
30#include "arcane/std/internal/TextReader2.h"
31#include "arcane/std/internal/TextWriter2.h"
32#include "arcane/std/internal/IHashDatabase.h"
33
34#include <fstream>
35#include <map>
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane::impl
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
47class Hasher
48{
49 public:
50
51 void computeHash(Span<const std::byte> bytes, Array<Byte>& hash_result)
52 {
53 ARCANE_CHECK_POINTER(m_hash_algorithm);
54 {
55 Real t1 = platform::getRealTime();
56 m_nb_processed_bytes += bytes.size();
57 m_hash_algorithm->computeHash64(bytes, hash_result);
58 Real t2 = platform::getRealTime();
59 m_hash_time += (t2 - t1);
60 }
61 }
62
63 void setHashAlgorithm(IHashAlgorithm* algo)
64 {
65 m_hash_algorithm = algo;
66 }
67
68 void printStats(ITraceMng* tm)
69 {
70 if (m_nb_processed_bytes == 0)
71 return;
72 Real nb_byte_per_second = static_cast<Real>(m_nb_processed_bytes) / (m_hash_time + 1.0e-9);
73 // Pour avoir en Mega-byte par seconde
74 nb_byte_per_second /= 1.0e6;
75 tm->info() << "Hasher:nb_processed=" << m_nb_processed_bytes
76 << " hash_time=" << m_hash_time
77 << " rate=" << static_cast<Int64>(nb_byte_per_second) << " MB/s"
78 << "\n";
79 }
80
81 private:
82
83 IHashAlgorithm* m_hash_algorithm = nullptr;
84 Int64 m_nb_processed_bytes = 0;
85 Real m_hash_time = 0.0;
86};
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
93{
94 public:
95
96 // La taille de cette structure ne doit pas être modifiée sous peine
97 // de rendre le format incompatible. Pour supporter des évolutions, on fixe
98 // une taille de 128 octets, soit 16 'Int64'
99 static constexpr Int64 STRUCT_SIZE = 128;
100
101 public:
102
104 {
105 checkStructureSize();
106 for (int i = 0; i < 10; ++i)
107 m_remaining_padding[i] = i;
108 }
109
110 public:
111
112 void setJSONDataInfoOffsetAndSize(Int64 file_offset, Int64 data_size)
113 {
114 m_json_data_info_file_offset = file_offset;
115 m_json_data_info_size = data_size;
116 }
117 Int32 version() const { return m_version; }
118 Int64 jsonDataInfoFileOffset() const { return m_json_data_info_file_offset; }
119 Int64 jsonDataInfoSize() const { return m_json_data_info_size; }
120 Span<std::byte> bytes()
121 {
122 return { reinterpret_cast<std::byte*>(this), STRUCT_SIZE };
123 }
124
125 private:
126
127 // Version de l'epilogue. A ne pas confondre avec la version du fichier
128 // qui est dans l'en-tête.
129 Int32 m_version = 1;
130 Int32 m_padding0 = 0;
131 Int64 m_padding1 = 0;
132 Int64 m_padding2 = 0;
133 Int64 m_padding3 = 0;
134 Int64 m_json_data_info_file_offset = -1;
135 Int64 m_json_data_info_size = 0;
136 Int64 m_remaining_padding[10];
137
138 public:
139
140 static void checkStructureSize()
141 {
143 if (s != STRUCT_SIZE)
144 ARCANE_FATAL("Invalid size for epilog format size={0} expected={1}", s, STRUCT_SIZE);
145 }
146};
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
153{
154 public:
155
156 // La taille de cette structure ne doit pas être modifiée sous peine
157 // de rendre le format incompatible. Pour supporter des évolutions, on fixe
158 // une taille de 128 octets, soit 16 'Int64'
159 static constexpr Int64 STRUCT_SIZE = 128;
160
161 public:
162
164 {
165 checkStructureSize();
166 for (int i = 0; i < 12; ++i)
167 m_remaining_padding[i] = i;
168 }
169
170 public:
171
172 Span<std::byte> bytes()
173 {
174 return { reinterpret_cast<std::byte*>(this), STRUCT_SIZE };
175 }
176 void setVersion(Int32 version) { m_version = version; }
177 Int32 version() const { return m_version; }
178 void checkHeader()
179 {
180 // Vérifie que le header est correct.
181 if (m_header_begin[0] != 'A' || m_header_begin[1] != 'C' || m_header_begin[2] != 'R' || m_header_begin[3] != (Byte)39)
182 ARCANE_FATAL("Bad header");
183 // TODO: tester indianess
184 }
185
186 private:
187
188 // 4 premiers octets pour indiquer qu'il s'agit d'un fichier de protections
189 // arcane (ACR pour Arcane Checkpoint Restart)
190 std::array<Byte, 4> m_header_begin = { 'A', 'C', 'R', 39 };
191 // 4 octets suivant pour indiquer l'indianness (pas encore utilisé)
192 Int32 m_endian_int = 0x01020304;
193 // Version du fichier (à modifier par l'appelant via setVersion())
194 Int32 m_version = 0;
195 Int32 m_padding0 = 0;
196 Int64 m_padding1 = 0;
197 Int64 m_padding2 = 0;
198 Int64 m_remaining_padding[12];
199
200 public:
201
202 static void checkStructureSize()
203 {
205 if (s != STRUCT_SIZE)
206 ARCANE_FATAL("Invalid size for header format size={0} expected={1}", s, STRUCT_SIZE);
207 }
208};
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
214: public TraceAccessor
215{
216 public:
217
219 {
220 static constexpr int MAX_SIZE = 8;
221 void fill(SmallSpan<const Int64> v)
222 {
223 nb = v.size();
224 if (nb > MAX_SIZE) {
225 m_large_extents = v;
226 return;
227 }
228 for (Int32 i = 0; i < nb; ++i)
229 sizes[i] = v[i];
230 }
231 Int64ConstArrayView view() const
232 {
233 if (nb <= MAX_SIZE)
234 return Int64ConstArrayView(nb, sizes);
235 return m_large_extents.view();
236 }
237 Int32 size() const { return nb; }
238
239 private:
240
241 Int32 nb = 0;
242
243 public:
244
245 Int64 sizes[MAX_SIZE];
246 UniqueArray<Int64> m_large_extents;
247 };
248
249 struct DataInfo
250 {
251 Int64 m_file_offset = 0;
252 ExtentsInfo m_extents;
253 };
254
255 public:
256
259 {
260 if (version >= 3) {
261 String hash_directory = platform::getEnvironmentVariable("ARCANE_HASHDATABASE_DIRECTORY");
262 if (!hash_directory.null()) {
263 info() << "Using Hash database at location '" << hash_directory << "'";
264 m_hash_database = createFileHashDatabase(tm, hash_directory);
265 }
266 else {
267 String redis_machine = platform::getEnvironmentVariable("ARCANE_HASHDATABASE_REDIS");
268 if (!redis_machine.null()){
269 info() << "Using Redis database at location '" << redis_machine << "'";
270 m_hash_database = createRedisHashDatabase(tm, redis_machine, 6379);
271 }
272 }
273 }
274 }
275
276 public:
277
278 DataInfo& findData(const String& key_name)
279 {
280 auto x = m_data_infos.find(key_name);
281 if (x == m_data_infos.end())
282 ARCANE_FATAL("Can not find key '{0}' in database", key_name);
283 return x->second;
284 }
285
286 public:
287
288 std::map<String, DataInfo> m_data_infos;
289 Ref<IDataCompressor> m_data_compressor;
290 Ref<IHashAlgorithm> m_hash_algorithm;
291 Ref<IHashDatabase> m_hash_database;
292};
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
302{
303 public:
304
305 Impl(ITraceMng* tm, const String& filename, Int32 version)
307 , m_writer(filename)
308 , m_version(version)
309 {
310 if (m_version >= 3)
311 _writeHeader();
312 }
313
314 ~Impl()
315 {
316 if (m_version >= 3)
317 arcaneCallFunctionAndTerminateIfThrow([&]() { _writeEpilog(); });
318 m_hasher.printStats(traceMng());
319 }
320
321 public:
322
323 Int64 fileOffset() { return m_writer.fileOffset(); }
324 void setExtents(const String& key_name, SmallSpan<const Int64> extents);
325 void write(const String& key, Span<const std::byte> values);
326
327 private:
328
329 void _addKey(const String& key, SmallSpan<const Int64> extents);
330 void _writeKey(const String& key);
331 void _writeHeader();
332 void _writeEpilog();
333
334 public:
335
336 TextWriter2 m_writer;
337 Int32 m_version;
338 Hasher m_hasher;
339
340 private:
341
342 void _write2(const String& key, Span<const std::byte> values);
343};
344
345/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347
348KeyValueTextWriter::
349KeyValueTextWriter(ITraceMng* tm, const String& filename, Int32 version)
351, m_p(new Impl(tm, filename, version))
352{
353}
354
355/*---------------------------------------------------------------------------*/
356/*---------------------------------------------------------------------------*/
357
358KeyValueTextWriter::
359~KeyValueTextWriter()
360{
361 delete m_p;
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
377{
379
380 // Actuellement si on passe dans cette partie de code,
381 // la version utilisée est 3 ou plus.
382 header.setVersion(m_version);
383 binaryWrite(m_writer.stream(), header.bytes());
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389void KeyValueTextWriter::Impl::
390_writeEpilog()
391{
392 // Ecrit les méta-données au format JSON.
394 {
396 jsw.writeKey("Data");
397 jsw.beginArray();
398 for (auto& x : m_data_infos) {
400 jsw.write("Name", x.first);
401 jsw.write("FileOffset", x.second.m_file_offset);
402 jsw.write("Extents", x.second.m_extents.view());
403 }
404 jsw.endArray();
405 }
406
407 std::ostream& stream = m_writer.stream();
408
409 // Conserve la position dans le fichier des méta-données
410 // ainsi que leur taille.
411 Int64 file_offset = m_writer.fileOffset();
412 StringView buf = jsw.getBuffer();
413 Int64 meta_data_size = buf.size();
414
415 binaryWrite(stream, asBytes(buf.bytes()));
416
417 {
419 epilog.setJSONDataInfoOffsetAndSize(file_offset, meta_data_size);
420 // Doit toujours être la dernière écriture du fichier
421 binaryWrite(stream, epilog.bytes());
422 }
423}
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
427
428void KeyValueTextWriter::Impl::
429setExtents(const String& key_name, SmallSpan<const Int64> extents)
430{
431 if (m_version >= 3) {
432 _addKey(key_name, extents);
433 }
434 else {
435 // Versions 1 et 2.
436 // On sauve directement dans le fichier à la position courante
437 // les valeurs des dimentions. Le nombre de valeur est donné par la taille
438 // de \a extents
439 Integer dimension_array_size = extents.size();
440 if (dimension_array_size != 0) {
441 String true_key_name = "Extents:" + key_name;
442 String comment = String::format("Writing Dim1Size for '{0}'", key_name);
443 if (m_version == 1) {
444 // Sauve les dimensions comme un tableau de Int32
445 UniqueArray<Integer> dims(dimension_array_size);
446 for (Integer i = 0; i < dimension_array_size; ++i)
447 dims[i] = CheckedConvert::toInteger(extents[i]);
448 m_writer.write(asBytes(dims));
449 }
450 else
451 // Sauve les dimensions comme un tableau de Int64
452 m_writer.write(asBytes(extents));
453 }
454 }
455}
456
457/*---------------------------------------------------------------------------*/
458/*---------------------------------------------------------------------------*/
459
460void KeyValueTextWriter::Impl::
461write(const String& key, Span<const std::byte> values)
462{
463 _writeKey(key);
464
465 IDataCompressor* d = m_data_compressor.get();
466 Int64 len = values.size();
467 if (d && len > d->minCompressSize()) {
468 UniqueArray<std::byte> compressed_values;
469 m_data_compressor->compress(values, compressed_values);
470 Int64 compressed_size = compressed_values.largeSize();
471 m_writer.write(asBytes(Span<const Int64>(&compressed_size, 1)));
472 _write2(key, compressed_values);
473 }
474 else
475 _write2(key, values);
476}
477
478/*---------------------------------------------------------------------------*/
479/*---------------------------------------------------------------------------*/
480
481void KeyValueTextWriter::Impl::
482_write2(const String& key, Span<const std::byte> values)
483{
484 if (m_hash_database.get()) {
485 IHashAlgorithm* hash_algo = m_hash_algorithm.get();
486 if (!hash_algo)
487 ARCANE_FATAL("Can not use hash database without hash algorithm");
488
489 SmallArray<Byte, 1024> hash_result;
490 m_hasher.computeHash(values, hash_result);
491 String hash_value = Convert::toHexaString(hash_result);
492
493 HashDatabaseWriteResult result;
494 HashDatabaseWriteArgs args(values, hash_value);
495 args.setKey(key);
496
497 m_hash_database->writeValues(args, result);
498 info(5) << "WRITE_KW_HASH key=" << key << " hash=" << hash_value << " len=" << values.size();
499 m_writer.write(asBytes(hash_result));
500 }
501 else
502 m_writer.write(values);
503}
504
505/*---------------------------------------------------------------------------*/
506/*---------------------------------------------------------------------------*/
507
508String KeyValueTextWriter::
509fileName() const
510{
511 return m_p->m_writer.fileName();
512}
513
514/*---------------------------------------------------------------------------*/
515/*---------------------------------------------------------------------------*/
516
517void KeyValueTextWriter::
518setDataCompressor(Ref<IDataCompressor> ds)
519{
520 m_p->m_data_compressor = ds;
521}
522
523/*---------------------------------------------------------------------------*/
524/*---------------------------------------------------------------------------*/
525
526Ref<IDataCompressor> KeyValueTextWriter::
527dataCompressor() const
528{
529 return m_p->m_data_compressor;
530}
531
532/*---------------------------------------------------------------------------*/
533/*---------------------------------------------------------------------------*/
534
535void KeyValueTextWriter::
536setHashAlgorithm(Ref<IHashAlgorithm> v)
537{
538 m_p->m_hash_algorithm = v;
539 m_p->m_hasher.setHashAlgorithm(v.get());
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
545Ref<IHashAlgorithm> KeyValueTextWriter::
546hashAlgorithm() const
547{
548 return m_p->m_hash_algorithm;
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
554Int64 KeyValueTextWriter::
555fileOffset()
556{
557 return m_p->m_writer.fileOffset();
558}
559
560/*---------------------------------------------------------------------------*/
561/*---------------------------------------------------------------------------*/
562
563void KeyValueTextWriter::Impl::
564_addKey(const String& key, SmallSpan<const Int64> extents)
565{
566 Impl::DataInfo d{ -1, Impl::ExtentsInfo() };
567 d.m_extents.fill(extents);
568 m_data_infos.insert(std::make_pair(key, d));
569}
570
571/*---------------------------------------------------------------------------*/
572/*---------------------------------------------------------------------------*/
573
574void KeyValueTextWriter::Impl::
575_writeKey(const String& key)
576{
577 if (m_version >= 3) {
578 auto x = m_data_infos.find(key);
579 if (x == m_data_infos.end())
580 ARCANE_FATAL("Key '{0}' is not in map. You should call setExtents() before", key);
581 x->second.m_file_offset = fileOffset();
582 }
583}
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
588/*---------------------------------------------------------------------------*/
589/*---------------------------------------------------------------------------*/
590
591void KeyValueTextWriter::
592setExtents(const String& key_name, SmallSpan<const Int64> extents)
593{
594 m_p->setExtents(key_name, extents);
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600void KeyValueTextWriter::
601write(const String& key, Span<const std::byte> values)
602{
603 m_p->write(key, values);
604}
605
606/*---------------------------------------------------------------------------*/
607/*---------------------------------------------------------------------------*/
608
609/*---------------------------------------------------------------------------*/
610/*---------------------------------------------------------------------------*/
611
614{
615 public:
616
617 Impl(ITraceMng* tm, const String& filename, Int32 version)
619 , m_reader(filename)
620 , m_version(version)
621 {
622 if (m_version >= 3) {
623 _readHeader();
624 _readJSON();
625 }
626 }
627
628 public:
629
630 void readIntegers(const String& key, Span<Integer> values);
631 void read(const String& key, Span<std::byte> values);
632
633 public:
634
635 void _readHeader();
636 void _readJSON();
637 void _readDirect(Int64 offset, Span<std::byte> bytes);
638 void _setFileOffset(const String& key_name);
639 void _read2(const String& key_name, Span<std::byte> values);
640
641 public:
642
643 TextReader2 m_reader;
644 Int32 m_version;
645};
646
647/*---------------------------------------------------------------------------*/
648/*---------------------------------------------------------------------------*/
649
650KeyValueTextReader::
651KeyValueTextReader(ITraceMng* tm, const String& filename, Int32 version)
653, m_p(new Impl(tm, filename, version))
654{
655}
656
657/*---------------------------------------------------------------------------*/
658/*---------------------------------------------------------------------------*/
659
660KeyValueTextReader::
661~KeyValueTextReader()
662{
663 delete m_p;
664}
665
666/*---------------------------------------------------------------------------*/
667/*---------------------------------------------------------------------------*/
668
669void KeyValueTextReader::Impl::
670_readDirect(Int64 offset, Span<std::byte> bytes)
671{
672 m_reader.setFileOffset(offset);
673 std::istream& s = m_reader.stream();
674 binaryRead(s, bytes);
675 if (s.fail())
676 ARCANE_FATAL("Can not read file part offset={0} length={1}", offset, bytes.length());
677}
678
679/*---------------------------------------------------------------------------*/
680/*---------------------------------------------------------------------------*/
689{
691 Span<std::byte> bytes(header.bytes());
692 _readDirect(0, bytes);
693 header.checkHeader();
694 Int32 version = header.version();
695 if (version != m_version)
696 ARCANE_FATAL("Invalid version for ACR file version={0} expected={1}", version, m_version);
697}
698
699/*---------------------------------------------------------------------------*/
700/*---------------------------------------------------------------------------*/
701
702void KeyValueTextReader::Impl::
703_readJSON()
704{
705 // Les informations sur la position dans le fichier et la longueur du
706 // texte JSON sont sauvgegardées dans l'épilogue.
707 Int64 file_length = m_reader.fileLength();
708 // Vérifie la longueur du fichier par précaution
709 Int64 struct_size = BasicReaderWriterDatabaseEpilogFormat::STRUCT_SIZE;
711 ARCANE_FATAL("File is too short length={0} minimum={1}", file_length, struct_size);
712
714
715 // Lit l'épilogue et verifie que la version est supportée.
716 {
717 _readDirect(file_length - struct_size, epilog.bytes());
718 const int expected_version = 1;
719 if (epilog.version() != expected_version)
720 ARCANE_FATAL("Bad version for epilog version={0} expected={1}",
721 epilog.version(), expected_version);
722 }
723
725
726 // Lit les données JSON
727 {
728 Int64 file_offset = epilog.jsonDataInfoFileOffset();
729 Int64 meta_data_size = epilog.jsonDataInfoSize();
730 //std::cout << "FILE_INFO: offset=" << file_offset << " meta_data_size=" << meta_data_size << "\n";
732 _readDirect(file_offset, json_bytes);
733 }
734
735 // Remplit les infos de la base de données à partir du JSON
736 {
738 json_doc.parse(json_bytes);
739 JSONValue root = json_doc.root();
740 JSONValue data = root.child("Data");
741 UniqueArray<Int64> extents;
742 extents.reserve(12);
743 for (JSONValue v : data.valueAsArray()) {
744 String name = v.child("Name").value();
745 Int64 file_offset = v.child("FileOffset").valueAsInt64();
746 //std::cout << "Name=" << name << "\n";
747 //std::cout << "FileOffset=" << file_offset << "\n";
748 JSONValueList extents_info = v.child("Extents").valueAsArray();
749 extents.clear();
750 for (JSONValue v2 : extents_info) {
751 extents.add(v2.valueAsInt64());
752 }
753 Impl::DataInfo x;
754 x.m_file_offset = file_offset;
755 x.m_extents.fill(extents.view());
756 m_data_infos.insert(std::make_pair(name, x));
757 }
758 }
759}
760
761/*---------------------------------------------------------------------------*/
762/*---------------------------------------------------------------------------*/
763
764void KeyValueTextReader::
765getExtents(const String& key_name, SmallSpan<Int64> extents)
766{
767 Integer dimension_array_size = extents.size();
768 if (m_p->m_version >= 3) {
769 Impl::DataInfo& data = m_p->findData(key_name);
770 Impl::ExtentsInfo& exi = data.m_extents;
771 if (extents.size() != exi.size())
772 ARCANE_FATAL("Bad size for extents size={0} expected={1}", extents.size(), exi.size());
773 extents.copy(exi.view());
774 }
775 else {
776 if (m_p->m_version == 1) {
777 // Dans la version 1, les dimensions sont des 'Int32'
779 if (dimension_array_size > 0) {
780 dims.resize(dimension_array_size);
781 m_p->m_reader.read(asWritableBytes(dims));
782 }
783 for (Integer i = 0; i < dimension_array_size; ++i)
784 extents[i] = dims[i];
785 }
786 else {
787 if (dimension_array_size > 0) {
788 m_p->m_reader.read(asWritableBytes(extents));
789 }
790 }
791 }
792}
793
794/*---------------------------------------------------------------------------*/
795/*---------------------------------------------------------------------------*/
796
797void KeyValueTextReader::Impl::
798readIntegers(const String& key, Span<Integer> values)
799{
800 _setFileOffset(key);
801 m_reader.readIntegers(values);
802}
803
804/*---------------------------------------------------------------------------*/
805/*---------------------------------------------------------------------------*/
806
807void KeyValueTextReader::Impl::
808read(const String& key, Span<std::byte> values)
809{
810 _setFileOffset(key);
811
812 IDataCompressor* d = m_data_compressor.get();
813 Int64 len = values.size();
814 if (d && len > d->minCompressSize()) {
815 UniqueArray<std::byte> compressed_values;
816 Int64 compressed_size = 0;
817 m_reader.read(asWritableBytes(Span<Int64>(&compressed_size, 1)));
818 compressed_values.resize(compressed_size);
819 _read2(key, compressed_values);
820 m_data_compressor->decompress(compressed_values, values);
821 }
822 else {
823 _read2(key, values);
824 }
825}
826
827/*---------------------------------------------------------------------------*/
828/*---------------------------------------------------------------------------*/
829
830void KeyValueTextReader::Impl::
831_read2(const String& key, Span<std::byte> values)
832{
833 if (m_hash_database.get()) {
834 IHashAlgorithm* hash_algo = m_hash_algorithm.get();
835 if (!hash_algo)
836 ARCANE_FATAL("Can not use hash database without hash algorithm");
837 Int32 hash_size = hash_algo->hashSize();
838 SmallArray<Byte, 1024> hash_as_bytes;
839 hash_as_bytes.resize(hash_size);
840 m_reader.read(asWritableBytes(hash_as_bytes));
841 String hash_value = Convert::toHexaString(hash_as_bytes);
842 info(5) << "READ_KW_HASH key=" << key << " hash=" << hash_value << " expected_len=" << values.size();
843 HashDatabaseReadArgs args(hash_value, values);
844 m_hash_database->readValues(args);
845 }
846 else
847 m_reader.read(values);
848}
849
850/*---------------------------------------------------------------------------*/
851/*---------------------------------------------------------------------------*/
852
853void KeyValueTextReader::Impl::
854_setFileOffset(const String& key_name)
855{
856 // Avec les versions antérieures à la version 3, c'est l'appelant qui
857 // positionne l'offset car il est le seul à le connaitre.
858 if (m_version >= 3) {
859 Impl::DataInfo& data = findData(key_name);
860 m_reader.setFileOffset(data.m_file_offset);
861 }
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
867/*---------------------------------------------------------------------------*/
868/*---------------------------------------------------------------------------*/
869
870String KeyValueTextReader::
871fileName() const
872{
873 return m_p->m_reader.fileName();
874}
875
876/*---------------------------------------------------------------------------*/
877/*---------------------------------------------------------------------------*/
878
879void KeyValueTextReader::
880setFileOffset(Int64 v)
881{
882 m_p->m_reader.setFileOffset(v);
883}
884
885/*---------------------------------------------------------------------------*/
886/*---------------------------------------------------------------------------*/
887
888void KeyValueTextReader::
889setDataCompressor(Ref<IDataCompressor> ds)
890{
891 m_p->m_data_compressor = ds;
892}
893
894/*---------------------------------------------------------------------------*/
895/*---------------------------------------------------------------------------*/
896
897Ref<IDataCompressor> KeyValueTextReader::
898dataCompressor() const
899{
900 return m_p->m_data_compressor;
901}
902
903/*---------------------------------------------------------------------------*/
904/*---------------------------------------------------------------------------*/
905
906void KeyValueTextReader::
907setHashAlgorithm(Ref<IHashAlgorithm> v)
908{
909 m_p->m_hash_algorithm = v;
910}
911
912/*---------------------------------------------------------------------------*/
913/*---------------------------------------------------------------------------*/
914
915Ref<IHashAlgorithm> KeyValueTextReader::
916hashAlgorithm() const
917{
918 return m_p->m_hash_algorithm;
919}
920
921/*---------------------------------------------------------------------------*/
922/*---------------------------------------------------------------------------*/
923
924void KeyValueTextReader::
925readIntegers(const String& key, Span<Integer> values)
926{
927 m_p->readIntegers(key, values);
928}
929
930/*---------------------------------------------------------------------------*/
931/*---------------------------------------------------------------------------*/
932
933void KeyValueTextReader::
934read(const String& key, Span<std::byte> values)
935{
936 m_p->read(key, values);
937}
938
939/*---------------------------------------------------------------------------*/
940/*---------------------------------------------------------------------------*/
941
942} // End namespace Arcane::impl
943
944/*---------------------------------------------------------------------------*/
945/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Interface d'un algorithme de hashage.
virtual void computeHash64(Span< const Byte > input, ByteArray &output)
Calcule la valeur du hash pour le tableau input.
Gestion d'un document JSON.
Definition JSONReader.h:230
Liste de valeurs d'un document JSON.
Definition JSONReader.h:199
Représente une valeur JSON.
Definition JSONReader.h:43
JSONValue child(StringView name) const
Valeur fille de nom name. Retourne une valeur nulle si non trouvé.
Ecrivain au format JSON.
Definition JSONWriter.h:33
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Classe pour calculer le hash d'un tableau.
void _readHeader()
En-tête du format de fichier.
void _writeHeader()
En-tête du format de fichier.
Classe d'écriture d'un fichier texte pour les protections/reprises.
Definition TextReader2.h:38
Classe d'écriture d'un fichier texte pour les protections/reprises.
Definition TextWriter2.h:38
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > view() const
Vue mutable sur ce tableau.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
Vue sur une chaîne de caractères UTF-8.
Definition StringView.h:47
constexpr Span< const Byte > bytes() const ARCCORE_NOEXCEPT
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition StringView.h:96
constexpr Int64 size() const ARCCORE_NOEXCEPT
Longueur en octet de la chaîne de caractères.
Definition StringView.h:102
Chaîne de caractères unicode.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
Integer len(const char *s)
Retourne la longueur de la chaîne s.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
String toHexaString(ByteConstArrayView input)
Converti un tableau d'octet en sa représentation hexadécimale.
Definition Convert.cc:388
void arcaneCallFunctionAndTerminateIfThrow(std::function< void()> function)
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:638
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Definition UtilsTypes.h:519
Int32 Integer
Type représentant un entier.
detail::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets non modifiables.
Definition Span.h:881
detail::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets modifiables.
Definition Span.h:916
std::int32_t Int32
Type entier signé sur 32 bits.