Arcane  4.2.1.0
Developer documentation
Loading...
Searching...
No Matches
BasicGenericReader.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/* BasicGenericReader.cc (C) 2000-2026 */
9/* */
10/* Simple reading for protections/recoveries. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/internal/BasicReader.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/IDataCompressor.h"
19#include "arcane/utils/JSONReader.h"
20#include "arcane/utils/Ref.h"
21
22#include "arcane/core/IApplication.h"
23#include "arcane/core/IXmlDocumentHolder.h"
24#include "arcane/core/IIOMng.h"
25#include "arcane/core/IData.h"
26#include "arcane/core/ArcaneException.h"
27#include "arcane/core/ISerializedData.h"
28#include "arcane/core/XmlNodeList.h"
29
30#include <fstream>
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane::impl
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41BasicGenericReader::
42BasicGenericReader(IApplication* app, Int32 version, Ref<KeyValueTextReader> text_reader)
43: TraceAccessor(app->traceMng())
44, m_application(app)
45, m_text_reader(text_reader)
46, m_version(version)
47{
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53void BasicGenericReader::
54initialize(const String& path, Int32 rank)
55{
56 // In the case of version 1 or 2, we cannot create the KeyValueTextReader
57 // before reading 'OwnMetaData' because they contain
58 // the version number.
59
60 m_path = path;
61 m_rank = rank;
62
63 info(4) << "BasicGenericReader::initialize known_version=" << m_version;
64
65 ScopedPtrT<IXmlDocumentHolder> xdoc;
66
67 if (m_version >= 3) {
68 if (!m_text_reader.get())
69 ARCANE_FATAL("Null text reader");
70 String dc_name;
71 if (m_text_reader->dataCompressor().get())
72 dc_name = m_text_reader->dataCompressor()->name();
73 info(4) << "BasicGenericReader::initialize data_compressor=" << dc_name;
74
75 // If we already know the version and it is greater than or equal to 3
76 // then the information is in the database. In this case we read
77 // the info directly from this database.
78 String main_filename = BasicReaderWriterCommon::_getBasicVariableFile(m_version, m_path, rank);
79 Int64 meta_data_size = 0;
80 String key_name = "Global:OwnMetadata";
81 m_text_reader->getExtents(key_name, Int64ArrayView(1, &meta_data_size));
82 UniqueArray<std::byte> bytes(meta_data_size);
83 m_text_reader->read(key_name, bytes);
84 info(4) << "Reading own metadata rank=" << rank << " from database";
85 xdoc = IXmlDocumentHolder::loadFromBuffer(bytes, "OwnMetadata", traceMng());
86 }
87 else {
88 StringBuilder filename = BasicReaderWriterCommon::_getOwnMetatadaFile(m_path, m_rank);
89 info(4) << "Reading own metadata rank=" << rank << " file=" << filename;
90 IApplication* app = m_application;
91 xdoc = app->ioMng()->parseXmlFile(filename);
92 }
93 XmlNode root = xdoc->documentNode().documentElement();
94 XmlNodeList variables_elem = root.children("variable-data");
95 String deflater_name = root.attrValue("deflater-service");
96 String hash_algorithm_name = root.attrValue("hash-algorithm-service");
97 String version_id = root.attrValue("version", false);
98 info(4) << "Infos from metadata deflater-service=" << deflater_name
99 << " hash-algorithm-service=" << hash_algorithm_name
100 << " version=" << version_id;
101 if (version_id.null() || version_id == "1")
102 // Version 1:
103 // - dimension size in 32 bits
104 m_version = 1;
105 else if (version_id == "2")
106 // Version 2:
107 // - dimension size in 64 bits
108 m_version = 2;
109 else if (version_id == "3")
110 // Version 3:
111 // - dimension size in 64 bits
112 // - only 1 file for all metadata
113 m_version = 3;
114 else
115 ARCANE_FATAL("Unsupported version '{0}' (max=3)", version_id);
116
117 Ref<IDataCompressor> deflater;
118 if (!deflater_name.null())
119 deflater = BasicReaderWriterCommon::_createDeflater(m_application, deflater_name);
120
121 Ref<IHashAlgorithm> hash_algorithm;
122 if (!hash_algorithm_name.null())
123 hash_algorithm = BasicReaderWriterCommon::_createHashAlgorithm(m_application, hash_algorithm_name);
124
125 // If available, try to reread the variable information in JSON format
126 bool do_json = true;
127 String json_variables_elem = root.child("variables-data-json").value();
128 if (do_json && !json_variables_elem.empty()) {
129 JSONDocument json_doc;
130 json_doc.parse(json_variables_elem.bytes(), "Internal variables data");
131 JSONValue json_root = json_doc.root();
132 JSONValue json_vars = json_root.expectedChild("Variables");
133 for (JSONKeyValue kv : json_vars.keyValueChildren()) {
134 String var_full_name = kv.name();
135 m_variables_data_info.add(var_full_name, kv.value());
136 }
137 }
138 else {
139 for (const XmlNode& n : variables_elem) {
140 String var_full_name = n.attrValue("full-name");
141 m_variables_data_info.add(var_full_name, n);
142 }
143 }
144
145 if (!m_text_reader.get()) {
146 String main_filename = BasicReaderWriterCommon::_getBasicVariableFile(m_version, m_path, rank);
147 m_text_reader = makeRef(new KeyValueTextReader(traceMng(), main_filename, m_version));
148 }
149
150 // There might already be a compression algorithm specified.
151 // It should not be overwritten if none is specified in 'OwnMetadata'.
152 // (Normally this should not happen unless there is an inconsistency).
153 if (deflater.get())
154 m_text_reader->setDataCompressor(deflater);
155 if (hash_algorithm.get())
156 m_text_reader->setHashAlgorithm(hash_algorithm);
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
162Ref<VariableDataInfo> BasicGenericReader::
163_getVarInfo(const String& full_name)
164{
165 Ref<VariableDataInfo> vdi = m_variables_data_info.find(full_name);
166 if (!vdi.get())
167 ARCANE_THROW(ReaderWriterException,
168 "Can not find own metadata infos for data var={0} rank={1}", full_name, m_rank);
169 return vdi;
170}
171
172/*---------------------------------------------------------------------------*/
173/*---------------------------------------------------------------------------*/
174
175void BasicGenericReader::
176readData(const String& var_full_name, IData* data)
177{
178 KeyValueTextReader* reader = m_text_reader.get();
179 String vname = var_full_name;
180 Ref<VariableDataInfo> vdi = _getVarInfo(vname);
181 if (m_version < 3)
182 reader->setFileOffset(vdi->fileOffset());
183
184 eDataType data_type = vdi->baseDataType();
185 Int64 memory_size = vdi->memorySize();
186 Integer dimension_array_size = vdi->dimensionArraySize();
187 Int64 nb_element = vdi->nbElement();
188 Integer nb_dimension = vdi->nbDimension();
189 Int64 nb_base_element = vdi->nbBaseElement();
190 bool is_multi_size = vdi->isMultiSize();
191 UniqueArray<Int64> extents(dimension_array_size);
192 reader->getExtents(var_full_name, extents.view());
193 ArrayShape shape = vdi->shape();
194
195 Ref<ISerializedData> sd(arcaneCreateSerializedDataRef(data_type, memory_size, nb_dimension, nb_element,
196 nb_base_element, is_multi_size, extents, shape));
197
198 Int64 storage_size = sd->memorySize();
199 info(4) << " READ DATA storage_size=" << storage_size << " DATA=" << data;
200
201 data->allocateBufferForSerializedData(sd.get());
202
203 if (storage_size != 0)
204 reader->read(var_full_name, asWritableBytes(sd->writableBytes()));
205
206 data->assignSerializedData(sd.get());
207}
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
211
212void BasicGenericReader::
213readItemGroup(const String& group_full_name, Int64Array& written_unique_ids,
214 Int64Array& wanted_unique_ids)
215{
216 if (m_version >= 3) {
217 {
218 String written_uid_name = String("GroupWrittenUid:") + group_full_name;
219 Int64 nb_written_uid = 0;
220 m_text_reader->getExtents(written_uid_name, Int64ArrayView(1, &nb_written_uid));
221 written_unique_ids.resize(nb_written_uid);
222 m_text_reader->read(written_uid_name, asWritableBytes(written_unique_ids.span()));
223 }
224 {
225 String wanted_uid_name = String("GroupWantedUid:") + group_full_name;
226 Int64 nb_wanted_uid = 0;
227 m_text_reader->getExtents(wanted_uid_name, Int64ArrayView(1, &nb_wanted_uid));
228 wanted_unique_ids.resize(nb_wanted_uid);
229 m_text_reader->read(wanted_uid_name, asWritableBytes(wanted_unique_ids.span()));
230 }
231 return;
232 }
233
234 info(5) << "READ GROUP " << group_full_name;
235 String filename = BasicReaderWriterCommon::_getBasicGroupFile(m_path, group_full_name, m_rank);
236 std::ifstream reader(filename.localstr(), std::ios::in | std::ios::binary);
237
238 {
239 Integer nb_unique_id = 0;
240 binaryRead(reader, asWritableBytes(SmallSpan<Integer>(&nb_unique_id, 1)));
241 info(5) << "NB_WRITTEN_UNIQUE_ID = " << nb_unique_id;
242 written_unique_ids.resize(nb_unique_id);
243 binaryRead(reader, asWritableBytes(written_unique_ids.span()));
244 }
245
246 {
247 Integer nb_unique_id = 0;
248 binaryRead(reader, asWritableBytes(SmallSpan<Integer>(&nb_unique_id, 1)));
249 info(5) << "NB_WANTED_UNIQUE_ID = " << nb_unique_id;
250 wanted_unique_ids.resize(nb_unique_id);
251 binaryRead(reader, asWritableBytes(wanted_unique_ids.span()));
252 }
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258String BasicGenericReader::
259comparisonHashValue(const String& var_full_name) const
260{
261 Ref<VariableDataInfo> vdi = m_variables_data_info.find(var_full_name);
262 if (vdi.get())
263 return vdi->comparisonHashValue();
264 return {};
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270} // namespace Arcane::impl
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:445
Ref< ISerializedData > arcaneCreateSerializedDataRef(eDataType data_type, Int64 memory_size, Integer nb_dim, Int64 nb_element, Int64 nb_base_element, bool is_multi_size, Int64ConstArrayView dimensions)
Creates serialized data.
Int32 Integer
Type representing an integer.
void binaryRead(std::istream &istr, const Span< std::byte > &bytes)
Reads the content of bytes from the stream istr in binary format.
Definition ArrayView.cc:102
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
Impl::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of modifiable bytes.
Definition Span.h:1066
eDataType
Data type.
Definition DataTypes.h:41
std::int32_t Int32
Signed integer type of 32 bits.